From 86ebfe002920c05d8193bbf775758a49b31edaa1 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Feb 2023 19:02:48 +0700 Subject: [PATCH 001/228] refactoring of document --- .../document_type/random_document.rs | 44 +- .../src/data_trigger/dpns_triggers/mod.rs | 11 +- .../reward_share_data_triggers/mod.rs | 27 +- .../{document_stub.rs => document.rs} | 239 +------- .../rs-dpp/src/document/document_factory.rs | 27 +- packages/rs-dpp/src/document/errors.rs | 10 +- .../fetch_and_validate_data_contract.rs | 2 +- packages/rs-dpp/src/document/mod.rs | 498 +---------------- packages/rs-dpp/src/document/serialize.rs | 256 ++++++++- ...pply_documents_batch_transition_factory.rs | 23 +- .../document_in_state_transition.rs | 512 ++++++++++++++++++ .../document_transition/mod.rs | 1 + .../validation/state/fetch_documents.rs | 15 +- ...lidate_documents_batch_transition_state.rs | 13 +- ...alidate_documents_uniqueness_by_indices.rs | 10 +- packages/rs-dpp/src/lib.rs | 2 +- packages/rs-dpp/src/state_repository.rs | 6 +- ...e_documents_batch_transition_state_spec.rs | 60 +- ...te_documents_uniqueness_by_indices_spec.rs | 36 +- .../validate_partial_compound_indices_spec.rs | 4 +- .../get_document_transitions_fixture.rs | 7 +- .../tests/fixtures/get_documents_fixture.rs | 8 +- .../fixtures/get_dpns_document_fixture.rs | 7 +- ...ternode_reward_shares_documents_fixture.rs | 7 +- .../src/contracts/reward_shares.rs | 8 +- packages/rs-drive-abci/src/state/genesis.rs | 9 +- .../src/test/helpers/fee_pools.rs | 8 +- .../tests/strategy_tests/main.rs | 4 +- packages/rs-drive/benches/benchmarks.rs | 6 +- .../drive/batch/drive_op_batch/document.rs | 14 +- .../src/drive/batch/drive_op_batch/mod.rs | 26 +- .../rs-drive/src/drive/document/delete.rs | 26 +- .../rs-drive/src/drive/document/insert.rs | 17 +- packages/rs-drive/src/drive/document/mod.rs | 4 +- .../rs-drive/src/drive/document/update.rs | 25 +- .../rs-drive/src/drive/object_size_info.rs | 12 +- packages/rs-drive/src/query/conditions.rs | 4 +- packages/rs-drive/src/query/mod.rs | 16 +- .../rs-drive/tests/deterministic_root_hash.rs | 4 +- packages/rs-drive/tests/query_tests.rs | 106 ++-- .../rs-drive/tests/query_tests_history.rs | 44 +- .../errors/mismatch_owners_ids_error.rs | 4 +- packages/wasm-dpp/src/document/factory.rs | 6 +- packages/wasm-dpp/src/document/mod.rs | 31 +- .../document_batch_transition/mod.rs | 15 +- packages/wasm-dpp/src/state_repository.rs | 6 +- 46 files changed, 1133 insertions(+), 1087 deletions(-) rename packages/rs-dpp/src/document/{document_stub.rs => document.rs} (50%) create mode 100644 packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs diff --git a/packages/rs-dpp/src/data_contract/document_type/random_document.rs b/packages/rs-dpp/src/data_contract/document_type/random_document.rs index 4657f758175..2a3fada856a 100644 --- a/packages/rs-dpp/src/data_contract/document_type/random_document.rs +++ b/packages/rs-dpp/src/data_contract/document_type/random_document.rs @@ -34,7 +34,7 @@ //! use crate::data_contract::document_type::DocumentType; -use crate::document::document_stub::DocumentStub; +use crate::document::Document; use crate::ProtocolError; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; @@ -43,26 +43,26 @@ use rand::{Rng, SeedableRng}; /// Functions for creating various types of random documents. pub trait CreateRandomDocument { /// Random documents - fn random_documents(&self, count: u32, seed: Option) -> Vec; + fn random_documents(&self, count: u32, seed: Option) -> Vec; /// Random documents with rng - fn random_documents_with_rng(&self, count: u32, rng: &mut StdRng) -> Vec; + fn random_documents_with_rng(&self, count: u32, rng: &mut StdRng) -> Vec; /// Document from bytes - fn document_from_bytes(&self, bytes: &[u8]) -> Result; + fn document_from_bytes(&self, bytes: &[u8]) -> Result; /// Random document - fn random_document(&self, seed: Option) -> DocumentStub; + fn random_document(&self, seed: Option) -> Document; /// Random document with rng - fn random_document_with_rng(&self, rng: &mut StdRng) -> DocumentStub; + fn random_document_with_rng(&self, rng: &mut StdRng) -> Document; /// Random filled documents - fn random_filled_documents(&self, count: u32, seed: Option) -> Vec; + fn random_filled_documents(&self, count: u32, seed: Option) -> Vec; /// Random filled document - fn random_filled_document(&self, seed: Option) -> DocumentStub; + fn random_filled_document(&self, seed: Option) -> Document; /// Random filled document with rng - fn random_filled_document_with_rng(&self, rng: &mut StdRng) -> DocumentStub; + fn random_filled_document_with_rng(&self, rng: &mut StdRng) -> Document; } impl CreateRandomDocument for DocumentType { /// Creates `count` Documents with random data using a seed if given, otherwise entropy. - fn random_documents(&self, count: u32, seed: Option) -> Vec { + fn random_documents(&self, count: u32, seed: Option) -> Vec { let mut rng = match seed { None => StdRng::from_entropy(), Some(seed_value) => StdRng::seed_from_u64(seed_value), @@ -71,8 +71,8 @@ impl CreateRandomDocument for DocumentType { } /// Creates `count` Documents with random data using the random number generator given. - fn random_documents_with_rng(&self, count: u32, rng: &mut StdRng) -> Vec { - let mut vec: Vec = vec![]; + fn random_documents_with_rng(&self, count: u32, rng: &mut StdRng) -> Vec { + let mut vec: Vec = vec![]; for _i in 0..count { vec.push(self.random_document_with_rng(rng)); } @@ -80,12 +80,12 @@ impl CreateRandomDocument for DocumentType { } /// Creates a Document from a serialized Document. - fn document_from_bytes(&self, bytes: &[u8]) -> Result { - DocumentStub::from_bytes(bytes, self) + fn document_from_bytes(&self, bytes: &[u8]) -> Result { + Document::from_bytes(bytes, self) } /// Creates a random Document using a seed if given, otherwise entropy. - fn random_document(&self, seed: Option) -> DocumentStub { + fn random_document(&self, seed: Option) -> Document { let mut rng = match seed { None => StdRng::from_entropy(), Some(seed_value) => StdRng::seed_from_u64(seed_value), @@ -94,7 +94,7 @@ impl CreateRandomDocument for DocumentType { } /// Creates a document with a random id, owner id, and properties using StdRng. - fn random_document_with_rng(&self, rng: &mut StdRng) -> DocumentStub { + fn random_document_with_rng(&self, rng: &mut StdRng) -> Document { let id = rng.gen::<[u8; 32]>(); let owner_id = rng.gen::<[u8; 32]>(); let properties = self @@ -105,7 +105,7 @@ impl CreateRandomDocument for DocumentType { }) .collect(); - DocumentStub { + Document { id, properties, owner_id, @@ -114,12 +114,12 @@ impl CreateRandomDocument for DocumentType { /// Creates `count` Documents with properties filled to max size with random data, along with /// a random id and owner id, using a seed if provided, otherwise entropy. - fn random_filled_documents(&self, count: u32, seed: Option) -> Vec { + fn random_filled_documents(&self, count: u32, seed: Option) -> Vec { let mut rng = match seed { None => rand::rngs::StdRng::from_entropy(), Some(seed_value) => rand::rngs::StdRng::seed_from_u64(seed_value), }; - let mut vec: Vec = vec![]; + let mut vec: Vec = vec![]; for _i in 0..count { vec.push(self.random_filled_document_with_rng(&mut rng)); } @@ -128,7 +128,7 @@ impl CreateRandomDocument for DocumentType { /// Creates a Document with properties filled to max size with random data, along with /// a random id and owner id, using a seed if provided, otherwise entropy. - fn random_filled_document(&self, seed: Option) -> DocumentStub { + fn random_filled_document(&self, seed: Option) -> Document { let mut rng = match seed { None => rand::rngs::StdRng::from_entropy(), Some(seed_value) => rand::rngs::StdRng::seed_from_u64(seed_value), @@ -138,7 +138,7 @@ impl CreateRandomDocument for DocumentType { /// Creates a Document with properties filled to max size with random data, along with /// a random id and owner id. - fn random_filled_document_with_rng(&self, rng: &mut StdRng) -> DocumentStub { + fn random_filled_document_with_rng(&self, rng: &mut StdRng) -> Document { let id = rng.gen::<[u8; 32]>(); let owner_id = rng.gen::<[u8; 32]>(); let properties = self @@ -152,7 +152,7 @@ impl CreateRandomDocument for DocumentType { }) .collect(); - DocumentStub { + Document { id, properties, owner_id, diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index e3df53d2b20..87da0c8061a 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -2,7 +2,7 @@ use anyhow::Context; use anyhow::{anyhow, bail}; use serde_json::{json, Value as JsonValue}; -use crate::document::Document; +use crate::document::DocumentInStateTransition; use crate::util::hash::hash; use crate::util::string_encoding::Encoding; use crate::{ @@ -132,7 +132,7 @@ where let parent_domain_label = parent_domain_segments.next().unwrap().to_string(); let grand_parent_domain_name = parent_domain_segments.collect::>().join("."); - let documents: Vec = context + let documents: Vec = context .state_repository .fetch_documents( &context.data_contract.id, @@ -191,7 +191,7 @@ where let salted_domain_hash = hash(salted_domain_buffer); - let preorder_documents: Vec = context + let preorder_documents: Vec = context .state_repository .fetch_documents( &context.data_contract.id, @@ -222,9 +222,10 @@ where #[cfg(test)] mod test { + use crate::document::DocumentInStateTransition; use crate::{ data_trigger::DataTriggerExecutionContext, - document::{document_transition::Action, Document}, + document::document_transition::Action, state_repository::MockStateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, tests::{ @@ -252,7 +253,7 @@ mod test { let first_transition = transitions.get(0).expect("transition should be present"); state_repository - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(|_, _, _, _| Ok(vec![])); transition_execution_context.enable_dry_run(); diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 35ceca53453..a0f5be76731 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -1,9 +1,10 @@ use anyhow::{anyhow, bail}; use serde_json::json; +use crate::document::DocumentInStateTransition; use crate::{ data_trigger::create_error, - document::{document_transition::DocumentTransition, Document}, + document::document_transition::DocumentTransition, get_from_transition, mocks::SMLStore, prelude::Identifier, @@ -87,7 +88,7 @@ where result.add_error(err.into()) } - let documents: Vec = context + let documents: Vec = context .state_repository .fetch_documents( &context.data_contract.id, @@ -139,14 +140,12 @@ mod test { use itertools::Itertools; use serde_json::json; + use crate::document::DocumentInStateTransition; use crate::identity::Identity; use crate::{ data_contract::DataContract, data_trigger::DataTriggerExecutionContext, - document::{ - document_transition::{Action, DocumentTransition, DocumentTransitionExt}, - Document, - }, + document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, mocks::{SMLEntry, SMLStore, SimplifiedMNList}, prelude::Identifier, state_repository::MockStateRepositoryLike, @@ -164,7 +163,7 @@ mod test { top_level_identifier: Identifier, data_contract: DataContract, sml_store: SMLStore, - documents: Vec, + documents: Vec, document_transition: DocumentTransition, identity: Identity, } @@ -296,7 +295,7 @@ mod test { .expect_fetch_identity() .returning(move |_, _| Ok(None)); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let execution_context = StateTransitionExecutionContext::default(); @@ -344,7 +343,7 @@ mod test { .expect_fetch_identity() .returning(move |_, _| Ok(None)); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let execution_context = StateTransitionExecutionContext::default(); @@ -384,7 +383,7 @@ mod test { .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let execution_context = StateTransitionExecutionContext::default(); @@ -419,9 +418,11 @@ mod test { state_repository_mock .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); - let documents_to_return: Vec = (0..16).map(|_| Document::default()).collect(); + let documents_to_return: Vec = (0..16) + .map(|_| DocumentInStateTransition::default()) + .collect(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .return_once(move |_, _, _, _| Ok(documents_to_return)); let execution_context = StateTransitionExecutionContext::default(); @@ -457,7 +458,7 @@ mod test { .expect_fetch_identity() .returning(move |_, _| Ok(None)); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let execution_context = StateTransitionExecutionContext::default(); diff --git a/packages/rs-dpp/src/document/document_stub.rs b/packages/rs-dpp/src/document/document.rs similarity index 50% rename from packages/rs-dpp/src/document/document_stub.rs rename to packages/rs-dpp/src/document/document.rs index b0cdc4d7f30..30f57313f00 100644 --- a/packages/rs-dpp/src/document/document_stub.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -43,7 +43,6 @@ use integer_encoding::VarIntWriter; use crate::data_contract::{DataContract, DriveContractExt}; use serde::{Deserialize, Serialize}; -use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::data_contract::errors::{DataContractError, StructureError}; use crate::data_contract::extra::common::{ @@ -54,10 +53,9 @@ use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::ProtocolError; -//todo: rename /// Documents contain the data that goes into data contracts. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct DocumentStub { +pub struct Document { /// The unique document ID. #[serde(rename = "$id")] pub id: [u8; 32], @@ -71,236 +69,7 @@ pub struct DocumentStub { pub owner_id: [u8; 32], } -impl DocumentStub { - /// Serializes the document. - /// - /// The serialization of a document follows the pattern: - /// id 32 bytes + owner_id 32 bytes + encoded values byte arrays - pub fn serialize(&self, document_type: &DocumentType) -> Result, ProtocolError> { - let mut buffer: Vec = self.id.as_slice().to_vec(); - buffer.extend(self.owner_id.as_slice()); - document_type - .properties - .iter() - .try_for_each(|(field_name, field)| { - if let Some(value) = self.properties.get(field_name) { - let value = field - .document_type - .encode_value_ref_with_size(value, field.required)?; - buffer.extend(value.as_slice()); - Ok(()) - } else if field.required { - Err(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey("a required field is not present"), - )) - } else { - // We don't have something that wasn't required - buffer.push(0); - Ok(()) - } - })?; - Ok(buffer) - } - - /// Serializes and consumes the document. - /// - /// The serialization of a document follows the pattern: - /// id 32 bytes + owner_id 32 bytes + encoded values byte arrays - pub fn serialize_consume( - mut self, - document_type: &DocumentType, - ) -> Result, ProtocolError> { - let mut buffer: Vec = Vec::try_from(self.id).unwrap(); - let mut owner_id = Vec::try_from(self.owner_id).unwrap(); - buffer.append(&mut owner_id); - document_type - .properties - .iter() - .try_for_each(|(field_name, field)| { - if let Some(value) = self.properties.remove(field_name) { - let value = field - .document_type - .encode_value_with_size(value, field.required)?; - buffer.extend(value.as_slice()); - Ok(()) - } else if field.required { - Err(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey("a required field is not present"), - )) - } else { - // We don't have something that wasn't required - buffer.push(0); - Ok(()) - } - })?; - Ok(buffer) - } - - /// Reads a serialized document and creates a Document from it. - pub fn from_bytes( - serialized_document: &[u8], - document_type: &DocumentType, - ) -> Result { - let mut buf = BufReader::new(serialized_document); - if serialized_document.len() < 64 { - return Err(ProtocolError::DecodingError( - "serialized document is too small, must have id and owner id".to_string(), - )); - } - let mut id = [0; 32]; - buf.read_exact(&mut id).map_err(|_| { - ProtocolError::DecodingError("error reading from serialized document".to_string()) - })?; - - let mut owner_id = [0; 32]; - buf.read_exact(&mut owner_id).map_err(|_| { - ProtocolError::DecodingError("error reading from serialized document".to_string()) - })?; - - let properties = document_type - .properties - .iter() - .filter_map(|(key, field)| { - let read_value = field.document_type.read_from(&mut buf, field.required); - match read_value { - Ok(read_value) => read_value.map(|read_value| Ok((key.clone(), read_value))), - Err(e) => Some(Err(e)), - } - }) - .collect::, ProtocolError>>()?; - Ok(DocumentStub { - id, - properties, - owner_id, - }) - } - - /// Reads a CBOR-serialized document and creates a Document from it. - /// If Document and Owner IDs are provided, they are used, otherwise they are created. - pub fn from_cbor( - document_cbor: &[u8], - document_id: Option<[u8; 32]>, - owner_id: Option<[u8; 32]>, - ) -> Result { - let SplitProtocolVersionOutcome { - main_message_bytes: read_document_cbor, - .. - } = deserializer::split_protocol_version(document_cbor)?; - - // first we need to deserialize the document and contract indices - // we would need dedicated deserialization functions based on the document type - let mut document: BTreeMap = ciborium::de::from_reader(read_document_cbor) - .map_err(|_| { - ProtocolError::StructureError(StructureError::InvalidCBOR( - "unable to decode contract for document call", - )) - })?; - - let owner_id: [u8; 32] = match owner_id { - None => { - let owner_id: Vec = - bytes_for_system_value_from_tree_map(&document, "$ownerId")?.ok_or({ - ProtocolError::DataContractError(DataContractError::DocumentOwnerIdMissing( - "unable to get document $ownerId", - )) - })?; - document.remove("$ownerId"); - if owner_id.len() != 32 { - return Err(ProtocolError::DataContractError( - DataContractError::FieldRequirementUnmet("invalid owner id"), - )); - } - owner_id.as_slice().try_into() - } - Some(owner_id) => Ok(owner_id), - } - .expect("conversion to 32bytes shouldn't fail"); - - let id: [u8; 32] = match document_id { - None => { - let document_id: Vec = bytes_for_system_value_from_tree_map(&document, "$id")? - .ok_or({ - ProtocolError::DataContractError(DataContractError::DocumentIdMissing( - "unable to get document $id", - )) - })?; - document.remove("$id"); - if document_id.len() != 32 { - return Err(ProtocolError::DataContractError( - DataContractError::FieldRequirementUnmet("invalid document id"), - )); - } - document_id.as_slice().try_into() - } - Some(document_id) => { - // we need to start by verifying that the document_id is a 256 bit number (32 bytes) - Ok(document_id) - } - } - .expect("document_id must be 32 bytes"); - - // dev-note: properties is everything other than the id and owner id - Ok(DocumentStub { - properties: document, - owner_id, - id, - }) - } - - /// Reads a CBOR-serialized document and creates a Document from it with the provided IDs. - pub fn from_cbor_with_id( - document_cbor: &[u8], - document_id: &[u8], - owner_id: &[u8], - ) -> Result { - // we need to start by verifying that the owner_id is a 256 bit number (32 bytes) - if owner_id.len() != 32 { - return Err(ProtocolError::DataContractError( - DataContractError::FieldRequirementUnmet("invalid owner id"), - )); - } - - if document_id.len() != 32 { - return Err(ProtocolError::DataContractError( - DataContractError::FieldRequirementUnmet("invalid document id"), - )); - } - let SplitProtocolVersionOutcome { - main_message_bytes: read_document_cbor, - .. - } = deserializer::split_protocol_version(document_cbor)?; - - // first we need to deserialize the document and contract indices - // we would need dedicated deserialization functions based on the document type - let properties: BTreeMap = ciborium::de::from_reader(read_document_cbor) - .map_err(|_| { - ProtocolError::StructureError(StructureError::InvalidCBOR( - "unable to decode contract for document call with id", - )) - })?; - - // dev-note: properties is everything other than the id and owner id - Ok(DocumentStub { - properties, - owner_id: owner_id - .try_into() - .expect("try_into shouldn't fail, document_id must be 32 bytes"), - id: document_id - .try_into() - .expect("try_into shouldn't fail, document_id must be 32 bytes"), - }) - } - - /// Serializes the Document to CBOR. - pub fn to_cbor(&self) -> Vec { - let mut buffer: Vec = Vec::new(); - buffer - .write_varint(PROTOCOL_VERSION) - .expect("writing protocol version caused error"); - ciborium::ser::into_writer(&self, &mut buffer).expect("unable to serialize into cbor"); - buffer - } - +impl Document { /// Return a value given the path to its key for a document type. pub fn get_raw_for_document_type<'a>( &'a self, @@ -385,7 +154,7 @@ impl DocumentStub { } } -impl fmt::Display for DocumentStub { +impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "id:{} ", bs58::encode(self.id).into_string())?; write!(f, "owner_id:{} ", bs58::encode(self.owner_id).into_string())?; @@ -455,7 +224,7 @@ mod tests { let document_cbor = document.to_cbor(); - let recovered_document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let recovered_document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("expected to get document"); assert_eq!(recovered_document, document); diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 3ab5b588701..9fd29ae47cd 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -4,6 +4,9 @@ use itertools::Itertools; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; +use crate::document::document_transition::document_in_state_transition::{ + property_names, DocumentInStateTransition, +}; use crate::{ data_contract::{errors::DataContractError, DataContract}, decode_protocol_entity_factory::DecodeProtocolEntity, @@ -20,7 +23,7 @@ use super::{ errors::DocumentError, fetch_and_validate_data_contract::DataContractFetcherAndValidator, generate_document_id::generate_document_id, - property_names, Document, DocumentsBatchTransition, + DocumentsBatchTransition, }; // TODO remove these const and use ones from super::document::property_names @@ -93,7 +96,7 @@ where owner_id: Identifier, document_type: String, data: JsonValue, - ) -> Result { + ) -> Result { if !data_contract.is_document_defined(&document_type) { return Err(DataContractError::InvalidDocumentTypeError { doc_type: document_type, @@ -151,7 +154,8 @@ where ))); } - let mut document = Document::from_raw_document(raw_document, data_contract)?; + let mut document = + DocumentInStateTransition::from_raw_document(raw_document, data_contract)?; document.entropy = document_entropy; Ok(document) @@ -159,11 +163,12 @@ where pub fn create_state_transition( &self, - documents_iter: impl IntoIterator)>, + documents_iter: impl IntoIterator)>, ) -> Result { let mut raw_documents_transitions: Vec = vec![]; let mut data_contracts: Vec = vec![]; - let documents: Vec<(Action, Vec)> = documents_iter.into_iter().collect(); + let documents: Vec<(Action, Vec)> = + documents_iter.into_iter().collect(); let flattened_documents_iter = documents.iter().flat_map(|(_, v)| v); if Self::is_empty(flattened_documents_iter.clone()) { @@ -214,7 +219,7 @@ where &self, buffer: impl AsRef<[u8]>, options: FactoryOptions, - ) -> Result { + ) -> Result { let result = DecodeProtocolEntity::decode_protocol_entity(buffer); match result { @@ -238,12 +243,12 @@ where &self, raw_document: JsonValue, options: FactoryOptions, - ) -> Result { + ) -> Result { let data_contract = self .validate_data_contract_for_document(&raw_document, options) .await?; - Document::from_raw_document(raw_document, data_contract) + DocumentInStateTransition::from_raw_document(raw_document, data_contract) } async fn validate_data_contract_for_document( @@ -286,7 +291,7 @@ where } fn raw_document_create_transitions( - documents: Vec, + documents: Vec, ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { @@ -318,7 +323,7 @@ where } fn raw_document_replace_transitions( - documents: Vec, + documents: Vec, ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { @@ -349,7 +354,7 @@ where } fn raw_document_delete_transitions( - documents: Vec, + documents: Vec, ) -> Result, ProtocolError> { Ok(documents .into_iter() diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index 1d49e05a1ea..564cc523fce 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -4,7 +4,7 @@ use thiserror::Error; use crate::errors::consensus::ConsensusError; use super::document_transition::DocumentTransition; -use super::Document; +use crate::document::DocumentInStateTransition; #[derive(Error, Debug)] pub enum DocumentError { @@ -28,10 +28,14 @@ pub enum DocumentError { raw_document: Value, }, #[error("Invalid Document initial revision '{}'", document.revision)] - InvalidInitialRevisionError { document: Box }, + InvalidInitialRevisionError { + document: Box, + }, #[error("Documents have mixed owner ids")] - MismatchOwnerIdsError { documents: Vec }, + MismatchOwnerIdsError { + documents: Vec, + }, #[error("No documents were supplied to state transition")] NoDocumentsSuppliedError, diff --git a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs index fd40405dedd..2b4cd4272c3 100644 --- a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs +++ b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs @@ -13,7 +13,7 @@ use crate::{ ProtocolError, }; -use super::property_names; +use crate::document::document_transition::document_in_state_transition::property_names; pub struct DataContractFetcherAndValidator { state_repository: Arc, diff --git a/packages/rs-dpp/src/document/mod.rs b/packages/rs-dpp/src/document/mod.rs index 81afa957835..49f5f229f67 100644 --- a/packages/rs-dpp/src/document/mod.rs +++ b/packages/rs-dpp/src/document/mod.rs @@ -21,8 +21,8 @@ use crate::util::hash::hash; use crate::util::json_value::{JsonValueExt, ReplaceWith}; use crate::util::{cbor_value, deserializer}; +mod document; pub mod document_factory; -pub mod document_stub; pub mod document_validator; pub mod errors; pub mod fetch_and_validate_data_contract; @@ -30,495 +30,7 @@ pub mod generate_document_id; pub mod serialize; pub mod state_transition; -pub mod property_names { - pub const PROTOCOL_VERSION: &str = "$protocolVersion"; - pub const ID: &str = "$id"; - pub const DOCUMENT_TYPE: &str = "$type"; - pub const REVISION: &str = "$revision"; - pub const DATA_CONTRACT_ID: &str = "$dataContractId"; - pub const OWNER_ID: &str = "$ownerId"; - pub const CREATED_AT: &str = "$createdAt"; - pub const UPDATED_AT: &str = "$updatedAt"; -} - -pub const IDENTIFIER_FIELDS: [&str; 3] = [ - property_names::ID, - property_names::DATA_CONTRACT_ID, - property_names::OWNER_ID, -]; - -/// The document object represents the data provided by the platform in response to a query. -#[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct Document { - #[serde(rename = "$protocolVersion")] - pub protocol_version: u32, - #[serde(rename = "$id")] - pub id: Identifier, - #[serde(rename = "$type")] - /// TODO: Why not &str? - pub document_type: String, - #[serde(rename = "$revision")] - pub revision: u32, - #[serde(rename = "$dataContractId")] - pub data_contract_id: Identifier, - #[serde(rename = "$ownerId")] - pub owner_id: Identifier, - #[serde(rename = "$createdAt", skip_serializing_if = "Option::is_none")] - // TODO: Must be TimestampMillis - pub created_at: Option, - #[serde(rename = "$updatedAt", skip_serializing_if = "Option::is_none")] - pub updated_at: Option, - // the serde_json::Value preserves the order (see .toml file) - #[serde(flatten)] - pub data: JsonValue, - #[serde(skip)] - pub data_contract: DataContract, - #[serde(skip)] - pub metadata: Option, - #[serde(skip)] - pub entropy: [u8; 32], -} - -impl Document { - /// Creates a Document from the json form. Json format contains strings instead of - /// arrays of u8 (bytes) - pub fn from_json_document( - json_document: JsonValue, - data_contract: DataContract, - ) -> Result { - let mut document = Self::from_value::(json_document, data_contract)?; - let mut document_data = document.data.take(); - - // replace only the dynamic data - let (identifier_paths, binary_paths) = document.get_identifiers_and_binary_paths()?; - document_data.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - document_data.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; - - document.data = document_data; - Ok(document) - } - - pub fn from_raw_document( - raw_document: JsonValue, - data_contract: DataContract, - ) -> Result { - Self::from_value::>(raw_document, data_contract) - } - - fn from_value( - mut document_value: JsonValue, - data_contract: DataContract, - ) -> Result - where - for<'de> S: Deserialize<'de> + TryInto, - { - let mut document = Document { - data_contract, - ..Default::default() - }; - - if let Ok(value) = document_value.remove(property_names::PROTOCOL_VERSION) { - document.protocol_version = serde_json::from_value(value)? - } - if let Ok(value) = document_value.remove(property_names::ID) { - let data: S = serde_json::from_value(value)?; - document.id = data.try_into()?; - } - if let Ok(value) = document_value.remove(property_names::DOCUMENT_TYPE) { - document.document_type = serde_json::from_value(value)? - } - if let Ok(value) = document_value.remove(property_names::DATA_CONTRACT_ID) { - let data: S = serde_json::from_value(value)?; - document.data_contract_id = data.try_into()? - } - if let Ok(value) = document_value.remove(property_names::OWNER_ID) { - let data: S = serde_json::from_value(value)?; - document.owner_id = data.try_into()? - } - if let Ok(value) = document_value.remove(property_names::REVISION) { - document.revision = serde_json::from_value(value)? - } - if let Ok(value) = document_value.remove(property_names::CREATED_AT) { - document.created_at = serde_json::from_value(value)? - } - if let Ok(value) = document_value.remove(property_names::UPDATED_AT) { - document.updated_at = serde_json::from_value(value)? - } - - document.data = document_value; - Ok(document) - } - - pub fn to_json(&self) -> Result { - let mut value = serde_json::to_value(self)?; - - let (identifier_paths, binary_paths) = self - .data_contract - .get_identifiers_and_binary_paths(&self.document_type)?; - - value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; - value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - - Ok(value) - } - - pub fn from_buffer(cbor_bytes: impl AsRef<[u8]>) -> Result { - let SplitProtocolVersionOutcome { - protocol_version, - main_message_bytes: document_cbor_bytes, - .. - } = deserializer::split_protocol_version(cbor_bytes.as_ref())?; - - let cbor_value: CborValue = ciborium::de::from_reader(document_cbor_bytes) - .map_err(|e| ProtocolError::EncodingError(format!("{}", e)))?; - - let mut json_value = cbor_value::cbor_value_to_json_value(&cbor_value)?; - - json_value.add_protocol_version(property_names::PROTOCOL_VERSION, protocol_version)?; - json_value.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Base58)?; - - let document: Document = serde_json::from_value(json_value)?; - - Ok(document) - } - - // The skipIdentifierConversion option is removed as it doesn't make sense in the case of - // of Rust. Rust doesn't distinguish between `Buffer` and `Identifier` - pub fn to_object(&self) -> Result { - let mut json_object = serde_json::to_value(self)?; - - let (identifier_paths, binary_paths) = self.get_identifiers_and_binary_paths()?; - let _ = json_object.replace_identifier_paths(identifier_paths, ReplaceWith::Bytes); - let _ = json_object.replace_binary_paths(binary_paths, ReplaceWith::Bytes); - - Ok(json_object) - } - - pub fn to_buffer(&self) -> Result, ProtocolError> { - let mut result_buf = self.protocol_version.encode_var_vec(); - - let map = CborValue::serialized(&self) - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - - let mut canonical_map: CborCanonicalMap = map.try_into()?; - - canonical_map.remove(property_names::PROTOCOL_VERSION); - - if self.updated_at.is_none() { - canonical_map.remove(property_names::UPDATED_AT); - } - - let (identifier_paths, binary_paths) = self - .data_contract - .get_identifiers_and_binary_paths(&self.document_type)?; - - // The static (part of structure) identifiers are being serialized to the String(base58) - canonical_map.replace_values(IDENTIFIER_FIELDS, ReplaceWith::Bytes); - // The DYNAMIC identifiers and binary fields are being serialized to the ArrayInt, therefore - // they both need to be converted to the the CborValue::Bytes - canonical_map.replace_paths( - identifier_paths.into_iter().chain(binary_paths), - FieldType::ArrayInt, - FieldType::Bytes, - ); - - let mut document_buffer = canonical_map - .to_bytes() - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - - result_buf.append(&mut document_buffer); - - Ok(result_buf) - } - - pub fn hash(&self) -> Result, ProtocolError> { - Ok(hash(self.to_buffer()?)) - } - - /// Set the value under given path. - /// The path supports syntax from `lodash` JS lib. Example: "root.people[0].name". - /// If parents are not present they will be automatically created - pub fn set(&mut self, path: &str, value: JsonValue) -> Result<(), ProtocolError> { - Ok(self.data.insert_with_path(path, value)?) - } - - /// Retrieves field specified by path - pub fn get(&self, path: &str) -> Option<&JsonValue> { - match self.data.get_value(path) { - Ok(v) => Some(v), - Err(_) => None, - } - } - - /// Get the Document's data - pub fn get_data(&self) -> &JsonValue { - &self.data - } - - /// Set the Document's data - pub fn set_data(&mut self, data: JsonValue) { - self.data = data; - } - - /// Get entropy - pub fn get_entropy(&self) -> &[u8] { - &self.entropy - } - - pub fn get_identifiers_and_binary_paths( - &self, - ) -> Result<(Vec<&str>, Vec<&str>), ProtocolError> { - let (identifiers_paths, binary_paths) = self - .data_contract - .get_identifiers_and_binary_paths(&self.document_type)?; - - Ok(( - identifiers_paths - .into_iter() - .chain(IDENTIFIER_FIELDS) - .unique() - .collect(), - binary_paths, - )) - } -} - -#[cfg(test)] -mod test { - use anyhow::Result; - use serde_json::{json, Value}; - - use super::*; - use crate::tests::utils::*; - use crate::util::string_encoding::Encoding; - use pretty_assertions::assert_eq; - - fn init() { - let _ = env_logger::builder() - .filter_level(log::LevelFilter::Debug) - .try_init(); - } - - fn data_contract_with_dynamic_properties() -> DataContract { - let data_contract = json!({ - "protocolVersion" :0, - "$id" : vec![0_u8;32], - "$schema" : "schema", - "version" : 0, - "ownerId" : vec![0_u8;32], - "documents" : { - "test" : { - "properties" : { - "alphaIdentifier" : { - "type": "array", - "byteArray": true, - "contentMediaType": "application/x.dash.dpp.identifier", - }, - "alphaBinary" : { - "type": "array", - "byteArray": true, - } - } - } - } - }); - DataContract::from_raw_object(data_contract).unwrap() - } - - #[test] - fn test_document_deserialize() -> Result<()> { - init(); - let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - let doc = serde_json::from_str::(&document_json)?; - assert_eq!(doc.document_type, "domain"); - assert_eq!(doc.protocol_version, 0); - assert_eq!( - doc.id.to_buffer(), - Identifier::from_string( - "4veLBZPHDkaCPF9LfZ8fX3JZiS5q5iUVGhdBbaa9ga5E", - Encoding::Base58 - ) - .unwrap() - .to_buffer() - ); - assert_eq!( - doc.data_contract_id.to_buffer(), - Identifier::from_string( - "566vcJkmebVCAb2Dkj2yVMSgGFcsshupnQqtsz1RFbcy", - Encoding::Base58 - ) - .unwrap() - .to_buffer() - ); - - assert_eq!(doc.data["label"], Value::String("user-9999".to_string())); - assert_eq!( - doc.data["records"]["dashUniqueIdentityId"], - Value::String("HBNMY5QWuBVKNFLhgBTC1VmpEnscrmqKPMXpnYSHwhfn".to_string()) - ); - assert_eq!( - doc.data["subdomainRules"]["allowSubdomains"], - Value::Bool(false) - ); - Ok(()) - } - - #[test] - fn test_buffer_serialize_deserialize() { - init(); - let init_doc = new_example_document(); - let buffer_document = init_doc.to_buffer().expect("no errors"); - - let doc = - Document::from_buffer(buffer_document).expect("document should be created from buffer"); - - assert_eq!(init_doc.created_at, doc.created_at); - assert_eq!(init_doc.updated_at, doc.updated_at); - assert_eq!(init_doc.id, doc.id); - assert_eq!(init_doc.data_contract_id, doc.data_contract_id); - assert_eq!(init_doc.owner_id, doc.owner_id); - } - - #[test] - fn test_to_object() { - init(); - let document_json = get_data_from_file("src/tests/payloads/document_dpns.json").unwrap(); - let document = serde_json::from_str::(&document_json).unwrap(); - let document_object = document.to_object().unwrap(); - - for property in IDENTIFIER_FIELDS { - let id = document_object - .get(property) - .unwrap() - .as_array() - .expect("the property must be an array"); - assert_eq!(32, id.len()) - } - } - - #[test] - fn test_json_serialize() -> Result<()> { - init(); - - let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - let document = serde_json::from_str::(&document_json)?; - - serde_json::to_string(&document)?; - Ok(()) - } - - #[test] - fn test_document_to_buffer() -> Result<()> { - init(); - - let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - serde_json::from_str::(&document_json)?; - Ok(()) - } - - #[test] - fn deserialize_js_cpp_cbor() -> Result<()> { - let document_cbor = document_cbor_bytes(); - - let document = Document::from_buffer(document_cbor)?; - - assert_eq!(document.protocol_version, 1); - assert_eq!( - document.id.to_buffer().to_vec(), - vec![ - 113, 93, 61, 101, 117, 96, 36, 162, 222, 10, 177, 178, 187, 30, 131, 181, 239, 41, - 123, 240, 198, 250, 97, 106, 173, 92, 136, 126, 79, 16, 222, 249 - ] - ); - assert_eq!(&document.document_type, "niceDocument"); - assert_eq!( - document.data_contract_id.to_buffer().to_vec(), - vec![ - 122, 188, 95, 154, 180, 188, 208, 97, 46, 214, 202, 206, 194, 4, 221, 109, 116, 17, - 165, 97, 39, 212, 36, 138, 241, 234, 218, 203, 147, 82, 93, 162 - ] - ); - assert_eq!( - document.owner_id.to_buffer().to_vec(), - vec![ - 182, 191, 55, 77, 48, 47, 190, 43, 81, 27, 67, 226, 61, 3, 63, 150, 94, 46, 51, - 160, 36, 199, 65, 157, 176, 117, 51, 212, 186, 125, 112, 142 - ] - ); - assert_eq!(document.revision, 1); - assert_eq!(document.created_at.unwrap(), 1656583332347); - assert_eq!(document.data.get("name").unwrap(), "Cutie"); - - Ok(()) - } - - #[test] - fn to_buffer_serialize_to_the_same_format_as_js_dpp() -> Result<()> { - let document_cbor = document_cbor_bytes(); - let document = Document::from_buffer(&document_cbor)?; - - let buffer = document.to_buffer()?; - - assert_eq!(document_cbor, buffer); - Ok(()) - } - - #[test] - fn json_should_generate_human_readable_binaries() { - let data_contract = data_contract_with_dynamic_properties(); - let alpha_value = vec![10_u8; 32]; - let id = vec![11_u8; 32]; - let owner_id = vec![12_u8; 32]; - let data_contract_id = vec![13_u8; 32]; - - let raw_document = json!({ - "$protocolVersion" : 0, - "$id" : id, - "$ownerId" : owner_id, - "$type" : "test", - "$dataContractId" : data_contract_id, - "revision" : 1, - "alphaBinary" : alpha_value, - "alphaIdentifier" : alpha_value, - }); - - let document = Document::from_raw_document(raw_document, data_contract).unwrap(); - let json_document = document.to_json().expect("no errors"); - - assert_eq!( - json_document["$id"], - Value::String(bs58::encode(&id).into_string()) - ); - assert_eq!( - json_document["$ownerId"], - Value::String(bs58::encode(&owner_id).into_string()) - ); - assert_eq!( - json_document["$dataContractId"], - Value::String(bs58::encode(&data_contract_id).into_string()) - ); - assert_eq!( - json_document["alphaBinary"], - Value::String(base64::encode(&alpha_value)) - ); - assert_eq!( - json_document["alphaIdentifier"], - Value::String(bs58::encode(&alpha_value).into_string()) - ); - } - - fn document_cbor_bytes() -> Vec { - hex::decode("01a7632469645820715d3d65756024a2de0ab1b2bb1e83b5ef297bf0c6fa616aad5c887e4f10def9646e616d656543757469656524747970656c6e696365446f63756d656e7468246f776e657249645820b6bf374d302fbe2b511b43e23d033f965e2e33a024c7419db07533d4ba7d708e69247265766973696f6e016a246372656174656441741b00000181b40fa1fb6f2464617461436f6e7472616374496458207abc5f9ab4bcd0612ed6cacec204dd6d7411a56127d4248af1eadacb93525da2").unwrap() - } - - fn new_example_document() -> Document { - Document { - id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), - owner_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), - data_contract_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), - created_at: Some(1648013404492), - updated_at: Some(1648013404492), - ..Default::default() - } - } -} +pub use document::Document; +pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::DocumentInStateTransition; +pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::property_names as document_in_state_transition_property_names; +pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::IDENTIFIER_FIELDS as DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index c242b7c3773..294363f3bda 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -1,34 +1,246 @@ +use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; +use crate::data_contract::document_type::DocumentType; +use crate::data_contract::errors::{DataContractError, StructureError}; +use crate::data_contract::extra::common::bytes_for_system_value_from_tree_map; use crate::document::Document; +use crate::document::DocumentInStateTransition; +use crate::util::deserializer; +use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::ProtocolError; use bincode::Options; +use ciborium::Value; +use integer_encoding::VarIntWriter; +use std::collections::BTreeMap; +use std::convert::{TryFrom, TryInto}; +use std::io::{BufReader, Read}; impl Document { - pub fn serialize(&self) -> Result, ProtocolError> { - bincode::DefaultOptions::default() - .with_varint_encoding() - .reject_trailing_bytes() - .with_big_endian() - .serialize(self) - .map_err(|_| ProtocolError::EncodingError(String::from("unable to serialize document"))) + /// Serializes the document. + /// + /// The serialization of a document follows the pattern: + /// id 32 bytes + owner_id 32 bytes + encoded values byte arrays + pub fn serialize(&self, document_type: &DocumentType) -> Result, ProtocolError> { + let mut buffer: Vec = self.id.as_slice().to_vec(); + buffer.extend(self.owner_id.as_slice()); + document_type + .properties + .iter() + .try_for_each(|(field_name, field)| { + if let Some(value) = self.properties.get(field_name) { + let value = field + .document_type + .encode_value_ref_with_size(value, field.required)?; + buffer.extend(value.as_slice()); + Ok(()) + } else if field.required { + Err(ProtocolError::DataContractError( + DataContractError::MissingRequiredKey("a required field is not present"), + )) + } else { + // We don't have something that wasn't required + buffer.push(0); + Ok(()) + } + })?; + Ok(buffer) } - pub fn serialized_size(&self) -> usize { - bincode::DefaultOptions::default() - .with_varint_encoding() - .reject_trailing_bytes() - .with_big_endian() - .serialized_size(self) - .unwrap() as usize // this should not be able to error + /// Serializes and consumes the document. + /// + /// The serialization of a document follows the pattern: + /// id 32 bytes + owner_id 32 bytes + encoded values byte arrays + pub fn serialize_consume( + mut self, + document_type: &DocumentType, + ) -> Result, ProtocolError> { + let mut buffer: Vec = Vec::try_from(self.id).unwrap(); + let mut owner_id = Vec::try_from(self.owner_id).unwrap(); + buffer.append(&mut owner_id); + document_type + .properties + .iter() + .try_for_each(|(field_name, field)| { + if let Some(value) = self.properties.remove(field_name) { + let value = field + .document_type + .encode_value_with_size(value, field.required)?; + buffer.extend(value.as_slice()); + Ok(()) + } else if field.required { + Err(ProtocolError::DataContractError( + DataContractError::MissingRequiredKey("a required field is not present"), + )) + } else { + // We don't have something that wasn't required + buffer.push(0); + Ok(()) + } + })?; + Ok(buffer) } - pub fn deserialize(bytes: &[u8]) -> Result { - bincode::DefaultOptions::default() - .with_varint_encoding() - .reject_trailing_bytes() - .with_big_endian() - .deserialize(bytes) - .map_err(|_| { - ProtocolError::EncodingError(String::from("unable to deserialize identity")) + /// Reads a serialized document and creates a Document from it. + pub fn from_bytes( + serialized_document: &[u8], + document_type: &DocumentType, + ) -> Result { + let mut buf = BufReader::new(serialized_document); + if serialized_document.len() < 64 { + return Err(ProtocolError::DecodingError( + "serialized document is too small, must have id and owner id".to_string(), + )); + } + let mut id = [0; 32]; + buf.read_exact(&mut id).map_err(|_| { + ProtocolError::DecodingError("error reading from serialized document".to_string()) + })?; + + let mut owner_id = [0; 32]; + buf.read_exact(&mut owner_id).map_err(|_| { + ProtocolError::DecodingError("error reading from serialized document".to_string()) + })?; + + let properties = document_type + .properties + .iter() + .filter_map(|(key, field)| { + let read_value = field.document_type.read_from(&mut buf, field.required); + match read_value { + Ok(read_value) => read_value.map(|read_value| Ok((key.clone(), read_value))), + Err(e) => Some(Err(e)), + } }) + .collect::, ProtocolError>>()?; + Ok(Document { + id, + properties, + owner_id, + }) + } + + /// Reads a CBOR-serialized document and creates a Document from it. + /// If Document and Owner IDs are provided, they are used, otherwise they are created. + pub fn from_cbor( + document_cbor: &[u8], + document_id: Option<[u8; 32]>, + owner_id: Option<[u8; 32]>, + ) -> Result { + let SplitProtocolVersionOutcome { + main_message_bytes: read_document_cbor, + .. + } = deserializer::split_protocol_version(document_cbor)?; + + // first we need to deserialize the document and contract indices + // we would need dedicated deserialization functions based on the document type + let mut document: BTreeMap = ciborium::de::from_reader(read_document_cbor) + .map_err(|_| { + ProtocolError::StructureError(StructureError::InvalidCBOR( + "unable to decode contract for document call", + )) + })?; + + let owner_id: [u8; 32] = match owner_id { + None => { + let owner_id: Vec = + bytes_for_system_value_from_tree_map(&document, "$ownerId")?.ok_or({ + ProtocolError::DataContractError(DataContractError::DocumentOwnerIdMissing( + "unable to get document $ownerId", + )) + })?; + document.remove("$ownerId"); + if owner_id.len() != 32 { + return Err(ProtocolError::DataContractError( + DataContractError::FieldRequirementUnmet("invalid owner id"), + )); + } + owner_id.as_slice().try_into() + } + Some(owner_id) => Ok(owner_id), + } + .expect("conversion to 32bytes shouldn't fail"); + + let id: [u8; 32] = match document_id { + None => { + let document_id: Vec = bytes_for_system_value_from_tree_map(&document, "$id")? + .ok_or({ + ProtocolError::DataContractError(DataContractError::DocumentIdMissing( + "unable to get document $id", + )) + })?; + document.remove("$id"); + if document_id.len() != 32 { + return Err(ProtocolError::DataContractError( + DataContractError::FieldRequirementUnmet("invalid document id"), + )); + } + document_id.as_slice().try_into() + } + Some(document_id) => { + // we need to start by verifying that the document_id is a 256 bit number (32 bytes) + Ok(document_id) + } + } + .expect("document_id must be 32 bytes"); + + // dev-note: properties is everything other than the id and owner id + Ok(Document { + properties: document, + owner_id, + id, + }) + } + + /// Reads a CBOR-serialized document and creates a Document from it with the provided IDs. + pub fn from_cbor_with_id( + document_cbor: &[u8], + document_id: &[u8], + owner_id: &[u8], + ) -> Result { + // we need to start by verifying that the owner_id is a 256 bit number (32 bytes) + if owner_id.len() != 32 { + return Err(ProtocolError::DataContractError( + DataContractError::FieldRequirementUnmet("invalid owner id"), + )); + } + + if document_id.len() != 32 { + return Err(ProtocolError::DataContractError( + DataContractError::FieldRequirementUnmet("invalid document id"), + )); + } + let SplitProtocolVersionOutcome { + main_message_bytes: read_document_cbor, + .. + } = deserializer::split_protocol_version(document_cbor)?; + + // first we need to deserialize the document and contract indices + // we would need dedicated deserialization functions based on the document type + let properties: BTreeMap = ciborium::de::from_reader(read_document_cbor) + .map_err(|_| { + ProtocolError::StructureError(StructureError::InvalidCBOR( + "unable to decode contract for document call with id", + )) + })?; + + // dev-note: properties is everything other than the id and owner id + Ok(Document { + properties, + owner_id: owner_id + .try_into() + .expect("try_into shouldn't fail, document_id must be 32 bytes"), + id: document_id + .try_into() + .expect("try_into shouldn't fail, document_id must be 32 bytes"), + }) + } + + /// Serializes the Document to CBOR. + pub fn to_cbor(&self) -> Vec { + let mut buffer: Vec = Vec::new(); + buffer + .write_varint(PROTOCOL_VERSION) + .expect("writing protocol version caused error"); + ciborium::ser::into_writer(&self, &mut buffer).expect("unable to serialize into cbor"); + buffer } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index a54c89df73c..95282bbb5a7 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -3,12 +3,10 @@ use std::collections::HashMap; use dashcore::{consensus, BlockHeader}; use serde_json::Value; +use crate::document::DocumentInStateTransition; use crate::{ - document::{errors::DocumentError, Document}, - prelude::Identifier, - state_repository::StateRepositoryLike, - state_transition::StateTransitionLike, - ProtocolError, + document::errors::DocumentError, prelude::Identifier, state_repository::StateRepositoryLike, + state_transition::StateTransitionLike, ProtocolError, }; use super::{ @@ -61,7 +59,7 @@ pub async fn apply_documents_batch_transition( ) .await?; - let fetched_documents_by_id: HashMap<&Identifier, &Document> = + let fetched_documents_by_id: HashMap<&Identifier, &DocumentInStateTransition> = fetched_documents.iter().map(|dt| (&dt.id, dt)).collect(); // since groveDB doesn't support parallel inserts, wee need to make them sequential @@ -120,9 +118,9 @@ pub async fn apply_documents_batch_transition( fn document_from_transition_create( document_create_transition: &DocumentCreateTransition, state_transition: &DocumentsBatchTransition, -) -> Document { +) -> DocumentInStateTransition { // TODO cloning is costly. Probably the [`Document`] should have properties of type `Cov<'a, K>` - Document { + DocumentInStateTransition { protocol_version: state_transition.protocol_version, id: document_create_transition.base.id, document_type: document_create_transition.base.document_type.clone(), @@ -149,9 +147,9 @@ fn document_from_transition_replace( document_replace_transition: &DocumentReplaceTransition, state_transition: &DocumentsBatchTransition, created_at: i64, -) -> Document { +) -> DocumentInStateTransition { // TODO cloning is costly. Probably the [`Document`] should have properties of type `Cov<'a, K>` - Document { + DocumentInStateTransition { protocol_version: state_transition.protocol_version, id: document_replace_transition.base.id, document_type: document_replace_transition.base.document_type.clone(), @@ -180,11 +178,12 @@ mod test { use dashcore::consensus; use serde_json::{json, Value}; + use crate::document::DocumentInStateTransition; use crate::tests::utils::new_block_header; use crate::{ document::{ document_transition::{Action, DocumentTransitionObjectLike}, - Document, DocumentsBatchTransition, + DocumentsBatchTransition, }, state_repository::MockStateRepositoryLike, state_transition::StateTransitionLike, @@ -225,7 +224,7 @@ mod test { state_transition.get_execution_context().enable_dry_run(); state_repository - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(|_, _, _, _| Ok(vec![])); state_repository .expect_update_document() diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs new file mode 100644 index 00000000000..379ef692bcf --- /dev/null +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs @@ -0,0 +1,512 @@ +use crate::data_contract::DataContract; +use crate::identifier::Identifier; +use crate::metadata::Metadata; +use crate::util::cbor_value::{CborCanonicalMap, FieldType}; +use crate::util::deserializer::SplitProtocolVersionOutcome; +use crate::util::hash::hash; +use crate::util::json_value::JsonValueExt; +use crate::util::json_value::ReplaceWith; +use crate::util::{cbor_value, deserializer}; +use crate::ProtocolError; +use ciborium::Value as CborValue; +use integer_encoding::VarInt; +use itertools::Itertools; +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; +use std::convert::TryInto; + +pub mod property_names { + pub const PROTOCOL_VERSION: &str = "$protocolVersion"; + pub const ID: &str = "$id"; + pub const DOCUMENT_TYPE: &str = "$type"; + pub const REVISION: &str = "$revision"; + pub const DATA_CONTRACT_ID: &str = "$dataContractId"; + pub const OWNER_ID: &str = "$ownerId"; + pub const CREATED_AT: &str = "$createdAt"; + pub const UPDATED_AT: &str = "$updatedAt"; +} + +pub const IDENTIFIER_FIELDS: [&str; 3] = [ + property_names::ID, + property_names::DATA_CONTRACT_ID, + property_names::OWNER_ID, +]; + +/// The document object represents the data provided by the platform in response to a query. +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct DocumentInStateTransition { + #[serde(rename = "$protocolVersion")] + pub protocol_version: u32, + #[serde(rename = "$id")] + pub id: Identifier, + #[serde(rename = "$type")] + pub document_type: String, + #[serde(rename = "$revision")] + pub revision: u32, + #[serde(rename = "$dataContractId")] + pub data_contract_id: Identifier, + #[serde(rename = "$ownerId")] + pub owner_id: Identifier, + #[serde(rename = "$createdAt", skip_serializing_if = "Option::is_none")] + // TODO: Must be TimestampMillis + pub created_at: Option, + #[serde(rename = "$updatedAt", skip_serializing_if = "Option::is_none")] + pub updated_at: Option, + // the serde_json::Value preserves the order (see .toml file) + #[serde(flatten)] + pub data: JsonValue, + #[serde(skip)] + pub data_contract: DataContract, + #[serde(skip)] + pub metadata: Option, + #[serde(skip)] + pub entropy: [u8; 32], +} + +impl DocumentInStateTransition { + /// Creates a Document from the json form. Json format contains strings instead of + /// arrays of u8 (bytes) + pub fn from_json_document( + json_document: JsonValue, + data_contract: DataContract, + ) -> Result { + let mut document = Self::from_value::(json_document, data_contract)?; + let mut document_data = document.data.take(); + + // replace only the dynamic data + let (identifier_paths, binary_paths) = document.get_identifiers_and_binary_paths()?; + document_data.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; + document_data.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; + + document.data = document_data; + Ok(document) + } + + pub fn from_raw_document( + raw_document: JsonValue, + data_contract: DataContract, + ) -> Result { + Self::from_value::>(raw_document, data_contract) + } + + fn from_value( + mut document_value: JsonValue, + data_contract: DataContract, + ) -> Result + where + for<'de> S: Deserialize<'de> + TryInto, + { + let mut document = Self { + data_contract, + ..Default::default() + }; + + if let Ok(value) = document_value.remove(property_names::PROTOCOL_VERSION) { + document.protocol_version = serde_json::from_value(value)? + } + if let Ok(value) = document_value.remove(property_names::ID) { + let data: S = serde_json::from_value(value)?; + document.id = data.try_into()?; + } + if let Ok(value) = document_value.remove(property_names::DOCUMENT_TYPE) { + document.document_type = serde_json::from_value(value)? + } + if let Ok(value) = document_value.remove(property_names::DATA_CONTRACT_ID) { + let data: S = serde_json::from_value(value)?; + document.data_contract_id = data.try_into()? + } + if let Ok(value) = document_value.remove(property_names::OWNER_ID) { + let data: S = serde_json::from_value(value)?; + document.owner_id = data.try_into()? + } + if let Ok(value) = document_value.remove(property_names::REVISION) { + document.revision = serde_json::from_value(value)? + } + if let Ok(value) = document_value.remove(property_names::CREATED_AT) { + document.created_at = serde_json::from_value(value)? + } + if let Ok(value) = document_value.remove(property_names::UPDATED_AT) { + document.updated_at = serde_json::from_value(value)? + } + + document.data = document_value; + Ok(document) + } + + pub fn to_json(&self) -> Result { + let mut value = serde_json::to_value(self)?; + + let (identifier_paths, binary_paths) = self + .data_contract + .get_identifiers_and_binary_paths(&self.document_type)?; + + value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; + value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; + + Ok(value) + } + + pub fn from_buffer(cbor_bytes: impl AsRef<[u8]>) -> Result { + let SplitProtocolVersionOutcome { + protocol_version, + main_message_bytes: document_cbor_bytes, + .. + } = deserializer::split_protocol_version(cbor_bytes.as_ref())?; + + let cbor_value: CborValue = ciborium::de::from_reader(document_cbor_bytes) + .map_err(|e| ProtocolError::EncodingError(format!("{}", e)))?; + + let mut json_value = cbor_value::cbor_value_to_json_value(&cbor_value)?; + + json_value.add_protocol_version(property_names::PROTOCOL_VERSION, protocol_version)?; + json_value.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Base58)?; + + let document: Self = serde_json::from_value(json_value)?; + + Ok(document) + } + + // The skipIdentifierConversion option is removed as it doesn't make sense in the case of + // of Rust. Rust doesn't distinguish between `Buffer` and `Identifier` + pub fn to_object(&self) -> Result { + let mut json_object = serde_json::to_value(self)?; + + let (identifier_paths, binary_paths) = self.get_identifiers_and_binary_paths()?; + let _ = json_object.replace_identifier_paths(identifier_paths, ReplaceWith::Bytes); + let _ = json_object.replace_binary_paths(binary_paths, ReplaceWith::Bytes); + + Ok(json_object) + } + + pub fn to_buffer(&self) -> Result, ProtocolError> { + let mut result_buf = self.protocol_version.encode_var_vec(); + + let map = CborValue::serialized(&self) + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; + + let mut canonical_map: CborCanonicalMap = map.try_into()?; + + canonical_map.remove(property_names::PROTOCOL_VERSION); + + if self.updated_at.is_none() { + canonical_map.remove(property_names::UPDATED_AT); + } + + let (identifier_paths, binary_paths) = self + .data_contract + .get_identifiers_and_binary_paths(&self.document_type)?; + + // The static (part of structure) identifiers are being serialized to the String(base58) + canonical_map.replace_values(IDENTIFIER_FIELDS, ReplaceWith::Bytes); + // The DYNAMIC identifiers and binary fields are being serialized to the ArrayInt, therefore + // they both need to be converted to the the CborValue::Bytes + canonical_map.replace_paths( + identifier_paths.into_iter().chain(binary_paths), + FieldType::ArrayInt, + FieldType::Bytes, + ); + + let mut document_buffer = canonical_map + .to_bytes() + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; + + result_buf.append(&mut document_buffer); + + Ok(result_buf) + } + + pub fn hash(&self) -> Result, ProtocolError> { + Ok(hash(self.to_buffer()?)) + } + + /// Set the value under given path. + /// The path supports syntax from `lodash` JS lib. Example: "root.people[0].name". + /// If parents are not present they will be automatically created + pub fn set(&mut self, path: &str, value: JsonValue) -> Result<(), ProtocolError> { + Ok(self.data.insert_with_path(path, value)?) + } + + /// Retrieves field specified by path + pub fn get(&self, path: &str) -> Option<&JsonValue> { + match self.data.get_value(path) { + Ok(v) => Some(v), + Err(_) => None, + } + } + + /// Get the Document's data + pub fn get_data(&self) -> &JsonValue { + &self.data + } + + /// Set the Document's data + pub fn set_data(&mut self, data: JsonValue) { + self.data = data; + } + + /// Get entropy + pub fn get_entropy(&self) -> &[u8] { + &self.entropy + } + + pub fn get_identifiers_and_binary_paths( + &self, + ) -> Result<(Vec<&str>, Vec<&str>), ProtocolError> { + let (identifiers_paths, binary_paths) = self + .data_contract + .get_identifiers_and_binary_paths(&self.document_type)?; + + Ok(( + identifiers_paths + .into_iter() + .chain(IDENTIFIER_FIELDS) + .unique() + .collect(), + binary_paths, + )) + } +} + +#[cfg(test)] +mod test { + use anyhow::Result; + use serde_json::{json, Value}; + + use crate::document::document_transition::document_in_state_transition::{ + DocumentInStateTransition, IDENTIFIER_FIELDS, + }; + use crate::document::*; + use crate::tests::utils::*; + use crate::util::string_encoding::Encoding; + use pretty_assertions::assert_eq; + + fn init() { + let _ = env_logger::builder() + .filter_level(log::LevelFilter::Debug) + .try_init(); + } + + fn data_contract_with_dynamic_properties() -> DataContract { + let data_contract = json!({ + "protocolVersion" :0, + "$id" : vec![0_u8;32], + "$schema" : "schema", + "version" : 0, + "ownerId" : vec![0_u8;32], + "documents" : { + "test" : { + "properties" : { + "alphaIdentifier" : { + "type": "array", + "byteArray": true, + "contentMediaType": "application/x.dash.dpp.identifier", + }, + "alphaBinary" : { + "type": "array", + "byteArray": true, + } + } + } + } + }); + DataContract::from_raw_object(data_contract).unwrap() + } + + #[test] + fn test_document_deserialize() -> Result<()> { + init(); + let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; + let doc = serde_json::from_str::(&document_json)?; + assert_eq!(doc.document_type, "domain"); + assert_eq!(doc.protocol_version, 0); + assert_eq!( + doc.id.to_buffer(), + Identifier::from_string( + "4veLBZPHDkaCPF9LfZ8fX3JZiS5q5iUVGhdBbaa9ga5E", + Encoding::Base58 + ) + .unwrap() + .to_buffer() + ); + assert_eq!( + doc.data_contract_id.to_buffer(), + Identifier::from_string( + "566vcJkmebVCAb2Dkj2yVMSgGFcsshupnQqtsz1RFbcy", + Encoding::Base58 + ) + .unwrap() + .to_buffer() + ); + + assert_eq!(doc.data["label"], Value::String("user-9999".to_string())); + assert_eq!( + doc.data["records"]["dashUniqueIdentityId"], + Value::String("HBNMY5QWuBVKNFLhgBTC1VmpEnscrmqKPMXpnYSHwhfn".to_string()) + ); + assert_eq!( + doc.data["subdomainRules"]["allowSubdomains"], + Value::Bool(false) + ); + Ok(()) + } + + #[test] + fn test_buffer_serialize_deserialize() { + init(); + let init_doc = new_example_document(); + let buffer_document = init_doc.to_buffer().expect("no errors"); + + let doc = DocumentInStateTransition::from_buffer(buffer_document) + .expect("document should be created from buffer"); + + assert_eq!(init_doc.created_at, doc.created_at); + assert_eq!(init_doc.updated_at, doc.updated_at); + assert_eq!(init_doc.id, doc.id); + assert_eq!(init_doc.data_contract_id, doc.data_contract_id); + assert_eq!(init_doc.owner_id, doc.owner_id); + } + + #[test] + fn test_to_object() { + init(); + let document_json = get_data_from_file("src/tests/payloads/document_dpns.json").unwrap(); + let document = serde_json::from_str::(&document_json).unwrap(); + let document_object = document.to_object().unwrap(); + + for property in IDENTIFIER_FIELDS { + let id = document_object + .get(property) + .unwrap() + .as_array() + .expect("the property must be an array"); + assert_eq!(32, id.len()) + } + } + + #[test] + fn test_json_serialize() -> Result<()> { + init(); + + let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; + let document = serde_json::from_str::(&document_json)?; + + serde_json::to_string(&document)?; + Ok(()) + } + + #[test] + fn test_document_to_buffer() -> Result<()> { + init(); + + let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; + serde_json::from_str::(&document_json)?; + Ok(()) + } + + #[test] + fn deserialize_js_cpp_cbor() -> Result<()> { + let document_cbor = document_cbor_bytes(); + + let document = DocumentInStateTransition::from_buffer(document_cbor)?; + + assert_eq!(document.protocol_version, 1); + assert_eq!( + document.id.to_buffer().to_vec(), + vec![ + 113, 93, 61, 101, 117, 96, 36, 162, 222, 10, 177, 178, 187, 30, 131, 181, 239, 41, + 123, 240, 198, 250, 97, 106, 173, 92, 136, 126, 79, 16, 222, 249 + ] + ); + assert_eq!(&document.document_type, "niceDocument"); + assert_eq!( + document.data_contract_id.to_buffer().to_vec(), + vec![ + 122, 188, 95, 154, 180, 188, 208, 97, 46, 214, 202, 206, 194, 4, 221, 109, 116, 17, + 165, 97, 39, 212, 36, 138, 241, 234, 218, 203, 147, 82, 93, 162 + ] + ); + assert_eq!( + document.owner_id.to_buffer().to_vec(), + vec![ + 182, 191, 55, 77, 48, 47, 190, 43, 81, 27, 67, 226, 61, 3, 63, 150, 94, 46, 51, + 160, 36, 199, 65, 157, 176, 117, 51, 212, 186, 125, 112, 142 + ] + ); + assert_eq!(document.revision, 1); + assert_eq!(document.created_at.unwrap(), 1656583332347); + assert_eq!(document.data.get("name").unwrap(), "Cutie"); + + Ok(()) + } + + #[test] + fn to_buffer_serialize_to_the_same_format_as_js_dpp() -> Result<()> { + let document_cbor = document_cbor_bytes(); + let document = DocumentInStateTransition::from_buffer(&document_cbor)?; + + let buffer = document.to_buffer()?; + + assert_eq!(document_cbor, buffer); + Ok(()) + } + + #[test] + fn json_should_generate_human_readable_binaries() { + let data_contract = data_contract_with_dynamic_properties(); + let alpha_value = vec![10_u8; 32]; + let id = vec![11_u8; 32]; + let owner_id = vec![12_u8; 32]; + let data_contract_id = vec![13_u8; 32]; + + let raw_document = json!({ + "$protocolVersion" : 0, + "$id" : id, + "$ownerId" : owner_id, + "$type" : "test", + "$dataContractId" : data_contract_id, + "revision" : 1, + "alphaBinary" : alpha_value, + "alphaIdentifier" : alpha_value, + }); + + let document = + DocumentInStateTransition::from_raw_document(raw_document, data_contract).unwrap(); + let json_document = document.to_json().expect("no errors"); + + assert_eq!( + json_document["$id"], + Value::String(bs58::encode(&id).into_string()) + ); + assert_eq!( + json_document["$ownerId"], + Value::String(bs58::encode(&owner_id).into_string()) + ); + assert_eq!( + json_document["$dataContractId"], + Value::String(bs58::encode(&data_contract_id).into_string()) + ); + assert_eq!( + json_document["alphaBinary"], + Value::String(base64::encode(&alpha_value)) + ); + assert_eq!( + json_document["alphaIdentifier"], + Value::String(bs58::encode(&alpha_value).into_string()) + ); + } + + fn document_cbor_bytes() -> Vec { + hex::decode("01a7632469645820715d3d65756024a2de0ab1b2bb1e83b5ef297bf0c6fa616aad5c887e4f10def9646e616d656543757469656524747970656c6e696365446f63756d656e7468246f776e657249645820b6bf374d302fbe2b511b43e23d033f965e2e33a024c7419db07533d4ba7d708e69247265766973696f6e016a246372656174656441741b00000181b40fa1fb6f2464617461436f6e7472616374496458207abc5f9ab4bcd0612ed6cacec204dd6d7411a56127d4248af1eadacb93525da2").unwrap() + } + + fn new_example_document() -> DocumentInStateTransition { + DocumentInStateTransition { + id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), + owner_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), + data_contract_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), + created_at: Some(1648013404492), + updated_at: Some(1648013404492), + ..Default::default() + } + } +} diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index be4f387c151..54f7fbcf3ee 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -12,6 +12,7 @@ use document_base_transition::DocumentBaseTransition; pub mod document_base_transition; pub mod document_create_transition; pub mod document_delete_transition; +pub mod document_in_state_transition; pub mod document_replace_transition; pub use document_base_transition::{Action, DocumentTransitionObjectLike}; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs index a6a9ae62107..2e537ae78a6 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs @@ -3,9 +3,9 @@ use std::collections::hash_map::{Entry, HashMap}; use futures::future::join_all; use serde_json::json; +use crate::document::DocumentInStateTransition; use crate::{ - document::{document_transition::DocumentTransition, Document}, - get_from_transition, + document::document_transition::DocumentTransition, get_from_transition, state_repository::StateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, util::string_encoding::Encoding, @@ -15,7 +15,7 @@ pub async fn fetch_documents( state_repository: &impl StateRepositoryLike, document_transitions: impl IntoIterator>, execution_context: &StateTransitionExecutionContext, -) -> Result, anyhow::Error> { +) -> Result, anyhow::Error> { let mut transitions_by_contracts_and_types: HashMap> = HashMap::new(); let collected_transitions: Vec<_> = document_transitions.into_iter().collect(); @@ -55,10 +55,11 @@ pub async fn fetch_documents( fetch_documents_futures.push(documents); } - let results: Result>, anyhow::Error> = join_all(fetch_documents_futures) - .await - .into_iter() - .collect(); + let results: Result>, anyhow::Error> = + join_all(fetch_documents_futures) + .await + .into_iter() + .collect(); let documents = results?.into_iter().flatten().collect(); Ok(documents) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index 989f479e4af..e414966d186 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -5,13 +5,14 @@ use futures::future::join_all; use itertools::Itertools; use serde::{Deserialize, Serialize}; +use crate::document::DocumentInStateTransition; use crate::{ block_time_window::validate_time_in_block_time_window::validate_time_in_block_time_window, consensus::ConsensusError, data_trigger::DataTriggerExecutionContext, document::{ document_transition::{Action, DocumentTransition, DocumentTransitionExt}, - Document, DocumentsBatchTransition, + DocumentsBatchTransition, }, prelude::{Identifier, TimestampMillis}, state_repository::StateRepositoryLike, @@ -159,7 +160,7 @@ pub async fn validate_document_transitions( fn validate_transition( transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[DocumentInStateTransition], last_header_block_time_millis: u64, owner_id: &Identifier, ) -> ValidationResult<()> { @@ -214,7 +215,7 @@ fn validate_transition( fn check_ownership( document_transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[DocumentInStateTransition], owner_id: &Identifier, ) -> ValidationResult<()> { let mut result = ValidationResult::default(); @@ -239,7 +240,7 @@ fn check_ownership( fn check_revision( document_transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[DocumentInStateTransition], ) -> ValidationResult<()> { let mut result = ValidationResult::default(); let fetched_document = match fetched_documents @@ -267,7 +268,7 @@ fn check_revision( fn check_if_document_is_already_present( document_transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[DocumentInStateTransition], ) -> ValidationResult<()> { let mut result = ValidationResult::default(); let maybe_fetched_document = fetched_documents @@ -286,7 +287,7 @@ fn check_if_document_is_already_present( fn check_if_document_can_be_found( document_transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[DocumentInStateTransition], ) -> ValidationResult<()> { let mut result = ValidationResult::default(); let maybe_fetched_document = fetched_documents diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs index a7cbb970fff..797b25bff7b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs @@ -2,11 +2,9 @@ use futures::future::join_all; use itertools::Itertools; use serde_json::{json, Value as JsonValue}; +use crate::document::DocumentInStateTransition; use crate::{ - document::{ - document_transition::{Action, DocumentTransition, DocumentTransitionExt}, - Document, - }, + document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, prelude::{DataContract, Identifier}, state_repository::StateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, @@ -54,7 +52,7 @@ where .filter(|query| !query.where_query.is_empty()) .map(|query| { ( - state_repository.fetch_documents::( + state_repository.fetch_documents::( &data_contract.id, query.document_type, json!( { "where": query.where_query}), @@ -140,7 +138,7 @@ fn build_query_for_index_definition( fn validate_uniqueness<'a>( futures_meta: Vec<(&'a Index, &'a DocumentTransition)>, - results: Vec, anyhow::Error>>, + results: Vec, anyhow::Error>>, ) -> Result, ProtocolError> { let mut validation_result = ValidationResult::default(); for (i, result) in results.into_iter().enumerate() { diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 14f5cf2c583..32bbcb937f8 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -48,7 +48,7 @@ pub mod prelude { pub use crate::data_contract::DataContract; pub use crate::data_trigger::DataTrigger; pub use crate::document::document_transition::DocumentTransition; - pub use crate::document::Document; + pub use crate::document::DocumentInStateTransition; pub use crate::errors::ProtocolError; pub use crate::identifier::Identifier; pub use crate::identity::Identity; diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index 72695c24fbb..67429c43640 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -54,7 +54,7 @@ pub trait StateRepositoryLike: Sync { ) -> AnyResult<()>; /// Fetch Documents by Data Contract Id and type - /// By default, the method should return data as bytes (`Vec`), but the deserialization to [`Document`] should be also possible + /// By default, the method should return data as bytes (`Vec`), but the deserialization to [`DocumentInStateTransition`] should be also possible async fn fetch_documents( &self, contract_id: &Identifier, @@ -68,14 +68,14 @@ pub trait StateRepositoryLike: Sync { /// Create Document async fn create_document( &self, - document: &Document, + document: &DocumentInStateTransition, execution_context: &StateTransitionExecutionContext, ) -> AnyResult<()>; /// Update Document async fn update_document( &self, - document: &Document, + document: &DocumentInStateTransition, execution_context: &StateTransitionExecutionContext, ) -> AnyResult<()>; diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 7fa966561db..84bbed0acd1 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -9,27 +9,27 @@ use crate::{ consensus::ConsensusError, data_contract::DataContract, document::{ - Document, document_transition::{Action, DocumentTransition, DocumentTransitionObjectLike}, DocumentsBatchTransition, state_transition::documents_batch_transition::validation::state::validate_documents_batch_transition_state::*, }, prelude::Identifier, prelude::ProtocolError, state_repository::MockStateRepositoryLike, + state_transition::StateTransitionLike, StateError, tests::{ fixtures::{ get_data_contract_fixture, get_document_transitions_fixture, get_documents_fixture, }, utils::{generate_random_identifier_struct, new_block_header}, - }, - validation::ValidationResult, state_transition::StateTransitionLike, + }, validation::ValidationResult, }; +use crate::document::DocumentInStateTransition; struct TestData { owner_id: Identifier, data_contract: DataContract, - documents: Vec, + documents: Vec, document_transitions: Vec, state_transition: DocumentsBatchTransition, state_repository_mock: MockStateRepositoryLike, @@ -176,7 +176,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_delete_ .expect("documents batch state transition should be created"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -202,9 +202,11 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace mut state_repository_mock, .. } = setup_test(); - let mut replace_document = - Document::from_raw_document(documents[0].to_object().unwrap(), data_contract.clone()) - .expect("document should be created"); + let mut replace_document = DocumentInStateTransition::from_raw_document( + documents[0].to_object().unwrap(), + data_contract.clone(), + ) + .expect("document should be created"); replace_document.revision = 3; documents[0].created_at = replace_document.created_at; @@ -259,14 +261,18 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace mut state_repository_mock, .. } = setup_test(); - let mut replace_document = - Document::from_raw_document(documents[0].to_object().unwrap(), data_contract.clone()) - .expect("document should be created"); + let mut replace_document = DocumentInStateTransition::from_raw_document( + documents[0].to_object().unwrap(), + data_contract.clone(), + ) + .expect("document should be created"); replace_document.revision = 1; - let mut fetched_document = - Document::from_raw_document(documents[0].to_object().unwrap(), data_contract.clone()) - .expect("document should be created"); + let mut fetched_document = DocumentInStateTransition::from_raw_document( + documents[0].to_object().unwrap(), + data_contract.clone(), + ) + .expect("document should be created"); let another_owner_id = generate_random_identifier_struct(); fetched_document.owner_id = another_owner_id; @@ -357,7 +363,7 @@ async fn should_return_invalid_result_if_timestamps_mismatch() { .for_each(|t| set_updated_at(t, Some(now_ts))); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -409,7 +415,7 @@ async fn should_return_invalid_result_if_crated_at_has_violated_time_window() { .for_each(|t| set_created_at(t, Some(now_ts_minus_6_mins))); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -462,7 +468,7 @@ async fn should_not_validate_time_in_block_window_on_dry_run() { .for_each(|t| set_created_at(t, Some(now_ts_minus_6_mins))); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let result = @@ -507,7 +513,7 @@ async fn should_return_invalid_result_if_updated_at_has_violated_time_window() { }); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -535,19 +541,23 @@ async fn should_return_valid_result_if_document_transitions_are_valid() { mut state_repository_mock, .. } = setup_test(); - let mut fetched_document_1 = - Document::from_raw_document(documents[1].to_object().unwrap(), data_contract.clone()) - .unwrap(); - let mut fetched_document_2 = - Document::from_raw_document(documents[2].to_object().unwrap(), data_contract.clone()) - .unwrap(); + let mut fetched_document_1 = DocumentInStateTransition::from_raw_document( + documents[1].to_object().unwrap(), + data_contract.clone(), + ) + .unwrap(); + let mut fetched_document_2 = DocumentInStateTransition::from_raw_document( + documents[2].to_object().unwrap(), + data_contract.clone(), + ) + .unwrap(); fetched_document_1.revision = 1; fetched_document_2.revision = 1; fetched_document_1.owner_id = owner_id; fetched_document_2.owner_id = owner_id; state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| { Ok(vec![fetched_document_1.clone(), fetched_document_2.clone()]) }); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 103a11504fe..883e58d469b 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -5,12 +5,12 @@ use crate::{ consensus::ConsensusError, data_contract::DataContract, document::{ - Document, document_transition::{Action, DocumentTransition}, state_transition::documents_batch_transition::validation::state::validate_documents_uniqueness_by_indices::*, }, prelude::Identifier, state_repository::MockStateRepositoryLike, + state_transition::state_transition_execution_context::StateTransitionExecutionContext, StateError, tests::{ fixtures::{ @@ -18,14 +18,14 @@ use crate::{ }, utils::generate_random_identifier_struct, }, - util::string_encoding::Encoding, - validation::ValidationResult, state_transition::state_transition_execution_context::StateTransitionExecutionContext, + util::string_encoding::Encoding, validation::ValidationResult, }; +use crate::document::DocumentInStateTransition; struct TestData { owner_id: Identifier, data_contract: DataContract, - documents: Vec, + documents: Vec, document_transitions: Vec, } @@ -55,7 +55,7 @@ async fn should_return_valid_result_if_documents_have_no_unique_indices() { } = setup_test(); let mut state_repository_mock = MockStateRepositoryLike::default(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(|_, _, _, _| Ok(vec![])); let document_transitions = @@ -88,7 +88,7 @@ async fn should_return_valid_result_if_document_has_unique_indices_and_there_are let expect_document = william_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -104,7 +104,7 @@ async fn should_return_valid_result_if_document_has_unique_indices_and_there_are let expect_document = william_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -149,7 +149,7 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a let expect_document = leon_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -165,7 +165,7 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a let expect_document = leon_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -181,7 +181,7 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a let expect_document = william_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -197,7 +197,7 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a let expect_document = william_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -257,7 +257,7 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an let expect_document = leon_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -273,7 +273,7 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an let expect_document = leon_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -289,7 +289,7 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an let expect_document = william_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -305,7 +305,7 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an let expect_document = william_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -350,7 +350,7 @@ async fn should_return_valid_result_if_document_has_undefined_field_from_index() let expect_document = indexed_document.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -366,7 +366,7 @@ async fn should_return_valid_result_if_document_has_undefined_field_from_index() let expect_document = indexed_document.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -408,7 +408,7 @@ async fn should_return_valid_result_if_document_being_created_and_has_created_at let expect_document = unique_dates_doc.to_owned(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("uniqueDates"), diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 0fdd71fd171..6fd70879012 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -4,7 +4,6 @@ use crate::{ consensus::{basic::BasicError, ConsensusError}, data_contract::DataContract, document::{ - Document, document_transition::{Action, DocumentTransitionObjectLike}, state_transition::documents_batch_transition::validation::basic::validate_partial_compound_indices::*, }, @@ -14,10 +13,11 @@ use crate::{ util::json_value::JsonValueExt, validation::ValidationResult, }; +use crate::document::DocumentInStateTransition; struct TestData { data_contract: DataContract, - documents: Vec, + documents: Vec, } fn setup_test() -> TestData { diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index df5123b37ee..aab4d17ea96 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -2,10 +2,10 @@ use std::collections::HashMap; use std::sync::Arc; use crate::document::fetch_and_validate_data_contract::DataContractFetcherAndValidator; +use crate::document::DocumentInStateTransition; use crate::document::{ document_factory::DocumentFactory, document_transition::{Action, DocumentTransition}, - Document, }; use crate::state_repository::MockStateRepositoryLike; use crate::version::LATEST_VERSION; @@ -13,7 +13,7 @@ use crate::version::LATEST_VERSION; use super::{get_data_contract_fixture, get_document_validator_fixture, get_documents_fixture}; pub fn get_document_transitions_fixture( - documents: impl IntoIterator)>, + documents: impl IntoIterator)>, ) -> Vec { let document_factory = DocumentFactory::new( LATEST_VERSION, @@ -21,7 +21,8 @@ pub fn get_document_transitions_fixture( DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())), ); - let mut documents_collected: HashMap> = documents.into_iter().collect(); + let mut documents_collected: HashMap> = + documents.into_iter().collect(); let create_documents = documents_collected .remove(&Action::Create) .unwrap_or_else(|| get_documents_fixture(get_data_contract_fixture(None)).unwrap()); diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index e0149958404..d7c4218a37d 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -17,7 +17,7 @@ use super::get_document_validator_fixture; pub fn get_documents_fixture_with_owner_id_from_contract( data_contract: DataContract, -) -> Result, ProtocolError> { +) -> Result, ProtocolError> { let data_contract_fetcher_and_validator = DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())); let factory = DocumentFactory::new( @@ -30,7 +30,9 @@ pub fn get_documents_fixture_with_owner_id_from_contract( get_documents(factory, data_contract, owner_id) } -pub fn get_documents_fixture(data_contract: DataContract) -> Result, ProtocolError> { +pub fn get_documents_fixture( + data_contract: DataContract, +) -> Result, ProtocolError> { let data_contract_fetcher_and_validator = DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())); let factory = DocumentFactory::new( @@ -47,7 +49,7 @@ fn get_documents( factory: DocumentFactory, data_contract: DataContract, owner_id: Identifier, -) -> Result, ProtocolError> { +) -> Result, ProtocolError> { let documents = vec![ factory.create( data_contract.clone(), diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs index 79ab0a1723b..3feb54a68c6 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs @@ -3,10 +3,11 @@ use std::sync::Arc; use getrandom::getrandom; use serde_json::json; +use crate::document::DocumentInStateTransition; use crate::{ document::{ document_factory::DocumentFactory, - fetch_and_validate_data_contract::DataContractFetcherAndValidator, Document, + fetch_and_validate_data_contract::DataContractFetcherAndValidator, }, prelude::Identifier, state_repository::MockStateRepositoryLike, @@ -32,7 +33,9 @@ impl Default for ParentDocumentOptions { } } -pub fn get_dpns_parent_document_fixture(options: ParentDocumentOptions) -> Document { +pub fn get_dpns_parent_document_fixture( + options: ParentDocumentOptions, +) -> DocumentInStateTransition { let document_factory = DocumentFactory::new( LATEST_VERSION, get_document_validator_fixture(), diff --git a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs index 4f7dc8e3e7f..e6760997e99 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs @@ -3,12 +3,14 @@ use std::sync::Arc; use data_contracts::SystemDataContract; use serde_json::json; +use crate::document::Document; +use crate::document::DocumentInStateTransition; use crate::system_data_contracts::load_system_data_contract; use crate::{ data_contract::DataContract, document::{ document_factory::DocumentFactory, - fetch_and_validate_data_contract::DataContractFetcherAndValidator, Document, + fetch_and_validate_data_contract::DataContractFetcherAndValidator, }, state_repository::MockStateRepositoryLike, tests::utils::generate_random_identifier_struct, @@ -17,7 +19,8 @@ use crate::{ use super::get_document_validator_fixture; -pub fn get_masternode_reward_shares_documents_fixture() -> (Vec, DataContract) { +pub fn get_masternode_reward_shares_documents_fixture( +) -> (Vec, DataContract) { let owner_id = generate_random_identifier_struct(); let pay_to_id = generate_random_identifier_struct(); let data_contract = load_system_data_contract(SystemDataContract::MasternodeRewards) diff --git a/packages/rs-drive-abci/src/contracts/reward_shares.rs b/packages/rs-drive-abci/src/contracts/reward_shares.rs index 2126d8b67a7..0048c49d4f9 100644 --- a/packages/rs-drive-abci/src/contracts/reward_shares.rs +++ b/packages/rs-drive-abci/src/contracts/reward_shares.rs @@ -41,7 +41,7 @@ use crate::error::Error; use crate::platform::Platform; use drive::contract::Contract; use drive::dpp::data_contract::DriveContractExt; -use drive::dpp::document::document_stub::DocumentStub; +use drive::dpp::document::Document; use drive::dpp::util::serializer; use drive::drive::block_info::BlockInfo; use drive::drive::flags::StorageFlags; @@ -65,7 +65,7 @@ impl Platform { &self, masternode_owner_id: &Vec, transaction: TransactionArg, - ) -> Result, Error> { + ) -> Result, Error> { let query_json = json!({ "where": [ ["$ownerId", "==", bs58::encode(masternode_owner_id).into_string()] @@ -86,8 +86,8 @@ impl Platform { items .iter() - .map(|cbor| DocumentStub::from_cbor(cbor, None, None).map_err(Error::Protocol)) - .collect::, Error>>() + .map(|cbor| Document::from_cbor(cbor, None, None).map_err(Error::Protocol)) + .collect::, Error>>() } /// A function to create and apply the masternode reward shares contract. diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index e940abc2757..fd661690c1c 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -33,11 +33,12 @@ use crate::platform::Platform; use ciborium::{cbor, Value}; use drive::contract::DataContract; use drive::dpp::data_contract::DriveContractExt; -use drive::dpp::document::document_stub::DocumentStub; +use drive::dpp::document::Document; +use drive::dpp::document::DocumentInStateTransition; use drive::dpp::identity::{ Identity, IdentityPublicKey, KeyType, Purpose, SecurityLevel, TimestampMillis, }; -use drive::dpp::prelude::{Document, Identifier}; +use drive::dpp::prelude::Identifier; use drive::dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use drive::dpp::util::string_encoding::{encode, Encoding}; use drive::drive::batch::{ @@ -203,7 +204,7 @@ impl Platform { // TODO: Add created and updated at to DPNS contract - let document = Document { + let document = DocumentInStateTransition { protocol_version: PROTOCOL_VERSION, id: Identifier::new(DPNS_DASH_TLD_DOCUMENT_ID), document_type: "domain".to_string(), @@ -265,7 +266,7 @@ impl Platform { let document_cbor = document.to_buffer()?; - let document_stub = DocumentStub { + let document_stub = Document { id: DPNS_DASH_TLD_DOCUMENT_ID, properties: document_stub_properties, owner_id: contract.owner_id.to_buffer(), diff --git a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs index 6882da564b0..4288778bd72 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -43,7 +43,7 @@ use rand::{Rng, SeedableRng}; use drive::common::helpers::identities::create_test_identity_with_rng; use drive::contract::Contract; use drive::dpp::data_contract::DriveContractExt; -use drive::dpp::document::document_stub::DocumentStub; +use drive::dpp::document::Document; use drive::drive::block_info::BlockInfo; use drive::drive::flags::StorageFlags; use drive::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; @@ -61,7 +61,7 @@ fn create_test_mn_share_document( pay_to_identity: &Identity, percentage: u16, transaction: TransactionArg, -) -> DocumentStub { +) -> Document { let id = rand::random::<[u8; 32]>(); let mut properties: BTreeMap = BTreeMap::new(); @@ -72,7 +72,7 @@ fn create_test_mn_share_document( ); properties.insert(String::from("percentage"), percentage.into()); - let document = DocumentStub { + let document = Document { id, properties, owner_id: identity_id, @@ -118,7 +118,7 @@ pub fn create_test_masternode_share_identities_and_documents( pro_tx_hashes: &Vec<[u8; 32]>, seed: Option, transaction: TransactionArg, -) -> Vec<(Identity, DocumentStub)> { +) -> Vec<(Identity, Document)> { let mut rng = match seed { None => StdRng::from_entropy(), Some(seed_value) => StdRng::seed_from_u64(seed_value), diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 81536466da1..69c8b40796a 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -33,7 +33,7 @@ use crate::DocumentAction::{DocumentActionDelete, DocumentActionInsert}; use drive::common::helpers::identities::create_test_masternode_identities_with_rng; use drive::contract::{Contract, CreateRandomDocument, DocumentType}; -use drive::dpp::document::document_stub::DocumentStub; +use drive::dpp::document::Document; use drive::dpp::identity::{Identity, KeyID, PartialIdentity}; use drive::dpp::util::deserializer::ProtocolVersion; use drive::drive::batch::{ @@ -271,7 +271,7 @@ impl Strategy { if !items.is_empty() { let first_item = items.remove(0); let document = - DocumentStub::from_bytes(first_item.as_slice(), &op.document_type) + Document::from_bytes(first_item.as_slice(), &op.document_type) .expect("expected to deserialize document"); let identity = platform .drive diff --git a/packages/rs-drive/benches/benchmarks.rs b/packages/rs-drive/benches/benchmarks.rs index 2f45c04880c..1fd8a6e79b8 100644 --- a/packages/rs-drive/benches/benchmarks.rs +++ b/packages/rs-drive/benches/benchmarks.rs @@ -36,7 +36,7 @@ use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use dpp::data_contract::extra::common::json_document_to_cbor; use dpp::data_contract::DriveContractExt; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use drive::contract::Contract; use drive::contract::CreateRandomDocument; use serde::Serialize; @@ -125,7 +125,7 @@ fn test_drive_10_deserialization(c: &mut Criterion) { group.bench_function("DDSR 10", |b| { b.iter(|| { serialized_documents.iter().for_each(|serialized_document| { - DocumentStub::from_bytes(serialized_document, document_type) + Document::from_bytes(serialized_document, document_type) .expect("expected to deserialize"); }) }) @@ -135,7 +135,7 @@ fn test_drive_10_deserialization(c: &mut Criterion) { cbor_serialized_documents .iter() .for_each(|serialized_document| { - DocumentStub::from_cbor(serialized_document, None, None) + Document::from_cbor(serialized_document, None, None) .expect("expected to deserialize"); }) }) diff --git a/packages/rs-drive/src/drive/batch/drive_op_batch/document.rs b/packages/rs-drive/src/drive/batch/drive_op_batch/document.rs index 8bafe9489f7..c5b9e813245 100644 --- a/packages/rs-drive/src/drive/batch/drive_op_batch/document.rs +++ b/packages/rs-drive/src/drive/batch/drive_op_batch/document.rs @@ -10,7 +10,7 @@ use crate::error::Error; use crate::fee::op::DriveOperation; use dpp::data_contract::document_type::DocumentType; use dpp::data_contract::{DataContract as Contract, DriveContractExt}; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; use std::borrow::{Borrow, Cow}; @@ -149,7 +149,7 @@ pub enum DocumentOperationType<'a> { /// Updates a document and returns the associated fee. UpdateDocumentForContract { /// The document to update - document: &'a DocumentStub, + document: &'a Document, /// The document in pre-serialized form serialized_document: &'a [u8], /// The contract @@ -185,7 +185,7 @@ impl DriveOperationConverter for DocumentOperationType<'_> { let contract = ::from_cbor(serialized_contract, None)?; - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = DocumentRefAndSerialization((&document, serialized_document, storage_flags)); @@ -217,7 +217,7 @@ impl DriveOperationConverter for DocumentOperationType<'_> { override_document, storage_flags, } => { - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = DocumentRefAndSerialization((&document, serialized_document, storage_flags)); @@ -306,7 +306,7 @@ impl DriveOperationConverter for DocumentOperationType<'_> { } => { let contract = ::from_cbor(contract_cbor, None)?; - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = DocumentRefAndSerialization((&document, serialized_document, storage_flags)); @@ -336,7 +336,7 @@ impl DriveOperationConverter for DocumentOperationType<'_> { owner_id, storage_flags, } => { - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = DocumentRefAndSerialization((&document, serialized_document, storage_flags)); @@ -466,7 +466,7 @@ impl DriveOperationConverter for DocumentOperationType<'_> { #[derive(Clone, Debug)] pub struct UpdateOperationInfo<'a> { /// The document to update - pub document: &'a DocumentStub, + pub document: &'a Document, /// The document in pre-serialized form pub serialized_document: Option<&'a [u8]>, /// The owner id, if none is specified will try to recover from serialized document diff --git a/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs index 41ec8dc50cd..54d0588804c 100644 --- a/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs @@ -187,7 +187,7 @@ mod tests { use dpp::data_contract::extra::common::json_document_to_cbor; use dpp::data_contract::DriveContractExt; - use dpp::document::document_stub::DocumentStub; + use dpp::document::Document; use dpp::util::serializer; use rand::Rng; use serde_json::json; @@ -435,7 +435,7 @@ mod tests { let mut operations = vec![]; - let document0 = DocumentStub::from_cbor( + let document0 = Document::from_cbor( dashpay_cr_serialized_document0.as_slice(), None, Some(random_owner_id), @@ -454,7 +454,7 @@ mod tests { override_document: false, }); - let document1 = DocumentStub::from_cbor( + let document1 = Document::from_cbor( dashpay_cr_serialized_document1.as_slice(), None, Some(random_owner_id), @@ -573,7 +573,7 @@ mod tests { let mut operations = vec![]; - let document0 = DocumentStub::from_cbor( + let document0 = Document::from_cbor( person_serialized_document0.as_slice(), None, Some(random_owner_id0), @@ -594,7 +594,7 @@ mod tests { let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); - let document1 = DocumentStub::from_cbor( + let document1 = Document::from_cbor( person_serialized_document1.as_slice(), None, Some(random_owner_id1), @@ -701,7 +701,7 @@ mod tests { let mut operations = vec![]; - let document0 = DocumentStub::from_cbor( + let document0 = Document::from_cbor( person_serialized_document0.as_slice(), None, Some(random_owner_id0), @@ -722,7 +722,7 @@ mod tests { let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); - let document1 = DocumentStub::from_cbor( + let document1 = Document::from_cbor( person_serialized_document1.as_slice(), None, Some(random_owner_id1), @@ -778,7 +778,7 @@ mod tests { let mut operations = vec![]; - let document0 = DocumentStub::from_cbor( + let document0 = Document::from_cbor( person_serialized_document0.as_slice(), None, Some(random_owner_id0), @@ -792,7 +792,7 @@ mod tests { storage_flags: None, })); - let document1 = DocumentStub::from_cbor( + let document1 = Document::from_cbor( person_serialized_document1.as_slice(), None, Some(random_owner_id1), @@ -940,7 +940,7 @@ mod tests { let mut operations = vec![]; - let document0 = DocumentStub::from_cbor( + let document0 = Document::from_cbor( person_serialized_document0.as_slice(), None, Some(random_owner_id0), @@ -961,7 +961,7 @@ mod tests { let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); - let document1 = DocumentStub::from_cbor( + let document1 = Document::from_cbor( person_serialized_document1.as_slice(), None, Some(random_owner_id1), @@ -1017,7 +1017,7 @@ mod tests { let mut operations = vec![]; - let document0 = DocumentStub::from_cbor( + let document0 = Document::from_cbor( person_serialized_document0.as_slice(), None, Some(random_owner_id0), @@ -1031,7 +1031,7 @@ mod tests { storage_flags: None, })); - let document1 = DocumentStub::from_cbor( + let document1 = Document::from_cbor( person_serialized_document1.as_slice(), None, Some(random_owner_id1), diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 928bf271e44..fdd60f472b2 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -59,7 +59,7 @@ use crate::drive::object_size_info::DocumentInfo::{ DocumentEstimatedAverageSize, DocumentWithoutSerialization, }; use crate::drive::object_size_info::DriveKeyInfo::KeyRef; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use crate::drive::grove_operations::BatchDeleteApplyType::{ StatefulBatchDelete, StatelessBatchDelete, @@ -722,9 +722,9 @@ impl Drive { } else if let Some(document_element) = &document_element { if let Element::Item(data, element_flags) = document_element { //todo: remove this hack - let document = match DocumentStub::from_cbor(data.as_slice(), None, owner_id) { + let document = match Document::from_cbor(data.as_slice(), None, owner_id) { Ok(document) => Ok(document), - Err(_) => DocumentStub::from_bytes(data.as_slice(), document_type), + Err(_) => Document::from_bytes(data.as_slice(), document_type), }?; let storage_flags = StorageFlags::map_cow_some_element_flags_ref(element_flags)?; DocumentWithoutSerialization((document, storage_flags)) @@ -789,7 +789,7 @@ mod tests { use crate::fee::default_costs::KnownCostItem::StorageDiskUsageCreditPerByte; use crate::fee_pools::epochs::Epoch; use crate::query::DriveQuery; - use dpp::document::document_stub::DocumentStub; + use dpp::document::Document; use dpp::util::serializer; #[test] @@ -817,7 +817,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let document = - DocumentStub::from_cbor(&person_serialized_document, None, Some(random_owner_id)) + Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) .expect("expected to deserialize the document"); let document_type = contract @@ -915,7 +915,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let document = - DocumentStub::from_cbor(&person_serialized_document, None, Some(random_owner_id)) + Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) .expect("expected to deserialize the document"); let document_type = contract @@ -1029,7 +1029,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let document = - DocumentStub::from_cbor(&person_serialized_document, None, Some(random_owner_id)) + Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) .expect("expected to deserialize the document"); let document_type = contract @@ -1068,7 +1068,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let document = - DocumentStub::from_cbor(&person_serialized_document, None, Some(random_owner_id)) + Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) .expect("expected to deserialize the document"); let document_type = contract @@ -1216,7 +1216,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let document = - DocumentStub::from_cbor(&person_serialized_document, None, Some(random_owner_id)) + Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) .expect("expected to deserialize the document"); let document_type = contract @@ -1255,7 +1255,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let document = - DocumentStub::from_cbor(&person_serialized_document, None, Some(random_owner_id)) + Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) .expect("expected to deserialize the document"); let document_type = contract @@ -1333,7 +1333,7 @@ mod tests { let db_transaction = drive.grove.start_transaction(); let document = - DocumentStub::from_cbor(&person_serialized_document, None, Some(random_owner_id)) + Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) .expect("expected to deserialize the document"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -1645,12 +1645,12 @@ mod tests { let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); - let documents: Vec = document_hexes + let documents: Vec = document_hexes .iter() .map(|document_hex| { let serialized_document = cbor_from_hex(document_hex.to_string()); - let document = DocumentStub::from_cbor(&serialized_document, None, None) + let document = Document::from_cbor(&serialized_document, None, None) .expect("expected to deserialize the document"); let document_type = contract diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 316c697d281..c7bc16bcd8a 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -83,7 +83,7 @@ use crate::drive::grove_operations::{BatchInsertApplyType, BatchInsertTreeApplyT use crate::error::document::DocumentError; use crate::error::fee::FeeError; use crate::fee::result::FeeResult; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; impl Drive { /// Adds a document to primary storage. @@ -448,7 +448,7 @@ impl Drive { ) -> Result { let contract = ::from_cbor(serialized_contract, None)?; - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = DocumentRefAndSerialization((&document, serialized_document, storage_flags)); @@ -484,7 +484,7 @@ impl Drive { storage_flags: Option>, transaction: TransactionArg, ) -> Result { - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = DocumentRefAndSerialization((&document, serialized_document, storage_flags)); @@ -533,7 +533,7 @@ impl Drive { let contract = &contract_fetch_info.contract; - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = DocumentRefAndSerialization((&document, serialized_document, storage_flags)); @@ -1229,7 +1229,7 @@ mod tests { use crate::fee::default_costs::KnownCostItem::StorageDiskUsageCreditPerByte; use crate::fee::op::DriveOperation; use crate::fee_pools::epochs::Epoch; - use dpp::document::document_stub::DocumentStub; + use dpp::document::Document; #[test] fn test_add_dashpay_documents_no_transaction() { @@ -1587,9 +1587,8 @@ mod tests { .expect("expected to get cbor document"); let owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let document = - DocumentStub::from_cbor(&dashpay_cr_serialized_document, None, Some(owner_id)) - .expect("expected to deserialize document successfully"); + let document = Document::from_cbor(&dashpay_cr_serialized_document, None, Some(owner_id)) + .expect("expected to deserialize document successfully"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -1684,7 +1683,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let document = DocumentStub::from_cbor( + let document = Document::from_cbor( &dpns_domain_serialized_document, None, Some(random_owner_id), diff --git a/packages/rs-drive/src/drive/document/mod.rs b/packages/rs-drive/src/drive/document/mod.rs index 310209b3b4d..828d93fd025 100644 --- a/packages/rs-drive/src/drive/document/mod.rs +++ b/packages/rs-drive/src/drive/document/mod.rs @@ -37,7 +37,7 @@ use crate::drive::defaults::DEFAULT_HASH_SIZE_U8; use crate::drive::flags::StorageFlags; use crate::drive::{defaults, RootTree}; use dpp::data_contract::document_type::DocumentType; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use grovedb::batch::key_info::KeyInfo; use grovedb::batch::KeyInfoPath; use grovedb::reference_path::ReferencePathType::UpstreamRootHeightReference; @@ -138,7 +138,7 @@ fn contract_documents_keeping_history_storage_time_reference_path_size( /// Creates a reference to a document. fn make_document_reference( - document: &DocumentStub, + document: &Document, document_type: &DocumentType, storage_flags: Option<&StorageFlags>, ) -> Element { diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index e245b17d842..c89acdbdc6b 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -52,7 +52,7 @@ use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentInfo::{ DocumentRefAndSerialization, DocumentWithoutSerialization, }; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use crate::drive::object_size_info::PathKeyElementInfo::PathKeyRefElement; use crate::drive::object_size_info::{ @@ -89,7 +89,7 @@ impl Drive { ) -> Result { let contract = ::from_cbor(contract_cbor, None)?; - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; self.update_document_for_contract( &document, @@ -134,7 +134,7 @@ impl Drive { let contract = &contract_fetch_info.contract; - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = DocumentRefAndSerialization((&document, serialized_document, storage_flags)); @@ -173,7 +173,7 @@ impl Drive { storage_flags: Option>, transaction: TransactionArg, ) -> Result { - let document = DocumentStub::from_cbor(serialized_document, None, owner_id)?; + let document = Document::from_cbor(serialized_document, None, owner_id)?; self.update_document_for_contract( &document, @@ -191,7 +191,7 @@ impl Drive { /// Updates a document and returns the associated fee. pub fn update_document_for_contract( &self, - document: &DocumentStub, + document: &Document, serialized_document: &[u8], contract: &Contract, document_type_name: &str, @@ -359,11 +359,8 @@ impl Drive { let old_document_info = if let Some(old_document_element) = old_document_element { if let Element::Item(old_serialized_document, element_flags) = old_document_element { - let document = DocumentStub::from_cbor( - old_serialized_document.as_slice(), - None, - owner_id, - )?; + let document = + Document::from_cbor(old_serialized_document.as_slice(), None, owner_id)?; let storage_flags = StorageFlags::map_some_element_flags_ref(&element_flags)?; Ok(DocumentWithoutSerialization(( document, @@ -763,7 +760,7 @@ mod tests { let alice_profile_cbor = hex::decode("01a763246964582035edfec54aea574df968990abb47b39c206abe5c43a6157885f62958a1f1230c6524747970656770726f66696c656561626f75746a4920616d20416c69636568246f776e65724964582041d52f93f6f7c5af79ce994381c90df73cce2863d3850b9c05ef586ff0fe795f69247265766973696f6e016961766174617255726c7819687474703a2f2f746573742e636f6d2f616c6963652e6a70676f2464617461436f6e747261637449645820b0248cd9a27f86d05badf475dd9ff574d63219cd60c52e2be1e540c2fdd71333").unwrap(); - let alice_profile = DocumentStub::from_cbor(alice_profile_cbor.as_slice(), None, None) + let alice_profile = Document::from_cbor(alice_profile_cbor.as_slice(), None, None) .expect("expected to get a document"); let document_type = contract @@ -856,7 +853,7 @@ mod tests { let alice_profile_cbor = hex::decode("01a763246964582035edfec54aea574df968990abb47b39c206abe5c43a6157885f62958a1f1230c6524747970656770726f66696c656561626f75746a4920616d20416c69636568246f776e65724964582041d52f93f6f7c5af79ce994381c90df73cce2863d3850b9c05ef586ff0fe795f69247265766973696f6e016961766174617255726c7819687474703a2f2f746573742e636f6d2f616c6963652e6a70676f2464617461436f6e747261637449645820b0248cd9a27f86d05badf475dd9ff574d63219cd60c52e2be1e540c2fdd71333").unwrap(); - let alice_profile = DocumentStub::from_cbor(alice_profile_cbor.as_slice(), None, None) + let alice_profile = Document::from_cbor(alice_profile_cbor.as_slice(), None, None) .expect("expected to get a document"); let document_type = contract @@ -969,7 +966,7 @@ mod tests { let alice_profile_cbor = hex::decode("01a763246964582035edfec54aea574df968990abb47b39c206abe5c43a6157885f62958a1f1230c6524747970656770726f66696c656561626f75746a4920616d20416c69636568246f776e65724964582041d52f93f6f7c5af79ce994381c90df73cce2863d3850b9c05ef586ff0fe795f69247265766973696f6e016961766174617255726c7819687474703a2f2f746573742e636f6d2f616c6963652e6a70676f2464617461436f6e747261637449645820b0248cd9a27f86d05badf475dd9ff574d63219cd60c52e2be1e540c2fdd71333").unwrap(); - let alice_profile = DocumentStub::from_cbor(alice_profile_cbor.as_slice(), None, None) + let alice_profile = Document::from_cbor(alice_profile_cbor.as_slice(), None, None) .expect("expected to get a document"); let document_type = contract @@ -2056,7 +2053,7 @@ mod tests { let value = serde_json::to_value(person).expect("serialized person"); let document_cbor = serializer::value_to_cbor(value, Some(defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract .document_type_for_name("person") diff --git a/packages/rs-drive/src/drive/object_size_info.rs b/packages/rs-drive/src/drive/object_size_info.rs index 8a440bfa6a5..e60233385b9 100644 --- a/packages/rs-drive/src/drive/object_size_info.rs +++ b/packages/rs-drive/src/drive/object_size_info.rs @@ -53,7 +53,7 @@ use crate::drive::defaults::{DEFAULT_FLOAT_SIZE_U16, DEFAULT_HASH_SIZE_U16, DEFA use crate::drive::flags::StorageFlags; use crate::error::drive::DriveError; use crate::error::Error; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use crate::drive::object_size_info::PathKeyElementInfo::PathKeyUnknownElementSize; use crate::error::fee::FeeError; @@ -529,13 +529,13 @@ pub struct DocumentAndContractInfo<'a> { #[derive(Clone, Debug)] pub enum DocumentInfo<'a> { /// The borrowed document and it's serialized form - DocumentRefAndSerialization((&'a DocumentStub, &'a [u8], Option>)), + DocumentRefAndSerialization((&'a Document, &'a [u8], Option>)), /// The borrowed document without it's serialized form - DocumentRefWithoutSerialization((&'a DocumentStub, Option>)), + DocumentRefWithoutSerialization((&'a Document, Option>)), /// The document and it's serialized form - DocumentAndSerialization((DocumentStub, Vec, Option>)), + DocumentAndSerialization((Document, Vec, Option>)), /// The document without it's serialized form - DocumentWithoutSerialization((DocumentStub, Option>)), + DocumentWithoutSerialization((Document, Option>)), /// An element size DocumentEstimatedAverageSize(u32), } @@ -552,7 +552,7 @@ impl<'a> DocumentInfo<'a> { } /// Gets the borrowed document - pub fn get_borrowed_document(&self) -> Option<&DocumentStub> { + pub fn get_borrowed_document(&self) -> Option<&Document> { match self { DocumentInfo::DocumentRefAndSerialization((document, _, _)) | DocumentInfo::DocumentRefWithoutSerialization((document, _)) => Some(document), diff --git a/packages/rs-drive/src/query/conditions.rs b/packages/rs-drive/src/query/conditions.rs index 580e966faef..605f8f6d3e1 100644 --- a/packages/rs-drive/src/query/conditions.rs +++ b/packages/rs-drive/src/query/conditions.rs @@ -44,7 +44,7 @@ use WhereOperator::{ use crate::error::query::QueryError; use crate::error::Error; use dpp::data_contract::document_type::DocumentType; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; /// Converts SQL values to CBOR. fn sql_value_to_cbor(sql_value: ast::Value) -> Option { @@ -599,7 +599,7 @@ impl<'a> WhereClause { pub(crate) fn to_path_query( &self, document_type: &DocumentType, - start_at_document: &Option<(DocumentStub, bool)>, + start_at_document: &Option<(Document, bool)>, left_to_right: bool, ) -> Result { // If there is a start_at_document, we need to get the value that it has for the diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 82e90f349d4..7b729126319 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -67,7 +67,7 @@ use crate::fee::op::DriveOperation; use crate::drive::contract::paths::ContractPaths; use dpp::data_contract::extra::common::bytes_for_system_value; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use dpp::ProtocolError; pub mod conditions; @@ -520,7 +520,7 @@ impl<'a> DriveQuery<'a> { .map(|a| a.to_vec()) .collect::>>(); - let starts_at_document: Option<(DocumentStub, bool)> = match &self.start_at { + let starts_at_document: Option<(Document, bool)> = match &self.start_at { None => Ok(None), Some(starts_at) => { // First if we have a startAt or or startsAfter we must get the element @@ -571,7 +571,7 @@ impl<'a> DriveQuery<'a> { )))?; if let Element::Item(item, _) = start_at_document { - let document = DocumentStub::from_cbor(item.as_slice(), None, None)?; + let document = Document::from_cbor(item.as_slice(), None, None)?; Ok(Some((document, self.start_at_included))) } else { Err(Error::Drive(DriveError::CorruptedDocumentPath( @@ -591,7 +591,7 @@ impl<'a> DriveQuery<'a> { pub fn get_primary_key_path_query( &self, document_type_path: Vec>, - starts_at_document: Option<(DocumentStub, bool)>, + starts_at_document: Option<(Document, bool)>, ) -> Result { let mut path = document_type_path; @@ -798,7 +798,7 @@ impl<'a> DriveQuery<'a> { /// Returns a `Query` that either starts at or after the given document ID if given. fn inner_query_from_starts_at_for_id( - starts_at_document: &Option<(DocumentStub, &DocumentType, &IndexProperty, bool)>, + starts_at_document: &Option<(Document, &DocumentType, &IndexProperty, bool)>, left_to_right: bool, ) -> Query { // We only need items after the start at document @@ -847,7 +847,7 @@ impl<'a> DriveQuery<'a> { // The index property (borrowed) // if the element itself should be included. ie StartAt vs StartAfter fn inner_query_from_starts_at( - starts_at_document: &Option<(DocumentStub, &DocumentType, &IndexProperty, bool)>, + starts_at_document: &Option<(Document, &DocumentType, &IndexProperty, bool)>, left_to_right: bool, ) -> Result { let mut inner_query = Query::new_with_direction(left_to_right); @@ -888,7 +888,7 @@ impl<'a> DriveQuery<'a> { query: Option<&mut Query>, left_over_index_properties: &[&IndexProperty], unique: bool, - starts_at_document: &Option<(DocumentStub, &DocumentType, &IndexProperty, bool)>, //for key level, included + starts_at_document: &Option<(Document, &DocumentType, &IndexProperty, bool)>, //for key level, included default_left_to_right: bool, order_by: Option<&IndexMap>, ) -> Result, Error> { @@ -1012,7 +1012,7 @@ impl<'a> DriveQuery<'a> { pub fn get_non_primary_key_path_query( &self, document_type_path: Vec>, - starts_at_document: Option<(DocumentStub, bool)>, + starts_at_document: Option<(Document, bool)>, ) -> Result { let index = self.find_best_index()?; let ordered_clauses: Vec<&WhereClause> = index diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index 2beed9052ac..3f218266dcc 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -34,7 +34,7 @@ use std::borrow::Cow; use std::option::Option::None; use dpp::data_contract::DriveContractExt; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use dpp::util::serializer; use drive::common; use drive::common::setup_contract; @@ -123,7 +123,7 @@ pub fn add_domains_to_contract( let document_cbor = serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract .document_type_for_name("domain") diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 8fcc214bdf8..8a25b8dbffe 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -60,7 +60,7 @@ use drive::error::{query::QueryError, Error}; use drive::query::DriveQuery; use dpp::data_contract::validation::data_contract_validator::DataContractValidator; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use dpp::prelude::DataContract; use dpp::util::serializer; @@ -195,7 +195,7 @@ pub fn setup_family_tests(count: u32, with_batching: bool, seed: u64) -> (Drive, let document_cbor = serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -273,7 +273,7 @@ pub fn setup_family_tests_with_nulls( let document_cbor = serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract .document_type_for_name("person") @@ -350,7 +350,7 @@ pub fn setup_family_tests_only_first_name_index( let document_cbor = serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -458,7 +458,7 @@ pub fn add_domains_to_contract( let document_cbor = serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract .document_type_for_name("domain") @@ -557,7 +557,7 @@ pub fn setup_dpns_test_with_data(path: &str) -> (Drive, Contract) { ) .expect("expected to serialize to cbor"); - let domain = DocumentStub::from_cbor(&domain_cbor, None, None) + let domain = Document::from_cbor(&domain_cbor, None, None) .expect("expected to deserialize the document"); let document_type = contract @@ -609,7 +609,7 @@ fn test_query_many() { let document_cbor = serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract .document_type_for_name("person") @@ -783,7 +783,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -883,7 +883,7 @@ fn test_family_basic_queries() { assert_eq!(root_hash, proof_root_hash); assert_eq!(results, proof_results); - let document = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let document = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let last_name = document .properties @@ -982,7 +982,7 @@ fn test_family_basic_queries() { assert_eq!(root_hash, proof_root_hash); assert_eq!(results, proof_results); - let document = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let document = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let last_name = document .properties @@ -1098,7 +1098,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1150,7 +1150,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1197,7 +1197,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1247,7 +1247,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1301,7 +1301,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1345,7 +1345,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1401,7 +1401,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1456,7 +1456,7 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1488,7 +1488,7 @@ fn test_family_basic_queries() { let ages: HashMap = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let name_value = document .properties @@ -1538,7 +1538,7 @@ fn test_family_basic_queries() { Some(drive::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(person_cbor.as_slice(), None, None) + let document = Document::from_cbor(person_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -1588,7 +1588,7 @@ fn test_family_basic_queries() { Some(drive::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(person_cbor.as_slice(), None, None) + let document = Document::from_cbor(person_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -1687,7 +1687,7 @@ fn test_family_basic_queries() { assert_eq!(results.len(), 2); - let last_person = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); assert_eq!( @@ -1728,7 +1728,7 @@ fn test_family_basic_queries() { assert_eq!(results.len(), 2); - let last_person = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); assert_eq!( @@ -1792,7 +1792,7 @@ fn test_family_basic_queries() { assert_eq!(results.len(), 12); - let last_person = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); assert_eq!( @@ -2067,7 +2067,7 @@ fn test_family_starts_at_queries() { let reduced_names_after: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -2122,7 +2122,7 @@ fn test_family_starts_at_queries() { let reduced_names_after: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -2171,7 +2171,7 @@ fn test_family_starts_at_queries() { let reduced_names_after: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -2227,7 +2227,7 @@ fn test_family_starts_at_queries() { let reduced_names_after: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -2451,7 +2451,7 @@ fn test_family_with_nulls_query() { .clone() .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -2479,7 +2479,7 @@ fn test_family_with_nulls_query() { let ids: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); base64::encode(document.id) }) @@ -2625,7 +2625,7 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -2672,7 +2672,7 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -2702,7 +2702,7 @@ fn test_dpns_query() { let ids: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); hex::encode(document.id) }) @@ -2747,7 +2747,7 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -2801,7 +2801,7 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -2827,7 +2827,7 @@ fn test_dpns_query() { let record_id_base64: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let records_value = document @@ -2872,7 +2872,7 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -2924,7 +2924,7 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -3142,7 +3142,7 @@ fn test_dpns_query_start_at() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -3229,7 +3229,7 @@ fn test_dpns_query_start_after() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -3316,7 +3316,7 @@ fn test_dpns_query_start_at_desc() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -3403,7 +3403,7 @@ fn test_dpns_query_start_after_desc() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -3460,7 +3460,7 @@ fn test_dpns_query_start_at_with_null_id() { let document_cbor0 = serializer::value_to_cbor(value0, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document0 = DocumentStub::from_cbor(document_cbor0.as_slice(), None, None) + let document0 = Document::from_cbor(document_cbor0.as_slice(), None, None) .expect("document should be properly deserialized"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -3505,7 +3505,7 @@ fn test_dpns_query_start_at_with_null_id() { let document_cbor1 = serializer::value_to_cbor(value1, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document1 = DocumentStub::from_cbor(document_cbor1.as_slice(), None, None) + let document1 = Document::from_cbor(document_cbor1.as_slice(), None, None) .expect("document should be properly deserialized"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -3594,7 +3594,7 @@ fn test_dpns_query_start_at_with_null_id() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -3659,7 +3659,7 @@ fn test_dpns_query_start_after_with_null_id() { let document_cbor0 = serializer::value_to_cbor(value0, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document0 = DocumentStub::from_cbor(document_cbor0.as_slice(), None, None) + let document0 = Document::from_cbor(document_cbor0.as_slice(), None, None) .expect("document should be properly deserialized"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -3704,7 +3704,7 @@ fn test_dpns_query_start_after_with_null_id() { let document_cbor1 = serializer::value_to_cbor(value1, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document1 = DocumentStub::from_cbor(document_cbor1.as_slice(), None, None) + let document1 = Document::from_cbor(document_cbor1.as_slice(), None, None) .expect("document should be properly deserialized"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -3800,7 +3800,7 @@ fn test_dpns_query_start_after_with_null_id() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties @@ -3861,7 +3861,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { let document_cbor0 = serializer::value_to_cbor(value0, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document0 = DocumentStub::from_cbor(document_cbor0.as_slice(), None, None) + let document0 = Document::from_cbor(document_cbor0.as_slice(), None, None) .expect("document should be properly deserialized"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -3906,7 +3906,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { let document_cbor1 = serializer::value_to_cbor(value1, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document1 = DocumentStub::from_cbor(document_cbor1.as_slice(), None, None) + let document1 = Document::from_cbor(document_cbor1.as_slice(), None, None) .expect("document should be properly deserialized"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -4006,7 +4006,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { .clone() .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); Vec::from(document.id) }) @@ -4054,7 +4054,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { let docs: Vec> = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); Vec::from(document.id) }) @@ -4103,7 +4103,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let normalized_label_value = document .properties diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 95721332fd2..e4f6e60ebd0 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -36,7 +36,7 @@ use std::fmt::{Debug, Formatter}; use std::option::Option::None; use dpp::data_contract::DriveContractExt; -use dpp::document::document_stub::DocumentStub; +use dpp::document::Document; use dpp::util::serializer; use rand::seq::SliceRandom; use rand::{Rng, SeedableRng}; @@ -199,7 +199,7 @@ pub fn setup( let document_cbor = serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(document_cbor.as_slice(), None, None) + let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract .document_type_for_name("person") @@ -304,7 +304,7 @@ fn test_query_historical() { let names: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -376,7 +376,7 @@ fn test_query_historical() { assert_eq!(results.len(), 1); - let document = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let document = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let last_name = document .properties @@ -451,7 +451,7 @@ fn test_query_historical() { assert_eq!(results.len(), 1); - let document = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let document = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let last_name = document .properties @@ -543,7 +543,7 @@ fn test_query_historical() { let names: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -589,7 +589,7 @@ fn test_query_historical() { let names: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -633,7 +633,7 @@ fn test_query_historical() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -663,7 +663,7 @@ fn test_query_historical() { let ids: HashMap> = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let name_value = document .properties @@ -709,7 +709,7 @@ fn test_query_historical() { let reduced_names_after: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -759,7 +759,7 @@ fn test_query_historical() { let reduced_names_after: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -801,7 +801,7 @@ fn test_query_historical() { let names: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -840,7 +840,7 @@ fn test_query_historical() { .clone() .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -856,7 +856,7 @@ fn test_query_historical() { let ages: Vec = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let age_value = document .properties @@ -912,7 +912,7 @@ fn test_query_historical() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -962,7 +962,7 @@ fn test_query_historical() { let names: Vec = results .iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -988,7 +988,7 @@ fn test_query_historical() { let ages: HashMap = results .into_iter() .map(|result| { - let document = DocumentStub::from_cbor(result.as_slice(), None, None) + let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); let name_value = document .properties @@ -1039,7 +1039,7 @@ fn test_query_historical() { Some(drive::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(person_cbor.as_slice(), None, None) + let document = Document::from_cbor(person_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -1090,7 +1090,7 @@ fn test_query_historical() { Some(drive::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to serialize to cbor"); - let document = DocumentStub::from_cbor(person_cbor.as_slice(), None, None) + let document = Document::from_cbor(person_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -1228,7 +1228,7 @@ fn test_query_historical() { assert_eq!(results.len(), 2); - let last_person = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); assert_eq!( @@ -1269,7 +1269,7 @@ fn test_query_historical() { assert_eq!(results.len(), 2); - let last_person = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); assert_eq!( @@ -1333,7 +1333,7 @@ fn test_query_historical() { assert_eq!(results.len(), 12); - let last_person = DocumentStub::from_cbor(results.first().unwrap().as_slice(), None, None) + let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) .expect("we should be able to deserialize the cbor"); assert_eq!( diff --git a/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs b/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs index 893f3be2da7..645438c65ab 100644 --- a/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs +++ b/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs @@ -1,4 +1,4 @@ -use dpp::prelude::Document; +use dpp::document::DocumentInStateTransition; use itertools::Itertools; use thiserror::Error; @@ -29,7 +29,7 @@ impl MismatchOwnerIdsError { } impl MismatchOwnerIdsError { - pub fn from_documents(documents: Vec) -> MismatchOwnerIdsError { + pub fn from_documents(documents: Vec) -> MismatchOwnerIdsError { Self { documents: documents.into_iter().map(DocumentWasm::from).collect_vec(), } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 9cbfea3d13e..fceb4ef5dcb 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use dpp::document::document_transition::document_in_state_transition; use dpp::{ document::{ self, @@ -137,7 +138,10 @@ impl DocumentFactoryWASM { // When `Identifier` crosses the WASM boundary, it becomes a String. From perspective of JS // `Identifier` and `Buffer` are used interchangeably, so we we can expect the replacing may fail when `Buffer` is provided let _ = raw_document - .replace_identifier_paths(document::IDENTIFIER_FIELDS, ReplaceWith::Bytes) + .replace_identifier_paths( + document_in_state_transition::IDENTIFIER_FIELDS, + ReplaceWith::Bytes, + ) .with_js_error(); let mut document = self diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 2b2c25d0c56..d471b2afcb8 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -7,8 +7,6 @@ use serde::{Deserialize, Serialize}; use std::convert::TryInto; use wasm_bindgen::prelude::*; -use dpp::document::{property_names, Document, IDENTIFIER_FIELDS}; - use crate::buffer::Buffer; use crate::errors::RustConversionError; use crate::identifier::IdentifierWrapper; @@ -25,6 +23,10 @@ pub mod state_transition; mod validator; pub use document_batch_transition::{DocumentsBatchTransitionWASM, DocumentsContainer}; +use dpp::document::{ + document_in_state_transition_property_names, DocumentInStateTransition, + DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS, +}; pub use factory::DocumentFactoryWASM; pub use validator::DocumentValidatorWasm; @@ -42,7 +44,7 @@ pub struct ConversionOptions { #[wasm_bindgen(js_name=Document)] #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DocumentWasm(Document); +pub struct DocumentWasm(DocumentInStateTransition); #[wasm_bindgen(js_class=Document)] impl DocumentWasm { @@ -54,7 +56,7 @@ impl DocumentWasm { let mut raw_document = with_serde_to_json_value(&js_raw_document)?; let document_type = raw_document - .get_string(property_names::DOCUMENT_TYPE) + .get_string(document_in_state_transition_property_names::DOCUMENT_TYPE) .with_js_error()?; let (identifier_paths, _) = js_data_contract @@ -67,15 +69,19 @@ impl DocumentWasm { // `Identifier` and `Buffer` are used interchangeably, so we we can expect the replacing may fail when `Buffer` is provided let _ = raw_document .replace_identifier_paths( - identifier_paths.into_iter().chain(IDENTIFIER_FIELDS), + identifier_paths + .into_iter() + .chain(DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS), ReplaceWith::Bytes, ) .with_js_error(); // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array - let document = - Document::from_raw_document(raw_document, js_data_contract.to_owned().into()) - .with_js_error()?; + let document = DocumentInStateTransition::from_raw_document( + raw_document, + js_data_contract.to_owned().into(), + ) + .with_js_error()?; Ok(document.into()) } @@ -275,7 +281,10 @@ impl DocumentWasm { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_value = value.serialize(&serializer)?; - for path in identifiers_paths.into_iter().chain(IDENTIFIER_FIELDS) { + for path in identifiers_paths + .into_iter() + .chain(DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS) + { if let Ok(bytes) = value.remove_path_into::>(path) { if !options.skip_identifiers_conversion { let buffer = Buffer::from_bytes(&bytes); @@ -343,8 +352,8 @@ impl DocumentWasm { } } -impl From for DocumentWasm { - fn from(d: Document) -> Self { +impl From for DocumentWasm { + fn from(d: DocumentInStateTransition) -> Self { DocumentWasm(d) } } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 6792c1bfdd3..928fc83e8fa 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,9 +1,10 @@ +use dpp::document::DocumentInStateTransition; use dpp::identity::KeyID; use dpp::{ document::{ state_transition::documents_batch_transition::property_names, DocumentsBatchTransition, }, - prelude::{DataContract, Document, Identifier}, + prelude::{DataContract, Identifier}, state_transition::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, @@ -34,9 +35,9 @@ pub struct DocumentsBatchTransitionWASM(DocumentsBatchTransition); #[derive(Debug, Default)] #[wasm_bindgen(js_name=DocumentsContainer)] pub struct DocumentsContainer { - create: Vec, - replace: Vec, - delete: Vec, + create: Vec, + replace: Vec, + delete: Vec, } #[wasm_bindgen(js_class=DocumentsContainer)] @@ -63,15 +64,15 @@ impl DocumentsContainer { } impl DocumentsContainer { - pub fn take_documents_create(&mut self) -> Vec { + pub fn take_documents_create(&mut self) -> Vec { std::mem::take(&mut self.create) } - pub fn take_documents_replace(&mut self) -> Vec { + pub fn take_documents_replace(&mut self) -> Vec { std::mem::take(&mut self.replace) } - pub fn take_documents_delete(&mut self) -> Vec { + pub fn take_documents_delete(&mut self) -> Vec { std::mem::take(&mut self.delete) } } diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 61c47cc3fb9..0e744981504 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -14,7 +14,6 @@ use dpp::prelude::{Revision, TimestampMillis}; use dpp::{ dashcore::InstantLock, data_contract::DataContract, - document::Document, prelude::{Identifier, Identity}, state_repository::{ FetchTransactionResponse as FetchTransactionResponseDPP, StateRepositoryLike, @@ -25,6 +24,7 @@ use js_sys::Uint8Array; use js_sys::{Array, Number}; use wasm_bindgen::__rt::Ref; +use dpp::document::DocumentInStateTransition; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; @@ -275,7 +275,7 @@ impl StateRepositoryLike for ExternalStateRepositoryLikeWrapper { async fn create_document( &self, - _document: &Document, + _document: &DocumentInStateTransition, _execution_context: &StateTransitionExecutionContext, ) -> Result<()> { todo!() @@ -283,7 +283,7 @@ impl StateRepositoryLike for ExternalStateRepositoryLikeWrapper { async fn update_document( &self, - _document: &Document, + _document: &DocumentInStateTransition, _execution_context: &StateTransitionExecutionContext, ) -> Result<()> { todo!() From 58872cbbe3dce87012361afb04e7ffa81b3e5442 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Feb 2023 20:01:09 +0700 Subject: [PATCH 002/228] added revision to documents when needed --- .../document_type/random_document.rs | 14 +++++ packages/rs-dpp/src/document/document.rs | 4 ++ packages/rs-dpp/src/document/serialize.rs | 37 +++++++++++- .../rs-dpp/src/util/cbor_value/cbor_map.rs | 58 ++++++++++++++++--- packages/rs-drive-abci/src/state/genesis.rs | 5 +- .../src/test/helpers/fee_pools.rs | 1 + 6 files changed, 108 insertions(+), 11 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/random_document.rs b/packages/rs-dpp/src/data_contract/document_type/random_document.rs index 2a3fada856a..efe3183f871 100644 --- a/packages/rs-dpp/src/data_contract/document_type/random_document.rs +++ b/packages/rs-dpp/src/data_contract/document_type/random_document.rs @@ -105,10 +105,17 @@ impl CreateRandomDocument for DocumentType { }) .collect(); + let revision = if self.documents_mutable { + Some(1) + } else { + None + }; + Document { id, properties, owner_id, + revision, } } @@ -152,10 +159,17 @@ impl CreateRandomDocument for DocumentType { }) .collect(); + let revision = if self.documents_mutable { + Some(1) + } else { + None + }; + Document { id, properties, owner_id, + revision, } } } diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 30f57313f00..08be21d2df2 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -67,6 +67,10 @@ pub struct Document { /// The ID of the document's owner. #[serde(rename = "$ownerId")] pub owner_id: [u8; 32], + + /// The document revision. + #[serde(rename = "$revision")] + pub revision: Option, } impl Document { diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 294363f3bda..bbdbc58bebb 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -4,10 +4,12 @@ use crate::data_contract::errors::{DataContractError, StructureError}; use crate::data_contract::extra::common::bytes_for_system_value_from_tree_map; use crate::document::Document; use crate::document::DocumentInStateTransition; +use crate::util::cbor_value::CborBTreeMapHelper; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::ProtocolError; use bincode::Options; +use byteorder::{BigEndian, ReadBytesExt}; use ciborium::Value; use integer_encoding::VarIntWriter; use std::collections::BTreeMap; @@ -22,6 +24,9 @@ impl Document { pub fn serialize(&self, document_type: &DocumentType) -> Result, ProtocolError> { let mut buffer: Vec = self.id.as_slice().to_vec(); buffer.extend(self.owner_id.as_slice()); + if let Some(revision) = self.revision { + buffer.extend(revision.to_be_bytes()) + } document_type .properties .iter() @@ -56,6 +61,10 @@ impl Document { let mut buffer: Vec = Vec::try_from(self.id).unwrap(); let mut owner_id = Vec::try_from(self.owner_id).unwrap(); buffer.append(&mut owner_id); + + if let Some(revision) = self.revision { + buffer.extend(revision.to_be_bytes()) + } document_type .properties .iter() @@ -92,14 +101,30 @@ impl Document { } let mut id = [0; 32]; buf.read_exact(&mut id).map_err(|_| { - ProtocolError::DecodingError("error reading from serialized document".to_string()) + ProtocolError::DecodingError( + "error reading from serialized document for id".to_string(), + ) })?; let mut owner_id = [0; 32]; buf.read_exact(&mut owner_id).map_err(|_| { - ProtocolError::DecodingError("error reading from serialized document".to_string()) + ProtocolError::DecodingError( + "error reading from serialized document for owner id".to_string(), + ) })?; + // if the document type is mutable then we should deserialize the revision + let revision = if document_type.documents_mutable { + let revision = buf.read_u32::().map_err(|_| { + ProtocolError::DecodingError( + "error reading revision from serialized document for revision".to_string(), + ) + })?; + Some(revision) + } else { + None + }; + let properties = document_type .properties .iter() @@ -115,6 +140,7 @@ impl Document { id, properties, owner_id, + revision, }) } @@ -182,14 +208,18 @@ impl Document { } .expect("document_id must be 32 bytes"); + let revision = document.remove_optional_integer("$revision")?; + // dev-note: properties is everything other than the id and owner id Ok(Document { properties: document, owner_id, id, + revision, }) } + //todo: remove (I think) /// Reads a CBOR-serialized document and creates a Document from it with the provided IDs. pub fn from_cbor_with_id( document_cbor: &[u8], @@ -222,6 +252,8 @@ impl Document { )) })?; + let revision = properties.get_optional_integer("$revision")?; + // dev-note: properties is everything other than the id and owner id Ok(Document { properties, @@ -231,6 +263,7 @@ impl Document { id: document_id .try_into() .expect("try_into shouldn't fail, document_id must be 32 bytes"), + revision, }) } diff --git a/packages/rs-dpp/src/util/cbor_value/cbor_map.rs b/packages/rs-dpp/src/util/cbor_value/cbor_map.rs index 77f779ea024..fac407de9c4 100644 --- a/packages/rs-dpp/src/util/cbor_value/cbor_map.rs +++ b/packages/rs-dpp/src/util/cbor_value/cbor_map.rs @@ -47,6 +47,12 @@ pub trait CborBTreeMapHelper { &'a self, key: &str, ) -> Result; + + fn remove_optional_integer>( + &mut self, + key: &str, + ) -> Result, ProtocolError>; + fn remove_integer>(&mut self, key: &str) -> Result; } pub trait CborMapExtension { @@ -108,14 +114,22 @@ where ) -> Result, ProtocolError> { self.get(key) .map(|v| { - i128::from(v.borrow().as_integer().ok_or_else(|| { - ProtocolError::DecodingError(format!("{key} must be an integer")) - })?) - .try_into() - .map_err(|_| { - ProtocolError::DecodingError(format!("{key} is out of required bounds")) - }) + if v.borrow().is_null() { + Ok::>, ProtocolError>(None) + } else { + Ok(Some( + i128::from(v.borrow().as_integer().ok_or_else(|| { + ProtocolError::DecodingError(format!("{key} must be an integer")) + })?) + .try_into() + .map_err(|_| { + ProtocolError::DecodingError(format!("{key} is out of required bounds")) + }), + )) + } }) + .transpose()? + .flatten() .transpose() } @@ -124,6 +138,36 @@ where .ok_or_else(|| ProtocolError::DecodingError(format!("unable to get property {key}"))) } + fn remove_optional_integer>( + &mut self, + key: &str, + ) -> Result, ProtocolError> { + self.remove(key) + .map(|v| { + if v.borrow().is_null() { + Ok::>, ProtocolError>(None) + } else { + Ok(Some( + i128::from(v.borrow().as_integer().ok_or_else(|| { + ProtocolError::DecodingError(format!("{key} must be an integer")) + })?) + .try_into() + .map_err(|_| { + ProtocolError::DecodingError(format!("{key} is out of required bounds")) + }), + )) + } + }) + .transpose()? + .flatten() + .transpose() + } + + fn remove_integer>(&mut self, key: &str) -> Result { + self.remove_optional_integer(key)? + .ok_or_else(|| ProtocolError::DecodingError(format!("unable to remove property {key}"))) + } + fn get_optional_bool(&self, key: &str) -> Result, ProtocolError> { self.get(key) .map(|v| { diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index fd661690c1c..32c1ba3212f 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -266,10 +266,11 @@ impl Platform { let document_cbor = document.to_buffer()?; - let document_stub = Document { + let document = Document { id: DPNS_DASH_TLD_DOCUMENT_ID, properties: document_stub_properties, owner_id: contract.owner_id.to_buffer(), + revision: None, }; let document_type = contract.document_type_for_name("domain")?; @@ -280,7 +281,7 @@ impl Platform { owned_document_info: OwnedDocumentInfo { //todo: remove cbor and use DocumentInfo::DocumentWithoutSerialization((document, None)) document_info: DocumentInfo::DocumentAndSerialization(( - document_stub, + document, document_cbor, None, )), diff --git a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs index 4288778bd72..eb381774646 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -76,6 +76,7 @@ fn create_test_mn_share_document( id, properties, owner_id: identity_id, + revision: Some(1), }; let document_type = contract From 8bf90ef1c7e56ff30574b6d75a951ce9e7520a33 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Feb 2023 04:22:27 +0700 Subject: [PATCH 003/228] more work on serialization --- .../document_type/random_document.rs | 28 ++- packages/rs-dpp/src/document/document.rs | 38 +++- packages/rs-dpp/src/document/serialize.rs | 192 +++++++++++++----- packages/rs-drive-abci/src/state/genesis.rs | 2 + .../src/test/helpers/fee_pools.rs | 2 + 5 files changed, 196 insertions(+), 66 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/random_document.rs b/packages/rs-dpp/src/data_contract/document_type/random_document.rs index efe3183f871..31522237f01 100644 --- a/packages/rs-dpp/src/data_contract/document_type/random_document.rs +++ b/packages/rs-dpp/src/data_contract/document_type/random_document.rs @@ -33,6 +33,7 @@ //! create various types of random documents. //! +use crate::data_contract::document_type::property_names::{CREATED_AT, UPDATED_AT}; use crate::data_contract::document_type::DocumentType; use crate::document::Document; use crate::ProtocolError; @@ -97,14 +98,31 @@ impl CreateRandomDocument for DocumentType { fn random_document_with_rng(&self, rng: &mut StdRng) -> Document { let id = rng.gen::<[u8; 32]>(); let owner_id = rng.gen::<[u8; 32]>(); - let properties = self + let mut created_at = None; + let mut updated_at = None; + let mut properties = self .properties .iter() - .map(|(key, document_field)| { - (key.clone(), document_field.document_type.random_value(rng)) + .filter_map(|(key, document_field)| { + if key == CREATED_AT { + created_at = Some(rng.gen_range(1575072000000..1890691200000)); + None + } else if key == UPDATED_AT { + updated_at = Some(0); + None + } else { + Some((key.clone(), document_field.document_type.random_value(rng))) + } }) .collect(); + if updated_at.is_some() { + if let Some(created_at) = created_at { + updated_at = Some(rng.gen_range(created_at..1990691200000)); + } else { + updated_at = Some(rng.gen_range(1575072000000..1890691200000)); + } + } let revision = if self.documents_mutable { Some(1) } else { @@ -116,6 +134,8 @@ impl CreateRandomDocument for DocumentType { properties, owner_id, revision, + created_at, + updated_at, } } @@ -170,6 +190,8 @@ impl CreateRandomDocument for DocumentType { properties, owner_id, revision, + created_at: None, + updated_at: None, } } } diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 08be21d2df2..8dedeac3df0 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -32,6 +32,7 @@ //! This module defines the `Document` struct and implements its functions. //! +use chrono::{DateTime, NaiveDateTime, Utc}; use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; use std::fmt; @@ -49,28 +50,40 @@ use crate::data_contract::extra::common::{ bytes_for_system_value_from_tree_map, get_key_from_cbor_map, reduced_value_string_representation, }; +use crate::identity::TimestampMillis; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::ProtocolError; +/// The property names of a document +pub mod property_names { + pub const ID: &str = "$id"; + pub const DOCUMENT_TYPE: &str = "$type"; + pub const REVISION: &str = "$revision"; + pub const OWNER_ID: &str = "$ownerId"; + pub const CREATED_AT: &str = "$createdAt"; + pub const UPDATED_AT: &str = "$updatedAt"; +} + /// Documents contain the data that goes into data contracts. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct Document { /// The unique document ID. #[serde(rename = "$id")] pub id: [u8; 32], - - /// The document's properties (data). - #[serde(flatten)] - pub properties: BTreeMap, - /// The ID of the document's owner. #[serde(rename = "$ownerId")] pub owner_id: [u8; 32], - + /// The document's properties (data). + #[serde(flatten)] + pub properties: BTreeMap, /// The document revision. #[serde(rename = "$revision")] pub revision: Option, + #[serde(rename = "$createdAt")] + pub created_at: Option, + #[serde(rename = "$updatedAt")] + pub updated_at: Option, } impl Document { @@ -162,6 +175,17 @@ impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "id:{} ", bs58::encode(self.id).into_string())?; write!(f, "owner_id:{} ", bs58::encode(self.owner_id).into_string())?; + if let Some(created_at) = self.created_at { + let naive = NaiveDateTime::from_timestamp_millis(created_at as i64).unwrap_or_default(); + let datetime: DateTime = DateTime::from_utc(naive, Utc); + write!(f, "created_at:{} ", datetime.format("%Y-%m-%d %H:%M:%S"))?; + } + if let Some(updated_at) = self.updated_at { + let naive = NaiveDateTime::from_timestamp_millis(updated_at as i64).unwrap_or_default(); + let datetime: DateTime = DateTime::from_utc(naive, Utc); + write!(f, "updated_at:{} ", datetime.format("%Y-%m-%d %H:%M:%S"))?; + } + if self.properties.is_empty() { write!(f, "no properties")?; } else { @@ -249,6 +273,6 @@ mod tests { let document = document_type.random_document(Some(3333)); let document_string = format!("{}", document); - assert_eq!(document_string.as_str(), "id:2vq574DjKi7ZD8kJ6dMHxT5wu6ZKD2bW5xKAyKAGW7qZ owner_id:ChTEGXJcpyknkADUC5s6tAzvPqVG7x6Lo1Nr5mFtj2mk $createdAt:1627081806.116 $updatedAt:1575820087.909 avatarUrl:1DbW18RuyblDX7hxB38O[...(106)] displayName:rzhRkzY2L213txD6gR2S[...(21)] publicMessage:ixPGeedfb4oeyipRFe8y[...(57)] ") + assert_eq!(document_string.as_str(), "id:2vq574DjKi7ZD8kJ6dMHxT5wu6ZKD2bW5xKAyKAGW7qZ owner_id:ChTEGXJcpyknkADUC5s6tAzvPqVG7x6Lo1Nr5mFtj2mk created_at:2027-09-24 14:16:54 updated_at:2030-06-20 21:52:44 avatarUrl:RD1DbW18RuyblDX7hxB3[...(1936)] displayName:jALmlamgYbnlKUkT1 publicMessage:oyGtAOjibsOvx9OUjxVO[...(110)] ") } } diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index bbdbc58bebb..51f4aca39b2 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -2,6 +2,7 @@ use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::data_contract::errors::{DataContractError, StructureError}; use crate::data_contract::extra::common::bytes_for_system_value_from_tree_map; +use crate::document::document::property_names::{CREATED_AT, UPDATED_AT}; use crate::document::Document; use crate::document::DocumentInStateTransition; use crate::util::cbor_value::CborBTreeMapHelper; @@ -31,7 +32,37 @@ impl Document { .properties .iter() .try_for_each(|(field_name, field)| { - if let Some(value) = self.properties.get(field_name) { + if field_name == CREATED_AT { + if let Some(created_at) = self.created_at { + buffer.extend(created_at.to_be_bytes()); + Ok(()) + } else if field.required { + Err(ProtocolError::DataContractError( + DataContractError::MissingRequiredKey( + "created at field is not present", + ), + )) + } else { + // We don't have the created_at that wasn't required + buffer.push(0); + Ok(()) + } + } else if field_name == UPDATED_AT { + if let Some(updated_at) = self.updated_at { + buffer.extend(updated_at.to_be_bytes()); + Ok(()) + } else if field.required { + Err(ProtocolError::DataContractError( + DataContractError::MissingRequiredKey( + "created at field is not present", + ), + )) + } else { + // We don't have the updated_at that wasn't required + buffer.push(0); + Ok(()) + } + } else if let Some(value) = self.properties.get(field_name) { let value = field .document_type .encode_value_ref_with_size(value, field.required)?; @@ -47,6 +78,7 @@ impl Document { Ok(()) } })?; + Ok(buffer) } @@ -69,7 +101,37 @@ impl Document { .properties .iter() .try_for_each(|(field_name, field)| { - if let Some(value) = self.properties.remove(field_name) { + if field_name == CREATED_AT { + if let Some(created_at) = self.created_at { + buffer.extend(created_at.to_be_bytes()); + Ok(()) + } else if field.required { + Err(ProtocolError::DataContractError( + DataContractError::MissingRequiredKey( + "created at field is not present", + ), + )) + } else { + // We don't have the created_at that wasn't required + buffer.push(0); + Ok(()) + } + } else if field_name == UPDATED_AT { + if let Some(updated_at) = self.updated_at { + buffer.extend(updated_at.to_be_bytes()); + Ok(()) + } else if field.required { + Err(ProtocolError::DataContractError( + DataContractError::MissingRequiredKey( + "created at field is not present", + ), + )) + } else { + // We don't have the updated_at that wasn't required + buffer.push(0); + Ok(()) + } + } else if let Some(value) = self.properties.remove(field_name) { let value = field .document_type .encode_value_with_size(value, field.required)?; @@ -85,6 +147,7 @@ impl Document { Ok(()) } })?; + Ok(buffer) } @@ -124,15 +187,74 @@ impl Document { } else { None }; - - let properties = document_type + let mut created_at = None; + let mut updated_at = None; + let mut properties = document_type .properties .iter() .filter_map(|(key, field)| { - let read_value = field.document_type.read_from(&mut buf, field.required); - match read_value { - Ok(read_value) => read_value.map(|read_value| Ok((key.clone(), read_value))), - Err(e) => Some(Err(e)), + if key == CREATED_AT { + if !field.required { + let marker_result = buf.read_u8().map_err(|_| { + ProtocolError::DataContractError(DataContractError::CorruptedSerialization( + "error reading created at optional byte from serialized document", + )) + }); + match marker_result { + Ok(marker) => { + if marker == 0 { + return None; + } + } + Err(e) => return Some(Err(e)), + } + } + let integer_result = buf.read_u64::().map_err(|_| { + ProtocolError::DataContractError(DataContractError::CorruptedSerialization( + "error reading created at from serialized document", + )) + }); + match integer_result { + Ok(integer) => { + created_at = Some(integer); + None + } + Err(e) => Some(Err(e)), + } + } else if key == UPDATED_AT { + if !field.required { + let marker_result = buf.read_u8().map_err(|_| { + ProtocolError::DataContractError(DataContractError::CorruptedSerialization( + "error reading updated at optional byte from serialized document", + )) + }); + match marker_result { + Ok(marker) => { + if marker == 0 { + return None; + } + } + Err(e) => return Some(Err(e)), + } + } + let integer_result = buf.read_u64::().map_err(|_| { + ProtocolError::DataContractError(DataContractError::CorruptedSerialization( + "error reading updated at from serialized document", + )) + }); + match integer_result { + Ok(integer) => { + updated_at = Some(integer); + None + } + Err(e) => Some(Err(e)), + } + } else { + let read_value = field.document_type.read_from(&mut buf, field.required); + match read_value { + Ok(read_value) => read_value.map(|read_value| Ok((key.clone(), read_value))), + Err(e) => Some(Err(e)), + } } }) .collect::, ProtocolError>>()?; @@ -141,6 +263,8 @@ impl Document { properties, owner_id, revision, + created_at, + updated_at, }) } @@ -209,6 +333,8 @@ impl Document { .expect("document_id must be 32 bytes"); let revision = document.remove_optional_integer("$revision")?; + let created_at = document.remove_optional_integer("$createdAt")?; + let updated_at = document.remove_optional_integer("$updatedAt")?; // dev-note: properties is everything other than the id and owner id Ok(Document { @@ -216,54 +342,8 @@ impl Document { owner_id, id, revision, - }) - } - - //todo: remove (I think) - /// Reads a CBOR-serialized document and creates a Document from it with the provided IDs. - pub fn from_cbor_with_id( - document_cbor: &[u8], - document_id: &[u8], - owner_id: &[u8], - ) -> Result { - // we need to start by verifying that the owner_id is a 256 bit number (32 bytes) - if owner_id.len() != 32 { - return Err(ProtocolError::DataContractError( - DataContractError::FieldRequirementUnmet("invalid owner id"), - )); - } - - if document_id.len() != 32 { - return Err(ProtocolError::DataContractError( - DataContractError::FieldRequirementUnmet("invalid document id"), - )); - } - let SplitProtocolVersionOutcome { - main_message_bytes: read_document_cbor, - .. - } = deserializer::split_protocol_version(document_cbor)?; - - // first we need to deserialize the document and contract indices - // we would need dedicated deserialization functions based on the document type - let properties: BTreeMap = ciborium::de::from_reader(read_document_cbor) - .map_err(|_| { - ProtocolError::StructureError(StructureError::InvalidCBOR( - "unable to decode contract for document call with id", - )) - })?; - - let revision = properties.get_optional_integer("$revision")?; - - // dev-note: properties is everything other than the id and owner id - Ok(Document { - properties, - owner_id: owner_id - .try_into() - .expect("try_into shouldn't fail, document_id must be 32 bytes"), - id: document_id - .try_into() - .expect("try_into shouldn't fail, document_id must be 32 bytes"), - revision, + created_at, + updated_at, }) } diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 32c1ba3212f..1a76565bac1 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -271,6 +271,8 @@ impl Platform { properties: document_stub_properties, owner_id: contract.owner_id.to_buffer(), revision: None, + created_at: None, + updated_at: None, }; let document_type = contract.document_type_for_name("domain")?; diff --git a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs index eb381774646..ac75ccbaf5d 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -77,6 +77,8 @@ fn create_test_mn_share_document( properties, owner_id: identity_id, revision: Some(1), + created_at: None, + updated_at: None, }; let document_type = contract From 3f5ffdc0444cc20566e72c46bbd9ad7f53be4409 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Feb 2023 04:56:18 +0700 Subject: [PATCH 004/228] all tests passing --- packages/rs-dpp/src/document/document.rs | 12 +++++++++++- packages/rs-drive-abci/tests/strategy_tests/main.rs | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 8dedeac3df0..24618c74466 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -44,7 +44,7 @@ use integer_encoding::VarIntWriter; use crate::data_contract::{DataContract, DriveContractExt}; use serde::{Deserialize, Serialize}; -use crate::data_contract::document_type::DocumentType; +use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType}; use crate::data_contract::errors::{DataContractError, StructureError}; use crate::data_contract::extra::common::{ bytes_for_system_value_from_tree_map, get_key_from_cbor_map, @@ -102,6 +102,16 @@ impl Document { // returns self.id or self.owner_id if key path is $id or $ownerId "$id" => return Ok(Some(Vec::from(self.id))), "$ownerId" => return Ok(Some(Vec::from(self.owner_id))), + "$createdAt" => { + return Ok(self + .created_at + .map(|time| encode_unsigned_integer(time).unwrap())) + } + "$updatedAt" => { + return Ok(self + .updated_at + .map(|time| encode_unsigned_integer(time).unwrap())) + } _ => {} } // split the key path diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 69c8b40796a..4af8b3cd1b7 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -985,7 +985,7 @@ mod tests { let day_in_ms = 1000 * 60 * 60 * 24; let block_count = 30; let outcome = run_chain_for_strategy(block_count, day_in_ms, strategy, config, 15); - assert_eq!(outcome.identities.len() as u64, 464); + assert_eq!(outcome.identities.len() as u64, 398); assert_eq!(outcome.masternode_identity_balances.len(), 100); let balance_count = outcome .masternode_identity_balances From 7fb9a264d185f18f4f2b5592aa5afaf47833f81e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Feb 2023 09:15:17 +0700 Subject: [PATCH 005/228] more work --- .../withdrawals_data_triggers/mod.rs | 7 +-- packages/rs-dpp/src/document/document.rs | 13 +++++ ...pply_documents_batch_transition_factory.rs | 29 +--------- .../document_create_transition.rs | 30 +++++++++- ...ty_credit_withdrawal_transition_factory.rs | 14 ++--- packages/rs-dpp/src/state_repository.rs | 5 +- .../rs-dpp/src/util/cbor_value/cbor_map.rs | 57 +++++-------------- packages/wasm-dpp/src/state_repository.rs | 6 +- 8 files changed, 69 insertions(+), 92 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index 9517b1122db..5c401050f71 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -10,6 +10,7 @@ use crate::get_from_transition; use crate::prelude::DocumentTransition; use crate::prelude::Identifier; use crate::state_repository::StateRepositoryLike; +use crate::util::cbor_value::CborBTreeMapHelper; pub async fn delete_withdrawal_data_trigger<'a, SR>( document_transition: &DocumentTransition, @@ -56,11 +57,7 @@ where return Ok(result); }; - let status = withdrawal - .get("status") - .ok_or_else(|| anyhow!("can't get withdrawal status property from the document"))? - .as_u64() - .ok_or_else(|| anyhow!("can't convert withdrawal status to u64"))? as u8; + let status : u8 = withdrawal.properties.get_integer("status")?; if status != withdrawals_contract::WithdrawalStatus::COMPLETE as u8 || status != withdrawals_contract::WithdrawalStatus::EXPIRED as u8 diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 24618c74466..c07546ef51f 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -68,6 +68,7 @@ pub mod property_names { /// Documents contain the data that goes into data contracts. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct Document { + //todo: add an optional version /// The unique document ID. #[serde(rename = "$id")] pub id: [u8; 32], @@ -179,6 +180,18 @@ impl Document { })?; self.get_raw_for_document_type(key, document_type, owner_id) } + + /// Set the value under given path. + /// The path supports syntax from `lodash` JS lib. Example: "root.people[0].name". + /// If parents are not present they will be automatically created + pub fn set(&mut self, path: &str, value: Value) { + self.properties.insert(path.to_string(), value); + } + + /// Retrieves field specified by path + pub fn get(&self, path: &str) -> Option<&Value> { + self.properties.get(path) + } } impl fmt::Display for Document { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 95282bbb5a7..55eb7de2b4c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use dashcore::{consensus, BlockHeader}; use serde_json::Value; -use crate::document::DocumentInStateTransition; +use crate::document::{Document, DocumentInStateTransition}; use crate::{ document::errors::DocumentError, prelude::Identifier, state_repository::StateRepositoryLike, state_transition::StateTransitionLike, ProtocolError, @@ -115,33 +115,6 @@ pub async fn apply_documents_batch_transition( } Ok(()) } -fn document_from_transition_create( - document_create_transition: &DocumentCreateTransition, - state_transition: &DocumentsBatchTransition, -) -> DocumentInStateTransition { - // TODO cloning is costly. Probably the [`Document`] should have properties of type `Cov<'a, K>` - DocumentInStateTransition { - protocol_version: state_transition.protocol_version, - id: document_create_transition.base.id, - document_type: document_create_transition.base.document_type.clone(), - data_contract_id: document_create_transition.base.data_contract_id, - owner_id: state_transition.owner_id, - data: document_create_transition - .data - .as_ref() - .unwrap_or(&serde_json::Value::Null) - .clone(), - created_at: document_create_transition.created_at, - updated_at: document_create_transition.updated_at, - entropy: document_create_transition.entropy, - revision: document_create_transition.get_revision(), - metadata: None, - - //? In the JS implementation the `data_contract` property is completely omitted, what suggest we should make - //? it optional. On the other end the `data_contract` seems obligatory as it's used by methods like `get_binary_properties()` - data_contract: Default::default(), - } -} fn document_from_transition_replace( document_replace_transition: &DocumentReplaceTransition, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index f09baaadcf0..612b04f3916 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -6,6 +6,9 @@ use crate::{ data_contract::DataContract, document::document_transition::Action, errors::ProtocolError, util::json_value::JsonValueExt, util::json_value::ReplaceWith, }; +use crate::document::{Document, DocumentsBatchTransition}; +use crate::identity::TimestampMillis; +use crate::util::serializer::value_to_cbor; use super::INITIAL_REVISION; use super::{ @@ -30,9 +33,9 @@ pub struct DocumentCreateTransition { pub entropy: [u8; 32], #[serde(rename = "$createdAt", skip_serializing_if = "Option::is_none")] - pub created_at: Option, + pub created_at: Option, #[serde(rename = "$updatedAt", skip_serializing_if = "Option::is_none")] - pub updated_at: Option, + pub updated_at: Option, #[serde(flatten, skip_serializing_if = "Option::is_none")] pub data: Option, @@ -49,6 +52,29 @@ impl DocumentCreateTransition { raw_create_document_transition.replace_binary_paths(BINARY_FIELDS, ReplaceWith::Base64)?; Ok(()) } + + + fn into_document( + self, + owner_id: [u8;32], + ) -> Document { + let properties = self.data.map(|value| value_to_cbor(a)); + Document { + id: document_create_transition.base.id, + owner_id, + properties: + data_contract_id: document_create_transition.base.data_contract_id, + + data: document_create_transition + .data + .as_ref() + .unwrap_or(&serde_json::Value::Null) + .clone(), + created_at: self.created_at, + updated_at: self.updated_at, + revision: document_create_transition.get_revision(), + } + } } impl DocumentTransitionObjectLike for DocumentCreateTransition { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs index b17f11f0505..46f68ba4d65 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs @@ -58,7 +58,7 @@ where consensus::deserialize(&latest_platform_block_header_bytes)?; let document_type = String::from(withdrawals_contract::document_types::WITHDRAWAL); - let document_created_at_millis: i64 = latest_platform_block_header.time as i64 * 1000i64; + let document_created_at_millis: u64 = latest_platform_block_header.time as u64 * 1000u64; let document_data = json!({ withdrawals_contract::property_names::AMOUNT: state_transition.amount, @@ -101,18 +101,12 @@ where // TODO: use DocumentFactory once it is complete let withdrawal_document = Document { - protocol_version: state_transition.protocol_version, - id: document_id, - document_type, + id: document_id.buffer, revision: 0, - data_contract_id: *data_contract_id, owner_id: state_transition.identity_id, created_at: Some(document_created_at_millis), - updated_at: Some(document_created_at_millis), - data: document_data, - data_contract: withdrawals_data_contract, - metadata: None, - entropy: [0; 32], + updated_at: Some(document_created_at_millis), , + properties: Default::default(), }; self.state_repository diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index af6ea5cd7dc..bbf5ea3be9d 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -11,6 +11,7 @@ use crate::{ prelude::*, state_transition::state_transition_execution_context::StateTransitionExecutionContext, }; +use crate::document::Document; impl From for ProtocolError { fn from(_: Infallible) -> Self { @@ -68,14 +69,14 @@ pub trait StateRepositoryLike: Sync { /// Create Document async fn create_document( &self, - document: &DocumentInStateTransition, + document: &Document, execution_context: &StateTransitionExecutionContext, ) -> AnyResult<()>; /// Update Document async fn update_document( &self, - document: &DocumentInStateTransition, + document: &Document, execution_context: &StateTransitionExecutionContext, ) -> AnyResult<()>; diff --git a/packages/rs-dpp/src/util/cbor_value/cbor_map.rs b/packages/rs-dpp/src/util/cbor_value/cbor_map.rs index 42468c71448..8c0a885e62a 100644 --- a/packages/rs-dpp/src/util/cbor_value/cbor_map.rs +++ b/packages/rs-dpp/src/util/cbor_value/cbor_map.rs @@ -17,11 +17,6 @@ pub trait CborBTreeMapHelper { fn get_optional_integer>(&self, key: &str) -> Result, ProtocolError>; fn get_integer>(&self, key: &str) -> Result; - fn remove_optional_integer>( - &mut self, - key: &str, - ) -> Result, ProtocolError>; - fn remove_integer>(&mut self, key: &str) -> Result; fn get_optional_bool(&self, key: &str) -> Result, ProtocolError>; fn get_bool(&self, key: &str) -> Result; fn get_optional_inner_value_array<'a, I: FromIterator<&'a CborValue>>( @@ -147,36 +142,6 @@ where }) } - fn remove_optional_integer>( - &mut self, - key: &str, - ) -> Result, ProtocolError> { - self.remove(key) - .map(|v| { - if v.borrow().is_null() { - Ok::>, ProtocolError>(None) - } else { - Ok(Some( - i128::from(v.borrow().as_integer().ok_or_else(|| { - ProtocolError::DecodingError(format!("{key} must be an integer")) - })?) - .try_into() - .map_err(|_| { - ProtocolError::DecodingError(format!("{key} is out of required bounds")) - }), - )) - } - }) - .transpose()? - .flatten() - .transpose() - } - - fn remove_integer>(&mut self, key: &str) -> Result { - self.remove_optional_integer(key)? - .ok_or_else(|| ProtocolError::DecodingError(format!("unable to remove property {key}"))) - } - fn get_optional_bool(&self, key: &str) -> Result, ProtocolError> { self.get(key) .map(|v| { @@ -199,14 +164,22 @@ where ) -> Result, ProtocolError> { self.remove(key) .map(|v| { - i128::from(v.borrow().as_integer().ok_or_else(|| { - ProtocolError::DecodingError(format!("{key} must be an integer")) - })?) - .try_into() - .map_err(|_| { - ProtocolError::DecodingError(format!("{key} is out of required bounds")) - }) + if v.borrow().is_null() { + Ok::>, ProtocolError>(None) + } else { + Ok(Some( + i128::from(v.borrow().as_integer().ok_or_else(|| { + ProtocolError::DecodingError(format!("{key} must be an integer")) + })?) + .try_into() + .map_err(|_| { + ProtocolError::DecodingError(format!("{key} is out of required bounds")) + }), + )) + } }) + .transpose()? + .flatten() .transpose() } diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 6546fc7a54f..1905d8f35dc 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -24,7 +24,7 @@ use js_sys::Uint8Array; use js_sys::{Array, Number}; use wasm_bindgen::__rt::Ref; -use dpp::document::DocumentInStateTransition; +use dpp::document::{Document, DocumentInStateTransition}; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; @@ -275,7 +275,7 @@ impl StateRepositoryLike for ExternalStateRepositoryLikeWrapper { async fn create_document( &self, - _document: &DocumentInStateTransition, + _document: &Document, _execution_context: &StateTransitionExecutionContext, ) -> Result<()> { todo!() @@ -283,7 +283,7 @@ impl StateRepositoryLike for ExternalStateRepositoryLikeWrapper { async fn update_document( &self, - _document: &DocumentInStateTransition, + _document: &Document, _execution_context: &StateTransitionExecutionContext, ) -> Result<()> { todo!() From 2755443544a0886802872812002c1d4905f2814f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 25 Feb 2023 21:27:23 +0700 Subject: [PATCH 006/228] compiles --- .../rs-dpp/src/data_contract/data_contract.rs | 6 +- .../document_type/document_factory.rs | 14 +- .../src/data_contract/document_type/mod.rs | 2 +- .../withdrawals_data_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/document.rs | 121 ++++++- .../rs-dpp/src/document/document_factory.rs | 10 +- packages/rs-dpp/src/document/errors.rs | 4 +- packages/rs-dpp/src/document/mod.rs | 2 +- packages/rs-dpp/src/document/serialize.rs | 39 +- ...pply_documents_batch_transition_factory.rs | 12 +- .../document_create_transition.rs | 49 +-- .../document_in_state_transition.rs | 18 +- .../document_replace_transition.rs | 62 ++-- .../document_transition/mod.rs | 2 +- .../validation/state/fetch_documents.rs | 9 +- ...lidate_documents_batch_transition_state.rs | 5 +- .../rs-dpp/src/errors/abstract_state_error.rs | 11 +- packages/rs-dpp/src/errors/codes.rs | 1 - packages/rs-dpp/src/identifier/identifier.rs | 13 +- packages/rs-dpp/src/state_repository.rs | 2 +- ...e_documents_batch_transition_state_spec.rs | 2 +- .../tests/fixtures/get_documents_fixture.rs | 12 +- ...edit_withdrawal_transition_factory_spec.rs | 17 +- .../rs-dpp/src/util/cbor_value/cbor_map.rs | 8 +- packages/rs-drive-abci/src/abci/handlers.rs | 3 +- .../src/identity_credit_withdrawal/mod.rs | 49 +-- .../src/test/helpers/fee_pools.rs | 2 +- packages/rs-drive/benches/benchmarks.rs | 9 +- packages/rs-drive/src/drive/contract/mod.rs | 10 +- .../drive/identity/withdrawals/documents.rs | 15 +- packages/rs-drive/src/tests/helpers/setup.rs | 4 +- packages/rs-drive/tests/query_tests.rs | 2 +- .../src/btreemap_extensions.rs | 4 +- packages/rs-platform-value/src/lib.rs | 2 +- .../src/data_contract/data_contract.rs | 2 +- .../document/document_in_state_transition.rs | 338 ++++++++++++++++++ .../errors/document_no_revision_error.rs | 25 ++ .../errors/invalid_initial_revision_error.rs | 9 +- .../errors/mismatch_owners_ids_error.rs | 10 +- packages/wasm-dpp/src/document/errors/mod.rs | 5 + packages/wasm-dpp/src/document/factory.rs | 21 +- packages/wasm-dpp/src/document/mod.rs | 212 +++++------ .../document_batch_transition/mod.rs | 8 +- .../invalid_document_revision_error.rs | 6 +- .../wasm-dpp/src/errors/consensus_error.rs | 2 +- packages/wasm-dpp/src/identifier/mod.rs | 8 + packages/wasm-dpp/src/utils.rs | 24 +- 47 files changed, 830 insertions(+), 363 deletions(-) create mode 100644 packages/wasm-dpp/src/document/document_in_state_transition.rs create mode 100644 packages/wasm-dpp/src/document/errors/document_no_revision_error.rs diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 151195569d9..7384fb4f750 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use std::convert::TryFrom; use anyhow::anyhow; @@ -403,13 +403,13 @@ impl DataContract { pub fn get_identifiers_and_binary_paths( &self, document_type: &str, - ) -> Result<(Vec<&str>, Vec<&str>), ProtocolError> { + ) -> Result<(HashSet<&str>, HashSet<&str>), ProtocolError> { let binary_properties = self.get_optional_binary_properties(document_type)?; // At this point we don't bother about returned error from `get_binary_properties`. // If document of given type isn't found, then empty vectors will be returned. let (binary_paths, identifiers_paths) = match binary_properties { - None => (vec![], vec![]), + None => (HashSet::new(), HashSet::new()), Some(binary_properties) => binary_properties.iter().partition_map(|(path, v)| { if let Some(JsonValue::String(content_type)) = v.get("contentMediaType") { if content_type == identifier::MEDIA_TYPE { diff --git a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs index 9ea3c8ef819..2f90d94f6cf 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs @@ -1,14 +1,14 @@ -use std::collections::BTreeMap; -use chrono::Utc; -use rand::rngs::StdRng; -use platform_value::Value; -use crate::data_contract::document_type::DocumentType; use crate::data_contract::document_type::property_names::{CREATED_AT, UPDATED_AT}; -use crate::document::Document; +use crate::data_contract::document_type::DocumentType; use crate::document::document_transition::INITIAL_REVISION; +use crate::document::Document; use crate::identifier::Identifier; use crate::prelude::TimestampMillis; use crate::ProtocolError; +use chrono::Utc; +use platform_value::Value; +use rand::rngs::StdRng; +use std::collections::BTreeMap; impl DocumentType { /// Creates a document at the current time based on document type information @@ -46,4 +46,4 @@ impl DocumentType { updated_at, }) } -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/data_contract/document_type/mod.rs b/packages/rs-dpp/src/data_contract/document_type/mod.rs index 3086f9de07f..909be9c9cdb 100644 --- a/packages/rs-dpp/src/data_contract/document_type/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/mod.rs @@ -1,9 +1,9 @@ pub mod array_field; +pub mod document_factory; pub mod document_field; pub mod document_type; pub mod index; pub mod random_document; -pub mod document_factory; use super::errors::DataContractError; diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index 5ddb0191f4b..827ab9f89a9 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -57,7 +57,7 @@ where return Ok(result); }; - let status : u8 = withdrawal.properties.get_integer("status")?; + let status: u8 = withdrawal.properties.get_integer("status")?; if status != withdrawals_contract::WithdrawalStatus::COMPLETE as u8 || status != withdrawals_contract::WithdrawalStatus::EXPIRED as u8 diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 15bc1cbbd5d..6479ddd509c 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -33,17 +33,20 @@ //! use chrono::{DateTime, NaiveDateTime, Utc}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, HashSet}; use std::convert::{TryFrom, TryInto}; use std::fmt; use std::io::{BufReader, Read}; +use std::iter::FromIterator; use ciborium::value::Value as CborValue; use integer_encoding::VarIntWriter; +use itertools::Itertools; +use serde_json::Value as JsonValue; -use crate::data_contract::{DataContract, DriveContractExt}; -use serde::{Deserialize, Serialize}; +use crate::data_contract::{DataContract, DriveContractExt, IDENTIFIER_FIELDS}; use platform_value::Value; +use serde::{Deserialize, Serialize}; use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType}; use crate::data_contract::errors::{DataContractError, StructureError}; @@ -52,10 +55,14 @@ use crate::data_contract::extra::common::{ reduced_value_string_representation, }; use crate::document::errors::DocumentError; +use crate::identifier::Identifier; use crate::identity::TimestampMillis; use crate::prelude::Revision; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; +use crate::util::hash::hash; +use crate::util::json_value::JsonValueExt; +use crate::util::json_value::ReplaceWith; use crate::ProtocolError; /// The property names of a document @@ -69,7 +76,7 @@ pub mod property_names { } /// Documents contain the data that goes into data contracts. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] pub struct Document { //todo: add an optional version /// The unique document ID. @@ -198,7 +205,6 @@ impl Document { self.properties.get(path) } - pub fn set_u8(&mut self, property_name: &str, value: u8) { self.properties .insert(property_name.to_string(), Value::U8(value)); @@ -214,10 +220,24 @@ impl Document { .insert(property_name.to_string(), Value::Bytes(value)); } - pub fn increment_revision(&mut self) -> Result<(), ProtocolError> { + /// The document is only unique within the contract and document type + /// Hence we must include contract and document type information to get uniqueness + pub fn hash( + &self, + contract: &DataContract, + document_type: &DocumentType, + ) -> Result, ProtocolError> { + let mut buf = contract.id.to_buffer_vec(); + buf.extend(document_type.name.as_bytes()); + buf.extend(self.serialize(document_type)?); + Ok(hash(buf)) + } + pub fn increment_revision(&mut self) -> Result<(), ProtocolError> { let Some(revision) = self.revision else { - return Err(ProtocolError::Document(Box::new(DocumentError::DocumentNoRevisionError))) + return Err(ProtocolError::Document(Box::new(DocumentError::DocumentNoRevisionError { + document: Box::new(self.clone()), + }))) }; let new_revision = revision @@ -228,6 +248,89 @@ impl Document { Ok(()) } + + pub fn get_identifiers_and_binary_paths<'a>( + &'a self, + data_contract: &'a DataContract, + document_type_name: &'a str, + ) -> Result<(HashSet<&'a str>, HashSet<&'a str>), ProtocolError> { + let (mut identifiers_paths, binary_paths) = + data_contract.get_identifiers_and_binary_paths(document_type_name)?; + + identifiers_paths.extend(IDENTIFIER_FIELDS); + Ok((identifiers_paths, binary_paths)) + } + + pub fn to_json( + &self, + data_contract: &DataContract, + document_type_name: &str, + ) -> Result { + let mut value = serde_json::to_value(self)?; + + let (identifier_paths, binary_paths) = + self.get_identifiers_and_binary_paths(data_contract, document_type_name)?; + + value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; + value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; + + Ok(value) + } + + // The skipIdentifierConversion option is removed as it doesn't make sense in the case of + // of Rust. Rust doesn't distinguish between `Buffer` and `Identifier` + pub fn to_object( + &self, + data_contract: &DataContract, + document_type_name: &str, + ) -> Result { + let mut json_object = serde_json::to_value(self)?; + + let (identifier_paths, binary_paths) = + self.get_identifiers_and_binary_paths(data_contract, document_type_name)?; + let _ = json_object.replace_identifier_paths(identifier_paths, ReplaceWith::Bytes); + let _ = json_object.replace_binary_paths(binary_paths, ReplaceWith::Bytes); + + Ok(json_object) + } + + pub fn from_raw_json_document(raw_document: JsonValue) -> Result { + Self::from_json_value::>(raw_document) + } + + fn from_json_value(mut document_value: JsonValue) -> Result + where + for<'de> S: Deserialize<'de> + TryInto, + { + let mut document = Self { + ..Default::default() + }; + + if let Ok(value) = document_value.remove(property_names::ID) { + let data: S = serde_json::from_value(value)?; + document.id = data.try_into()?.buffer; + } + if let Ok(value) = document_value.remove(property_names::OWNER_ID) { + let data: S = serde_json::from_value(value)?; + document.owner_id = data.try_into()?.buffer; + } + if let Ok(value) = document_value.remove(property_names::REVISION) { + document.revision = serde_json::from_value(value)? + } + if let Ok(value) = document_value.remove(property_names::CREATED_AT) { + document.created_at = serde_json::from_value(value)? + } + if let Ok(value) = document_value.remove(property_names::UPDATED_AT) { + document.updated_at = serde_json::from_value(value)? + } + + let platform_value: Value = document_value.into(); + + document.properties = platform_value + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + Ok(document) + } } impl fmt::Display for Document { @@ -276,7 +379,7 @@ mod tests { .expect("expected to get profile document type"); let document = document_type.random_document(Some(3333)); - let document_cbor = document.to_cbor(); + let document_cbor = document.to_cbor().expect("expected to encode to cbor"); let serialized_document = document .serialize(document_type) @@ -309,7 +412,7 @@ mod tests { .expect("expected to get profile document type"); let document = document_type.random_document(Some(3333)); - let document_cbor = document.to_cbor(); + let document_cbor = document.to_cbor().expect("expected to encode to cbor"); let recovered_document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("expected to get document"); diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index dcf5dbba7dc..8c0ead2ae64 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -1,17 +1,19 @@ -use std::collections::BTreeMap; use anyhow::Context; use chrono::Utc; use ciborium::cbor; use itertools::Itertools; +use platform_value::Value; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; -use platform_value::Value; +use std::collections::BTreeMap; +use crate::data_contract::document_type::DocumentType; use crate::document::document_transition::document_in_state_transition::{ property_names, DocumentInStateTransition, }; +use crate::document::Document; use crate::{ data_contract::{errors::DataContractError, DataContract}, decode_protocol_entity_factory::DecodeProtocolEntity, @@ -21,8 +23,6 @@ use crate::{ util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, ProtocolError, }; -use crate::data_contract::document_type::DocumentType; -use crate::document::Document; use super::{ document_transition::{self, Action}, @@ -100,7 +100,7 @@ where protocol_version, document_validator: validate_document, data_contract_fetcher_and_validator, - rng + rng, } } diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index e24769bbdf2..43f5abc4caa 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -4,7 +4,7 @@ use thiserror::Error; use crate::errors::consensus::ConsensusError; use super::document_transition::DocumentTransition; -use crate::document::DocumentInStateTransition; +use crate::document::{Document, DocumentInStateTransition}; #[derive(Error, Debug)] pub enum DocumentError { @@ -38,7 +38,7 @@ pub enum DocumentError { }, #[error("No previous revision error")] - DocumentNoRevisionError, + DocumentNoRevisionError { document: Box }, #[error("No documents were supplied to state transition")] NoDocumentsSuppliedError, diff --git a/packages/rs-dpp/src/document/mod.rs b/packages/rs-dpp/src/document/mod.rs index d22a9c48821..da835cb436b 100644 --- a/packages/rs-dpp/src/document/mod.rs +++ b/packages/rs-dpp/src/document/mod.rs @@ -32,4 +32,4 @@ pub mod state_transition; pub use document::Document; pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::DocumentInStateTransition; pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::property_names as document_in_state_transition_property_names; -pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::IDENTIFIER_FIELDS as DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS; \ No newline at end of file +pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::IDENTIFIER_FIELDS as DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 13c95192a58..dcfda2cdb46 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -2,9 +2,13 @@ use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::data_contract::errors::{DataContractError, StructureError}; use crate::data_contract::extra::common::bytes_for_system_value_from_tree_map; +use crate::document::document::property_names; use crate::document::document::property_names::{CREATED_AT, UPDATED_AT}; +use crate::document::document_transition::INITIAL_REVISION; use crate::document::Document; use crate::document::DocumentInStateTransition; +use crate::identity::TimestampMillis; +use crate::prelude::Revision; use crate::util::cbor_value::CborBTreeMapHelper; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; @@ -13,17 +17,12 @@ use bincode::Options; use byteorder::{BigEndian, ReadBytesExt}; use ciborium::Value as CborValue; use integer_encoding::VarIntWriter; -use std::collections::BTreeMap; -use std::convert::{TryFrom, TryInto}; -use std::io::{BufReader, Read}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; -use crate::document::document::property_names; -use crate::document::document_transition::INITIAL_REVISION; -use crate::identity::TimestampMillis; -use crate::prelude::Revision; use serde::{Deserialize, Serialize}; - +use std::collections::BTreeMap; +use std::convert::{TryFrom, TryInto}; +use std::io::{BufReader, Read}; //todo: delete in later PR #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] @@ -58,7 +57,9 @@ impl TryFrom for DocumentForCbor { id, properties, owner_id, - revision, created_at, updated_at, + revision, + created_at, + updated_at, } = value; Ok(DocumentForCbor { id, @@ -360,8 +361,7 @@ impl Document { Some(document_id) => document_id, }; - let revision = document - .remove_optional_integer(property_names::REVISION)?; + let revision = document.remove_optional_integer(property_names::REVISION)?; let created_at = document.remove_optional_integer(property_names::CREATED_AT)?; let updated_at = document.remove_optional_integer(property_names::UPDATED_AT)?; @@ -378,14 +378,15 @@ impl Document { } /// Serializes the Document to CBOR. - pub fn to_cbor(&self) -> Vec { + pub fn to_cbor(&self) -> Result, ProtocolError> { let mut buffer: Vec = Vec::new(); - buffer - .write_varint(PROTOCOL_VERSION) - .expect("writing protocol version caused error"); - let cbor_document = DocumentForCbor::try_from(self.clone()).unwrap(); - ciborium::ser::into_writer(&cbor_document, &mut buffer) - .expect("unable to serialize into cbor"); - buffer + buffer.write_varint(PROTOCOL_VERSION).map_err(|_| { + ProtocolError::EncodingError("error writing protocol version".to_string()) + })?; + let cbor_document = DocumentForCbor::try_from(self.clone())?; + ciborium::ser::into_writer(&cbor_document, &mut buffer).map_err(|_| { + ProtocolError::EncodingError("unable to serialize into cbor".to_string()) + })?; + Ok(buffer) } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index a939ed5232b..c22940d3266 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -5,11 +5,11 @@ use dashcore::{consensus, BlockHeader}; use serde_json::Value; use crate::document::{Document, DocumentInStateTransition}; +use crate::prelude::TimestampMillis; use crate::{ document::errors::DocumentError, prelude::Identifier, state_repository::StateRepositoryLike, state_transition::StateTransitionLike, ProtocolError, }; -use crate::prelude::TimestampMillis; use super::{ document_transition::{ @@ -61,15 +61,18 @@ pub async fn apply_documents_batch_transition( ) .await?; - let mut fetched_documents_by_id: HashMap = - fetched_documents.into_iter().map(|dt| (dt.id.into(), dt)).collect(); + let mut fetched_documents_by_id: HashMap = fetched_documents + .into_iter() + .map(|dt| (dt.id.into(), dt)) + .collect(); // since groveDB doesn't support parallel inserts, we need to make them sequential for document_transition in state_transition.get_transitions() { match document_transition { DocumentTransition::Create(document_create_transition) => { - let document = document_create_transition.to_document(state_transition.owner_id.to_buffer())?; + let document = document_create_transition + .to_document(state_transition.owner_id.to_buffer())?; //todo: eventually we should use Cow instead state_repository .create_document(&document, state_transition.get_execution_context()) @@ -93,7 +96,6 @@ pub async fn apply_documents_batch_transition( .update_document(document, state_transition.get_execution_context()) .await?; }; - } DocumentTransition::Delete(document_delete_transition) => { state_repository diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 59efcbba1c3..0a14ef8bd73 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,17 +1,17 @@ -use std::convert::TryInto; use itertools::Itertools; +use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use platform_value::Value; +use std::convert::TryInto; -use crate::{ - data_contract::DataContract, document::document_transition::Action, errors::ProtocolError, - util::json_value::JsonValueExt, util::json_value::ReplaceWith, -}; use crate::document::{Document, DocumentsBatchTransition}; use crate::identity::TimestampMillis; use crate::prelude::Revision; use crate::util::serializer::value_to_cbor; +use crate::{ + data_contract::DataContract, document::document_transition::Action, errors::ProtocolError, + util::json_value::JsonValueExt, util::json_value::ReplaceWith, +}; use super::INITIAL_REVISION; use super::{ @@ -57,15 +57,16 @@ impl DocumentCreateTransition { Ok(()) } - pub(crate) fn to_document( - &self, - owner_id: [u8;32], - ) -> Result { - let properties = self.data.as_ref().map(|json_value| { - let value : Value = json_value.clone().into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }) - .transpose()?.unwrap_or_default(); + pub(crate) fn to_document(&self, owner_id: [u8; 32]) -> Result { + let properties = self + .data + .as_ref() + .map(|json_value| { + let value: Value = json_value.clone().into(); + value.into_btree_map().map_err(ProtocolError::ValueError) + }) + .transpose()? + .unwrap_or_default(); Ok(Document { id: self.base.id.to_buffer(), owner_id, @@ -76,19 +77,19 @@ impl DocumentCreateTransition { }) } - - pub(crate) fn into_document( - self, - owner_id: [u8;32], - ) -> Result { + pub(crate) fn into_document(self, owner_id: [u8; 32]) -> Result { let id = self.base.id.to_buffer(); let revision = self.get_revision(); let created_at = self.created_at; let updated_at = self.updated_at; - let properties = self.data.map(|json_value| { - let value : Value = json_value.into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }).transpose()?.unwrap_or_default(); + let properties = self + .data + .map(|json_value| { + let value: Value = json_value.into(); + value.into_btree_map().map_err(ProtocolError::ValueError) + }) + .transpose()? + .unwrap_or_default(); Ok(Document { id, owner_id, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs index 9ea6512494f..902dbf4ea29 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs @@ -1,6 +1,7 @@ use crate::data_contract::DataContract; use crate::identifier::Identifier; use crate::metadata::Metadata; +use crate::prelude::{Revision, TimestampMillis}; use crate::util::cbor_value::{CborCanonicalMap, FieldType}; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::util::hash::hash; @@ -13,8 +14,8 @@ use integer_encoding::VarInt; use itertools::Itertools; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use std::collections::HashSet; use std::convert::TryInto; -use crate::prelude::{Revision, TimestampMillis}; pub mod property_names { pub const PROTOCOL_VERSION: &str = "$protocolVersion"; @@ -251,19 +252,14 @@ impl DocumentInStateTransition { pub fn get_identifiers_and_binary_paths( &self, - ) -> Result<(Vec<&str>, Vec<&str>), ProtocolError> { - let (identifiers_paths, binary_paths) = self + ) -> Result<(HashSet<&str>, HashSet<&str>), ProtocolError> { + let (mut identifiers_paths, binary_paths) = self .data_contract .get_identifiers_and_binary_paths(&self.document_type)?; - Ok(( - identifiers_paths - .into_iter() - .chain(IDENTIFIER_FIELDS) - .unique() - .collect(), - binary_paths, - )) + identifiers_paths.extend(IDENTIFIER_FIELDS); + + Ok((identifiers_paths, binary_paths)) } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index f32b3a9c12e..709a498945c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -1,15 +1,15 @@ +use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use platform_value::Value; +use crate::document::Document; +use crate::identity::TimestampMillis; +use crate::prelude::Revision; use crate::{ data_contract::DataContract, errors::ProtocolError, util::json_value::{JsonValueExt, ReplaceWith}, }; -use crate::document::Document; -use crate::identity::TimestampMillis; -use crate::prelude::Revision; use super::{ document_base_transition, document_base_transition::DocumentBaseTransition, @@ -33,16 +33,19 @@ pub struct DocumentReplaceTransition { } impl DocumentReplaceTransition { - pub(crate) fn to_document_for_dry_run( - &self, - ) -> Result { - let properties = self.data.as_ref().map(|json_value| { - let value : Value = json_value.clone().into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }).transpose()?.unwrap_or_default(); + pub(crate) fn to_document_for_dry_run(&self) -> Result { + let properties = self + .data + .as_ref() + .map(|json_value| { + let value: Value = json_value.clone().into(); + value.into_btree_map().map_err(ProtocolError::ValueError) + }) + .transpose()? + .unwrap_or_default(); Ok(Document { id: self.base.id.to_buffer(), - owner_id: [0;32], //0s are fine here + owner_id: [0; 32], //0s are fine here properties, created_at: self.updated_at, // we can use the same time, as it can't be worse updated_at: self.updated_at, @@ -50,28 +53,31 @@ impl DocumentReplaceTransition { }) } - pub(crate) fn replace_document( - &self, - document: &mut Document, - ) -> Result<(), ProtocolError> { - let properties = self.data.as_ref().map(|json_value| { - let value : Value = json_value.clone().into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }).transpose()?.unwrap_or_default(); + pub(crate) fn replace_document(&self, document: &mut Document) -> Result<(), ProtocolError> { + let properties = self + .data + .as_ref() + .map(|json_value| { + let value: Value = json_value.clone().into(); + value.into_btree_map().map_err(ProtocolError::ValueError) + }) + .transpose()? + .unwrap_or_default(); document.revision = Some(self.revision); document.updated_at = self.updated_at; document.properties = properties; Ok(()) } - pub(crate) fn patch_document( - self, - document: &mut Document, - ) -> Result<(), ProtocolError> { - let properties = self.data.map(|json_value| { - let value : Value = json_value.into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }).transpose()?.unwrap_or_default(); + pub(crate) fn patch_document(self, document: &mut Document) -> Result<(), ProtocolError> { + let properties = self + .data + .map(|json_value| { + let value: Value = json_value.into(); + value.into_btree_map().map_err(ProtocolError::ValueError) + }) + .transpose()? + .unwrap_or_default(); document.revision = Some(self.revision); document.updated_at = self.updated_at; document.properties.extend(properties); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index c9fb9912cca..0c5178c09b5 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -15,11 +15,11 @@ pub mod document_delete_transition; pub mod document_in_state_transition; pub mod document_replace_transition; +use crate::identity::TimestampMillis; pub use document_base_transition::{Action, DocumentTransitionObjectLike}; pub use document_create_transition::DocumentCreateTransition; pub use document_delete_transition::DocumentDeleteTransition; pub use document_replace_transition::DocumentReplaceTransition; -use crate::identity::TimestampMillis; /// the initial revision of newly created document pub const INITIAL_REVISION: u64 = 1; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs index c06b152680c..c25cb7c61b1 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs @@ -55,11 +55,10 @@ pub async fn fetch_documents( fetch_documents_futures.push(documents); } - let results: Result>, anyhow::Error> = - join_all(fetch_documents_futures) - .await - .into_iter() - .collect(); + let results: Result>, anyhow::Error> = join_all(fetch_documents_futures) + .await + .into_iter() + .collect(); let documents = results?.into_iter().flatten().collect(); Ok(documents) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index 20c8a61d1ce..bc11ad301a0 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -256,8 +256,9 @@ fn check_revision( }; let Some(previous_revision) = fetched_document.revision else { result.add_error(ConsensusError::StateError(Box::new( - StateError::InvalidDocumentNoPreviousRevisionError { + StateError::InvalidDocumentRevisionError { document_id: document_transition.base().id, + current_revision: None, }, ))); return result; @@ -267,7 +268,7 @@ fn check_revision( result.add_error(ConsensusError::StateError(Box::new( StateError::InvalidDocumentRevisionError { document_id: document_transition.base().id, - current_revision: previous_revision, + current_revision: Some(previous_revision), }, ))) } diff --git a/packages/rs-dpp/src/errors/abstract_state_error.rs b/packages/rs-dpp/src/errors/abstract_state_error.rs index 9a2f5dfce03..cc50816e9fe 100644 --- a/packages/rs-dpp/src/errors/abstract_state_error.rs +++ b/packages/rs-dpp/src/errors/abstract_state_error.rs @@ -40,18 +40,11 @@ pub enum StateError { }, #[error( - "Document {document_id} has invalid revision. The current revision is {current_revision}" + "Document {document_id} has invalid revision. The current revision is {current_revision:?}" )] InvalidDocumentRevisionError { document_id: Identifier, - current_revision: Revision, - }, - - #[error( - "Document {document_id} had no previous revision but was trying to be updated" - )] - InvalidDocumentNoPreviousRevisionError { - document_id: Identifier, + current_revision: Option, }, #[error("Data Contract {data_contract_id} is already present")] diff --git a/packages/rs-dpp/src/errors/codes.rs b/packages/rs-dpp/src/errors/codes.rs index 302f2000bc1..d7db9ded82e 100644 --- a/packages/rs-dpp/src/errors/codes.rs +++ b/packages/rs-dpp/src/errors/codes.rs @@ -83,7 +83,6 @@ impl ErrorWithCode for StateError { Self::DuplicatedIdentityPublicKeyError { .. } => 4021, Self::DuplicatedIdentityPublicKeyIdError { .. } => 4022, Self::IdentityPublicKeyIsDisabledError { .. } => 4023, - Self::InvalidDocumentNoPreviousRevisionError { .. } => 4024, } } } diff --git a/packages/rs-dpp/src/identifier/identifier.rs b/packages/rs-dpp/src/identifier/identifier.rs index 7e5c2ac34ab..5b84b5fbc8e 100644 --- a/packages/rs-dpp/src/identifier/identifier.rs +++ b/packages/rs-dpp/src/identifier/identifier.rs @@ -1,6 +1,6 @@ -use std::convert::{TryFrom, TryInto}; -use rand::Rng; use rand::rngs::StdRng; +use rand::Rng; +use std::convert::{TryFrom, TryInto}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; @@ -35,11 +35,8 @@ impl Identifier { Identifier { buffer } } - pub fn random(rng: &mut StdRng) -> Identifier - { - Identifier { - buffer: rng.gen(), - } + pub fn random(rng: &mut StdRng) -> Identifier { + Identifier { buffer: rng.gen() } } pub fn as_bytes(&self) -> &[u8; 32] { @@ -174,4 +171,4 @@ impl PartialEq for [u8; 32] { fn eq(&self, other: &Identifier) -> bool { self == &other.buffer } -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index a4b55612442..ebc1483c0dd 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -6,12 +6,12 @@ use mockall::{automock, predicate::*}; use serde_json::Value as JsonValue; use std::convert::{Infallible, TryInto}; +use crate::document::Document; use crate::identity::KeyID; use crate::{ prelude::*, state_transition::state_transition_execution_context::StateTransitionExecutionContext, }; -use crate::document::Document; impl From for ProtocolError { fn from(_: Infallible) -> Self { diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 9605ebc7878..d27ab584e6d 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -247,7 +247,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace state_error, StateError::InvalidDocumentRevisionError { document_id, current_revision } if { document_id == &transition_id && - current_revision == &1 + current_revision == &Some(1) } )); } diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index ffcb31f89d8..3693a40375b 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -1,11 +1,14 @@ -use std::convert::TryInto; -use std::sync::Arc; use rand::rngs::StdRng; use rand::SeedableRng; +use std::convert::TryInto; +use std::sync::Arc; -use serde_json::{json, Value as JsonValue}; use platform_value::Value; +use serde_json::{json, Value as JsonValue}; +use crate::contracts::withdrawals_contract::document_types; +use crate::data_contract::DriveContractExt; +use crate::document::Document; use crate::{ contracts::withdrawals_contract, document::{ @@ -17,9 +20,6 @@ use crate::{ tests::utils::generate_random_identifier_struct as gen_owner_id, version::LATEST_VERSION, }; -use crate::contracts::withdrawals_contract::document_types; -use crate::data_contract::DriveContractExt; -use crate::document::Document; use super::get_document_validator_fixture; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs index a5de319cf72..a693ba865c3 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs @@ -1,9 +1,12 @@ #[cfg(test)] mod apply_identity_credit_withdrawal_transition_factory { - use std::collections::BTreeMap; use dashcore::{consensus, BlockHeader}; use serde_json::json; + use std::collections::BTreeMap; + use crate::contracts::withdrawals_contract::property_names::{ + AMOUNT, CORE_FEE_PER_BYTE, OUTPUT_SCRIPT, POOLING, STATUS, + }; use crate::{ contracts::withdrawals_contract, document::Document, @@ -15,9 +18,8 @@ mod apply_identity_credit_withdrawal_transition_factory { tests::fixtures::get_data_contract_fixture, }; use mockall::predicate::{always, eq}; - use std::default::Default; use platform_value::Value; - use crate::contracts::withdrawals_contract::property_names::{AMOUNT, CORE_FEE_PER_BYTE, OUTPUT_SCRIPT, POOLING, STATUS}; + use std::default::Default; #[tokio::test] async fn should_fail_if_data_contract_was_not_found() { @@ -89,11 +91,16 @@ mod apply_identity_credit_withdrawal_transition_factory { let created_at_match = doc.created_at == Some(block_time_seconds as u64 * 1000); let updated_at_match = doc.created_at == Some(block_time_seconds as u64 * 1000); - let document_expected_properties = BTreeMap::from([(AMOUNT.to_string(),Value::U64(10)), + let document_expected_properties = BTreeMap::from([ + (AMOUNT.to_string(), Value::U64(10)), (CORE_FEE_PER_BYTE.to_string(), Value::U64(0)), (POOLING.to_string(), Value::U8(Pooling::Never as u8)), (OUTPUT_SCRIPT.to_string(), Value::Bytes(vec![])), - (STATUS.to_string(), Value::U8(withdrawals_contract::WithdrawalStatus::QUEUED as u8))]); + ( + STATUS.to_string(), + Value::U8(withdrawals_contract::WithdrawalStatus::QUEUED as u8), + ), + ]); let document_data_match = doc.properties == document_expected_properties; diff --git a/packages/rs-dpp/src/util/cbor_value/cbor_map.rs b/packages/rs-dpp/src/util/cbor_value/cbor_map.rs index 8c0a885e62a..7b9248fbc18 100644 --- a/packages/rs-dpp/src/util/cbor_value/cbor_map.rs +++ b/packages/rs-dpp/src/util/cbor_value/cbor_map.rs @@ -171,10 +171,10 @@ where i128::from(v.borrow().as_integer().ok_or_else(|| { ProtocolError::DecodingError(format!("{key} must be an integer")) })?) - .try_into() - .map_err(|_| { - ProtocolError::DecodingError(format!("{key} is out of required bounds")) - }), + .try_into() + .map_err(|_| { + ProtocolError::DecodingError(format!("{key} is out of required bounds")) + }), )) } }) diff --git a/packages/rs-drive-abci/src/abci/handlers.rs b/packages/rs-drive-abci/src/abci/handlers.rs index b7225688760..f2e0da0bf96 100644 --- a/packages/rs-drive-abci/src/abci/handlers.rs +++ b/packages/rs-drive-abci/src/abci/handlers.rs @@ -321,7 +321,8 @@ mod tests { "transactionId": tx_id, }), None, - ).expect("expected withdrawal document"); + ) + .expect("expected withdrawal document"); let document_type = data_contract .document_type_for_name(withdrawals_contract::document_types::WITHDRAWAL) diff --git a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs index 3590bf829e7..62fa9fd7e18 100644 --- a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs @@ -9,6 +9,8 @@ use dashcore::{ hashes::Hash, QuorumHash, Script, TxOut, }; +use dpp::document::Document; +use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use drive::dpp::contracts::withdrawals_contract; use drive::dpp::data_contract::DriveContractExt; use drive::dpp::identifier::Identifier; @@ -21,8 +23,6 @@ use drive::{ query::TransactionArg, }; use serde_json::Value as JsonValue; -use dpp::document::Document; -use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use crate::{ error::{execution::ExecutionError, Error}, @@ -81,7 +81,8 @@ impl Platform { let documents_to_update: Vec = broadcasted_withdrawal_documents .into_iter() .map(|mut document| { - let transaction_sign_height: u32 = document.properties + let transaction_sign_height: u32 = document + .properties .get_integer(withdrawals_contract::property_names::TRANSACTION_SIGN_HEIGHT) .map_err(|_| { Error::Execution(ExecutionError::CorruptedCodeExecution( @@ -89,7 +90,8 @@ impl Platform { )) })?; - let transaction_id_bytes = document.properties + let transaction_id_bytes = document + .properties .get_bytes(withdrawals_contract::property_names::TRANSACTION_ID) .map_err(|_| { Error::Execution(ExecutionError::CorruptedCodeExecution( @@ -97,7 +99,8 @@ impl Platform { )) })?; - let transaction_index = document.properties + let transaction_index = document + .properties .get_integer(withdrawals_contract::property_names::TRANSACTION_INDEX) .map_err(|_| { Error::Execution(ExecutionError::CorruptedCodeExecution( @@ -463,7 +466,8 @@ impl Platform { )?; for (i, document) in documents.iter().enumerate() { - let output_script_bytes = document.properties + let output_script_bytes = document + .properties .get_bytes(withdrawals_contract::property_names::OUTPUT_SCRIPT) .map_err(|_| { Error::Execution(ExecutionError::CorruptedCodeExecution( @@ -471,7 +475,8 @@ impl Platform { )) })?; - let amount = document.properties + let amount = document + .properties .get_integer(withdrawals_contract::property_names::AMOUNT) .map_err(|_| { Error::Execution(ExecutionError::CorruptedCodeExecution( @@ -479,7 +484,8 @@ impl Platform { )) })?; - let core_fee_per_byte: u32 = document.properties + let core_fee_per_byte: u32 = document + .properties .get_integer(withdrawals_contract::property_names::CORE_FEE_PER_BYTE) .map_err(|_| { Error::Execution(ExecutionError::CorruptedCodeExecution( @@ -742,6 +748,7 @@ mod tests { use dpp::data_contract::DriveContractExt; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; + use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::prelude::Identifier; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use drive::dpp::contracts::withdrawals_contract; @@ -777,7 +784,8 @@ mod tests { "transactionIndex": 1, }), None, - ).expect("expected withdrawal document"); + ) + .expect("expected withdrawal document"); let document_type = data_contract .document_type_for_name(withdrawals_contract::document_types::WITHDRAWAL) @@ -803,7 +811,8 @@ mod tests { "transactionIndex": 2, }), None, - ).expect("expected withdrawal document"); + ) + .expect("expected withdrawal document"); setup_document( &platform.drive, @@ -850,9 +859,10 @@ mod tests { ]; for document in updated_documents { - assert_eq!(document.revision, 2); + assert_eq!(document.revision, Some(2)); let tx_id: Vec = document + .properties .get_bytes("transactionId") .expect("to get transactionId"); @@ -931,17 +941,14 @@ mod tests { mod build_withdrawal_transactions_from_documents { use crate::test::helpers::setup::setup_platform_with_initial_state_structure; use dpp::data_contract::DriveContractExt; + use dpp::document::Document; + use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; use dpp::prelude::Identifier; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; - use dpp::{ - document::document_stub::Document, - identity::state_transition::identity_credit_withdrawal_transition::Pooling, - }; use drive::drive::block_info::BlockInfo; use drive::drive::identity::withdrawals::WithdrawalTransactionIdAndBytes; use drive::tests::helpers::setup::setup_system_data_contract; use itertools::Itertools; - use dpp::document::Document; use super::*; @@ -970,7 +977,8 @@ mod tests { "transactionIndex": 1, }), None, - ).expect("expected withdrawal document"); + ) + .expect("expected withdrawal document"); let document_type = data_contract .document_type_for_name(withdrawals_contract::document_types::WITHDRAWAL) @@ -996,7 +1004,8 @@ mod tests { "transactionIndex": 2, }), None, - ).expect("expected withdrawal document"); + ) + .expect("expected withdrawal document"); setup_document( &platform.drive, @@ -1008,13 +1017,13 @@ mod tests { let documents = vec![ Document::from_cbor( - &document_1.to_buffer().expect("to convert document to cbor"), + &document_1.to_cbor().expect("to convert document to cbor"), None, None, ) .expect("to create document from cbor"), Document::from_cbor( - &document_2.to_buffer().expect("to convert document to cbor"), + &document_2.to_cbor().expect("to convert document to cbor"), None, None, ) diff --git a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs index 035dced95ff..67d9c210754 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -88,7 +88,7 @@ fn create_test_mn_share_document( let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); - let document_cbor = document.to_cbor(); + let document_cbor = document.to_cbor().expect("expected to encode to cbor"); drive .add_document_for_contract( diff --git a/packages/rs-drive/benches/benchmarks.rs b/packages/rs-drive/benches/benchmarks.rs index 26de228572f..099a53cf048 100644 --- a/packages/rs-drive/benches/benchmarks.rs +++ b/packages/rs-drive/benches/benchmarks.rs @@ -78,7 +78,7 @@ fn test_drive_10_serialization(c: &mut Criterion) { || document_type.random_documents(10, Some(3333)), |documents| { documents.iter().for_each(|document| { - document.to_cbor(); + document.to_cbor().expect("expected to encode to cbor"); }) }, BatchSize::LargeInput, @@ -116,7 +116,12 @@ fn test_drive_10_deserialization(c: &mut Criterion) { document_type .random_documents(10, Some(3333)) .iter() - .map(|a| (a.serialize(document_type).unwrap(), a.to_cbor())) + .map(|a| { + ( + a.serialize(document_type).unwrap(), + a.to_cbor().expect("expected to encode to cbor"), + ) + }) .unzip(); let mut group = c.benchmark_group("Deserialization"); diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index b4dd0adbdc3..66f4a5e11c4 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -1186,7 +1186,10 @@ mod tests { owned_document_info: OwnedDocumentInfo { document_info: DocumentInfo::DocumentRefAndSerialization(( &document, - document.to_cbor().as_slice(), + document + .to_cbor() + .expect("expected to encode to cbor") + .as_slice(), storage_flags, )), owner_id: Some(random_owner_id), @@ -1225,7 +1228,10 @@ mod tests { owned_document_info: OwnedDocumentInfo { document_info: DocumentInfo::DocumentRefAndSerialization(( &document, - document.to_cbor().as_slice(), + document + .to_cbor() + .expect("expected to encode to cbor") + .as_slice(), storage_flags, )), owner_id: Some(random_owner_id), diff --git a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs index 56c11b1066f..9701e9b1d8c 100644 --- a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs +++ b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs @@ -1,14 +1,12 @@ use std::collections::BTreeMap; use dpp::data_contract::document_type::random_document::CreateRandomDocument; +use dpp::document::Document; use dpp::platform_value::Value; -use dpp::{ - contracts::withdrawals_contract, data_contract::DriveContractExt, -}; +use dpp::{contracts::withdrawals_contract, data_contract::DriveContractExt}; use grovedb::TransactionArg; use indexmap::IndexMap; use lazy_static::__Deref; -use dpp::document::Document; use crate::{ drive::{query::QueryDocumentsOutcome, Drive}, @@ -238,7 +236,8 @@ mod tests { "transactionIndex": 1, }), None, - ).expect("expected withdrawal document"); + ) + .expect("expected withdrawal document"); let document_type = data_contract .document_type_for_name(withdrawals_contract::document_types::WITHDRAWAL) @@ -264,7 +263,8 @@ mod tests { "transactionIndex": 2, }), None, - ).expect("expected withdrawal document"); + ) + .expect("expected withdrawal document"); setup_document( &drive, @@ -327,7 +327,8 @@ mod tests { "transactionId": (0..32).collect::>(), }), None, - ).expect("expected to get withdrawal document"); + ) + .expect("expected to get withdrawal document"); let document_type = data_contract .document_type_for_name(withdrawals_contract::document_types::WITHDRAWAL) diff --git a/packages/rs-drive/src/tests/helpers/setup.rs b/packages/rs-drive/src/tests/helpers/setup.rs index 8a50d2798aa..986a06b3078 100644 --- a/packages/rs-drive/src/tests/helpers/setup.rs +++ b/packages/rs-drive/src/tests/helpers/setup.rs @@ -40,10 +40,10 @@ use crate::fee_pools::epochs::Epoch; use crate::drive::object_size_info::DocumentInfo::DocumentRefWithoutSerialization; use crate::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use dpp::data_contract::document_type::DocumentType; -use grovedb::TransactionArg; -use tempfile::TempDir; use dpp::data_contract::DataContract; use dpp::document::Document; +use grovedb::TransactionArg; +use tempfile::TempDir; /// Struct with options regarding setting up fee pools. pub struct SetupFeePoolsOptions { diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index d43256ef126..68b8b1585db 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -556,7 +556,7 @@ pub fn setup_dpns_test_with_data(path: &str) -> (Drive, Contract) { .expect("expected to serialize to cbor"); let domain = Document::from_cbor(&domain_cbor, None, None) - .expect("expected to deserialize the document"); + .expect("expected to deserialize the document"); let document_type = contract .document_type_for_name("domain") diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 32ac63b3c1d..07a6f1b4f20 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -392,9 +392,7 @@ where } fn get_optional_bytes(&self, key: &str) -> Result>, Error> { - self.get(key) - .map(|v| v.borrow().to_bytes()) - .transpose() + self.get(key).map(|v| v.borrow().to_bytes()).transpose() } fn get_bytes(&self, key: &str) -> Result, Error> { diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 35899929a33..573c068fc47 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -14,9 +14,9 @@ mod integer; pub mod system_bytes; pub mod value_map; -use serde::{Deserialize, Serialize}; pub use error::Error; pub use integer::Integer; +use serde::{Deserialize, Serialize}; pub type ValueMap = Vec<(Value, Value)>; pub type Hash256 = [u8; 32]; diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index 48719f8fa95..b172b728310 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -18,7 +18,7 @@ use crate::{buffer::Buffer, identifier::IdentifierWrapper}; #[wasm_bindgen(js_name=DataContract)] #[derive(Debug, Clone)] -pub struct DataContractWasm(DataContract); +pub struct DataContractWasm(pub(crate) DataContract); impl std::convert::From for DataContractWasm { fn from(v: DataContract) -> Self { diff --git a/packages/wasm-dpp/src/document/document_in_state_transition.rs b/packages/wasm-dpp/src/document/document_in_state_transition.rs new file mode 100644 index 00000000000..cc64eb1064a --- /dev/null +++ b/packages/wasm-dpp/src/document/document_in_state_transition.rs @@ -0,0 +1,338 @@ +use dpp::dashcore::anyhow::Context; +use dpp::document::{ + document_in_state_transition_property_names, DocumentInStateTransition, + DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS, +}; +use dpp::prelude::{Identifier, Revision}; +use dpp::util::json_schema::JsonSchemaExt; +use dpp::util::json_value::{JsonValueExt, ReplaceWith}; +use dpp::util::string_encoding::Encoding; +use serde::{Deserialize, Serialize}; +use std::convert::TryInto; +use wasm_bindgen::prelude::*; + +use crate::buffer::Buffer; +use crate::document::BinaryType; +use crate::errors::RustConversionError; +use crate::identifier::IdentifierWrapper; +use crate::lodash::lodash_set; +use crate::utils::WithJsError; +use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt}; +use crate::{with_js_error, ConversionOptions}; +use crate::{DataContractWasm, MetadataWasm}; + +#[wasm_bindgen(js_name=DocumentInStateTransition)] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DocumentInStateTransitionWasm(pub(crate) DocumentInStateTransition); + +#[wasm_bindgen(js_class=DocumentInStateTransition)] +impl DocumentInStateTransitionWasm { + #[wasm_bindgen(constructor)] + pub fn new( + js_raw_document: JsValue, + js_data_contract: &DataContractWasm, + ) -> Result { + let mut raw_document = with_serde_to_json_value(&js_raw_document)?; + + let document_type = raw_document + .get_string(document_in_state_transition_property_names::DOCUMENT_TYPE) + .with_js_error()?; + + let (identifier_paths, _) = js_data_contract + .inner() + .get_identifiers_and_binary_paths(document_type) + .with_js_error()?; + + // Errors are ignored. When `Buffer` crosses the WASM boundary it becomes an Array. + // When `Identifier` crosses the WASM boundary it becomes a String. From perspective of JS + // `Identifier` and `Buffer` are used interchangeably, so we we can expect the replacing may fail when `Buffer` is provided + let _ = raw_document + .replace_identifier_paths( + identifier_paths + .into_iter() + .chain(DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS), + ReplaceWith::Bytes, + ) + .with_js_error(); + // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array + + let document = DocumentInStateTransition::from_raw_document( + raw_document, + js_data_contract.to_owned().into(), + ) + .with_js_error()?; + + Ok(document.into()) + } + + #[wasm_bindgen(js_name=getProtocolVersion)] + pub fn get_protocol_version(&self) -> u32 { + self.0.protocol_version + } + + #[wasm_bindgen(js_name=getId)] + pub fn get_id(&self) -> IdentifierWrapper { + self.0.id.into() + } + + #[wasm_bindgen(js_name=setId)] + pub fn set_id(&mut self, js_id: IdentifierWrapper) { + self.0.id = js_id.inner(); + } + + #[wasm_bindgen(js_name=getType)] + pub fn get_type(&self) -> String { + self.0.document_type.clone() + } + + #[wasm_bindgen(js_name=getDataContractId)] + pub fn get_data_contract_id(&self) -> IdentifierWrapper { + self.0.data_contract_id.into() + } + + #[wasm_bindgen(js_name=getDataContract)] + pub fn get_data_contract(&self) -> DataContractWasm { + self.0.data_contract.clone().into() + } + + #[wasm_bindgen(js_name=setOwnerId)] + pub fn set_owner_id(&mut self, owner_id: IdentifierWrapper) { + self.0.owner_id = owner_id.inner(); + } + + #[wasm_bindgen(js_name=getOwnerId)] + pub fn get_owner_id(&self) -> IdentifierWrapper { + self.0.owner_id.into() + } + + #[wasm_bindgen(js_name=setRevision)] + pub fn set_revision(&mut self, rev: Revision) { + self.0.revision = rev + } + + #[wasm_bindgen(js_name=getRevision)] + pub fn get_revision(&self) -> Revision { + self.0.revision + } + + #[wasm_bindgen(js_name=setEntropy)] + pub fn set_entropy(&mut self, e: Vec) -> Result<(), JsValue> { + let entropy: [u8; 32] = e.try_into().map_err(|_| { + RustConversionError::Error(String::from( + "unable to turn the data into 32 bytes array of bytes", + )) + .to_js_value() + })?; + self.0.entropy = entropy; + Ok(()) + } + + #[wasm_bindgen(js_name=getEntropy)] + pub fn get_entropy(&mut self) -> Buffer { + Buffer::from_bytes(&self.0.entropy) + } + + #[wasm_bindgen(js_name=setData)] + pub fn set_data(&mut self, d: JsValue) -> Result<(), JsValue> { + self.0.data = with_js_error!(serde_wasm_bindgen::from_value(d))?; + Ok(()) + } + + #[wasm_bindgen(js_name=getData)] + pub fn get_data(&mut self) -> Result { + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + + Ok(with_js_error!(self.0.data.serialize(&serializer))?) + } + + #[wasm_bindgen(js_name=set)] + pub fn set(&mut self, path: String, js_value_to_set: JsValue) -> Result<(), JsValue> { + let (identifier_paths, _) = self.0.get_identifiers_and_binary_paths().with_js_error()?; + for property_path in identifier_paths { + if property_path == path { + let id_value = js_value_to_set.with_serde_to_json_value()?; + let id_string = id_value + .as_str() + .context("the value must be a string") + .with_js_error()?; + let id = Identifier::from_string(id_string, Encoding::Base58).with_js_error()?; + let new_value = serde_json::to_value(id.as_bytes()).with_js_error()?; + + return self.0.set(&path, new_value).with_js_error(); + } else if property_path.starts_with(&path) { + let (_, suffix) = property_path.split_at(path.len() + 1); + let mut value = js_value_to_set.with_serde_to_json_value()?; + + if value.get_value(suffix).is_ok() { + let id_string = value + .remove_path_into::(suffix) + .with_context(|| format!("unable convert `{path}` into string")) + .map_err(|e| format!("{e:#}"))?; + let id: IdentifierWrapper = + Identifier::from_string(&id_string, Encoding::Base58) + .with_js_error()? + .into(); + let new_value = serde_json::to_value(id.inner().as_bytes()).with_js_error()?; + value.insert_with_path(suffix, new_value).with_js_error()?; + + return self.0.set(&path, value).with_js_error(); + } + } + } + + let value = js_value_to_set.with_serde_to_json_value()?; + self.0.set(&path, value).with_js_error() + } + + #[wasm_bindgen(js_name=get)] + pub fn get(&mut self, path: String) -> JsValue { + let binary_type = self.get_binary_type_of_path(&path); + + if let Some(value) = self.0.get(&path) { + match binary_type { + BinaryType::Identifier => { + if let Ok(bytes) = serde_json::from_value::>(value.to_owned()) { + let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); + + return id.into(); + } + } + BinaryType::Buffer => { + if let Ok(bytes) = serde_json::from_value::>(value.to_owned()) { + return Buffer::from_bytes(&bytes).into(); + } + } + BinaryType::None => { + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + if let Ok(js_value) = value.serialize(&serializer) { + return js_value; + } + } + } + } + + JsValue::undefined() + } + + #[wasm_bindgen(js_name=setCreatedAt)] + pub fn set_created_at(&mut self, ts: f64) { + self.0.created_at = Some(ts as u64); + } + + #[wasm_bindgen(js_name=setUpdatedAt)] + pub fn set_updated_at(&mut self, ts: f64) { + self.0.updated_at = Some(ts as u64); + } + + #[wasm_bindgen(js_name=getCreatedAt)] + pub fn get_created_at(&self) -> Option { + self.0.created_at.map(|v| v as f64) + } + + #[wasm_bindgen(js_name=getUpdatedAt)] + pub fn get_updated_at(&self) -> Option { + self.0.updated_at.map(|v| v as f64) + } + + #[wasm_bindgen(js_name=getMetadata)] + pub fn get_metadata(&self) -> Option { + self.0.metadata.clone().map(Into::into) + } + + #[wasm_bindgen(js_name=setMetadata)] + pub fn set_metadata(mut self, metadata: MetadataWasm) -> Self { + self.0.metadata = Some(metadata.into()); + self + } + + #[wasm_bindgen(js_name=toObject)] + pub fn to_object(&self, options: &JsValue) -> Result { + let options: ConversionOptions = if !options.is_undefined() && options.is_object() { + let raw_options = options.with_serde_to_json_value()?; + serde_json::from_value(raw_options).with_js_error()? + } else { + Default::default() + }; + let mut value = self.0.to_object().with_js_error()?; + + let (identifiers_paths, binary_paths) = + self.0.get_identifiers_and_binary_paths().with_js_error()?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + let js_value = value.serialize(&serializer)?; + + for path in identifiers_paths + .into_iter() + .chain(DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS) + { + if let Ok(bytes) = value.remove_path_into::>(path) { + if !options.skip_identifiers_conversion { + let buffer = Buffer::from_bytes(&bytes); + lodash_set(&js_value, path, buffer.into()); + } else { + let id = IdentifierWrapper::new(bytes)?; + lodash_set(&js_value, path, id.into()); + } + } + } + + for path in binary_paths { + if let Ok(bytes) = value.remove_path_into::>(path) { + let buffer = Buffer::from_bytes(&bytes); + lodash_set(&js_value, path, buffer.into()); + } + } + + Ok(js_value) + } + + #[wasm_bindgen(js_name=toJSON)] + pub fn to_json(&self) -> Result { + let value = self.0.to_json().with_js_error()?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + + with_js_error!(value.serialize(&serializer)) + } + + #[wasm_bindgen(js_name=toBuffer)] + pub fn to_buffer(&self) -> Result { + let bytes = self.0.to_buffer().with_js_error()?; + + Ok(Buffer::from_bytes(&bytes)) + } + + #[wasm_bindgen(js_name=hash)] + pub fn hash(&self) -> Result { + let bytes = self.0.hash().with_js_error()?; + Ok(Buffer::from_bytes(&bytes)) + } + + #[wasm_bindgen(js_name=clone)] + pub fn deep_clone(&self) -> Self { + self.clone() + } +} + +impl DocumentInStateTransitionWasm { + fn get_binary_type_of_path(&self, path: &String) -> BinaryType { + let maybe_binary_properties = self + .0 + .data_contract + .get_binary_properties(&self.0.document_type); + + if let Ok(binary_properties) = maybe_binary_properties { + if let Some(data) = binary_properties.get(path) { + if data.is_type_of_identifier() { + return BinaryType::Identifier; + } + return BinaryType::Buffer; + } + } + BinaryType::None + } +} + +impl From for DocumentInStateTransitionWasm { + fn from(d: DocumentInStateTransition) -> Self { + DocumentInStateTransitionWasm(d) + } +} diff --git a/packages/wasm-dpp/src/document/errors/document_no_revision_error.rs b/packages/wasm-dpp/src/document/errors/document_no_revision_error.rs new file mode 100644 index 00000000000..2b94d2d82b8 --- /dev/null +++ b/packages/wasm-dpp/src/document/errors/document_no_revision_error.rs @@ -0,0 +1,25 @@ +use thiserror::Error; + +use crate::DocumentWasm; + +use super::*; + +#[wasm_bindgen] +#[derive(Error, Debug)] +#[error("Document no revision")] +pub struct DocumentNoRevisionError { + document: DocumentWasm, +} + +#[wasm_bindgen] +impl DocumentNoRevisionError { + #[wasm_bindgen(constructor)] + pub fn new(document: DocumentWasm) -> DocumentNoRevisionError { + Self { document } + } + + #[wasm_bindgen(js_name=getDocument)] + pub fn get_document_transition(&self) -> DocumentWasm { + self.document.clone() + } +} diff --git a/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs b/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs index 8c3f678aa3f..c0224df3ad4 100644 --- a/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs +++ b/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs @@ -1,25 +1,24 @@ +use crate::DocumentInStateTransitionWasm; use thiserror::Error; -use crate::DocumentWasm; - use super::*; #[wasm_bindgen] #[derive(Error, Debug)] #[error("Invalid Document Initial revision '{}'", document.get_revision())] pub struct InvalidInitialRevisionError { - document: DocumentWasm, + document: DocumentInStateTransitionWasm, } #[wasm_bindgen] impl InvalidInitialRevisionError { #[wasm_bindgen(constructor)] - pub fn new(document: DocumentWasm) -> InvalidInitialRevisionError { + pub fn new(document: DocumentInStateTransitionWasm) -> InvalidInitialRevisionError { Self { document } } #[wasm_bindgen(js_name=getDocument)] - pub fn get_document_transition(&self) -> DocumentWasm { + pub fn get_document_transition(&self) -> DocumentInStateTransitionWasm { self.document.clone() } } diff --git a/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs b/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs index 645438c65ab..41bde47f60a 100644 --- a/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs +++ b/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs @@ -1,16 +1,15 @@ +use crate::DocumentInStateTransitionWasm; use dpp::document::DocumentInStateTransition; use itertools::Itertools; use thiserror::Error; -use crate::DocumentWasm; - use super::*; #[wasm_bindgen] #[derive(Error, Debug)] #[error("Documents have mixed owner ids")] pub struct MismatchOwnerIdsError { - documents: Vec, + documents: Vec, } #[wasm_bindgen] @@ -31,7 +30,10 @@ impl MismatchOwnerIdsError { impl MismatchOwnerIdsError { pub fn from_documents(documents: Vec) -> MismatchOwnerIdsError { Self { - documents: documents.into_iter().map(DocumentWasm::from).collect_vec(), + documents: documents + .into_iter() + .map(DocumentInStateTransitionWasm::from) + .collect_vec(), } } } diff --git a/packages/wasm-dpp/src/document/errors/mod.rs b/packages/wasm-dpp/src/document/errors/mod.rs index a0f79906201..4b92bd5e2f9 100644 --- a/packages/wasm-dpp/src/document/errors/mod.rs +++ b/packages/wasm-dpp/src/document/errors/mod.rs @@ -1,6 +1,7 @@ use serde::Serialize; use wasm_bindgen::prelude::*; +use crate::document::errors::document_no_revision_error::DocumentNoRevisionError; pub use document_already_exists_error::*; pub use document_not_provided_error::*; use dpp::document::errors::DocumentError; @@ -15,6 +16,7 @@ use crate::errors::consensus_error::from_consensus_error; use crate::utils::*; mod document_already_exists_error; +mod document_no_revision_error; mod document_not_provided_error; mod invalid_action_name_error; mod invalid_document_action_error; @@ -55,5 +57,8 @@ pub fn from_document_to_js_error(e: DocumentError) -> JsValue { MismatchOwnerIdsError::from_documents(documents).into() } DocumentError::NoDocumentsSuppliedError => NoDocumentsSuppliedError::new().into(), + DocumentError::DocumentNoRevisionError { document } => { + DocumentNoRevisionError::new((*document).into()).into() + } } } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index fd45569a26a..891c227af78 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -16,7 +16,8 @@ use crate::{ identifier::identifier_from_js_value, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, utils::{ToSerdeJSONExt, WithJsError}, - DataContractWasm, DocumentWasm, DocumentsBatchTransitionWASM, DocumentsContainer, + DataContractWasm, DocumentInStateTransitionWasm, DocumentsBatchTransitionWASM, + DocumentsContainer, }; use super::validator::DocumentValidatorWasm; @@ -24,9 +25,9 @@ use super::validator::DocumentValidatorWasm; #[wasm_bindgen(js_name=DocumentTransitions)] #[derive(Debug, Default)] pub struct DocumentTransitions { - create: Vec, - replace: Vec, - delete: Vec, + create: Vec, + replace: Vec, + delete: Vec, } #[wasm_bindgen(js_class=DocumentTransitions)] @@ -37,17 +38,17 @@ impl DocumentTransitions { } #[wasm_bindgen(js_name = "addTransitionCreate")] - pub fn add_transition_create(&mut self, transition: DocumentWasm) { + pub fn add_transition_create(&mut self, transition: DocumentInStateTransitionWasm) { self.create.push(transition) } #[wasm_bindgen(js_name = "addTransitionReplace")] - pub fn add_transition_replace(&mut self, transition: DocumentWasm) { + pub fn add_transition_replace(&mut self, transition: DocumentInStateTransitionWasm) { self.replace.push(transition) } #[wasm_bindgen(js_name = "addTransitionDelete")] - pub fn add_transition_delete(&mut self, transition: DocumentWasm) { + pub fn add_transition_delete(&mut self, transition: DocumentInStateTransitionWasm) { self.delete.push(transition) } } @@ -83,7 +84,7 @@ impl DocumentFactoryWASM { js_owner_id: &JsValue, document_type: &str, data: &JsValue, - ) -> Result { + ) -> Result { let owner_id = identifier_from_js_value(js_owner_id)?; let dynamic_data = data.with_serde_to_json_value()?; let document = self @@ -126,7 +127,7 @@ impl DocumentFactoryWASM { &self, raw_document_js: JsValue, options: JsValue, - ) -> Result { + ) -> Result { let mut raw_document = raw_document_js.with_serde_to_json_value()?; let options: FactoryOptions = if !options.is_undefined() && options.is_object() { let raw_options = options.with_serde_to_json_value()?; @@ -172,7 +173,7 @@ impl DocumentFactoryWASM { &self, buffer: Vec, options: &JsValue, - ) -> Result { + ) -> Result { let options: FactoryOptions = if !options.is_undefined() && options.is_object() { let raw_options = options.with_serde_to_json_value()?; serde_json::from_value(raw_options).with_js_error()? diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index d471b2afcb8..a770bb73610 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -1,5 +1,5 @@ use dpp::dashcore::anyhow::Context; -use dpp::prelude::Identifier; +use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::{JsonValueExt, ReplaceWith}; use dpp::util::string_encoding::Encoding; @@ -12,22 +12,29 @@ use crate::errors::RustConversionError; use crate::identifier::IdentifierWrapper; use crate::lodash::lodash_set; use crate::utils::WithJsError; -use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt}; +use crate::utils::{with_serde_to_json_value, with_serde_to_platform_value, ToSerdeJSONExt}; use crate::with_js_error; use crate::{DataContractWasm, MetadataWasm}; pub mod errors; pub use state_transition::*; +mod document_in_state_transition; mod factory; pub mod state_transition; mod validator; pub use document_batch_transition::{DocumentsBatchTransitionWASM, DocumentsContainer}; +pub use document_in_state_transition::DocumentInStateTransitionWasm; +use dpp::data_contract::{DataContract, DriveContractExt}; use dpp::document::{ - document_in_state_transition_property_names, DocumentInStateTransition, + document_in_state_transition_property_names, Document, DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS, }; +use dpp::identity::TimestampMillis; +use dpp::platform_value::Value; +use dpp::ProtocolError; pub use factory::DocumentFactoryWASM; +use serde_json::Value as JsonValue; pub use validator::DocumentValidatorWasm; pub(super) enum BinaryType { @@ -44,7 +51,7 @@ pub struct ConversionOptions { #[wasm_bindgen(js_name=Document)] #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DocumentWasm(DocumentInStateTransition); +pub struct DocumentWasm(Document); #[wasm_bindgen(js_class=Document)] impl DocumentWasm { @@ -77,20 +84,11 @@ impl DocumentWasm { .with_js_error(); // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array - let document = DocumentInStateTransition::from_raw_document( - raw_document, - js_data_contract.to_owned().into(), - ) - .with_js_error()?; + let document = Document::from_raw_json_document(raw_document).with_js_error()?; Ok(document.into()) } - #[wasm_bindgen(js_name=getProtocolVersion)] - pub fn get_protocol_version(&self) -> u32 { - self.0.protocol_version - } - #[wasm_bindgen(js_name=getId)] pub fn get_id(&self) -> IdentifierWrapper { self.0.id.into() @@ -98,27 +96,12 @@ impl DocumentWasm { #[wasm_bindgen(js_name=setId)] pub fn set_id(&mut self, js_id: IdentifierWrapper) { - self.0.id = js_id.inner(); - } - - #[wasm_bindgen(js_name=getType)] - pub fn get_type(&self) -> String { - self.0.document_type.clone() - } - - #[wasm_bindgen(js_name=getDataContractId)] - pub fn get_data_contract_id(&self) -> IdentifierWrapper { - self.0.data_contract_id.into() - } - - #[wasm_bindgen(js_name=getDataContract)] - pub fn get_data_contract(&self) -> DataContractWasm { - self.0.data_contract.clone().into() + self.0.id = js_id.inner().to_buffer(); } #[wasm_bindgen(js_name=setOwnerId)] pub fn set_owner_id(&mut self, owner_id: IdentifierWrapper) { - self.0.owner_id = owner_id.inner(); + self.0.owner_id = owner_id.inner().to_buffer(); } #[wasm_bindgen(js_name=getOwnerId)] @@ -127,122 +110,80 @@ impl DocumentWasm { } #[wasm_bindgen(js_name=setRevision)] - pub fn set_revision(&mut self, rev: u32) { - self.0.revision = rev + pub fn set_revision(&mut self, revision: Option) { + self.0.revision = revision } #[wasm_bindgen(js_name=getRevision)] - pub fn get_revision(&self) -> u32 { + pub fn get_revision(&self) -> Option { self.0.revision } - #[wasm_bindgen(js_name=setEntropy)] - pub fn set_entropy(&mut self, e: Vec) -> Result<(), JsValue> { - let entropy: [u8; 32] = e.try_into().map_err(|_| { - RustConversionError::Error(String::from( - "unable to turn the data into 32 bytes array of bytes", - )) - .to_js_value() - })?; - self.0.entropy = entropy; - Ok(()) - } - - #[wasm_bindgen(js_name=getEntropy)] - pub fn get_entropy(&mut self) -> Buffer { - Buffer::from_bytes(&self.0.entropy) - } - #[wasm_bindgen(js_name=setData)] - pub fn set_data(&mut self, d: JsValue) -> Result<(), JsValue> { - self.0.data = with_js_error!(serde_wasm_bindgen::from_value(d))?; + pub fn set_properties(&mut self, d: JsValue) -> Result<(), JsValue> { + self.0.properties = with_js_error!(serde_wasm_bindgen::from_value(d))?; Ok(()) } #[wasm_bindgen(js_name=getData)] - pub fn get_data(&mut self) -> Result { + pub fn get_properties(&mut self) -> Result { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - Ok(with_js_error!(self.0.data.serialize(&serializer))?) + Ok(with_js_error!(self.0.properties.serialize(&serializer))?) } #[wasm_bindgen(js_name=set)] pub fn set(&mut self, path: String, js_value_to_set: JsValue) -> Result<(), JsValue> { - let (identifier_paths, _) = self.0.get_identifiers_and_binary_paths().with_js_error()?; - for property_path in identifier_paths { - if property_path == path { - let id_value = js_value_to_set.with_serde_to_json_value()?; - let id_string = id_value - .as_str() - .context("the value must be a string") - .with_js_error()?; - let id = Identifier::from_string(id_string, Encoding::Base58).with_js_error()?; - let new_value = serde_json::to_value(id.as_bytes()).with_js_error()?; - - return self.0.set(&path, new_value).with_js_error(); - } else if property_path.starts_with(&path) { - let (_, suffix) = property_path.split_at(path.len() + 1); - let mut value = js_value_to_set.with_serde_to_json_value()?; - - if value.get_value(suffix).is_ok() { - let id_string = value - .remove_path_into::(suffix) - .with_context(|| format!("unable convert `{path}` into string")) - .map_err(|e| format!("{e:#}"))?; - let id: IdentifierWrapper = - Identifier::from_string(&id_string, Encoding::Base58) - .with_js_error()? - .into(); - let new_value = serde_json::to_value(id.inner().as_bytes()).with_js_error()?; - value.insert_with_path(suffix, new_value).with_js_error()?; - - return self.0.set(&path, value).with_js_error(); - } - } - } - - let value = js_value_to_set.with_serde_to_json_value()?; - self.0.set(&path, value).with_js_error() + let value = js_value_to_set.with_serde_to_platform_value()?; + Ok(self.0.set(&path, value)) } #[wasm_bindgen(js_name=get)] - pub fn get(&mut self, path: String) -> JsValue { - let binary_type = self.get_binary_type_of_path(&path); + pub fn get( + &mut self, + path: String, + data_contract: DataContractWasm, + document_type_name: String, + ) -> Result { + let binary_type = self.get_binary_type_of_path(&path, data_contract, document_type_name); if let Some(value) = self.0.get(&path) { + let json_value_result: Result = + value.clone().try_into().map_err(ProtocolError::ValueError); + let json_value = json_value_result.with_js_error()?; match binary_type { BinaryType::Identifier => { - if let Ok(bytes) = serde_json::from_value::>(value.to_owned()) { + if let Ok(bytes) = serde_json::from_value::>(json_value) { let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); - return id.into(); + return Ok(id.into()); } } BinaryType::Buffer => { - if let Ok(bytes) = serde_json::from_value::>(value.to_owned()) { - return Buffer::from_bytes(&bytes).into(); + if let Ok(bytes) = serde_json::from_value::>(json_value) { + return Ok(Buffer::from_bytes(&bytes).into()); } } BinaryType::None => { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - if let Ok(js_value) = value.serialize(&serializer) { - return js_value; + if let Ok(js_value) = json_value.serialize(&serializer) { + return Ok(js_value); } } } } - JsValue::undefined() + Ok(JsValue::undefined()) } #[wasm_bindgen(js_name=setCreatedAt)] pub fn set_created_at(&mut self, ts: f64) { - self.0.created_at = Some(ts as i64); + self.0.created_at = Some(ts as TimestampMillis); } #[wasm_bindgen(js_name=setUpdatedAt)] pub fn set_updated_at(&mut self, ts: f64) { - self.0.updated_at = Some(ts as i64); + self.0.updated_at = Some(ts as TimestampMillis); } #[wasm_bindgen(js_name=getCreatedAt)] @@ -255,36 +196,32 @@ impl DocumentWasm { self.0.updated_at.map(|v| v as f64) } - #[wasm_bindgen(js_name=getMetadata)] - pub fn get_metadata(&self) -> Option { - self.0.metadata.clone().map(Into::into) - } - - #[wasm_bindgen(js_name=setMetadata)] - pub fn set_metadata(mut self, metadata: MetadataWasm) -> Self { - self.0.metadata = Some(metadata.into()); - self - } - #[wasm_bindgen(js_name=toObject)] - pub fn to_object(&self, options: &JsValue) -> Result { + pub fn to_object( + &self, + options: &JsValue, + data_contract: &DataContractWasm, + document_type_name: &str, + ) -> Result { let options: ConversionOptions = if !options.is_undefined() && options.is_object() { let raw_options = options.with_serde_to_json_value()?; serde_json::from_value(raw_options).with_js_error()? } else { Default::default() }; - let mut value = self.0.to_object().with_js_error()?; + let mut value = self + .0 + .to_object(&data_contract.0, document_type_name) + .with_js_error()?; - let (identifiers_paths, binary_paths) = - self.0.get_identifiers_and_binary_paths().with_js_error()?; + let (identifiers_paths, binary_paths) = self + .0 + .get_identifiers_and_binary_paths(&data_contract.0, document_type_name) + .with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_value = value.serialize(&serializer)?; - for path in identifiers_paths - .into_iter() - .chain(DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS) - { + for path in identifiers_paths.into_iter() { if let Ok(bytes) = value.remove_path_into::>(path) { if !options.skip_identifiers_conversion { let buffer = Buffer::from_bytes(&bytes); @@ -308,7 +245,7 @@ impl DocumentWasm { #[wasm_bindgen(js_name=toJSON)] pub fn to_json(&self) -> Result { - let value = self.0.to_json().with_js_error()?; + let value = self.0.to_cbor().with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); with_js_error!(value.serialize(&serializer)) @@ -316,14 +253,25 @@ impl DocumentWasm { #[wasm_bindgen(js_name=toBuffer)] pub fn to_buffer(&self) -> Result { - let bytes = self.0.to_buffer().with_js_error()?; + let bytes = self.0.to_cbor().with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } #[wasm_bindgen(js_name=hash)] - pub fn hash(&self) -> Result { - let bytes = self.0.hash().with_js_error()?; + pub fn hash( + &self, + data_contract: DataContractWasm, + document_type_name: String, + ) -> Result { + let document_type = data_contract + .0 + .document_type_for_name(document_type_name.as_str()) + .with_js_error()?; + let bytes = self + .0 + .hash(&data_contract.0, document_type) + .with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } @@ -334,11 +282,15 @@ impl DocumentWasm { } impl DocumentWasm { - fn get_binary_type_of_path(&self, path: &String) -> BinaryType { - let maybe_binary_properties = self + fn get_binary_type_of_path( + &self, + path: &String, + data_contract: DataContractWasm, + document_type_name: String, + ) -> BinaryType { + let maybe_binary_properties = data_contract .0 - .data_contract - .get_binary_properties(&self.0.document_type); + .get_binary_properties(document_type_name.as_str()); if let Ok(binary_properties) = maybe_binary_properties { if let Some(data) = binary_properties.get(path) { @@ -352,8 +304,8 @@ impl DocumentWasm { } } -impl From for DocumentWasm { - fn from(d: DocumentInStateTransition) -> Self { +impl From for DocumentWasm { + fn from(d: Document) -> Self { DocumentWasm(d) } } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 928fc83e8fa..70e63e00c6d 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -23,7 +23,7 @@ use crate::{ identifier::IdentifierWrapper, lodash::lodash_set, utils::{ToSerdeJSONExt, WithJsError}, - DocumentWasm, IdentityPublicKeyWasm, + DocumentInStateTransitionWasm, IdentityPublicKeyWasm, }; pub mod document_transition; @@ -48,17 +48,17 @@ impl DocumentsContainer { } #[wasm_bindgen(js_name=pushDocumentCreate)] - pub fn push_document_create(&mut self, d: DocumentWasm) { + pub fn push_document_create(&mut self, d: DocumentInStateTransitionWasm) { self.create.push(d.0); } #[wasm_bindgen(js_name=pushDocumentReplace)] - pub fn push_document_replace(&mut self, d: DocumentWasm) { + pub fn push_document_replace(&mut self, d: DocumentInStateTransitionWasm) { self.replace.push(d.0); } #[wasm_bindgen(js_name=pushDocumentDelete)] - pub fn push_document_delete(&mut self, d: DocumentWasm) { + pub fn push_document_delete(&mut self, d: DocumentInStateTransitionWasm) { self.delete.push(d.0); } } diff --git a/packages/wasm-dpp/src/errors/consensus/state/document/invalid_document_revision_error.rs b/packages/wasm-dpp/src/errors/consensus/state/document/invalid_document_revision_error.rs index 43af8cd40de..268f48173ae 100644 --- a/packages/wasm-dpp/src/errors/consensus/state/document/invalid_document_revision_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/state/document/invalid_document_revision_error.rs @@ -5,7 +5,7 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen(js_name=InvalidDocumentRevisionError)] pub struct InvalidDocumentRevisionErrorWasm { document_id: Identifier, - current_revision: Revision, + current_revision: Option, code: u32, } @@ -17,7 +17,7 @@ impl InvalidDocumentRevisionErrorWasm { } #[wasm_bindgen(js_name=getCurrentRevision)] - pub fn current_revision(&self) -> Revision { + pub fn current_revision(&self) -> Option { self.current_revision } @@ -28,7 +28,7 @@ impl InvalidDocumentRevisionErrorWasm { } impl InvalidDocumentRevisionErrorWasm { - pub fn new(document_id: Identifier, current_revision: Revision, code: u32) -> Self { + pub fn new(document_id: Identifier, current_revision: Option, code: u32) -> Self { Self { document_id, current_revision, diff --git a/packages/wasm-dpp/src/errors/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus_error.rs index 0365ce06671..cfcd627807c 100644 --- a/packages/wasm-dpp/src/errors/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus_error.rs @@ -2,7 +2,7 @@ use crate::errors::consensus::basic::{ IncompatibleProtocolVersionErrorWasm, InvalidIdentifierErrorWasm, JsonSchemaErrorWasm, UnsupportedProtocolVersionErrorWasm, }; -use dpp::consensus::ConsensusError as DPPConsensusError; +use dpp::consensus::{ConsensusError as DPPConsensusError, ConsensusError}; use std::ops::Deref; use crate::errors::consensus::basic::identity::{ diff --git a/packages/wasm-dpp/src/identifier/mod.rs b/packages/wasm-dpp/src/identifier/mod.rs index 8b1c960f3c7..59410fd82e8 100644 --- a/packages/wasm-dpp/src/identifier/mod.rs +++ b/packages/wasm-dpp/src/identifier/mod.rs @@ -39,6 +39,14 @@ impl std::convert::From for IdentifierWrapper { } } +impl std::convert::From<[u8; 32]> for IdentifierWrapper { + fn from(s: [u8; 32]) -> Self { + IdentifierWrapper { + wrapped: Identifier::new(s), + } + } +} + impl std::convert::From for Identifier { fn from(s: IdentifierWrapper) -> Self { s.wrapped diff --git a/packages/wasm-dpp/src/utils.rs b/packages/wasm-dpp/src/utils.rs index 668cfd43a8a..3115e34b43f 100644 --- a/packages/wasm-dpp/src/utils.rs +++ b/packages/wasm-dpp/src/utils.rs @@ -3,16 +3,18 @@ use dpp::{ ProtocolError, }; +use dpp::platform_value::Value; use js_sys::Function; use serde::de::DeserializeOwned; -use serde_json::Value; +use serde_json::Value as JsonValue; use wasm_bindgen::convert::RefFromWasmAbi; use wasm_bindgen::prelude::*; use crate::errors::{from_dpp_err, RustConversionError}; pub trait ToSerdeJSONExt { - fn with_serde_to_json_value(&self) -> Result; + fn with_serde_to_json_value(&self) -> Result; + fn with_serde_to_platform_value(&self) -> Result; fn with_serde_into(&self) -> Result where D: for<'de> serde::de::Deserialize<'de> + 'static; @@ -21,10 +23,16 @@ pub trait ToSerdeJSONExt { impl ToSerdeJSONExt for JsValue { /// Converts the `JsValue` into `serde_json::Value`. It's an expensive conversion, /// as `JsValue` must be stringified first - fn with_serde_to_json_value(&self) -> Result { + fn with_serde_to_json_value(&self) -> Result { with_serde_to_json_value(self) } + /// Converts the `JsValue` into `platform::Value`. It's an expensive conversion, + /// as `JsValue` must be stringified first + fn with_serde_to_platform_value(&self) -> Result { + with_serde_to_platform_value(self) + } + /// converts the `JsValue` into any type that is supported by serde. It's an expensive conversion /// as the `jsValue` must be stringified first fn with_serde_into(&self) -> Result @@ -44,7 +52,7 @@ where pub fn to_vec_of_serde_values( values: impl IntoIterator>, -) -> Result, JsValue> { +) -> Result, JsValue> { values .into_iter() .map(|v| v.as_ref().with_serde_to_json_value()) @@ -60,14 +68,18 @@ where .collect() } -pub fn with_serde_to_json_value(data: &JsValue) -> Result { +pub fn with_serde_to_json_value(data: &JsValue) -> Result { let data = stringify(data)?; - let value: Value = serde_json::from_str(&data) + let value: JsonValue = serde_json::from_str(&data) .with_context(|| format!("cant convert {data:#?} to serde json value")) .map_err(|e| format!("{e:#}"))?; Ok(value) } +pub fn with_serde_to_platform_value(data: &JsValue) -> Result { + Ok(with_serde_to_json_value(data)?.into()) +} + pub fn with_serde_into(data: &JsValue) -> Result where D: for<'de> serde::de::Deserialize<'de> + 'static, From 358eeb213975242927669caf70379423ddecfe0b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 25 Feb 2023 22:41:01 +0700 Subject: [PATCH 007/228] many more fixes --- .../src/data_trigger/dpns_triggers/mod.rs | 8 +- .../reward_share_data_triggers/mod.rs | 39 ++-- packages/rs-dpp/src/document/document.rs | 26 +++ .../rs-dpp/src/document/document_factory.rs | 7 +- .../rs-dpp/src/document/document_validator.rs | 5 +- ...pply_documents_batch_transition_factory.rs | 7 +- .../documents_batch_transition/mod.rs | 5 +- ...alidate_documents_uniqueness_by_indices.rs | 6 +- ...ty_credit_withdrawal_transition_factory.rs | 35 +++- ...e_documents_batch_transition_state_spec.rs | 79 ++++---- ...te_documents_uniqueness_by_indices_spec.rs | 171 +++++++++++------- .../validate_partial_compound_indices_spec.rs | 5 +- .../get_document_transitions_fixture.rs | 5 +- .../tests/fixtures/get_documents_fixture.rs | 15 +- ...edit_withdrawal_transition_factory_spec.rs | 6 +- 15 files changed, 263 insertions(+), 156 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 87da0c8061a..bc39c82caf2 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -2,7 +2,7 @@ use anyhow::Context; use anyhow::{anyhow, bail}; use serde_json::{json, Value as JsonValue}; -use crate::document::DocumentInStateTransition; +use crate::document::{Document, DocumentInStateTransition}; use crate::util::hash::hash; use crate::util::string_encoding::Encoding; use crate::{ @@ -191,7 +191,7 @@ where let salted_domain_hash = hash(salted_domain_buffer); - let preorder_documents: Vec = context + let preorder_documents: Vec = context .state_repository .fetch_documents( &context.data_contract.id, @@ -222,7 +222,7 @@ where #[cfg(test)] mod test { - use crate::document::DocumentInStateTransition; + use crate::document::{Document, DocumentInStateTransition}; use crate::{ data_trigger::DataTriggerExecutionContext, document::document_transition::Action, @@ -253,7 +253,7 @@ mod test { let first_transition = transitions.get(0).expect("transition should be present"); state_repository - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(|_, _, _, _| Ok(vec![])); transition_execution_context.enable_dry_run(); diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index a0f5be76731..e783e9155bb 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -1,7 +1,8 @@ use anyhow::{anyhow, bail}; +use platform_value::btreemap_extensions::BTreeValueMapHelper; use serde_json::json; -use crate::document::DocumentInStateTransition; +use crate::document::{Document, DocumentInStateTransition}; use crate::{ data_trigger::create_error, document::document_transition::DocumentTransition, @@ -88,7 +89,7 @@ where result.add_error(err.into()) } - let documents: Vec = context + let documents: Vec = context .state_repository .fetch_documents( &context.data_contract.id, @@ -119,7 +120,7 @@ where let mut total_percent: u64 = percentage; for d in documents.iter() { - total_percent += d.data.get_u64(PROPERTY_PERCENTAGE)?; + total_percent += d.properties.get_integer::(PROPERTY_PERCENTAGE)?; } if total_percent > MAX_PERCENTAGE { @@ -139,8 +140,9 @@ mod test { use super::*; use itertools::Itertools; use serde_json::json; + use std::convert::TryInto; - use crate::document::DocumentInStateTransition; + use crate::document::{Document, DocumentInStateTransition}; use crate::identity::Identity; use crate::{ data_contract::DataContract, @@ -156,14 +158,14 @@ mod test { }, utils::generate_random_identifier_struct, }, - DataTriggerError, StateError, + DataTriggerError, ProtocolError, StateError, }; struct TestData { top_level_identifier: Identifier, data_contract: DataContract, sml_store: SMLStore, - documents: Vec, + documents_in_state_transitions: Vec, document_transition: DocumentTransition, identity: Identity, } @@ -207,7 +209,7 @@ mod test { get_document_transitions_fixture([(Action::Create, vec![documents[0].clone()])]); TestData { - documents, + documents_in_state_transitions: documents, data_contract, top_level_identifier, sml_store, @@ -237,13 +239,20 @@ mod test { async fn should_return_an_error_if_percentage_greater_than_1000() { let TestData { mut document_transition, - documents, + documents_in_state_transitions, sml_store, data_contract, top_level_identifier, .. } = setup_test(); + let documents = documents_in_state_transitions + .clone() + .into_iter() + .map(|dt| dt.try_into()) + .collect::, ProtocolError>>() + .expect("expected to convert to documents"); + let mut state_repository_mock = MockStateRepositoryLike::new(); state_repository_mock .expect_fetch_sml_store() @@ -295,7 +304,7 @@ mod test { .expect_fetch_identity() .returning(move |_, _| Ok(None)); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let execution_context = StateTransitionExecutionContext::default(); @@ -343,7 +352,7 @@ mod test { .expect_fetch_identity() .returning(move |_, _| Ok(None)); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let execution_context = StateTransitionExecutionContext::default(); @@ -383,7 +392,7 @@ mod test { .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let execution_context = StateTransitionExecutionContext::default(); @@ -418,11 +427,9 @@ mod test { state_repository_mock .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); - let documents_to_return: Vec = (0..16) - .map(|_| DocumentInStateTransition::default()) - .collect(); + let documents_to_return: Vec = (0..16).map(|_| Document::default()).collect(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .return_once(move |_, _, _, _| Ok(documents_to_return)); let execution_context = StateTransitionExecutionContext::default(); @@ -458,7 +465,7 @@ mod test { .expect_fetch_identity() .returning(move |_, _| Ok(None)); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let execution_context = StateTransitionExecutionContext::default(); diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 6479ddd509c..bc2ba6e1d0f 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -55,6 +55,7 @@ use crate::data_contract::extra::common::{ reduced_value_string_representation, }; use crate::document::errors::DocumentError; +use crate::document::DocumentInStateTransition; use crate::identifier::Identifier; use crate::identity::TimestampMillis; use crate::prelude::Revision; @@ -359,6 +360,31 @@ impl fmt::Display for Document { } } +impl TryFrom for Document { + type Error = ProtocolError; + + fn try_from(value: DocumentInStateTransition) -> Result { + let DocumentInStateTransition { + id, + revision, + owner_id, + created_at, + updated_at, + data, + .. + } = value; + let value: Value = data.into(); + Ok(Document { + id: id.buffer, + owner_id: owner_id.buffer, + properties: value.into_btree_map()?, + revision: Some(revision), + created_at, + updated_at, + }) + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 8c0ead2ae64..861ad3d9168 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -395,6 +395,7 @@ where mod test { use std::sync::Arc; + use crate::tests::fixtures::get_documents_in_state_transitions_fixture; use crate::{ assert_error_contains, state_repository::MockStateRepositoryLike, @@ -470,7 +471,7 @@ mod test { #[test] fn create_transition_mismatch_user_id() { let data_contract = get_data_contract_fixture(None); - let mut documents = get_documents_fixture(data_contract).unwrap(); + let mut documents = get_documents_in_state_transitions_fixture(data_contract).unwrap(); let factory = DocumentFactory::new( 1, @@ -487,7 +488,7 @@ mod test { #[test] fn create_transition_invalid_initial_revision() { let data_contract = get_data_contract_fixture(None); - let mut documents = get_documents_fixture(data_contract).unwrap(); + let mut documents = get_documents_in_state_transitions_fixture(data_contract).unwrap(); documents[0].revision = 3; let factory = DocumentFactory::new( @@ -503,7 +504,7 @@ mod test { #[test] fn create_transitions_with_passed_documents() { let data_contract = get_data_contract_fixture(None); - let documents = get_documents_fixture(data_contract).unwrap(); + let documents = get_documents_in_state_transitions_fixture(data_contract).unwrap(); let factory = DocumentFactory::new( 1, get_document_validator_fixture(), diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 236f378b242..685463a1c1c 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -106,6 +106,7 @@ mod test { use serde_json::Value as JsonValue; use test_case::test_case; + use crate::tests::fixtures::get_documents_in_state_transitions_fixture; use crate::{ codes::ErrorWithCode, consensus::{basic::JsonSchemaError, ConsensusError}, @@ -126,7 +127,7 @@ mod test { fn get_test_data() -> TestData { let data_contract = get_data_contract_fixture(None); - let documents = get_documents_fixture(data_contract.clone()).unwrap(); + let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); let raw_document = documents .iter() .map(|d| d.to_object()) @@ -472,7 +473,7 @@ mod test { .. } = get_test_data(); - let documents = get_documents_fixture(data_contract.clone()).unwrap(); + let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); let document = documents.get(8).unwrap(); let data = [0u8; 32]; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index c22940d3266..b7c2119966a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -147,7 +147,8 @@ mod test { use dashcore::consensus; use serde_json::{json, Value}; - use crate::document::DocumentInStateTransition; + use crate::document::{Document, DocumentInStateTransition}; + use crate::tests::fixtures::get_documents_in_state_transitions_fixture; use crate::tests::utils::new_block_header; use crate::{ document::{ @@ -172,7 +173,7 @@ mod test { let owner_id = generate_random_identifier_struct(); let data_contract = get_data_contract_fixture(None); - let documents = get_documents_fixture(data_contract.clone()).unwrap(); + let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); let documents_transitions = get_document_transitions_fixture([ (Action::Replace, documents), (Action::Create, vec![]), @@ -193,7 +194,7 @@ mod test { state_transition.get_execution_context().enable_dry_run(); state_repository - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(|_, _, _, _| Ok(vec![])); state_repository .expect_update_document() diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 4a58943bc46..b447a8a80ae 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -416,6 +416,7 @@ mod test { use serde_json::json; + use crate::tests::fixtures::get_documents_in_state_transitions_fixture; use crate::{ document::{ document_factory::DocumentFactory, @@ -455,7 +456,7 @@ mod test { // 0 is niceDocument, // 1 and 2 are pretty documents, // 3 and 4 are indexed documents that do not have security level specified - let documents = get_documents_fixture(data_contract).unwrap(); + let documents = get_documents_in_state_transitions_fixture(data_contract).unwrap(); let medium_security_document = documents.get(0).unwrap(); let master_security_document = documents.get(1).unwrap(); let no_security_level_document = documents.get(3).unwrap(); @@ -526,7 +527,7 @@ mod test { let mut data_contract = get_data_contract_fixture(Some(owner_id)); data_contract.id = data_contract_id; - let documents = get_documents_fixture(data_contract.clone()).unwrap(); + let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); let mut document = documents.first().unwrap().to_owned(); document.entropy = entropy_bytes; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs index 797b25bff7b..6fc73fda225 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs @@ -2,7 +2,7 @@ use futures::future::join_all; use itertools::Itertools; use serde_json::{json, Value as JsonValue}; -use crate::document::DocumentInStateTransition; +use crate::document::{Document, DocumentInStateTransition}; use crate::{ document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, prelude::{DataContract, Identifier}, @@ -52,7 +52,7 @@ where .filter(|query| !query.where_query.is_empty()) .map(|query| { ( - state_repository.fetch_documents::( + state_repository.fetch_documents::( &data_contract.id, query.document_type, json!( { "where": query.where_query}), @@ -138,7 +138,7 @@ fn build_query_for_index_definition( fn validate_uniqueness<'a>( futures_meta: Vec<(&'a Index, &'a DocumentTransition)>, - results: Vec, anyhow::Error>>, + results: Vec, anyhow::Error>>, ) -> Result, ProtocolError> { let mut validation_result = ValidationResult::default(); for (i, result) in results.into_iter().enumerate() { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs index 35f1d0abe75..da65795953a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs @@ -1,10 +1,13 @@ use anyhow::{anyhow, Result}; use dashcore::{consensus, BlockHeader}; use lazy_static::__Deref; +use std::collections::BTreeMap; use std::convert::TryInto; +use platform_value::Value; use serde_json::json; +use crate::contracts::withdrawals_contract::property_names; use crate::{ contracts::withdrawals_contract, data_contract::DataContract, document::generate_document_id, document::Document, identity::state_transition::identity_credit_withdrawal_transition::Pooling, @@ -60,13 +63,28 @@ where let document_type = String::from(withdrawals_contract::document_types::WITHDRAWAL); let document_created_at_millis: u64 = latest_platform_block_header.time as u64 * 1000u64; - let document_data = json!({ - withdrawals_contract::property_names::AMOUNT: state_transition.amount, - withdrawals_contract::property_names::CORE_FEE_PER_BYTE: state_transition.core_fee_per_byte, - withdrawals_contract::property_names::POOLING: Pooling::Never, - withdrawals_contract::property_names::OUTPUT_SCRIPT: state_transition.output_script.as_bytes(), - withdrawals_contract::property_names::STATUS: withdrawals_contract::WithdrawalStatus::QUEUED, - }); + let document_properties = BTreeMap::from([ + ( + property_names::AMOUNT.to_string(), + Value::U64(state_transition.amount), + ), + ( + property_names::CORE_FEE_PER_BYTE.to_string(), + Value::U32(state_transition.core_fee_per_byte), + ), + ( + property_names::POOLING.to_string(), + Value::U8(Pooling::Never as u8), + ), + ( + property_names::OUTPUT_SCRIPT.to_string(), + Value::Bytes(state_transition.output_script.as_bytes().to_vec()), + ), + ( + property_names::STATUS.to_string(), + Value::U8(withdrawals_contract::WithdrawalStatus::QUEUED as u8), + ), + ]); let mut document_id; @@ -99,14 +117,13 @@ where } } - // TODO: use DocumentFactory once it is complete let withdrawal_document = Document { id: document_id.buffer, revision: None, owner_id: state_transition.identity_id.buffer, created_at: Some(document_created_at_millis), updated_at: Some(document_created_at_millis), - properties: Default::default(), + properties: document_properties, }; self.state_repository diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index d27ab584e6d..7592ae271c4 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -1,3 +1,4 @@ +use std::convert::TryInto; use std::time::Duration; use chrono::Utc; @@ -24,13 +25,14 @@ use crate::{ utils::{generate_random_identifier_struct, new_block_header}, }, validation::ValidationResult, }; -use crate::document::DocumentInStateTransition; +use crate::document::{Document, DocumentInStateTransition}; use crate::identity::TimestampMillis; +use crate::tests::fixtures::get_documents_in_state_transitions_fixture; struct TestData { owner_id: Identifier, data_contract: DataContract, - documents: Vec, + documents_in_state_transitions: Vec, document_transitions: Vec, state_transition: DocumentsBatchTransition, state_repository_mock: MockStateRepositoryLike, @@ -46,7 +48,7 @@ fn setup_test() -> TestData { init(); let owner_id = generate_random_identifier_struct(); let data_contract = get_data_contract_fixture(Some(owner_id)); - let documents = get_documents_fixture(data_contract.clone()).unwrap(); + let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); let document_transitions = get_document_transitions_fixture([(Action::Create, documents.clone())]); @@ -82,7 +84,7 @@ fn setup_test() -> TestData { owner_id, data_contract, document_transitions, - documents, + documents_in_state_transitions: documents, state_transition, state_repository_mock, } @@ -152,7 +154,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_delete_ let TestData { data_contract, owner_id, - documents, + documents_in_state_transitions: documents, mut state_repository_mock, .. } = setup_test(); @@ -177,7 +179,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_delete_ .expect("documents batch state transition should be created"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -199,12 +201,20 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let TestData { data_contract, owner_id, - mut documents, + mut documents_in_state_transitions, mut state_repository_mock, .. } = setup_test(); + + let mut documents = documents_in_state_transitions + .clone() + .into_iter() + .map(|dt| dt.try_into()) + .collect::, ProtocolError>>() + .expect("expected to convert to documents"); + let mut replace_document = DocumentInStateTransition::from_raw_document( - documents[0].to_object().unwrap(), + documents_in_state_transitions[0].to_object().unwrap(), data_contract.clone(), ) .expect("document should be created"); @@ -258,7 +268,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let TestData { data_contract, owner_id, - documents, + documents_in_state_transitions: documents, mut state_repository_mock, .. } = setup_test(); @@ -269,13 +279,10 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace .expect("document should be created"); replace_document.revision = 1; - let mut fetched_document = DocumentInStateTransition::from_raw_document( - documents[0].to_object().unwrap(), - data_contract.clone(), - ) - .expect("document should be created"); + let mut fetched_document = Document::from_raw_json_document(documents[0].to_object().unwrap()) + .expect("document should be created"); let another_owner_id = generate_random_identifier_struct(); - fetched_document.owner_id = another_owner_id; + fetched_document.owner_id = another_owner_id.buffer; let document_transitions = get_document_transitions_fixture([ (Action::Create, vec![]), @@ -336,7 +343,7 @@ async fn should_return_invalid_result_if_timestamps_mismatch() { let TestData { data_contract, owner_id, - documents, + documents_in_state_transitions: documents, mut state_repository_mock, .. } = setup_test(); @@ -364,7 +371,7 @@ async fn should_return_invalid_result_if_timestamps_mismatch() { .for_each(|t| set_updated_at(t, Some(now_ts))); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -387,7 +394,7 @@ async fn should_return_invalid_result_if_crated_at_has_violated_time_window() { let TestData { data_contract, owner_id, - documents, + documents_in_state_transitions: documents, mut state_repository_mock, .. } = setup_test(); @@ -416,7 +423,7 @@ async fn should_return_invalid_result_if_crated_at_has_violated_time_window() { .for_each(|t| set_created_at(t, Some(now_ts_minus_6_mins))); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -440,7 +447,7 @@ async fn should_not_validate_time_in_block_window_on_dry_run() { let TestData { data_contract, owner_id, - documents, + documents_in_state_transitions: documents, mut state_repository_mock, .. } = setup_test(); @@ -469,7 +476,7 @@ async fn should_not_validate_time_in_block_window_on_dry_run() { .for_each(|t| set_created_at(t, Some(now_ts_minus_6_mins))); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let result = @@ -485,7 +492,7 @@ async fn should_return_invalid_result_if_updated_at_has_violated_time_window() { let TestData { data_contract, owner_id, - documents, + documents_in_state_transitions: documents, mut state_repository_mock, .. } = setup_test(); @@ -514,7 +521,7 @@ async fn should_return_invalid_result_if_updated_at_has_violated_time_window() { }); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -538,27 +545,21 @@ async fn should_return_valid_result_if_document_transitions_are_valid() { let TestData { data_contract, owner_id, - documents, + documents_in_state_transitions: documents, mut state_repository_mock, .. } = setup_test(); - let mut fetched_document_1 = DocumentInStateTransition::from_raw_document( - documents[1].to_object().unwrap(), - data_contract.clone(), - ) - .unwrap(); - let mut fetched_document_2 = DocumentInStateTransition::from_raw_document( - documents[2].to_object().unwrap(), - data_contract.clone(), - ) - .unwrap(); - fetched_document_1.revision = 1; - fetched_document_2.revision = 1; - fetched_document_1.owner_id = owner_id; - fetched_document_2.owner_id = owner_id; + let mut fetched_document_1 = + Document::from_raw_json_document(documents[1].to_object().unwrap()).unwrap(); + let mut fetched_document_2 = + Document::from_raw_json_document(documents[2].to_object().unwrap()).unwrap(); + fetched_document_1.revision = Some(1); + fetched_document_2.revision = Some(1); + fetched_document_1.owner_id = owner_id.to_buffer(); + fetched_document_2.owner_id = owner_id.to_buffer(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(move |_, _, _, _| { Ok(vec![fetched_document_1.clone(), fetched_document_2.clone()]) }); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 883e58d469b..6a14e27d9e7 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -1,38 +1,32 @@ +use futures::StreamExt; use mockall::predicate; use serde_json::json; - -use crate::{ - consensus::ConsensusError, - data_contract::DataContract, - document::{ - document_transition::{Action, DocumentTransition}, - state_transition::documents_batch_transition::validation::state::validate_documents_uniqueness_by_indices::*, - }, - prelude::Identifier, - state_repository::MockStateRepositoryLike, - state_transition::state_transition_execution_context::StateTransitionExecutionContext, - StateError, - tests::{ - fixtures::{ - get_data_contract_fixture, get_document_transitions_fixture, get_documents_fixture, - }, - utils::generate_random_identifier_struct, +use std::convert::TryInto; + +use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ + document_transition::{Action, DocumentTransition}, + state_transition::documents_batch_transition::validation::state::validate_documents_uniqueness_by_indices::*, +}, prelude::Identifier, ProtocolError, state_repository::MockStateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, StateError, tests::{ + fixtures::{ + get_data_contract_fixture, get_document_transitions_fixture, get_documents_fixture, }, - util::string_encoding::Encoding, validation::ValidationResult, -}; -use crate::document::DocumentInStateTransition; + utils::generate_random_identifier_struct, +}, util::string_encoding::Encoding, validation::ValidationResult}; +use crate::document::{Document, DocumentInStateTransition}; +use crate::tests::fixtures::get_documents_in_state_transitions_fixture; struct TestData { owner_id: Identifier, data_contract: DataContract, - documents: Vec, + documents: Vec, + documents_in_state_transitions: Vec, document_transitions: Vec, } fn setup_test() -> TestData { let owner_id = generate_random_identifier_struct(); let data_contract = get_data_contract_fixture(Some(owner_id)); - let documents = get_documents_fixture(data_contract.clone()).unwrap(); + let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); TestData { owner_id, @@ -41,7 +35,13 @@ fn setup_test() -> TestData { Action::Create, documents.clone(), )]), - documents, + documents: documents + .clone() + .into_iter() + .map(|d| d.try_into()) + .collect::, ProtocolError>>() + .expect("expected to get documents"), + documents_in_state_transitions: documents, } } @@ -50,16 +50,18 @@ async fn should_return_valid_result_if_documents_have_no_unique_indices() { let TestData { owner_id, data_contract, - documents, + documents_in_state_transitions, .. } = setup_test(); let mut state_repository_mock = MockStateRepositoryLike::default(); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .returning(|_, _, _, _| Ok(vec![])); - let document_transitions = - get_document_transitions_fixture([(Action::Create, vec![documents[0].clone()])]); + let document_transitions = get_document_transitions_fixture([( + Action::Create, + vec![documents_in_state_transitions[0].clone()], + )]); let validation_result = validate_documents_uniqueness_by_indices( &state_repository_mock, &owner_id, @@ -77,18 +79,21 @@ async fn should_return_valid_result_if_document_has_unique_indices_and_there_are let TestData { owner_id, data_contract, - documents, + documents_in_state_transitions, .. } = setup_test(); - let william_doc = documents[3].clone(); + let william_doc = documents_in_state_transitions[3].clone(); let owner_id_base58 = owner_id.to_string(Encoding::Base58); let mut state_repository_mock = MockStateRepositoryLike::default(); let document_transitions = get_document_transitions_fixture([(Action::Create, vec![william_doc.clone()])]); - let expect_document = william_doc.to_owned(); + let expect_document: Document = william_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -102,9 +107,12 @@ async fn should_return_valid_result_if_document_has_unique_indices_and_there_are ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document = william_doc.to_owned(); + let expect_document: Document = william_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -135,11 +143,11 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a let TestData { owner_id, data_contract, - documents, + documents_in_state_transitions, .. } = setup_test(); - let william_doc = documents[3].clone(); - let leon_doc = documents[4].clone(); + let william_doc = documents_in_state_transitions[3].clone(); + let leon_doc = documents_in_state_transitions[4].clone(); let owner_id_base58 = owner_id.to_string(Encoding::Base58); let mut state_repository_mock = MockStateRepositoryLike::default(); let document_transitions = get_document_transitions_fixture([( @@ -147,9 +155,12 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a vec![william_doc.clone(), leon_doc.clone()], )]); - let expect_document = leon_doc.to_owned(); + let expect_document: Document = leon_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -163,9 +174,12 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document = leon_doc.to_owned(); + let expect_document: Document = leon_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -179,9 +193,12 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document = william_doc.to_owned(); + let expect_document: Document = william_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -195,9 +212,12 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document = william_doc.to_owned(); + let expect_document: Document = william_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -243,11 +263,11 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an let TestData { owner_id, data_contract, - documents, + documents_in_state_transitions, .. } = setup_test(); - let william_doc = documents[3].clone(); - let leon_doc = documents[4].clone(); + let william_doc = documents_in_state_transitions[3].clone(); + let leon_doc = documents_in_state_transitions[4].clone(); let owner_id_base58 = owner_id.to_string(Encoding::Base58); let mut state_repository_mock = MockStateRepositoryLike::default(); let document_transitions = get_document_transitions_fixture([( @@ -255,9 +275,12 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an vec![william_doc.clone(), leon_doc.clone()], )]); - let expect_document = leon_doc.to_owned(); + let expect_document: Document = leon_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -271,9 +294,12 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document = leon_doc.to_owned(); + let expect_document: Document = leon_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -287,9 +313,12 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document = william_doc.to_owned(); + let expect_document: Document = william_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -303,9 +332,12 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document = william_doc.to_owned(); + let expect_document: Document = william_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -339,18 +371,21 @@ async fn should_return_valid_result_if_document_has_undefined_field_from_index() let TestData { owner_id, data_contract, - documents, + documents_in_state_transitions, .. } = setup_test(); - let indexed_document = documents[7].clone(); + let indexed_document = documents_in_state_transitions[7].clone(); let document_transitions = get_document_transitions_fixture([(Action::Create, vec![indexed_document.clone()])]); let owner_id_base58 = owner_id.to_string(Encoding::Base58); let mut state_repository_mock = MockStateRepositoryLike::default(); - let expect_document = indexed_document.to_owned(); + let expect_document: Document = indexed_document + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -364,9 +399,12 @@ async fn should_return_valid_result_if_document_has_undefined_field_from_index() ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document = indexed_document.to_owned(); + let expect_document: Document = indexed_document + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("indexedDocument"), @@ -398,17 +436,20 @@ async fn should_return_valid_result_if_document_being_created_and_has_created_at let TestData { owner_id, data_contract, - documents, + documents_in_state_transitions, .. } = setup_test(); - let unique_dates_doc = documents[6].clone(); + let unique_dates_doc = documents_in_state_transitions[6].clone(); let document_transitions = get_document_transitions_fixture([(Action::Create, vec![unique_dates_doc.clone()])]); let mut state_repository_mock = MockStateRepositoryLike::default(); - let expect_document = unique_dates_doc.to_owned(); + let expect_document: Document = unique_dates_doc + .to_owned() + .try_into() + .expect("expected to convert to document"); state_repository_mock - .expect_fetch_documents::() + .expect_fetch_documents::() .with( predicate::eq(data_contract.id), predicate::eq("uniqueDates"), diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 6fd70879012..e2c3d3825a0 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -14,6 +14,7 @@ use crate::{ validation::ValidationResult, }; use crate::document::DocumentInStateTransition; +use crate::tests::fixtures::get_documents_in_state_transitions_fixture; struct TestData { data_contract: DataContract, @@ -22,8 +23,8 @@ struct TestData { fn setup_test() -> TestData { let data_contract = get_data_contract_fixture(None); - let documents = - get_documents_fixture(data_contract.clone()).expect("documents should be created"); + let documents = get_documents_in_state_transitions_fixture(data_contract.clone()) + .expect("documents should be created"); TestData { data_contract, diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index 2bd62412f97..95cf5fcdba0 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -8,6 +8,7 @@ use crate::document::{ document_transition::{Action, DocumentTransition}, }; use crate::state_repository::MockStateRepositoryLike; +use crate::tests::fixtures::get_documents_in_state_transitions_fixture; use crate::version::LATEST_VERSION; use super::{get_data_contract_fixture, get_document_validator_fixture, get_documents_fixture}; @@ -26,7 +27,9 @@ pub fn get_document_transitions_fixture( documents.into_iter().collect(); let create_documents = documents_collected .remove(&Action::Create) - .unwrap_or_else(|| get_documents_fixture(get_data_contract_fixture(None)).unwrap()); + .unwrap_or_else(|| { + get_documents_in_state_transitions_fixture(get_data_contract_fixture(None)).unwrap() + }); let replace_documents = documents_collected .remove(&Action::Replace) .unwrap_or_default(); diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 3693a40375b..7609230fcd7 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -36,10 +36,17 @@ pub fn get_documents_fixture_with_owner_id_from_contract( ); let owner_id = *data_contract.owner_id(); - get_documents(factory, data_contract, owner_id) + get_documents_in_state_transitions(factory, data_contract, owner_id) } -pub fn get_documents_fixture( +pub fn get_documents_fixture(data_contract: DataContract) -> Result, ProtocolError> { + get_documents_in_state_transitions_fixture(data_contract)? + .into_iter() + .map(|dt| dt.try_into()) + .collect() +} + +pub fn get_documents_in_state_transitions_fixture( data_contract: DataContract, ) -> Result, ProtocolError> { let data_contract_fetcher_and_validator = @@ -52,10 +59,10 @@ pub fn get_documents_fixture( ); let owner_id = gen_owner_id(); - get_documents(factory, data_contract, owner_id) + get_documents_in_state_transitions(factory, data_contract, owner_id) } -fn get_documents( +fn get_documents_in_state_transitions( factory: DocumentFactory, data_contract: DataContract, owner_id: Identifier, diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs index a693ba865c3..5243e513b7a 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs @@ -87,13 +87,13 @@ mod apply_identity_credit_withdrawal_transition_factory { state_repository .expect_create_document() .times(1) - .withf(move |doc, _| { + .withf(move |doc: &Document, _| { let created_at_match = doc.created_at == Some(block_time_seconds as u64 * 1000); - let updated_at_match = doc.created_at == Some(block_time_seconds as u64 * 1000); + let updated_at_match = doc.updated_at == Some(block_time_seconds as u64 * 1000); let document_expected_properties = BTreeMap::from([ (AMOUNT.to_string(), Value::U64(10)), - (CORE_FEE_PER_BYTE.to_string(), Value::U64(0)), + (CORE_FEE_PER_BYTE.to_string(), Value::U32(0)), (POOLING.to_string(), Value::U8(Pooling::Never as u8)), (OUTPUT_SCRIPT.to_string(), Value::Bytes(vec![])), ( From 871329b4276b4a7208aec31f859c41a3c61bcb02 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 25 Feb 2023 23:12:50 +0700 Subject: [PATCH 008/228] everything passing --- .../src/btreemap_extensions.rs | 56 ++++++++++++++++--- packages/rs-platform-value/src/display.rs | 2 +- packages/rs-platform-value/src/lib.rs | 19 +++++++ 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 07a6f1b4f20..b9582ebbdeb 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -177,7 +177,17 @@ where + TryFrom + TryFrom, { - self.get(key).map(|v| v.borrow().to_integer()).transpose() + self.get(key) + .map(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_integer()) + } + }) + .flatten() + .transpose() } fn get_integer(&self, key: &str) -> Result @@ -211,7 +221,15 @@ where + TryFrom, { self.remove(key) - .map(|v| v.borrow().to_integer()) + .map(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_integer()) + } + }) + .flatten() .transpose() } @@ -236,10 +254,14 @@ where fn get_optional_bool(&self, key: &str) -> Result, Error> { self.get(key) .map(|v| { - v.borrow() - .as_bool() - .ok_or_else(|| Error::StructureError(format!("{key} must be a bool"))) + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_bool()) + } }) + .flatten() .transpose() } @@ -451,7 +473,17 @@ where } fn remove_optional_float(&mut self, key: &str) -> Result, Error> { - self.remove(key).map(|v| v.borrow().to_float()).transpose() + self.remove(key) + .map(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_float()) + } + }) + .flatten() + .transpose() } fn remove_float(&mut self, key: &str) -> Result { @@ -460,7 +492,17 @@ where } fn get_optional_float(&self, key: &str) -> Result, Error> { - self.get(key).map(|v| v.borrow().to_float()).transpose() + self.get(key) + .map(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_float()) + } + }) + .flatten() + .transpose() } fn get_float(&self, key: &str) -> Result { diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index 57f925757c7..dd9c444bf8c 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -26,7 +26,7 @@ impl Value { Value::Bool(b) => { format!("{}", b) } - Value::Null => "None".to_string(), + Value::Null => "Null".to_string(), Value::Tag(_, _) => "Tag".to_string(), Value::Array(value) => { let inner_values = value diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 573c068fc47..437efa8167f 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -597,6 +597,25 @@ impl Value { } } + /// If the `Value` is a `Bool`, returns a the associated `bool` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Value}; + /// # + /// let value = Value::Bool(false); + /// assert_eq!(value.to_bool(), Ok(false)); + /// + /// let value = Value::Float(17.); + /// assert_eq!(value.to_bool(), Err(Error::StructureError("value is not a bool".to_string()))); + /// ``` + pub fn to_bool(&self) -> Result { + match self { + Value::Bool(b) => Ok(*b), + _other => Err(Error::StructureError("value is not a bool".to_string())), + } + } + /// Returns true if the `Value` is a `Null`. Returns false otherwise. /// /// ``` From 84ef98921a568fcdecdb7f4f7d517c3a6d518a06 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 25 Feb 2023 23:22:22 +0700 Subject: [PATCH 009/228] fix --- .../document_type/document_factory.rs | 2 +- .../document_type/random_document.rs | 2 +- .../src/data_trigger/dpns_triggers/mod.rs | 2 +- .../reward_share_data_triggers/mod.rs | 2 +- .../withdrawals_data_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/document.rs | 19 +++++------ .../rs-dpp/src/document/document_factory.rs | 14 ++++---- .../rs-dpp/src/document/document_validator.rs | 2 +- packages/rs-dpp/src/document/mod.rs | 32 +++++++++---------- packages/rs-dpp/src/document/serialize.rs | 12 +++---- ...pply_documents_batch_transition_factory.rs | 12 +++---- .../document_create_transition.rs | 6 ++-- .../document_in_state_transition.rs | 4 ++- .../documents_batch_transition/mod.rs | 2 +- .../validation/state/fetch_documents.rs | 2 +- ...lidate_documents_batch_transition_state.rs | 4 +-- ...alidate_documents_uniqueness_by_indices.rs | 2 +- ...ty_credit_withdrawal_transition_factory.rs | 2 +- ...e_documents_batch_transition_state_spec.rs | 4 +-- ...te_documents_uniqueness_by_indices_spec.rs | 2 +- .../validate_partial_compound_indices_spec.rs | 2 +- .../get_document_transitions_fixture.rs | 2 +- .../tests/fixtures/get_documents_fixture.rs | 1 - ...ternode_reward_shares_documents_fixture.rs | 2 +- ...edit_withdrawal_transition_factory_spec.rs | 2 +- 25 files changed, 68 insertions(+), 70 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs index 2f90d94f6cf..b46852af33b 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs @@ -7,7 +7,7 @@ use crate::prelude::TimestampMillis; use crate::ProtocolError; use chrono::Utc; use platform_value::Value; -use rand::rngs::StdRng; + use std::collections::BTreeMap; impl DocumentType { diff --git a/packages/rs-dpp/src/data_contract/document_type/random_document.rs b/packages/rs-dpp/src/data_contract/document_type/random_document.rs index 31522237f01..a42f79db18a 100644 --- a/packages/rs-dpp/src/data_contract/document_type/random_document.rs +++ b/packages/rs-dpp/src/data_contract/document_type/random_document.rs @@ -100,7 +100,7 @@ impl CreateRandomDocument for DocumentType { let owner_id = rng.gen::<[u8; 32]>(); let mut created_at = None; let mut updated_at = None; - let mut properties = self + let properties = self .properties .iter() .filter_map(|(key, document_field)| { diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index bc39c82caf2..c909cc37c76 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -222,7 +222,7 @@ where #[cfg(test)] mod test { - use crate::document::{Document, DocumentInStateTransition}; + use crate::document::{Document}; use crate::{ data_trigger::DataTriggerExecutionContext, document::document_transition::Action, diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index e783e9155bb..bfa4396c5d4 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use serde_json::json; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document}; use crate::{ data_trigger::create_error, document::document_transition::DocumentTransition, diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index 827ab9f89a9..230b1ef3a52 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, bail}; +use anyhow::{bail}; use serde_json::json; use crate::contracts::withdrawals_contract; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index bc2ba6e1d0f..4df668f32a5 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -36,11 +36,11 @@ use chrono::{DateTime, NaiveDateTime, Utc}; use std::collections::{BTreeMap, HashSet}; use std::convert::{TryFrom, TryInto}; use std::fmt; -use std::io::{BufReader, Read}; -use std::iter::FromIterator; -use ciborium::value::Value as CborValue; -use integer_encoding::VarIntWriter; + + + + use itertools::Itertools; use serde_json::Value as JsonValue; @@ -49,18 +49,15 @@ use platform_value::Value; use serde::{Deserialize, Serialize}; use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType}; -use crate::data_contract::errors::{DataContractError, StructureError}; -use crate::data_contract::extra::common::{ - bytes_for_system_value_from_tree_map, get_key_from_cbor_map, - reduced_value_string_representation, -}; +use crate::data_contract::errors::{DataContractError}; + use crate::document::errors::DocumentError; use crate::document::DocumentInStateTransition; use crate::identifier::Identifier; use crate::identity::TimestampMillis; use crate::prelude::Revision; -use crate::util::deserializer; -use crate::util::deserializer::SplitProtocolVersionOutcome; + + use crate::util::hash::hash; use crate::util::json_value::JsonValueExt; use crate::util::json_value::ReplaceWith; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 861ad3d9168..488885c4193 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -1,19 +1,19 @@ use anyhow::Context; use chrono::Utc; -use ciborium::cbor; + use itertools::Itertools; -use platform_value::Value; + use rand::rngs::StdRng; -use rand::{Rng, SeedableRng}; +use rand::{SeedableRng}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; -use std::collections::BTreeMap; -use crate::data_contract::document_type::DocumentType; + + use crate::document::document_transition::document_in_state_transition::{ property_names, DocumentInStateTransition, }; -use crate::document::Document; + use crate::{ data_contract::{errors::DataContractError, DataContract}, decode_protocol_entity_factory::DecodeProtocolEntity, @@ -401,7 +401,7 @@ mod test { state_repository::MockStateRepositoryLike, tests::{ fixtures::{ - get_data_contract_fixture, get_document_validator_fixture, get_documents_fixture, + get_data_contract_fixture, get_document_validator_fixture, }, utils::generate_random_identifier_struct, }, diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 685463a1c1c..7235084cecb 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -111,7 +111,7 @@ mod test { codes::ErrorWithCode, consensus::{basic::JsonSchemaError, ConsensusError}, data_contract::DataContract, - tests::fixtures::{get_data_contract_fixture, get_documents_fixture}, + tests::fixtures::{get_data_contract_fixture}, util::json_value::JsonValueExt, validation::ValidationResult, version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}, diff --git a/packages/rs-dpp/src/document/mod.rs b/packages/rs-dpp/src/document/mod.rs index da835cb436b..97c2fb43069 100644 --- a/packages/rs-dpp/src/document/mod.rs +++ b/packages/rs-dpp/src/document/mod.rs @@ -1,25 +1,25 @@ -use std::convert::TryInto; -use ciborium::value::Value as CborValue; -use integer_encoding::VarInt; -use itertools::Itertools; -use serde::{Deserialize, Serialize}; -use serde_json::Value as JsonValue; + + + + + + pub use state_transition::documents_batch_transition::document_transition; pub use state_transition::documents_batch_transition::validation; pub use state_transition::documents_batch_transition::DocumentsBatchTransition; -use crate::data_contract::DataContract; -use crate::errors::ProtocolError; -use crate::identifier::Identifier; -use crate::metadata::Metadata; -use crate::util::cbor_value::CborCanonicalMap; -use crate::util::cbor_value::FieldType; -use crate::util::deserializer::SplitProtocolVersionOutcome; -use crate::util::hash::hash; -use crate::util::json_value::{JsonValueExt, ReplaceWith}; -use crate::util::{cbor_value, deserializer}; + + + + + + + + + + mod document; pub mod document_factory; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index dcfda2cdb46..3bc3e321396 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -1,19 +1,19 @@ use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::data_contract::errors::{DataContractError, StructureError}; -use crate::data_contract::extra::common::bytes_for_system_value_from_tree_map; + use crate::document::document::property_names; use crate::document::document::property_names::{CREATED_AT, UPDATED_AT}; -use crate::document::document_transition::INITIAL_REVISION; + use crate::document::Document; -use crate::document::DocumentInStateTransition; + use crate::identity::TimestampMillis; use crate::prelude::Revision; use crate::util::cbor_value::CborBTreeMapHelper; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::ProtocolError; -use bincode::Options; + use byteorder::{BigEndian, ReadBytesExt}; use ciborium::Value as CborValue; use integer_encoding::VarIntWriter; @@ -21,7 +21,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; -use std::convert::{TryFrom, TryInto}; +use std::convert::{TryFrom}; use std::io::{BufReader, Read}; //todo: delete in later PR @@ -245,7 +245,7 @@ impl Document { }; let mut created_at = None; let mut updated_at = None; - let mut properties = document_type + let properties = document_type .properties .iter() .filter_map(|(key, field)| { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index b7c2119966a..ba14cee33d7 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; -use std::convert::TryInto; -use dashcore::{consensus, BlockHeader}; -use serde_json::Value; + + + use crate::document::{Document, DocumentInStateTransition}; use crate::prelude::TimestampMillis; @@ -13,7 +13,7 @@ use crate::{ use super::{ document_transition::{ - Action, DocumentCreateTransition, DocumentReplaceTransition, DocumentTransition, + Action, DocumentReplaceTransition, DocumentTransition, }, validation::state::fetch_documents::fetch_documents, DocumentsBatchTransition, @@ -147,7 +147,7 @@ mod test { use dashcore::consensus; use serde_json::{json, Value}; - use crate::document::{Document, DocumentInStateTransition}; + use crate::document::{Document}; use crate::tests::fixtures::get_documents_in_state_transitions_fixture; use crate::tests::utils::new_block_header; use crate::{ @@ -159,7 +159,7 @@ mod test { state_transition::StateTransitionLike, tests::{ fixtures::{ - get_data_contract_fixture, get_document_transitions_fixture, get_documents_fixture, + get_data_contract_fixture, get_document_transitions_fixture, }, utils::generate_random_identifier_struct, }, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 0a14ef8bd73..f304d675117 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -2,12 +2,12 @@ use itertools::Itertools; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use std::convert::TryInto; -use crate::document::{Document, DocumentsBatchTransition}; + +use crate::document::{Document}; use crate::identity::TimestampMillis; use crate::prelude::Revision; -use crate::util::serializer::value_to_cbor; + use crate::{ data_contract::DataContract, document::document_transition::Action, errors::ProtocolError, util::json_value::JsonValueExt, util::json_value::ReplaceWith, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs index 902dbf4ea29..62d67ebbf02 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs @@ -11,7 +11,7 @@ use crate::util::{cbor_value, deserializer}; use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; -use itertools::Itertools; + use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::HashSet; @@ -275,6 +275,8 @@ mod test { use crate::tests::utils::*; use crate::util::string_encoding::Encoding; use pretty_assertions::assert_eq; + use crate::data_contract::DataContract; + use crate::identifier::Identifier; fn init() { let _ = env_logger::builder() diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index b447a8a80ae..d7d6db418d2 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -425,7 +425,7 @@ mod test { state_repository::MockStateRepositoryLike, tests::fixtures::{ get_data_contract_fixture, get_document_transitions_fixture, - get_document_validator_fixture, get_documents_fixture, + get_document_validator_fixture, }, }; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs index c25cb7c61b1..6b18bcdcfef 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs @@ -3,7 +3,7 @@ use std::collections::hash_map::{Entry, HashMap}; use futures::future::join_all; use serde_json::json; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document}; use crate::{ document::document_transition::DocumentTransition, get_from_transition, state_repository::StateRepositoryLike, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index bc11ad301a0..f1b8c9b9155 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -5,7 +5,7 @@ use futures::future::join_all; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document}; use crate::{ block_time_window::validate_time_in_block_time_window::validate_time_in_block_time_window, consensus::ConsensusError, @@ -14,7 +14,7 @@ use crate::{ document_transition::{Action, DocumentTransition, DocumentTransitionExt}, DocumentsBatchTransition, }, - prelude::{Identifier, Revision, TimestampMillis}, + prelude::{Identifier, TimestampMillis}, state_repository::StateRepositoryLike, state_transition::{ state_transition_execution_context::StateTransitionExecutionContext, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs index 6fc73fda225..46801b47606 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs @@ -2,7 +2,7 @@ use futures::future::join_all; use itertools::Itertools; use serde_json::{json, Value as JsonValue}; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document}; use crate::{ document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, prelude::{DataContract, Identifier}, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs index da65795953a..5b5ea0e8ad0 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs @@ -49,7 +49,7 @@ where .transpose() .map_err(Into::into)?; - let withdrawals_data_contract = maybe_withdrawals_data_contract + let _withdrawals_data_contract = maybe_withdrawals_data_contract .ok_or_else(|| anyhow!("Withdrawals data contract not found"))?; let latest_platform_block_header_bytes: Vec = self diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 7592ae271c4..57147115102 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -20,7 +20,7 @@ use crate::{ StateError, tests::{ fixtures::{ - get_data_contract_fixture, get_document_transitions_fixture, get_documents_fixture, + get_data_contract_fixture, get_document_transitions_fixture, }, utils::{generate_random_identifier_struct, new_block_header}, }, validation::ValidationResult, @@ -201,7 +201,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let TestData { data_contract, owner_id, - mut documents_in_state_transitions, + documents_in_state_transitions, mut state_repository_mock, .. } = setup_test(); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 6a14e27d9e7..a8a9f05849d 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -8,7 +8,7 @@ use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ state_transition::documents_batch_transition::validation::state::validate_documents_uniqueness_by_indices::*, }, prelude::Identifier, ProtocolError, state_repository::MockStateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, StateError, tests::{ fixtures::{ - get_data_contract_fixture, get_document_transitions_fixture, get_documents_fixture, + get_data_contract_fixture, get_document_transitions_fixture, }, utils::generate_random_identifier_struct, }, util::string_encoding::Encoding, validation::ValidationResult}; diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index e2c3d3825a0..6262e72cec8 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -8,7 +8,7 @@ use crate::{ state_transition::documents_batch_transition::validation::basic::validate_partial_compound_indices::*, }, tests::fixtures::{ - get_data_contract_fixture, get_document_transitions_fixture, get_documents_fixture, + get_data_contract_fixture, get_document_transitions_fixture, }, util::json_value::JsonValueExt, validation::ValidationResult, diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index 95cf5fcdba0..00fc36932e5 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -11,7 +11,7 @@ use crate::state_repository::MockStateRepositoryLike; use crate::tests::fixtures::get_documents_in_state_transitions_fixture; use crate::version::LATEST_VERSION; -use super::{get_data_contract_fixture, get_document_validator_fixture, get_documents_fixture}; +use super::{get_data_contract_fixture, get_document_validator_fixture}; pub fn get_document_transitions_fixture( documents: impl IntoIterator)>, diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 7609230fcd7..34f3f2d85b0 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -10,7 +10,6 @@ use crate::contracts::withdrawals_contract::document_types; use crate::data_contract::DriveContractExt; use crate::document::Document; use crate::{ - contracts::withdrawals_contract, document::{ document_factory::DocumentFactory, fetch_and_validate_data_contract::DataContractFetcherAndValidator, diff --git a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs index f9234bdd0f4..30ce04f4f0e 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use data_contracts::SystemDataContract; use serde_json::json; -use crate::document::Document; + use crate::document::DocumentInStateTransition; use crate::system_data_contracts::load_system_data_contract; use crate::{ diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs index 5243e513b7a..fdac95d4f51 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod apply_identity_credit_withdrawal_transition_factory { use dashcore::{consensus, BlockHeader}; - use serde_json::json; + use std::collections::BTreeMap; use crate::contracts::withdrawals_contract::property_names::{ From dffbfd4c81abc8aabb3900322d7c7303be94b53b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 25 Feb 2023 23:59:36 +0700 Subject: [PATCH 010/228] fixes --- packages/rs-dpp/src/document/document.rs | 2 +- .../apply_documents_batch_transition_factory.rs | 4 ++-- .../document_create_transition.rs | 4 ++-- .../document_in_state_transition.rs | 2 +- ...validate_documents_batch_transition_state.rs | 4 ++-- packages/rs-dpp/src/identity/identity.rs | 4 +--- .../rs-drive-abci/src/test/helpers/fee_pools.rs | 2 +- packages/rs-drive/src/tests/helpers/setup.rs | 2 +- .../src/btreemap_extensions.rs | 15 +++++---------- packages/wasm-dpp/src/document/factory.rs | 1 - packages/wasm-dpp/src/document/mod.rs | 17 +++++++++-------- packages/wasm-dpp/src/errors/consensus_error.rs | 2 +- packages/wasm-dpp/src/state_repository.rs | 2 +- 13 files changed, 27 insertions(+), 34 deletions(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 4df668f32a5..2596391ebd9 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -350,7 +350,7 @@ impl fmt::Display for Document { write!(f, "no properties")?; } else { for (key, value) in self.properties.iter() { - write!(f, "{}:{} ", key, value.to_string())? + write!(f, "{}:{} ", key, value)? } } Ok(()) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index ba14cee33d7..7dbd9d9a389 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -85,13 +85,13 @@ pub async fn apply_documents_batch_transition( .update_document(&document, state_transition.get_execution_context()) .await?; } else { - let mut document = fetched_documents_by_id + let document = fetched_documents_by_id .get_mut(&document_replace_transition.base.id) .ok_or(DocumentError::DocumentNotProvidedError { document_transition: document_transition.clone(), })?; - document_replace_transition.replace_document(&mut document); + document_replace_transition.replace_document(document); state_repository .update_document(document, state_transition.get_execution_context()) .await?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index f304d675117..d7c6a26954d 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -71,8 +71,8 @@ impl DocumentCreateTransition { id: self.base.id.to_buffer(), owner_id, properties, - created_at: self.created_at.clone(), - updated_at: self.updated_at.clone(), + created_at: self.created_at, + updated_at: self.updated_at, revision: self.get_revision(), }) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs index 62d67ebbf02..c326a662045 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs @@ -271,7 +271,7 @@ mod test { use crate::document::document_transition::document_in_state_transition::{ DocumentInStateTransition, IDENTIFIER_FIELDS, }; - use crate::document::*; + use crate::tests::utils::*; use crate::util::string_encoding::Encoding; use pretty_assertions::assert_eq; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index f1b8c9b9155..cd9982ac95b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -337,7 +337,7 @@ fn check_created_inside_time_window( let created_at = match document_transition.get_created_at() { Some(t) => t, None => return result, - } as u64; + }; let window_validation = validate_time_in_block_time_window(last_block_ts_millis, created_at); if !window_validation.is_valid() { @@ -362,7 +362,7 @@ fn check_updated_inside_time_window( let updated_at = match document_transition.get_updated_at() { Some(t) => t, None => return result, - } as u64; + }; let window_validation = validate_time_in_block_time_window(last_block_ts_millis, updated_at); if !window_validation.is_valid() { diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 8bc3c0b9c87..aba0cb8a27c 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -234,9 +234,7 @@ impl Identity { identity_json.replace_identifier_paths(IDENTIFIER_FIELDS_RAW_OBJECT, ReplaceWith::Bytes)?; let pk_values = self - .public_keys - .iter() - .map(|(_, pk)| pk.to_raw_json_object()) + .public_keys.values().map(|pk| pk.to_raw_json_object()) .collect::, SerdeParsingError>>()?; identity_json.insert( diff --git a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs index 67d9c210754..cad89c426cf 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -77,7 +77,7 @@ fn create_test_mn_share_document( id, properties, owner_id: identity_id, - revision: Some(INITIAL_REVISION as u64), + revision: Some(INITIAL_REVISION), created_at: None, updated_at: None, }; diff --git a/packages/rs-drive/src/tests/helpers/setup.rs b/packages/rs-drive/src/tests/helpers/setup.rs index 986a06b3078..f9850e91ad0 100644 --- a/packages/rs-drive/src/tests/helpers/setup.rs +++ b/packages/rs-drive/src/tests/helpers/setup.rs @@ -115,7 +115,7 @@ pub fn setup_document( .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&document, None)), + document_info: DocumentRefWithoutSerialization((document, None)), owner_id: None, }, contract: data_contract, diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index b9582ebbdeb..b8c57295885 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -178,7 +178,7 @@ where + TryFrom, { self.get(key) - .map(|v| { + .and_then(|v| { let borrowed = v.borrow(); if borrowed.is_null() { None @@ -186,7 +186,6 @@ where Some(v.borrow().to_integer()) } }) - .flatten() .transpose() } @@ -221,7 +220,7 @@ where + TryFrom, { self.remove(key) - .map(|v| { + .and_then(|v| { let borrowed = v.borrow(); if borrowed.is_null() { None @@ -229,7 +228,6 @@ where Some(v.borrow().to_integer()) } }) - .flatten() .transpose() } @@ -253,7 +251,7 @@ where fn get_optional_bool(&self, key: &str) -> Result, Error> { self.get(key) - .map(|v| { + .and_then(|v| { let borrowed = v.borrow(); if borrowed.is_null() { None @@ -261,7 +259,6 @@ where Some(v.borrow().to_bool()) } }) - .flatten() .transpose() } @@ -474,7 +471,7 @@ where fn remove_optional_float(&mut self, key: &str) -> Result, Error> { self.remove(key) - .map(|v| { + .and_then(|v| { let borrowed = v.borrow(); if borrowed.is_null() { None @@ -482,7 +479,6 @@ where Some(v.borrow().to_float()) } }) - .flatten() .transpose() } @@ -493,7 +489,7 @@ where fn get_optional_float(&self, key: &str) -> Result, Error> { self.get(key) - .map(|v| { + .and_then(|v| { let borrowed = v.borrow(); if borrowed.is_null() { None @@ -501,7 +497,6 @@ where Some(v.borrow().to_float()) } }) - .flatten() .transpose() } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 891c227af78..c0eb8d6c729 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use dpp::document::document_transition::document_in_state_transition; use dpp::{ document::{ - self, document_factory::{DocumentFactory, FactoryOptions}, document_transition::Action, fetch_and_validate_data_contract::DataContractFetcherAndValidator, diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index a770bb73610..89e772d0c24 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -1,20 +1,20 @@ -use dpp::dashcore::anyhow::Context; + use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::{JsonValueExt, ReplaceWith}; -use dpp::util::string_encoding::Encoding; + use serde::{Deserialize, Serialize}; use std::convert::TryInto; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; -use crate::errors::RustConversionError; + use crate::identifier::IdentifierWrapper; use crate::lodash::lodash_set; use crate::utils::WithJsError; -use crate::utils::{with_serde_to_json_value, with_serde_to_platform_value, ToSerdeJSONExt}; +use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt}; use crate::with_js_error; -use crate::{DataContractWasm, MetadataWasm}; +use crate::{DataContractWasm}; pub mod errors; pub use state_transition::*; @@ -25,13 +25,13 @@ mod validator; pub use document_batch_transition::{DocumentsBatchTransitionWASM, DocumentsContainer}; pub use document_in_state_transition::DocumentInStateTransitionWasm; -use dpp::data_contract::{DataContract, DriveContractExt}; +use dpp::data_contract::{DriveContractExt}; use dpp::document::{ document_in_state_transition_property_names, Document, DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS, }; use dpp::identity::TimestampMillis; -use dpp::platform_value::Value; + use dpp::ProtocolError; pub use factory::DocumentFactoryWASM; use serde_json::Value as JsonValue; @@ -135,7 +135,8 @@ impl DocumentWasm { #[wasm_bindgen(js_name=set)] pub fn set(&mut self, path: String, js_value_to_set: JsValue) -> Result<(), JsValue> { let value = js_value_to_set.with_serde_to_platform_value()?; - Ok(self.0.set(&path, value)) + self.0.set(&path, value); + Ok(()) } #[wasm_bindgen(js_name=get)] diff --git a/packages/wasm-dpp/src/errors/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus_error.rs index cfcd627807c..3eb6f344a2c 100644 --- a/packages/wasm-dpp/src/errors/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus_error.rs @@ -2,7 +2,7 @@ use crate::errors::consensus::basic::{ IncompatibleProtocolVersionErrorWasm, InvalidIdentifierErrorWasm, JsonSchemaErrorWasm, UnsupportedProtocolVersionErrorWasm, }; -use dpp::consensus::{ConsensusError as DPPConsensusError, ConsensusError}; +use dpp::consensus::{ConsensusError as DPPConsensusError}; use std::ops::Deref; use crate::errors::consensus::basic::identity::{ diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index ba1b6e4637f..6dc689c7243 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -24,7 +24,7 @@ use js_sys::Uint8Array; use js_sys::{Array, Number}; use wasm_bindgen::__rt::Ref; -use dpp::document::{Document, DocumentInStateTransition}; +use dpp::document::{Document}; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; From a74d0dc97c675acd5e31314727adb8f07825ccd9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 26 Feb 2023 00:19:43 +0700 Subject: [PATCH 011/228] fixes --- packages/rs-dpp/src/document/document.rs | 7 ++++++- packages/rs-dpp/src/document/mod.rs | 20 +------------------ .../document_create_transition.rs | 10 ++++++---- .../document_replace_transition.rs | 6 ++++-- 4 files changed, 17 insertions(+), 26 deletions(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 2596391ebd9..0aec145a979 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -44,7 +44,7 @@ use std::fmt; use itertools::Itertools; use serde_json::Value as JsonValue; -use crate::data_contract::{DataContract, DriveContractExt, IDENTIFIER_FIELDS}; +use crate::data_contract::{DataContract, DriveContractExt}; use platform_value::Value; use serde::{Deserialize, Serialize}; @@ -73,6 +73,11 @@ pub mod property_names { pub const UPDATED_AT: &str = "$updatedAt"; } +pub const IDENTIFIER_FIELDS: [&str; 2] = [ + property_names::ID, + property_names::OWNER_ID, +]; + /// Documents contain the data that goes into data contracts. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] pub struct Document { diff --git a/packages/rs-dpp/src/document/mod.rs b/packages/rs-dpp/src/document/mod.rs index 97c2fb43069..ddcdeb61581 100644 --- a/packages/rs-dpp/src/document/mod.rs +++ b/packages/rs-dpp/src/document/mod.rs @@ -1,25 +1,7 @@ - - - - - - - - pub use state_transition::documents_batch_transition::document_transition; pub use state_transition::documents_batch_transition::validation; pub use state_transition::documents_batch_transition::DocumentsBatchTransition; - - - - - - - - - - - +pub use document::{property_names, IDENTIFIER_FIELDS}; mod document; pub mod document_factory; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index a5bc75ae362..72621198f10 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -12,6 +12,8 @@ use dpp::{ }; use serde::Serialize; use wasm_bindgen::prelude::*; +use dpp::identity::TimestampMillis; +use dpp::prelude::Revision; use crate::{ buffer::Buffer, @@ -45,7 +47,7 @@ impl DocumentCreateTransitionWasm { let data_contract: DataContract = data_contract.clone().into(); let mut value = raw_object.with_serde_to_json_value()?; let document_type = value - .get_string(document::property_names::DOCUMENT_TYPE) + .get_string(dpp::document::property_names::DOCUMENT_TYPE) .with_js_error()?; let (identifier_paths, _) = data_contract @@ -71,17 +73,17 @@ impl DocumentCreateTransitionWasm { } #[wasm_bindgen(js_name=getCreatedAt)] - pub fn created_at(&self) -> Option { + pub fn created_at(&self) -> Option { self.inner.created_at } #[wasm_bindgen(js_name=getUpdatedAt)] - pub fn updated_at(&self) -> Option { + pub fn updated_at(&self) -> Option { self.inner.updated_at } #[wasm_bindgen(js_name=getRevision)] - pub fn revision(&self) -> u32 { + pub fn revision(&self) -> Revision { document_transition::INITIAL_REVISION } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 529b19cf5d9..eecba81f652 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -16,6 +16,8 @@ use dpp::{ }; use serde::Serialize; use wasm_bindgen::prelude::*; +use dpp::identity::TimestampMillis; +use dpp::prelude::Revision; use crate::{ buffer::Buffer, @@ -73,12 +75,12 @@ impl DocumentReplaceTransitionWasm { } #[wasm_bindgen(js_name=getRevision)] - pub fn revision(&self) -> u32 { + pub fn revision(&self) -> Revision { self.inner.revision } #[wasm_bindgen(js_name=getUpdatedAt)] - pub fn updated_at(&self) -> Option { + pub fn updated_at(&self) -> Option { self.inner.updated_at } From faeb3db668f70e4d32172761c58824813088bd59 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 26 Feb 2023 00:20:43 +0700 Subject: [PATCH 012/228] fixes --- .../state/validate_data_contract_create_transition_basic.rs | 1 - .../state_transition/data_contract_create_transition/mod.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 2 +- .../document_transition/document_create_transition.rs | 1 - 4 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs index e96b6145bd5..4d7af635a84 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs @@ -16,7 +16,6 @@ use crate::{ util::json_value::JsonValueExt, validation::{ DataValidator, DataValidatorWithContext, JsonSchemaValidator, SimpleValidationResult, - ValidationResult, }, version::ProtocolVersionValidator, ProtocolError, diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index d8e38f2da5a..24896ce10f4 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; -use dpp::identity::KeyID; + use dpp::{ data_contract::state_transition::DataContractCreateTransition, state_transition::{ diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 5b8a3c8af4d..796d58bf022 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -4,7 +4,7 @@ use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::{JsonValueExt, ReplaceWith}; use serde::{Deserialize, Serialize}; -use std::convert::{self, TryInto}; +use std::convert::{TryInto}; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 72621198f10..eae244cd887 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -17,7 +17,6 @@ use dpp::prelude::Revision; use crate::{ buffer::Buffer, - document, document_batch_transition::document_transition::to_object, identifier::IdentifierWrapper, lodash::lodash_set, From 5a0ceb7c3c4dd918e3824340174e3bb325d0e407 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 26 Feb 2023 00:29:40 +0700 Subject: [PATCH 013/228] fixes --- .../src/data_trigger/dpns_triggers/mod.rs | 2 +- .../reward_share_data_triggers/mod.rs | 2 +- .../withdrawals_data_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/document.rs | 12 ++-------- .../rs-dpp/src/document/document_factory.rs | 8 ++----- .../rs-dpp/src/document/document_validator.rs | 2 +- packages/rs-dpp/src/document/mod.rs | 2 +- packages/rs-dpp/src/document/serialize.rs | 2 +- ...pply_documents_batch_transition_factory.rs | 14 +++-------- .../document_create_transition.rs | 3 +-- .../document_in_state_transition.rs | 6 ++--- .../validation/state/fetch_documents.rs | 2 +- ...lidate_documents_batch_transition_state.rs | 2 +- ...alidate_documents_uniqueness_by_indices.rs | 2 +- packages/rs-dpp/src/identity/identity.rs | 4 +++- ...ternode_reward_shares_documents_fixture.rs | 1 - ...edit_withdrawal_transition_factory_spec.rs | 2 +- packages/rs-platform-value/src/lib.rs | 24 +++++++++---------- .../data_contract_create_transition/mod.rs | 1 - packages/wasm-dpp/src/document/mod.rs | 7 +++--- .../document_create_transition.rs | 6 ++--- .../document_delete_transition.rs | 4 ++-- .../document_replace_transition.rs | 8 +++---- .../wasm-dpp/src/errors/consensus_error.rs | 2 +- packages/wasm-dpp/src/state_repository.rs | 2 +- 25 files changed, 50 insertions(+), 72 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index c909cc37c76..dfe1cb58d36 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -222,7 +222,7 @@ where #[cfg(test)] mod test { - use crate::document::{Document}; + use crate::document::Document; use crate::{ data_trigger::DataTriggerExecutionContext, document::document_transition::Action, diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index bfa4396c5d4..acdd26635ea 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use serde_json::json; -use crate::document::{Document}; +use crate::document::Document; use crate::{ data_trigger::create_error, document::document_transition::DocumentTransition, diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index 230b1ef3a52..311d2747e33 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -1,4 +1,4 @@ -use anyhow::{bail}; +use anyhow::bail; use serde_json::json; use crate::contracts::withdrawals_contract; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 0aec145a979..f9f19f8041e 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -37,10 +37,6 @@ use std::collections::{BTreeMap, HashSet}; use std::convert::{TryFrom, TryInto}; use std::fmt; - - - - use itertools::Itertools; use serde_json::Value as JsonValue; @@ -49,7 +45,7 @@ use platform_value::Value; use serde::{Deserialize, Serialize}; use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType}; -use crate::data_contract::errors::{DataContractError}; +use crate::data_contract::errors::DataContractError; use crate::document::errors::DocumentError; use crate::document::DocumentInStateTransition; @@ -57,7 +53,6 @@ use crate::identifier::Identifier; use crate::identity::TimestampMillis; use crate::prelude::Revision; - use crate::util::hash::hash; use crate::util::json_value::JsonValueExt; use crate::util::json_value::ReplaceWith; @@ -73,10 +68,7 @@ pub mod property_names { pub const UPDATED_AT: &str = "$updatedAt"; } -pub const IDENTIFIER_FIELDS: [&str; 2] = [ - property_names::ID, - property_names::OWNER_ID, -]; +pub const IDENTIFIER_FIELDS: [&str; 2] = [property_names::ID, property_names::OWNER_ID]; /// Documents contain the data that goes into data contracts. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)] diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 488885c4193..0a40b0eab02 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -4,12 +4,10 @@ use chrono::Utc; use itertools::Itertools; use rand::rngs::StdRng; -use rand::{SeedableRng}; +use rand::SeedableRng; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; - - use crate::document::document_transition::document_in_state_transition::{ property_names, DocumentInStateTransition, }; @@ -400,9 +398,7 @@ mod test { assert_error_contains, state_repository::MockStateRepositoryLike, tests::{ - fixtures::{ - get_data_contract_fixture, get_document_validator_fixture, - }, + fixtures::{get_data_contract_fixture, get_document_validator_fixture}, utils::generate_random_identifier_struct, }, util::string_encoding::Encoding, diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 7235084cecb..85fe602b5b9 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -111,7 +111,7 @@ mod test { codes::ErrorWithCode, consensus::{basic::JsonSchemaError, ConsensusError}, data_contract::DataContract, - tests::fixtures::{get_data_contract_fixture}, + tests::fixtures::get_data_contract_fixture, util::json_value::JsonValueExt, validation::ValidationResult, version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}, diff --git a/packages/rs-dpp/src/document/mod.rs b/packages/rs-dpp/src/document/mod.rs index ddcdeb61581..bf6ec6208bc 100644 --- a/packages/rs-dpp/src/document/mod.rs +++ b/packages/rs-dpp/src/document/mod.rs @@ -1,7 +1,7 @@ +pub use document::{property_names, IDENTIFIER_FIELDS}; pub use state_transition::documents_batch_transition::document_transition; pub use state_transition::documents_batch_transition::validation; pub use state_transition::documents_batch_transition::DocumentsBatchTransition; -pub use document::{property_names, IDENTIFIER_FIELDS}; mod document; pub mod document_factory; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 3bc3e321396..7240d8ece41 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -21,7 +21,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; -use std::convert::{TryFrom}; +use std::convert::TryFrom; use std::io::{BufReader, Read}; //todo: delete in later PR diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 7dbd9d9a389..5c2dee7e4c9 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -1,9 +1,5 @@ use std::collections::HashMap; - - - - use crate::document::{Document, DocumentInStateTransition}; use crate::prelude::TimestampMillis; use crate::{ @@ -12,9 +8,7 @@ use crate::{ }; use super::{ - document_transition::{ - Action, DocumentReplaceTransition, DocumentTransition, - }, + document_transition::{Action, DocumentReplaceTransition, DocumentTransition}, validation::state::fetch_documents::fetch_documents, DocumentsBatchTransition, }; @@ -147,7 +141,7 @@ mod test { use dashcore::consensus; use serde_json::{json, Value}; - use crate::document::{Document}; + use crate::document::Document; use crate::tests::fixtures::get_documents_in_state_transitions_fixture; use crate::tests::utils::new_block_header; use crate::{ @@ -158,9 +152,7 @@ mod test { state_repository::MockStateRepositoryLike, state_transition::StateTransitionLike, tests::{ - fixtures::{ - get_data_contract_fixture, get_document_transitions_fixture, - }, + fixtures::{get_data_contract_fixture, get_document_transitions_fixture}, utils::generate_random_identifier_struct, }, }; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index d7c6a26954d..75390a2815a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -3,8 +3,7 @@ use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; - -use crate::document::{Document}; +use crate::document::Document; use crate::identity::TimestampMillis; use crate::prelude::Revision; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs index c326a662045..543160189c3 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs @@ -271,12 +271,12 @@ mod test { use crate::document::document_transition::document_in_state_transition::{ DocumentInStateTransition, IDENTIFIER_FIELDS, }; - + + use crate::data_contract::DataContract; + use crate::identifier::Identifier; use crate::tests::utils::*; use crate::util::string_encoding::Encoding; use pretty_assertions::assert_eq; - use crate::data_contract::DataContract; - use crate::identifier::Identifier; fn init() { let _ = env_logger::builder() diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs index 6b18bcdcfef..0738bc2cda9 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs @@ -3,7 +3,7 @@ use std::collections::hash_map::{Entry, HashMap}; use futures::future::join_all; use serde_json::json; -use crate::document::{Document}; +use crate::document::Document; use crate::{ document::document_transition::DocumentTransition, get_from_transition, state_repository::StateRepositoryLike, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index cd9982ac95b..e2e1964ddb7 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -5,7 +5,7 @@ use futures::future::join_all; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use crate::document::{Document}; +use crate::document::Document; use crate::{ block_time_window::validate_time_in_block_time_window::validate_time_in_block_time_window, consensus::ConsensusError, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs index 46801b47606..5b001998e22 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs @@ -2,7 +2,7 @@ use futures::future::join_all; use itertools::Itertools; use serde_json::{json, Value as JsonValue}; -use crate::document::{Document}; +use crate::document::Document; use crate::{ document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, prelude::{DataContract, Identifier}, diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index aba0cb8a27c..0a51f3e1a0d 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -234,7 +234,9 @@ impl Identity { identity_json.replace_identifier_paths(IDENTIFIER_FIELDS_RAW_OBJECT, ReplaceWith::Bytes)?; let pk_values = self - .public_keys.values().map(|pk| pk.to_raw_json_object()) + .public_keys + .values() + .map(|pk| pk.to_raw_json_object()) .collect::, SerdeParsingError>>()?; identity_json.insert( diff --git a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs index 30ce04f4f0e..8ffd3dcc265 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs @@ -3,7 +3,6 @@ use std::sync::Arc; use data_contracts::SystemDataContract; use serde_json::json; - use crate::document::DocumentInStateTransition; use crate::system_data_contracts::load_system_data_contract; use crate::{ diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs index fdac95d4f51..10df7ca3346 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod apply_identity_credit_withdrawal_transition_factory { use dashcore::{consensus, BlockHeader}; - + use std::collections::BTreeMap; use crate::contracts::withdrawals_contract::property_names::{ diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 437efa8167f..3e2b0a1238f 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -94,19 +94,19 @@ impl Value { /// assert!(value.is_integer()); /// ``` pub fn is_integer(&self) -> bool { - match self { + matches!( + self, Value::U128(_) - | Value::I128(_) - | Value::U64(_) - | Value::I64(_) - | Value::U32(_) - | Value::I32(_) - | Value::U16(_) - | Value::I16(_) - | Value::U8(_) - | Value::I8(_) => true, - _ => false, - } + | Value::I128(_) + | Value::U64(_) + | Value::I64(_) + | Value::U32(_) + | Value::I32(_) + | Value::U16(_) + | Value::I16(_) + | Value::U8(_) + | Value::I8(_) + ) } /// If the `Value` is a `Integer`, returns a reference to the associated `Integer` data. diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 24896ce10f4..098d78aca41 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -6,7 +6,6 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; - use dpp::{ data_contract::state_transition::DataContractCreateTransition, state_transition::{ diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 796d58bf022..80b6db91eb9 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -1,10 +1,9 @@ - use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::{JsonValueExt, ReplaceWith}; use serde::{Deserialize, Serialize}; -use std::convert::{TryInto}; +use std::convert::TryInto; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; @@ -14,7 +13,7 @@ use crate::lodash::lodash_set; use crate::utils::WithJsError; use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt}; use crate::with_js_error; -use crate::{DataContractWasm}; +use crate::DataContractWasm; pub mod errors; pub use state_transition::*; @@ -26,7 +25,7 @@ mod validator; pub use document_batch_transition::{DocumentsBatchTransitionWASM, DocumentsContainer}; pub use document_in_state_transition::DocumentInStateTransitionWasm; -use dpp::data_contract::{DriveContractExt}; +use dpp::data_contract::DriveContractExt; use dpp::document::{ document_in_state_transition_property_names, Document, DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS, diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index eae244cd887..6110d9bc8af 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -1,5 +1,7 @@ use std::convert; +use dpp::identity::TimestampMillis; +use dpp::prelude::Revision; use dpp::{ document::document_transition::{ self, document_create_transition, DocumentCreateTransition, DocumentTransitionObjectLike, @@ -12,8 +14,6 @@ use dpp::{ }; use serde::Serialize; use wasm_bindgen::prelude::*; -use dpp::identity::TimestampMillis; -use dpp::prelude::Revision; use crate::{ buffer::Buffer, @@ -89,7 +89,7 @@ impl DocumentCreateTransitionWasm { // AbstractDocumentTransitionMethods #[wasm_bindgen(js_name=getId)] pub fn id(&self) -> IdentifierWrapper { - self.inner.base.id.clone().into() + self.inner.base.id.into() } #[wasm_bindgen(js_name=getType)] diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs index baa04f072b1..35fb5f2c6fe 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs @@ -49,7 +49,7 @@ impl DocumentDeleteTransitionWasm { // AbstractDocumentTransition #[wasm_bindgen(js_name=getId)] pub fn id(&self) -> IdentifierWrapper { - self.inner.base.id.clone().into() + self.inner.base.id.into() } #[wasm_bindgen(js_name=getType)] @@ -64,7 +64,7 @@ impl DocumentDeleteTransitionWasm { #[wasm_bindgen(js_name=getDataContractId)] pub fn data_contract_id(&self) -> IdentifierWrapper { - self.inner.base.data_contract.id.clone().into() + self.inner.base.data_contract.id.into() } #[wasm_bindgen(js_name=get)] diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index eecba81f652..31d3b1bec8b 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -1,5 +1,7 @@ use std::convert; +use dpp::identity::TimestampMillis; +use dpp::prelude::Revision; use dpp::{ document::{ self, @@ -16,8 +18,6 @@ use dpp::{ }; use serde::Serialize; use wasm_bindgen::prelude::*; -use dpp::identity::TimestampMillis; -use dpp::prelude::Revision; use crate::{ buffer::Buffer, @@ -151,7 +151,7 @@ impl DocumentReplaceTransitionWasm { // AbstractDocumentTransition #[wasm_bindgen(js_name=getId)] pub fn id(&self) -> IdentifierWrapper { - self.inner.base.id.clone().into() + self.inner.base.id.into() } #[wasm_bindgen(js_name=getType)] @@ -166,7 +166,7 @@ impl DocumentReplaceTransitionWasm { #[wasm_bindgen(js_name=getDataContractId)] pub fn data_contract_id(&self) -> IdentifierWrapper { - self.inner.base.data_contract.id.clone().into() + self.inner.base.data_contract.id.into() } #[wasm_bindgen(js_name=get)] diff --git a/packages/wasm-dpp/src/errors/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus_error.rs index 3eb6f344a2c..0365ce06671 100644 --- a/packages/wasm-dpp/src/errors/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus_error.rs @@ -2,7 +2,7 @@ use crate::errors::consensus::basic::{ IncompatibleProtocolVersionErrorWasm, InvalidIdentifierErrorWasm, JsonSchemaErrorWasm, UnsupportedProtocolVersionErrorWasm, }; -use dpp::consensus::{ConsensusError as DPPConsensusError}; +use dpp::consensus::ConsensusError as DPPConsensusError; use std::ops::Deref; use crate::errors::consensus::basic::identity::{ diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 81fa638dae4..355419b9f2b 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -24,7 +24,7 @@ use js_sys::Uint8Array; use js_sys::{Array, Number}; use wasm_bindgen::__rt::Ref; -use dpp::document::{Document}; +use dpp::document::Document; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; From 4e4831e62fe1093aa1ae55ce294500a59b503482 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 26 Feb 2023 10:53:53 +0700 Subject: [PATCH 014/228] small refactoring --- .../rs-dpp/src/data_contract/data_contract.rs | 160 ++---------------- .../src/data_contract/extra/drive_api.rs | 16 +- packages/rs-dpp/src/data_contract/mod.rs | 1 + .../src/data_contract/serialization/cbor.rs | 113 +++++++++++++ .../src/data_contract/serialization/mod.rs | 1 + ...e_data_contract_create_transition_state.rs | 2 +- ...e_data_contract_update_transition_basic.rs | 4 +- .../data_trigger/dashpay_data_triggers/mod.rs | 4 +- .../feature_flags_data_triggers/mod.rs | 4 +- .../withdrawals_data_triggers/mod.rs | 6 +- ...lidate_documents_batch_transition_basic.rs | 4 +- .../validate_state_transition_fee.rs | 10 +- ...te_indices_are_backward_compatible_spec.rs | 4 +- ..._documents_batch_transitions_basic_spec.rs | 2 +- .../tests/fixtures/get_documents_fixture.rs | 2 +- packages/rs-drive/src/drive/cache.rs | 8 +- packages/rs-drive/src/drive/contract/mod.rs | 18 +- packages/rs-drive/src/drive/contract/paths.rs | 6 +- .../src/drive/document/estimation_costs.rs | 2 +- .../rs-drive/src/drive/document/insert.rs | 6 +- .../test/unit/document/Document.spec.js | 2 +- 21 files changed, 179 insertions(+), 196 deletions(-) create mode 100644 packages/rs-dpp/src/data_contract/serialization/cbor.rs create mode 100644 packages/rs-dpp/src/data_contract/serialization/mod.rs diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 7384fb4f750..c5982e456ef 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -86,6 +86,12 @@ pub struct DataContract { pub schema: String, pub version: u32, pub owner_id: Identifier, + #[serde(skip)] + pub document_types: BTreeMap, + #[serde(skip)] + pub metadata: Option, + #[serde(skip)] + pub(crate) config: ContractConfig, #[serde(rename = "documents")] pub documents: BTreeMap, @@ -97,16 +103,8 @@ pub struct DataContract { #[serde(skip)] pub entropy: [u8; 32], - #[serde(skip)] - pub metadata: Option, #[serde(skip)] pub binary_properties: BTreeMap>, - - #[serde(skip)] - pub(crate) config: ContractConfig, - - #[serde(skip)] - pub document_types: BTreeMap, } impl DataContract { @@ -137,69 +135,6 @@ impl DataContract { Self::from_cbor(b) } - pub fn from_cbor(cbor_bytes: impl AsRef<[u8]>) -> Result { - let SplitProtocolVersionOutcome { - protocol_version, - protocol_version_size, - main_message_bytes: contract_cbor_bytes, - } = deserializer::split_protocol_version(cbor_bytes.as_ref())?; - - let data_contract_cbor_map: BTreeMap = - ciborium::de::from_reader(contract_cbor_bytes).map_err(|_| { - ProtocolError::DecodingError(format!( - "unable to decode contract with protocol version {} offset {}", - protocol_version, protocol_version_size - )) - })?; - - let data_contract_map: BTreeMap = - Value::convert_from_cbor_map(data_contract_cbor_map); - - let contract_id: [u8; 32] = data_contract_map.get_identifier(property_names::ID)?; - let owner_id: [u8; 32] = data_contract_map.get_identifier(property_names::OWNER_ID)?; - let schema = data_contract_map.get_string(property_names::SCHEMA)?; - let version = data_contract_map.get_integer(property_names::VERSION)?; - - // Defs - let defs = - data_contract_map.get_optional_inner_str_json_value_map::>("$defs")?; - - // Documents - let documents: BTreeMap = data_contract_map - .get_inner_str_json_value_map("documents") - .map_err(ProtocolError::ValueError)?; - - let mutability = get_contract_configuration_properties(&data_contract_map) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; - let definition_references = get_definitions(&data_contract_map)?; - let document_types = get_document_types( - &data_contract_map, - definition_references, - mutability.documents_keep_history_contract_default, - mutability.documents_mutable_contract_default, - ) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; - - let mut data_contract = Self { - protocol_version, - id: Identifier::new(contract_id), - schema, - version, - owner_id: Identifier::new(owner_id), - documents, - defs, - metadata: None, - entropy: [0; 32], - binary_properties: Default::default(), - document_types, - config: mutability, - }; - - data_contract.generate_binary_properties(); - - Ok(data_contract) - } - pub fn to_object(&self, skip_identifiers_conversion: bool) -> Result { let mut json_object = serde_json::to_value(self)?; if !json_object.is_object() { @@ -222,73 +157,6 @@ impl DataContract { self.to_cbor() } - pub fn to_cbor(&self) -> Result, ProtocolError> { - let mut buf = self.protocol_version().encode_var_vec(); - - let contract_cbor_map = self.to_cbor_canonical_map()?; - let mut contract_buf = contract_cbor_map - .to_bytes() - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - - buf.append(&mut contract_buf); - Ok(buf) - } - - pub(crate) fn to_cbor_canonical_map(&self) -> Result { - let mut contract_cbor_map = CborCanonicalMap::new(); - - contract_cbor_map.insert(property_names::ID, self.id().to_buffer().to_vec()); - contract_cbor_map.insert(property_names::SCHEMA, self.schema()); - contract_cbor_map.insert(property_names::VERSION, self.version()); - contract_cbor_map.insert( - property_names::OWNER_ID, - self.owner_id().to_buffer().to_vec(), - ); - - let docs = CborValue::serialized(&self.documents) - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - - contract_cbor_map.insert(property_names::DOCUMENTS, docs); - - if let Some(defs) = &self.defs { - contract_cbor_map.insert( - property_names::DEFINITIONS, - CborValue::serialized(defs) - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?, - ); - } - - Ok(contract_cbor_map) - } - - pub fn documents(&self) -> &BTreeMap { - &self.documents - } - - pub fn entropy(&self) -> [u8; 32] { - self.entropy - } - - pub fn owner_id(&self) -> &Identifier { - &self.owner_id - } - - pub fn protocol_version(&self) -> u32 { - self.protocol_version - } - - pub fn id(&self) -> &Identifier { - &self.id - } - - pub fn schema(&self) -> &str { - &self.schema - } - - pub fn version(&self) -> u32 { - self.version - } - pub fn definitions(&self) -> Option<&BTreeMap> { self.defs.as_ref() } @@ -392,7 +260,7 @@ impl DataContract { .map(Some) } - fn generate_binary_properties(&mut self) { + pub(crate) fn generate_binary_properties(&mut self) { self.binary_properties = self .documents .iter() @@ -784,22 +652,22 @@ mod test { let data_contract = DataContract::from_buffer(data_contract_cbor).unwrap(); - assert_eq!(data_contract.version(), 1); - assert_eq!(data_contract.protocol_version(), 1); + assert_eq!(data_contract.version, 1); + assert_eq!(data_contract.protocol_version, 1); assert_eq!( - data_contract.schema(), + data_contract.schema, "https://schema.dash.org/dpp-0-4-0/meta/data-contract" ); assert_eq!( - data_contract.owner_id(), - &Identifier::new([ + data_contract.owner_id, + Identifier::new([ 150, 32, 136, 170, 56, 18, 187, 51, 134, 208, 201, 19, 14, 219, 222, 81, 228, 190, 23, 187, 45, 16, 3, 29, 65, 71, 200, 89, 127, 172, 238, 37 ]) ); assert_eq!( - data_contract.id(), - &Identifier::new([ + data_contract.id, + Identifier::new([ 142, 254, 247, 51, 140, 13, 52, 178, 228, 8, 65, 27, 148, 115, 215, 36, 203, 249, 182, 117, 202, 114, 179, 18, 111, 127, 142, 125, 235, 66, 174, 81 ]) diff --git a/packages/rs-dpp/src/data_contract/extra/drive_api.rs b/packages/rs-dpp/src/data_contract/extra/drive_api.rs index b8f86f79df6..ec0c40a99a6 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -144,7 +144,7 @@ impl DriveContractExt for DataContract { /// `to_cbor` overloads the original method from [`DataContract`] and adds the properties /// from [`super::Mutability`]. fn to_cbor(&self) -> Result, ProtocolError> { - let mut buf = self.protocol_version().encode_var_vec(); + let mut buf = self.protocol_version.encode_var_vec(); let mut contract_cbor_map = self.to_cbor_canonical_map()?; @@ -294,16 +294,16 @@ mod test { let data_contract = DataContract::from_cbor(cbor_bytes).expect("contract should be deserialized"); - assert_eq!(1, data_contract.protocol_version()); - assert_eq!(expect_id, data_contract.id().as_bytes()); - assert_eq!(expect_owner_id, data_contract.owner_id().as_bytes()); + assert_eq!(1, data_contract.protocol_version); + assert_eq!(expect_id, data_contract.id.as_bytes()); + assert_eq!(expect_owner_id, data_contract.owner_id.as_bytes()); - assert_eq!(7, data_contract.documents().len()); - assert_eq!(7, data_contract.document_types().len()); - assert_eq!(1, data_contract.version()); + assert_eq!(7, data_contract.documents.len()); + assert_eq!(7, data_contract.document_types.len()); + assert_eq!(1, data_contract.version); assert_eq!( "https://schema.dash.org/dpp-0-4-0/meta/data-contract", - data_contract.schema() + data_contract.schema ); for expect in expected_documents() { diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index fd675f47f81..fea292b6849 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -16,6 +16,7 @@ pub mod enrich_data_contract_with_base_schema; mod generate_data_contract; pub mod get_binary_properties_from_schema; pub mod get_property_definition_by_path; +pub mod serialization; pub mod state_transition; pub mod validation; diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs new file mode 100644 index 00000000000..ffc007225f2 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -0,0 +1,113 @@ +use crate::data_contract::{property_names, DataContract}; +use crate::identifier::Identifier; +use crate::util::cbor_value::CborCanonicalMap; +use crate::util::deserializer; +use crate::util::deserializer::SplitProtocolVersionOutcome; +use crate::{data_contract, ProtocolError}; +use ciborium::Value as CborValue; +use integer_encoding::VarInt; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; +use serde_json::Value as JsonValue; +use std::collections::BTreeMap; + +impl DataContract { + pub fn from_cbor(cbor_bytes: impl AsRef<[u8]>) -> Result { + let SplitProtocolVersionOutcome { + protocol_version, + protocol_version_size, + main_message_bytes: contract_cbor_bytes, + } = deserializer::split_protocol_version(cbor_bytes.as_ref())?; + + let data_contract_cbor_map: BTreeMap = + ciborium::de::from_reader(contract_cbor_bytes).map_err(|_| { + ProtocolError::DecodingError(format!( + "unable to decode contract with protocol version {} offset {}", + protocol_version, protocol_version_size + )) + })?; + + let data_contract_map: BTreeMap = + Value::convert_from_cbor_map(data_contract_cbor_map); + + let contract_id: [u8; 32] = data_contract_map.get_identifier(property_names::ID)?; + let owner_id: [u8; 32] = data_contract_map.get_identifier(property_names::OWNER_ID)?; + let schema = data_contract_map.get_string(property_names::SCHEMA)?; + let version = data_contract_map.get_integer(property_names::VERSION)?; + + // Defs + let defs = + data_contract_map.get_optional_inner_str_json_value_map::>("$defs")?; + + // Documents + let documents: BTreeMap = data_contract_map + .get_inner_str_json_value_map("documents") + .map_err(ProtocolError::ValueError)?; + + let mutability = data_contract::get_contract_configuration_properties(&data_contract_map) + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + let definition_references = data_contract::get_definitions(&data_contract_map)?; + let document_types = data_contract::get_document_types( + &data_contract_map, + definition_references, + mutability.documents_keep_history_contract_default, + mutability.documents_mutable_contract_default, + ) + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + + let mut data_contract = Self { + protocol_version, + id: Identifier::new(contract_id), + schema, + version, + owner_id: Identifier::new(owner_id), + documents, + defs, + metadata: None, + entropy: [0; 32], + binary_properties: Default::default(), + document_types, + config: mutability, + }; + + data_contract.generate_binary_properties(); + + Ok(data_contract) + } + + pub fn to_cbor(&self) -> Result, ProtocolError> { + let mut buf = self.protocol_version.encode_var_vec(); + + let contract_cbor_map = self.to_cbor_canonical_map()?; + let mut contract_buf = contract_cbor_map + .to_bytes() + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; + + buf.append(&mut contract_buf); + Ok(buf) + } + + pub(crate) fn to_cbor_canonical_map(&self) -> Result { + let mut contract_cbor_map = CborCanonicalMap::new(); + + contract_cbor_map.insert(property_names::ID, self.id.to_buffer().to_vec()); + contract_cbor_map.insert(property_names::SCHEMA, self.schema.as_str()); + contract_cbor_map.insert(property_names::VERSION, self.version); + contract_cbor_map.insert(property_names::OWNER_ID, self.owner_id.to_buffer().to_vec()); + + let docs = CborValue::serialized(&self.documents) + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; + + contract_cbor_map.insert(property_names::DOCUMENTS, docs); + + if let Some(defs) = &self.defs { + contract_cbor_map.insert( + property_names::DEFINITIONS, + CborValue::serialized(defs) + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?, + ); + } + + Ok(contract_cbor_map) + } +} diff --git a/packages/rs-dpp/src/data_contract/serialization/mod.rs b/packages/rs-dpp/src/data_contract/serialization/mod.rs new file mode 100644 index 00000000000..e8bc30512c9 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/serialization/mod.rs @@ -0,0 +1 @@ +pub mod cbor; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs index f0bda530197..947fe3af7d7 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs @@ -89,7 +89,7 @@ mod test { let mut state_repository_mock = MockStateRepositoryLike::new(); let data_contract = get_data_contract_fixture(None); let state_transition = &DataContractCreateTransition { - entropy: data_contract.entropy().to_owned(), + entropy: data_contract.entropy.clone(), data_contract, ..Default::default() }; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 24b963bdcf7..8f22425c5a4 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -168,7 +168,7 @@ where .as_object() .ok_or_else(|| anyhow!("the 'documents' property is not an array"))?; let result = validate_indices_are_backward_compatible( - existing_data_contract.documents(), + &existing_data_contract.documents, new_documents, )?; if !result.is_valid() { @@ -176,7 +176,7 @@ where } // Schema should be backward compatible - let old_schema = existing_data_contract.documents(); + let old_schema = &existing_data_contract.documents; let new_schema = raw_data_contract.get_value("documents")?; for (document_type, document_schema) in old_schema.iter() { diff --git a/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs index 2c1b26c2d06..10a82fdf2bf 100644 --- a/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs @@ -84,12 +84,12 @@ mod test { let transition_execution_context = StateTransitionExecutionContext::default(); let state_repository = MockStateRepositoryLike::new(); let data_contract = get_data_contract_fixture(None); - let owner_id = data_contract.owner_id().to_owned(); + let owner_id = &data_contract.owner_id; let document_transition = DocumentTransition::Create(Default::default()); let data_trigger_context = DataTriggerExecutionContext { data_contract: &data_contract, - owner_id: &owner_id, + owner_id, state_repository: &state_repository, state_transition_execution_context: &transition_execution_context, }; diff --git a/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs index 584c6c56a2c..18f07029c6a 100644 --- a/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs @@ -85,12 +85,12 @@ mod test { let transition_execution_context = StateTransitionExecutionContext::default(); let state_repository = MockStateRepositoryLike::new(); let data_contract = get_data_contract_fixture(None); - let owner_id = data_contract.owner_id().to_owned(); + let owner_id = &data_contract.owner_id; let document_transition = DocumentTransition::Create(Default::default()); let data_trigger_context = DataTriggerExecutionContext { data_contract: &data_contract, - owner_id: &owner_id, + owner_id, state_repository: &state_repository, state_transition_execution_context: &transition_execution_context, }; diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index 311d2747e33..dceda8ece14 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -93,7 +93,7 @@ mod tests { let transition_execution_context = StateTransitionExecutionContext::default(); let mut state_repository = MockStateRepositoryLike::new(); let data_contract = get_data_contract_fixture(None); - let owner_id = data_contract.owner_id().to_owned(); + let owner_id = &data_contract.owner_id; state_repository .expect_fetch_documents::() @@ -102,7 +102,7 @@ mod tests { let document_transition = DocumentTransition::Delete(Default::default()); let data_trigger_context = DataTriggerExecutionContext { data_contract: &data_contract, - owner_id: &owner_id, + owner_id, state_repository: &state_repository, state_transition_execution_context: &transition_execution_context, }; @@ -126,7 +126,7 @@ mod tests { let data_contract = load_system_data_contract(data_contracts::SystemDataContract::Withdrawals) .expect("to load system data contract"); - let owner_id = data_contract.owner_id().to_owned(); + let owner_id = data_contract.owner_id().clone(); let document = get_withdrawal_document_fixture( &data_contract, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 6d4204bd348..81cc92ae236 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -216,7 +216,7 @@ fn validate_raw_transitions<'a>( if !data_contract.is_document_defined(document_type) { result.add_error(BasicError::InvalidDocumentTypeError { document_type: document_type.to_string(), - data_contract_id: *data_contract.id(), + data_contract_id: data_contract.id, }); return Ok(result); } @@ -266,7 +266,7 @@ fn validate_raw_transitions<'a>( let entropy = raw_document_transition.get_bytes("$entropy")?; // validate the id generation let generated_document_id = - generate_document_id(data_contract.id(), owner_id, document_type, &entropy); + generate_document_id(&data_contract.id, owner_id, document_type, &entropy); if generated_document_id != document_id { result.add_error(BasicError::InvalidDocumentTransitionIdError { diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs index b32653ca600..4d08a0db258 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs @@ -198,7 +198,7 @@ mod test { let data_contract = get_data_contract_fixture(None); let data_contract_create_transition = DataContractCreateTransition { - entropy: data_contract.entropy().to_owned(), + entropy: data_contract.entropy.clone(), data_contract, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -231,7 +231,7 @@ mod test { let data_contract = get_data_contract_fixture(None); let data_contract_create_transition = DataContractCreateTransition { - entropy: data_contract.entropy().to_owned(), + entropy: data_contract.entropy.clone(), data_contract, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -260,7 +260,7 @@ mod test { get_documents_fixture_with_owner_id_from_contract(data_contract.clone()).unwrap(); let transitions = get_document_transitions_fixture([(Action::Create, documents)]); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id().to_owned(), + owner_id: data_contract.owner_id().clone(), transitions, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -296,7 +296,7 @@ mod test { get_documents_fixture_with_owner_id_from_contract(data_contract.clone()).unwrap(); let transitions = get_document_transitions_fixture([(Action::Create, documents)]); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id().to_owned(), + owner_id: data_contract.owner_id().clone(), transitions, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -328,7 +328,7 @@ mod test { execution_context.enable_dry_run(); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id().to_owned(), + owner_id: data_contract.owner_id().clone(), transitions, execution_context, ..Default::default() diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_indices_are_backward_compatible_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_indices_are_backward_compatible_spec.rs index af4fa45a2ca..3cadfaa4530 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_indices_are_backward_compatible_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_indices_are_backward_compatible_spec.rs @@ -50,8 +50,8 @@ fn setup_test() -> TestData { })) .expect("the non-unique index should be added to the document"); new_data_contract.set_document_schema(String::from("indexedDocument"), indexed_document); - let old_documents_schema = old_data_contract.documents().to_owned(); - let new_documents_schema = new_data_contract.documents().to_owned(); + let old_documents_schema = old_data_contract.documents.to_owned(); + let new_documents_schema = new_data_contract.documents.to_owned(); TestData { old_data_contract, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index f621726b900..a4e866636e9 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -59,7 +59,7 @@ fn setup_test(action: Action) -> TestData { json!({ "protocolVersion": LATEST_VERSION, "ownerId" : owner_id.as_bytes(), - "contractId" : data_contract.id().as_bytes(), + "contractId" : data_contract.id.as_bytes(), "transitions" : raw_transitions, "signature": signature, "signaturePublicKeyId": 0, diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 34f3f2d85b0..9e6fd52ddb2 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -33,7 +33,7 @@ pub fn get_documents_fixture_with_owner_id_from_contract( data_contract_fetcher_and_validator, None, ); - let owner_id = *data_contract.owner_id(); + let owner_id = data_contract.owner_id.clone(); get_documents_in_state_transitions(factory, data_contract, owner_id) } diff --git a/packages/rs-drive/src/drive/cache.rs b/packages/rs-drive/src/drive/cache.rs index 890fc17050b..7f5800cd0d9 100644 --- a/packages/rs-drive/src/drive/cache.rs +++ b/packages/rs-drive/src/drive/cache.rs @@ -42,7 +42,7 @@ impl DataContractCache { /// Inserts Data Contract to block cache /// otherwise to goes to global cache pub fn insert(&mut self, fetch_info: Arc, is_block_cache: bool) { - let data_contract_id_bytes = fetch_info.contract.id().to_buffer(); + let data_contract_id_bytes = fetch_info.contract.id.to_buffer(); if is_block_cache { self.block_cache.insert(data_contract_id_bytes, fetch_info); @@ -96,7 +96,7 @@ mod tests { // Create global contract let fetch_info_global = Arc::new(ContractFetchInfo::default()); - let contract_id = fetch_info_global.contract.id().to_buffer(); + let contract_id = fetch_info_global.contract.id.to_buffer(); data_contract_cache .global_cache @@ -126,7 +126,7 @@ mod tests { let fetch_info_global = Arc::new(ContractFetchInfo::default()); - let contract_id = fetch_info_global.contract.id().to_buffer(); + let contract_id = fetch_info_global.contract.id.to_buffer(); data_contract_cache .global_cache @@ -145,7 +145,7 @@ mod tests { let fetch_info_block = Arc::new(ContractFetchInfo::default()); - let contract_id = fetch_info_block.contract.id().to_buffer(); + let contract_id = fetch_info_block.contract.id.to_buffer(); data_contract_cache .block_cache diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index c58177a50f6..385d0930234 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -419,7 +419,7 @@ impl Drive { let contract = ::from_cbor(&contract_cbor, contract_id)?; - let contract_id = contract_id.unwrap_or_else(|| *contract.id().as_bytes()); + let contract_id = contract_id.unwrap_or_else(|| *contract.id.as_bytes()); // Since we can update the contract by definition it already has storage flags let storage_flags = Some(StorageFlags::new_single_epoch( @@ -1407,20 +1407,20 @@ mod tests { .expect("should update contract"); let fetch_info_from_database = drive - .get_contract_with_fetch_info(contract.id().to_buffer(), None, None) + .get_contract_with_fetch_info(contract.id.to_buffer(), None, None) .expect("should get contract") .1 .expect("should be present"); - assert_eq!(fetch_info_from_database.contract.version(), 1); + assert_eq!(fetch_info_from_database.contract.version, 1); let fetch_info_from_cache = drive - .get_contract_with_fetch_info(contract.id().to_buffer(), None, Some(&transaction)) + .get_contract_with_fetch_info(contract.id.to_buffer(), None, Some(&transaction)) .expect("should get contract") .1 .expect("should be present"); - assert_eq!(fetch_info_from_cache.contract.version(), 2); + assert_eq!(fetch_info_from_cache.contract.version, 2); } #[test] @@ -1516,7 +1516,7 @@ mod tests { let mut deep_contract_fetch_info_transactional = drive .get_contract_with_fetch_info( - deep_contract.id().to_buffer(), + deep_contract.id.to_buffer(), Some(&Epoch::new(0)), Some(&transaction), ) @@ -1540,7 +1540,7 @@ mod tests { */ let deep_contract_fetch_info = drive - .get_contract_with_fetch_info(deep_contract.id().to_buffer(), None, None) + .get_contract_with_fetch_info(deep_contract.id.to_buffer(), None, None) .expect("got contract") .1 .expect("got contract fetch info"); @@ -1575,7 +1575,7 @@ mod tests { */ let deep_contract_fetch_info_without_cache = drive - .get_contract_with_fetch_info(deep_contract.id().to_buffer(), None, None) + .get_contract_with_fetch_info(deep_contract.id.to_buffer(), None, None) .expect("got contract") .1 .expect("got contract fetch info"); @@ -1642,7 +1642,7 @@ mod tests { let mut deep_contract_fetch_info_transactional2 = drive .get_contract_with_fetch_info( - deep_contract.id().to_buffer(), + deep_contract.id.to_buffer(), Some(&Epoch::new(0)), Some(&transaction), ) diff --git a/packages/rs-drive/src/drive/contract/paths.rs b/packages/rs-drive/src/drive/contract/paths.rs index a9a905281ae..8fc9a423980 100644 --- a/packages/rs-drive/src/drive/contract/paths.rs +++ b/packages/rs-drive/src/drive/contract/paths.rs @@ -24,14 +24,14 @@ impl ContractPaths for DataContract { fn root_path(&self) -> [&[u8]; 2] { [ Into::<&[u8; 1]>::into(RootTree::ContractDocuments), - self.id().as_bytes(), + self.id.as_bytes(), ] } fn documents_path(&self) -> [&[u8]; 3] { [ Into::<&[u8; 1]>::into(RootTree::ContractDocuments), - self.id().as_bytes(), + self.id.as_bytes(), &[1], ] } @@ -62,7 +62,7 @@ impl ContractPaths for DataContract { ) -> [&'a [u8]; 6] { [ Into::<&[u8; 1]>::into(RootTree::ContractDocuments), - self.id().as_bytes(), + self.id.as_bytes(), &[1], document_type_name.as_bytes(), &[0], diff --git a/packages/rs-drive/src/drive/document/estimation_costs.rs b/packages/rs-drive/src/drive/document/estimation_costs.rs index 32fe5a0ba7a..7ef0a0d59fe 100644 --- a/packages/rs-drive/src/drive/document/estimation_costs.rs +++ b/packages/rs-drive/src/drive/document/estimation_costs.rs @@ -93,7 +93,7 @@ impl Drive { ); let document_id_in_primary_path = contract_documents_keeping_history_primary_key_path_for_document_id( - contract.id().as_bytes(), + contract.id.as_bytes(), document_type.name.as_str(), document.id.as_slice(), ); diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 67002446944..edc2fc9e0f7 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -104,7 +104,7 @@ impl Drive { let contract = document_and_contract_info.contract; let document_type = document_and_contract_info.document_type; let primary_key_path = contract_documents_primary_key_path( - contract.id().as_bytes(), + contract.id.as_bytes(), document_type.name.as_str(), ); // if we are trying to get estimated costs we should add this level @@ -187,7 +187,7 @@ impl Drive { ); let document_id_in_primary_path = contract_documents_keeping_history_primary_key_path_for_document_id( - contract.id().as_bytes(), + contract.id.as_bytes(), document_type.name.as_str(), document.id.as_slice(), ); @@ -204,7 +204,7 @@ impl Drive { ); let document_id_in_primary_path = contract_documents_keeping_history_primary_key_path_for_document_id( - contract.id().as_bytes(), + contract.id.as_bytes(), document_type.name.as_str(), document.id.as_slice(), ); diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index 2d28c6f4bd0..ca9eef637f3 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -152,7 +152,7 @@ describe('Document', () => { ...data, }; - document = new Document(rawDocument, dataContract); + document = new DocumentInStateTranstion(rawDocument, dataContract); expect(document.getDataContractId().toBuffer()) .to.deep.equal(rawDocument.$dataContractId.toBuffer()); From 2d6ff0a217c001b00826ca3d788c5239d6d2a634 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Mon, 27 Feb 2023 14:12:43 +0000 Subject: [PATCH 015/228] test(wasm-dpp): use DocumentInStateTransition instead of Document --- .../document/document_in_state_transition.rs | 10 ++++---- packages/wasm-dpp/src/document/mod.rs | 10 ++++---- .../test/unit/document/Document.spec.js | 23 ++++++++++--------- .../unit/document/DocumentFactory.spec.js | 14 +++++------ .../DocumentsBatchTransition.spec.js | 6 ++--- 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/packages/wasm-dpp/src/document/document_in_state_transition.rs b/packages/wasm-dpp/src/document/document_in_state_transition.rs index cc64eb1064a..72a4eb412f0 100644 --- a/packages/wasm-dpp/src/document/document_in_state_transition.rs +++ b/packages/wasm-dpp/src/document/document_in_state_transition.rs @@ -106,13 +106,15 @@ impl DocumentInStateTransitionWasm { } #[wasm_bindgen(js_name=setRevision)] - pub fn set_revision(&mut self, rev: Revision) { - self.0.revision = rev + pub fn set_revision(&mut self, rev: u32) { + // TODO: js feeds Number (u32). Is casting revision to u64 safe? + self.0.revision = rev as Revision; } #[wasm_bindgen(js_name=getRevision)] - pub fn get_revision(&self) -> Revision { - self.0.revision + pub fn get_revision(&self) -> u32 { + // TODO: js expects Number (u32). Is casting revision to u32 safe? + self.0.revision as u32 } #[wasm_bindgen(js_name=setEntropy)] diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 80b6db91eb9..a77505a2494 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -111,13 +111,15 @@ impl DocumentWasm { } #[wasm_bindgen(js_name=setRevision)] - pub fn set_revision(&mut self, revision: Option) { - self.0.revision = revision + pub fn set_revision(&mut self, revision: Option) { + // TODO: JS feeding Number here (u32). Is it okay to cast u32 to u64? + self.0.revision = revision.map(|r| r as u64); } #[wasm_bindgen(js_name=getRevision)] - pub fn get_revision(&self) -> Option { - self.0.revision + pub fn get_revision(&self) -> Option { + // TODO: JS tests expecting Number (u32). Is it okay to cast u64 to u32 here? + self.0.revision.map(|r| r as u32) } #[wasm_bindgen(js_name=setProperties)] diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index ca9eef637f3..eff363bb4ed 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -15,8 +15,9 @@ const { default: loadWasmDpp } = require('../../../dist'); let DataContractFactory; let DataContractValidator; let Identifier; -let Document; +let DocumentInStateTransition; +// TODO: should be renamed to DocumentInStateTransition? describe('Document', () => { let rawDocument; let document; @@ -29,7 +30,7 @@ describe('Document', () => { // eslint-disable-next-line prefer-arrow-callback beforeEach(async function beforeEach() { ({ - Identifier, Document, DataContractFactory, DataContractValidator, + Identifier, DataContractFactory, DataContractValidator, DocumentInStateTransition, } = await loadWasmDpp()); const now = new Date().getTime(); @@ -100,7 +101,7 @@ describe('Document', () => { $updatedAt: now, }; - document = new Document(rawDocument, dataContract); + document = new DocumentInStateTransition(rawDocument, dataContract); rawDocumentJs = lodash.cloneDeepWith(rawDocument); rawDocumentJs.$id = jsId; rawDocumentJs.$ownerId = jsOwnerId; @@ -122,7 +123,7 @@ describe('Document', () => { ...data, }; - document = new Document(rawDocument, dataContract); + document = new DocumentInStateTransition(rawDocument, dataContract); expect(document.getId().toBuffer()).to.deep.equal(rawDocument.$id.toBuffer()); }); @@ -136,7 +137,7 @@ describe('Document', () => { ...data, }; - document = new Document(rawDocument, dataContract); + document = new DocumentCreateTransition(rawDocument, dataContract); expect(document.getType()).to.equal(rawDocument.$type); }); @@ -152,7 +153,7 @@ describe('Document', () => { ...data, }; - document = new DocumentInStateTranstion(rawDocument, dataContract); + document = new DocumentInStateTransition(rawDocument, dataContract); expect(document.getDataContractId().toBuffer()) .to.deep.equal(rawDocument.$dataContractId.toBuffer()); @@ -169,7 +170,7 @@ describe('Document', () => { ...data, }; - document = new Document(rawDocument, dataContract); + document = new DocumentInStateTransition(rawDocument, dataContract); expect(document.getOwnerId().toBuffer()).to.deep.equal(rawDocument.$ownerId.toBuffer()); }); @@ -184,7 +185,7 @@ describe('Document', () => { ...data, }; - document = new Document(rawDocument, dataContract); + document = new DocumentInStateTransition(rawDocument, dataContract); expect(document.get('action')).to.equal(undefined); }); @@ -199,7 +200,7 @@ describe('Document', () => { ...data, }; - document = new Document(rawDocument, dataContract); + document = new DocumentInStateTransition(rawDocument, dataContract); expect(document.getRevision()).to.equal(rawDocument.$revision); }); @@ -217,7 +218,7 @@ describe('Document', () => { ...data, }; - document = new Document(rawDocument, dataContract); + document = new DocumentInStateTransition(rawDocument, dataContract); expect(document.getCreatedAt()).to.equal(rawDocument.$createdAt); }); @@ -235,7 +236,7 @@ describe('Document', () => { ...data, }; - document = new Document(rawDocument, dataContract); + document = new DocumentInStateTransition(rawDocument, dataContract); expect(document.getUpdatedAt()).to.equal(rawDocument.$updatedAt); }); diff --git a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js index dc57d9f6b5f..34af16f82cc 100644 --- a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js @@ -29,7 +29,7 @@ const { default: loadWasmDpp } = require('../../../dist'); let Identifier; let DocumentFactory; let DataContract; -let Document; +let DocumentInStateTransition; let DocumentValidator; let ProtocolVersionValidator; @@ -66,7 +66,7 @@ describe('DocumentFactory', () => { beforeEach(async () => { ({ Identifier, ProtocolVersionValidator, DocumentValidator, DocumentFactory, - DataContract, Document, + DataContract, DocumentInStateTransition, // Errors: InvalidDocumentTypeInDataContractError, InvalidDocumentError, @@ -90,7 +90,7 @@ describe('DocumentFactory', () => { documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { - const doc = new Document(d.toObject(), dataContract); + const doc = new DocumentInStateTransition(d.toObject(), dataContract); doc.setEntropy(d.entropy); return doc; }); @@ -166,7 +166,7 @@ describe('DocumentFactory', () => { { name }, ); - expect(newDocument).to.be.an.instanceOf(Document); + expect(newDocument).to.be.an.instanceOf(DocumentInStateTransition); expect(newDocumentJs).to.be.an.instanceOf(DocumentJs); expect(newDocumentJs.getType()).to.equal(newRawDocument.$type); @@ -277,7 +277,7 @@ describe('DocumentFactory', () => { it('should return new Data Contract with data from passed object - Rust', async () => { const result = await factory.createFromObject(rawDocument); - expect(result).to.be.an.instanceOf(Document); + expect(result).to.be.an.instanceOf(DocumentInStateTransition); expect(result.toJSON()).to.deep.equal(document.toJSON()); expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnce(); @@ -305,7 +305,7 @@ describe('DocumentFactory', () => { it('should return new Document without validation if "skipValidation" option is passed - Rust', async () => { delete rawDocument.lastName; const result = await factory.createFromObject(rawDocument, { skipValidation: true }); - expect(result).to.be.an.instanceOf(Document); + expect(result).to.be.an.instanceOf(DocumentInStateTransition); expect(result.toObject()).to.deep.equal(rawDocument); expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnce(); @@ -589,7 +589,7 @@ describe('DocumentFactory', () => { it('should create DocumentsBatchTransition with passed documents - Rust', async () => { const [newDocumentJs] = getDocumentsFixture(dataContractJs); - const newDocument = new Document(newDocumentJs.toObject(), dataContract); + const newDocument = new DocumentInStateTransition(newDocumentJs.toObject(), dataContract); const stateTransitionJs = factoryJs.createStateTransition({ create: documentsJs, diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js index 20741755685..fbf3c23ada3 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js @@ -9,7 +9,7 @@ const newDocumentsContainer = require('../../../../../lib/test/utils/newDocument let DocumentFactory; let DataContract; -let Document; +let DocumentInStateTransition; let DocumentValidator; let ProtocolVersionValidator; @@ -25,7 +25,7 @@ describe('DocumentsBatchTransition', () => { beforeEach(async () => { ({ ProtocolVersionValidator, DocumentValidator, DocumentFactory, DataContract, - Document, + DocumentInStateTransition, } = await loadWasmDpp()); }); @@ -35,7 +35,7 @@ describe('DocumentsBatchTransition', () => { documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { - const doc = new Document(d.toObject(), dataContract); + const doc = new DocumentInStateTransition(d.toObject(), dataContract); doc.setEntropy(d.entropy); return doc; }); From 31a8440469ed533aabf583f2b65bd872b95a9719 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 28 Feb 2023 10:32:46 +0700 Subject: [PATCH 016/228] small fixes --- .../src/data_trigger/withdrawals_data_triggers/mod.rs | 2 +- .../rs-dpp/src/state_transition/state_transition_factory.rs | 4 ++-- .../validation/validate_state_transition_fee.rs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index dceda8ece14..f5abbbd1a62 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -126,7 +126,7 @@ mod tests { let data_contract = load_system_data_contract(data_contracts::SystemDataContract::Withdrawals) .expect("to load system data contract"); - let owner_id = data_contract.owner_id().clone(); + let owner_id = data_contract.owner_id.clone(); let document = get_withdrawal_document_fixture( &data_contract, diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 321d63b52df..236b420d4e8 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -151,7 +151,7 @@ mod test { let state_transition_data = json!( { "protocolVersion" : PROTOCOL_VERSION, - "entropy": data_contract.entropy(), + "entropy": data_contract.entropy, "dataContract": data_contract.to_object(false).unwrap(), } ); @@ -195,7 +195,7 @@ mod test { let state_transition_data = json!( { "protocolVersion" : PROTOCOL_VERSION, - "ownerId": data_contract.owner_id().as_bytes(), + "ownerId": data_contract.owner_id.as_bytes(), "transitions": raw_document_transitions, } ); diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs index 4d08a0db258..af8cf70e1da 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs @@ -260,7 +260,7 @@ mod test { get_documents_fixture_with_owner_id_from_contract(data_contract.clone()).unwrap(); let transitions = get_document_transitions_fixture([(Action::Create, documents)]); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id().clone(), + owner_id: data_contract.owner_id.clone(), transitions, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -296,7 +296,7 @@ mod test { get_documents_fixture_with_owner_id_from_contract(data_contract.clone()).unwrap(); let transitions = get_document_transitions_fixture([(Action::Create, documents)]); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id().clone(), + owner_id: data_contract.owner_id.clone(), transitions, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -328,7 +328,7 @@ mod test { execution_context.enable_dry_run(); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id().clone(), + owner_id: data_contract.owner_id.clone(), transitions, execution_context, ..Default::default() From ffa19a108706c61270e19a392bb4b4b64d557c2e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 28 Feb 2023 18:04:22 +0700 Subject: [PATCH 017/228] renamed to extended document --- .../src/data_trigger/dpns_triggers/mod.rs | 4 +-- .../reward_share_data_triggers/mod.rs | 4 +-- packages/rs-dpp/src/document/document.rs | 8 ++--- .../rs-dpp/src/document/document_factory.rs | 26 +++++++---------- packages/rs-dpp/src/document/errors.rs | 10 ++----- ...ate_transition.rs => extended_document.rs} | 29 +++++++++---------- .../fetch_and_validate_data_contract.rs | 2 +- packages/rs-dpp/src/document/mod.rs | 8 +++-- ...pply_documents_batch_transition_factory.rs | 6 ++-- .../document_transition/mod.rs | 1 - packages/rs-dpp/src/lib.rs | 2 +- packages/rs-dpp/src/state_repository.rs | 2 +- ...e_documents_batch_transition_state_spec.rs | 8 ++--- ...te_documents_uniqueness_by_indices_spec.rs | 4 +-- .../validate_partial_compound_indices_spec.rs | 4 +-- .../get_document_transitions_fixture.rs | 6 ++-- .../tests/fixtures/get_documents_fixture.rs | 6 ++-- .../fixtures/get_dpns_document_fixture.rs | 6 ++-- ...ternode_reward_shares_documents_fixture.rs | 5 ++-- packages/rs-drive-abci/src/state/genesis.rs | 4 +-- .../document/document_in_state_transition.rs | 16 +++++----- .../errors/mismatch_owners_ids_error.rs | 4 +-- packages/wasm-dpp/src/document/factory.rs | 7 ++--- .../document_batch_transition/mod.rs | 14 ++++----- 24 files changed, 84 insertions(+), 102 deletions(-) rename packages/rs-dpp/src/document/{state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs => extended_document.rs} (94%) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index dfe1cb58d36..219dc0562d2 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -2,7 +2,7 @@ use anyhow::Context; use anyhow::{anyhow, bail}; use serde_json::{json, Value as JsonValue}; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document, ExtendedDocument}; use crate::util::hash::hash; use crate::util::string_encoding::Encoding; use crate::{ @@ -132,7 +132,7 @@ where let parent_domain_label = parent_domain_segments.next().unwrap().to_string(); let grand_parent_domain_name = parent_domain_segments.collect::>().join("."); - let documents: Vec = context + let documents: Vec = context .state_repository .fetch_documents( &context.data_contract.id, diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index acdd26635ea..046e36c4b89 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -142,7 +142,7 @@ mod test { use serde_json::json; use std::convert::TryInto; - use crate::document::{Document, DocumentInStateTransition}; + use crate::document::{Document, ExtendedDocument}; use crate::identity::Identity; use crate::{ data_contract::DataContract, @@ -165,7 +165,7 @@ mod test { top_level_identifier: Identifier, data_contract: DataContract, sml_store: SMLStore, - documents_in_state_transitions: Vec, + documents_in_state_transitions: Vec, document_transition: DocumentTransition, identity: Identity, } diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index f9f19f8041e..814a5e1b73e 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -48,7 +48,7 @@ use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType} use crate::data_contract::errors::DataContractError; use crate::document::errors::DocumentError; -use crate::document::DocumentInStateTransition; +use crate::document::ExtendedDocument; use crate::identifier::Identifier; use crate::identity::TimestampMillis; use crate::prelude::Revision; @@ -354,11 +354,11 @@ impl fmt::Display for Document { } } -impl TryFrom for Document { +impl TryFrom for Document { type Error = ProtocolError; - fn try_from(value: DocumentInStateTransition) -> Result { - let DocumentInStateTransition { + fn try_from(value: ExtendedDocument) -> Result { + let ExtendedDocument { id, revision, owner_id, diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 0a40b0eab02..a31f5f6fc0d 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -8,9 +8,7 @@ use rand::SeedableRng; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; -use crate::document::document_transition::document_in_state_transition::{ - property_names, DocumentInStateTransition, -}; +use crate::document::extended_document::{property_names, ExtendedDocument}; use crate::{ data_contract::{errors::DataContractError, DataContract}, @@ -108,7 +106,7 @@ where owner_id: Identifier, document_type: String, data: JsonValue, - ) -> Result { + ) -> Result { if !data_contract.is_document_defined(&document_type) { return Err(DataContractError::InvalidDocumentTypeError { doc_type: document_type, @@ -166,8 +164,7 @@ where ))); } - let mut document = - DocumentInStateTransition::from_raw_document(raw_document, data_contract)?; + let mut document = ExtendedDocument::from_raw_document(raw_document, data_contract)?; document.entropy = document_entropy; Ok(document) @@ -175,12 +172,11 @@ where pub fn create_state_transition( &self, - documents_iter: impl IntoIterator)>, + documents_iter: impl IntoIterator)>, ) -> Result { let mut raw_documents_transitions: Vec = vec![]; let mut data_contracts: Vec = vec![]; - let documents: Vec<(Action, Vec)> = - documents_iter.into_iter().collect(); + let documents: Vec<(Action, Vec)> = documents_iter.into_iter().collect(); let flattened_documents_iter = documents.iter().flat_map(|(_, v)| v); if Self::is_empty(flattened_documents_iter.clone()) { @@ -231,7 +227,7 @@ where &self, buffer: impl AsRef<[u8]>, options: FactoryOptions, - ) -> Result { + ) -> Result { let result = DecodeProtocolEntity::decode_protocol_entity(buffer); match result { @@ -255,12 +251,12 @@ where &self, raw_document: JsonValue, options: FactoryOptions, - ) -> Result { + ) -> Result { let data_contract = self .validate_data_contract_for_document(&raw_document, options) .await?; - DocumentInStateTransition::from_raw_document(raw_document, data_contract) + ExtendedDocument::from_raw_document(raw_document, data_contract) } async fn validate_data_contract_for_document( @@ -303,7 +299,7 @@ where } fn raw_document_create_transitions( - documents: Vec, + documents: Vec, ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { @@ -335,7 +331,7 @@ where } fn raw_document_replace_transitions( - documents: Vec, + documents: Vec, ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { @@ -366,7 +362,7 @@ where } fn raw_document_delete_transitions( - documents: Vec, + documents: Vec, ) -> Result, ProtocolError> { Ok(documents .into_iter() diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index 43f5abc4caa..1cb6acfb83f 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -4,7 +4,7 @@ use thiserror::Error; use crate::errors::consensus::ConsensusError; use super::document_transition::DocumentTransition; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document, ExtendedDocument}; #[derive(Error, Debug)] pub enum DocumentError { @@ -28,14 +28,10 @@ pub enum DocumentError { raw_document: Value, }, #[error("Invalid Document initial revision '{}'", document.revision)] - InvalidInitialRevisionError { - document: Box, - }, + InvalidInitialRevisionError { document: Box }, #[error("Documents have mixed owner ids")] - MismatchOwnerIdsError { - documents: Vec, - }, + MismatchOwnerIdsError { documents: Vec }, #[error("No previous revision error")] DocumentNoRevisionError { document: Box }, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs b/packages/rs-dpp/src/document/extended_document.rs similarity index 94% rename from packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs rename to packages/rs-dpp/src/document/extended_document.rs index 543160189c3..56ab1c43277 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_in_state_transition.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -36,7 +36,7 @@ pub const IDENTIFIER_FIELDS: [&str; 3] = [ /// The document object represents the data provided by the platform in response to a query. #[derive(Serialize, Deserialize, Debug, Clone, Default)] -pub struct DocumentInStateTransition { +pub struct ExtendedDocument { #[serde(rename = "$protocolVersion")] pub protocol_version: u32, #[serde(rename = "$id")] @@ -64,7 +64,7 @@ pub struct DocumentInStateTransition { pub entropy: [u8; 32], } -impl DocumentInStateTransition { +impl ExtendedDocument { /// Creates a Document from the json form. Json format contains strings instead of /// arrays of u8 (bytes) pub fn from_json_document( @@ -268,9 +268,7 @@ mod test { use anyhow::Result; use serde_json::{json, Value}; - use crate::document::document_transition::document_in_state_transition::{ - DocumentInStateTransition, IDENTIFIER_FIELDS, - }; + use crate::document::extended_document::{ExtendedDocument, IDENTIFIER_FIELDS}; use crate::data_contract::DataContract; use crate::identifier::Identifier; @@ -314,7 +312,7 @@ mod test { fn test_document_deserialize() -> Result<()> { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - let doc = serde_json::from_str::(&document_json)?; + let doc = serde_json::from_str::(&document_json)?; assert_eq!(doc.document_type, "domain"); assert_eq!(doc.protocol_version, 0); assert_eq!( @@ -354,7 +352,7 @@ mod test { let init_doc = new_example_document(); let buffer_document = init_doc.to_buffer().expect("no errors"); - let doc = DocumentInStateTransition::from_buffer(buffer_document) + let doc = ExtendedDocument::from_buffer(buffer_document) .expect("document should be created from buffer"); assert_eq!(init_doc.created_at, doc.created_at); @@ -368,7 +366,7 @@ mod test { fn test_to_object() { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json").unwrap(); - let document = serde_json::from_str::(&document_json).unwrap(); + let document = serde_json::from_str::(&document_json).unwrap(); let document_object = document.to_object().unwrap(); for property in IDENTIFIER_FIELDS { @@ -386,7 +384,7 @@ mod test { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - let document = serde_json::from_str::(&document_json)?; + let document = serde_json::from_str::(&document_json)?; serde_json::to_string(&document)?; Ok(()) @@ -397,7 +395,7 @@ mod test { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - serde_json::from_str::(&document_json)?; + serde_json::from_str::(&document_json)?; Ok(()) } @@ -405,7 +403,7 @@ mod test { fn deserialize_js_cpp_cbor() -> Result<()> { let document_cbor = document_cbor_bytes(); - let document = DocumentInStateTransition::from_buffer(document_cbor)?; + let document = ExtendedDocument::from_buffer(document_cbor)?; assert_eq!(document.protocol_version, 1); assert_eq!( @@ -440,7 +438,7 @@ mod test { #[test] fn to_buffer_serialize_to_the_same_format_as_js_dpp() -> Result<()> { let document_cbor = document_cbor_bytes(); - let document = DocumentInStateTransition::from_buffer(&document_cbor)?; + let document = ExtendedDocument::from_buffer(&document_cbor)?; let buffer = document.to_buffer()?; @@ -467,8 +465,7 @@ mod test { "alphaIdentifier" : alpha_value, }); - let document = - DocumentInStateTransition::from_raw_document(raw_document, data_contract).unwrap(); + let document = ExtendedDocument::from_raw_document(raw_document, data_contract).unwrap(); let json_document = document.to_json().expect("no errors"); assert_eq!( @@ -497,8 +494,8 @@ mod test { hex::decode("01a7632469645820715d3d65756024a2de0ab1b2bb1e83b5ef297bf0c6fa616aad5c887e4f10def9646e616d656543757469656524747970656c6e696365446f63756d656e7468246f776e657249645820b6bf374d302fbe2b511b43e23d033f965e2e33a024c7419db07533d4ba7d708e69247265766973696f6e016a246372656174656441741b00000181b40fa1fb6f2464617461436f6e7472616374496458207abc5f9ab4bcd0612ed6cacec204dd6d7411a56127d4248af1eadacb93525da2").unwrap() } - fn new_example_document() -> DocumentInStateTransition { - DocumentInStateTransition { + fn new_example_document() -> ExtendedDocument { + ExtendedDocument { id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), owner_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), data_contract_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), diff --git a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs index 2b4cd4272c3..fe1f5d3b83a 100644 --- a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs +++ b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs @@ -13,7 +13,7 @@ use crate::{ ProtocolError, }; -use crate::document::document_transition::document_in_state_transition::property_names; +use crate::document::extended_document::property_names; pub struct DataContractFetcherAndValidator { state_repository: Arc, diff --git a/packages/rs-dpp/src/document/mod.rs b/packages/rs-dpp/src/document/mod.rs index bf6ec6208bc..b4e16d31715 100644 --- a/packages/rs-dpp/src/document/mod.rs +++ b/packages/rs-dpp/src/document/mod.rs @@ -7,11 +7,13 @@ mod document; pub mod document_factory; pub mod document_validator; pub mod errors; +pub mod extended_document; pub mod fetch_and_validate_data_contract; pub mod generate_document_id; pub mod serialize; pub mod state_transition; + pub use document::Document; -pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::DocumentInStateTransition; -pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::property_names as document_in_state_transition_property_names; -pub use state_transition::documents_batch_transition::document_transition::document_in_state_transition::IDENTIFIER_FIELDS as DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS; +pub use extended_document::property_names as extended_document_property_names; +pub use extended_document::ExtendedDocument; +pub use extended_document::IDENTIFIER_FIELDS as EXTENDED_DOCUMENT_IDENTIFIER_FIELDS; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 5c2dee7e4c9..6816c6407b0 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document, ExtendedDocument}; use crate::prelude::TimestampMillis; use crate::{ document::errors::DocumentError, prelude::Identifier, state_repository::StateRepositoryLike, @@ -110,9 +110,9 @@ fn document_from_transition_replace( document_replace_transition: &DocumentReplaceTransition, state_transition: &DocumentsBatchTransition, created_at: TimestampMillis, -) -> DocumentInStateTransition { +) -> ExtendedDocument { // TODO cloning is costly. Probably the [`Document`] should have properties of type `Cow<'a, K>` - DocumentInStateTransition { + ExtendedDocument { protocol_version: state_transition.protocol_version, id: document_replace_transition.base.id, document_type: document_replace_transition.base.document_type.clone(), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index 0c5178c09b5..e76e6e19a71 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -12,7 +12,6 @@ use document_base_transition::DocumentBaseTransition; pub mod document_base_transition; pub mod document_create_transition; pub mod document_delete_transition; -pub mod document_in_state_transition; pub mod document_replace_transition; use crate::identity::TimestampMillis; diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 8593348217d..859638efb8d 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -49,7 +49,7 @@ pub mod prelude { pub use crate::data_contract::DataContract; pub use crate::data_trigger::DataTrigger; pub use crate::document::document_transition::DocumentTransition; - pub use crate::document::DocumentInStateTransition; + pub use crate::document::ExtendedDocument; pub use crate::errors::ProtocolError; pub use crate::identifier::Identifier; pub use crate::identity::Identity; diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index ebc1483c0dd..fc529183229 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -55,7 +55,7 @@ pub trait StateRepositoryLike: Sync { ) -> AnyResult<()>; /// Fetch Documents by Data Contract Id and type - /// By default, the method should return data as bytes (`Vec`), but the deserialization to [`DocumentInStateTransition`] should be also possible + /// By default, the method should return data as bytes (`Vec`), but the deserialization to [`ExtendedDocument`] should be also possible async fn fetch_documents( &self, contract_id: &Identifier, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 57147115102..735bc2a17bd 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -25,14 +25,14 @@ use crate::{ utils::{generate_random_identifier_struct, new_block_header}, }, validation::ValidationResult, }; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document, ExtendedDocument}; use crate::identity::TimestampMillis; use crate::tests::fixtures::get_documents_in_state_transitions_fixture; struct TestData { owner_id: Identifier, data_contract: DataContract, - documents_in_state_transitions: Vec, + documents_in_state_transitions: Vec, document_transitions: Vec, state_transition: DocumentsBatchTransition, state_repository_mock: MockStateRepositoryLike, @@ -213,7 +213,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace .collect::, ProtocolError>>() .expect("expected to convert to documents"); - let mut replace_document = DocumentInStateTransition::from_raw_document( + let mut replace_document = ExtendedDocument::from_raw_document( documents_in_state_transitions[0].to_object().unwrap(), data_contract.clone(), ) @@ -272,7 +272,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace mut state_repository_mock, .. } = setup_test(); - let mut replace_document = DocumentInStateTransition::from_raw_document( + let mut replace_document = ExtendedDocument::from_raw_document( documents[0].to_object().unwrap(), data_contract.clone(), ) diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index a8a9f05849d..8f1b88dafbe 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -12,14 +12,14 @@ use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ }, utils::generate_random_identifier_struct, }, util::string_encoding::Encoding, validation::ValidationResult}; -use crate::document::{Document, DocumentInStateTransition}; +use crate::document::{Document, ExtendedDocument}; use crate::tests::fixtures::get_documents_in_state_transitions_fixture; struct TestData { owner_id: Identifier, data_contract: DataContract, documents: Vec, - documents_in_state_transitions: Vec, + documents_in_state_transitions: Vec, document_transitions: Vec, } diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 6262e72cec8..32aee188250 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -13,12 +13,12 @@ use crate::{ util::json_value::JsonValueExt, validation::ValidationResult, }; -use crate::document::DocumentInStateTransition; +use crate::document::ExtendedDocument; use crate::tests::fixtures::get_documents_in_state_transitions_fixture; struct TestData { data_contract: DataContract, - documents: Vec, + documents: Vec, } fn setup_test() -> TestData { diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index 00fc36932e5..eef8d036078 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::sync::Arc; use crate::document::fetch_and_validate_data_contract::DataContractFetcherAndValidator; -use crate::document::DocumentInStateTransition; +use crate::document::ExtendedDocument; use crate::document::{ document_factory::DocumentFactory, document_transition::{Action, DocumentTransition}, @@ -14,7 +14,7 @@ use crate::version::LATEST_VERSION; use super::{get_data_contract_fixture, get_document_validator_fixture}; pub fn get_document_transitions_fixture( - documents: impl IntoIterator)>, + documents: impl IntoIterator)>, ) -> Vec { let document_factory = DocumentFactory::new( LATEST_VERSION, @@ -23,7 +23,7 @@ pub fn get_document_transitions_fixture( None, ); - let mut documents_collected: HashMap> = + let mut documents_collected: HashMap> = documents.into_iter().collect(); let create_documents = documents_collected .remove(&Action::Create) diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 9e6fd52ddb2..f713ddfb5b3 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -24,7 +24,7 @@ use super::get_document_validator_fixture; pub fn get_documents_fixture_with_owner_id_from_contract( data_contract: DataContract, -) -> Result, ProtocolError> { +) -> Result, ProtocolError> { let data_contract_fetcher_and_validator = DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())); let factory = DocumentFactory::new( @@ -47,7 +47,7 @@ pub fn get_documents_fixture(data_contract: DataContract) -> Result Result, ProtocolError> { +) -> Result, ProtocolError> { let data_contract_fetcher_and_validator = DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())); let factory = DocumentFactory::new( @@ -65,7 +65,7 @@ fn get_documents_in_state_transitions( factory: DocumentFactory, data_contract: DataContract, owner_id: Identifier, -) -> Result, ProtocolError> { +) -> Result, ProtocolError> { let documents = vec![ factory.create_document_for_state_transition( data_contract.clone(), diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs index 5c7ec59e59d..9e9e14e1e39 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use getrandom::getrandom; use serde_json::json; -use crate::document::DocumentInStateTransition; +use crate::document::ExtendedDocument; use crate::{ document::{ document_factory::DocumentFactory, @@ -33,9 +33,7 @@ impl Default for ParentDocumentOptions { } } -pub fn get_dpns_parent_document_fixture( - options: ParentDocumentOptions, -) -> DocumentInStateTransition { +pub fn get_dpns_parent_document_fixture(options: ParentDocumentOptions) -> ExtendedDocument { let document_factory = DocumentFactory::new( LATEST_VERSION, get_document_validator_fixture(), diff --git a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs index 8ffd3dcc265..ded9ff2a7b2 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use data_contracts::SystemDataContract; use serde_json::json; -use crate::document::DocumentInStateTransition; +use crate::document::ExtendedDocument; use crate::system_data_contracts::load_system_data_contract; use crate::{ data_contract::DataContract, @@ -18,8 +18,7 @@ use crate::{ use super::get_document_validator_fixture; -pub fn get_masternode_reward_shares_documents_fixture( -) -> (Vec, DataContract) { +pub fn get_masternode_reward_shares_documents_fixture() -> (Vec, DataContract) { let owner_id = generate_random_identifier_struct(); let pay_to_id = generate_random_identifier_struct(); let data_contract = load_system_data_contract(SystemDataContract::MasternodeRewards) diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index b9747fd9f83..5ecb694932c 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -36,7 +36,7 @@ use dpp::ProtocolError; use drive::contract::DataContract; use drive::dpp::data_contract::DriveContractExt; use drive::dpp::document::Document; -use drive::dpp::document::DocumentInStateTransition; +use drive::dpp::document::ExtendedDocument; use drive::dpp::identity::{ Identity, IdentityPublicKey, KeyType, Purpose, SecurityLevel, TimestampMillis, }; @@ -206,7 +206,7 @@ impl Platform { // TODO: Add created and updated at to DPNS contract - let document = DocumentInStateTransition { + let document = ExtendedDocument { protocol_version: PROTOCOL_VERSION, id: Identifier::new(DPNS_DASH_TLD_DOCUMENT_ID), document_type: "domain".to_string(), diff --git a/packages/wasm-dpp/src/document/document_in_state_transition.rs b/packages/wasm-dpp/src/document/document_in_state_transition.rs index 72a4eb412f0..de22903a7aa 100644 --- a/packages/wasm-dpp/src/document/document_in_state_transition.rs +++ b/packages/wasm-dpp/src/document/document_in_state_transition.rs @@ -1,6 +1,6 @@ use dpp::dashcore::anyhow::Context; use dpp::document::{ - document_in_state_transition_property_names, DocumentInStateTransition, + document_in_state_transition_property_names, ExtendedDocument, DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS, }; use dpp::prelude::{Identifier, Revision}; @@ -23,7 +23,7 @@ use crate::{DataContractWasm, MetadataWasm}; #[wasm_bindgen(js_name=DocumentInStateTransition)] #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DocumentInStateTransitionWasm(pub(crate) DocumentInStateTransition); +pub struct DocumentInStateTransitionWasm(pub(crate) ExtendedDocument); #[wasm_bindgen(js_class=DocumentInStateTransition)] impl DocumentInStateTransitionWasm { @@ -56,11 +56,9 @@ impl DocumentInStateTransitionWasm { .with_js_error(); // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array - let document = DocumentInStateTransition::from_raw_document( - raw_document, - js_data_contract.to_owned().into(), - ) - .with_js_error()?; + let document = + ExtendedDocument::from_raw_document(raw_document, js_data_contract.to_owned().into()) + .with_js_error()?; Ok(document.into()) } @@ -333,8 +331,8 @@ impl DocumentInStateTransitionWasm { } } -impl From for DocumentInStateTransitionWasm { - fn from(d: DocumentInStateTransition) -> Self { +impl From for DocumentInStateTransitionWasm { + fn from(d: ExtendedDocument) -> Self { DocumentInStateTransitionWasm(d) } } diff --git a/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs b/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs index 41bde47f60a..ec509bf3688 100644 --- a/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs +++ b/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs @@ -1,5 +1,5 @@ use crate::DocumentInStateTransitionWasm; -use dpp::document::DocumentInStateTransition; +use dpp::document::ExtendedDocument; use itertools::Itertools; use thiserror::Error; @@ -28,7 +28,7 @@ impl MismatchOwnerIdsError { } impl MismatchOwnerIdsError { - pub fn from_documents(documents: Vec) -> MismatchOwnerIdsError { + pub fn from_documents(documents: Vec) -> MismatchOwnerIdsError { Self { documents: documents .into_iter() diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index c0eb8d6c729..4bd2b34391c 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use dpp::document::document_transition::document_in_state_transition; +use dpp::document::document_transition::extended_document; use dpp::{ document::{ document_factory::{DocumentFactory, FactoryOptions}, @@ -139,10 +139,7 @@ impl DocumentFactoryWASM { // When `Identifier` crosses the WASM boundary, it becomes a String. From perspective of JS // `Identifier` and `Buffer` are used interchangeably, so we we can expect the replacing may fail when `Buffer` is provided let _ = raw_document - .replace_identifier_paths( - document_in_state_transition::IDENTIFIER_FIELDS, - ReplaceWith::Bytes, - ) + .replace_identifier_paths(extended_document::IDENTIFIER_FIELDS, ReplaceWith::Bytes) .with_js_error(); let mut document = self diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index b5f6969702d..0d24696c430 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,4 +1,4 @@ -use dpp::document::DocumentInStateTransition; +use dpp::document::ExtendedDocument; use dpp::identity::KeyID; use dpp::{ document::{ @@ -35,9 +35,9 @@ pub struct DocumentsBatchTransitionWASM(DocumentsBatchTransition); #[derive(Debug, Default)] #[wasm_bindgen(js_name=DocumentsContainer)] pub struct DocumentsContainer { - create: Vec, - replace: Vec, - delete: Vec, + create: Vec, + replace: Vec, + delete: Vec, } #[derive(Debug, Serialize, Deserialize, Default, Clone, Copy)] @@ -79,15 +79,15 @@ impl DocumentsContainer { } impl DocumentsContainer { - pub fn take_documents_create(&mut self) -> Vec { + pub fn take_documents_create(&mut self) -> Vec { std::mem::take(&mut self.create) } - pub fn take_documents_replace(&mut self) -> Vec { + pub fn take_documents_replace(&mut self) -> Vec { std::mem::take(&mut self.replace) } - pub fn take_documents_delete(&mut self) -> Vec { + pub fn take_documents_delete(&mut self) -> Vec { std::mem::take(&mut self.delete) } } From abf4e809d022d31691a64d04332e8223814d8055 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 28 Feb 2023 19:32:45 +0700 Subject: [PATCH 018/228] more refactoring --- .../src/data_trigger/dpns_triggers/mod.rs | 9 +- .../reward_share_data_triggers/mod.rs | 13 +- packages/rs-dpp/src/document/document.rs | 27 +-- .../rs-dpp/src/document/document_factory.rs | 60 ++++--- .../rs-dpp/src/document/document_validator.rs | 6 +- packages/rs-dpp/src/document/errors.rs | 8 +- .../rs-dpp/src/document/extended_document.rs | 157 +++++++++++------- ...pply_documents_batch_transition_factory.rs | 29 ++-- .../documents_batch_transition/mod.rs | 6 +- packages/rs-dpp/src/state_repository.rs | 14 +- ...e_documents_batch_transition_state_spec.rs | 33 ++-- ...te_documents_uniqueness_by_indices_spec.rs | 114 ++++--------- .../validate_partial_compound_indices_spec.rs | 11 +- .../get_document_transitions_fixture.rs | 4 +- .../tests/fixtures/get_documents_fixture.rs | 12 +- packages/rs-drive-abci/src/state/genesis.rs | 2 +- .../src/btreemap_extensions.rs | 11 +- .../src/converter/serde_json.rs | 15 ++ .../document/document_in_state_transition.rs | 13 +- packages/wasm-dpp/src/document/factory.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 7 +- 21 files changed, 288 insertions(+), 265 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 219dc0562d2..b46a28661ca 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -1,5 +1,6 @@ use anyhow::Context; use anyhow::{anyhow, bail}; +use platform_value::btreemap_extensions::BTreeValueMapHelper; use serde_json::{json, Value as JsonValue}; use crate::document::{Document, ExtendedDocument}; @@ -132,7 +133,7 @@ where let parent_domain_label = parent_domain_segments.next().unwrap().to_string(); let grand_parent_domain_name = parent_domain_segments.collect::>().join("."); - let documents: Vec = context + let documents: Vec = context .state_repository .fetch_documents( &context.data_contract.id, @@ -169,10 +170,8 @@ where } if (!parent_domain - .data - .get_value(PROPERTY_ALLOW_SUBDOMAINS)? - .as_bool() - .unwrap()) + .properties + .get_bool(PROPERTY_ALLOW_SUBDOMAINS)?) && context.owner_id != &parent_domain.owner_id { let err = create_error( diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 046e36c4b89..b5ea4f6c090 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -165,7 +165,7 @@ mod test { top_level_identifier: Identifier, data_contract: DataContract, sml_store: SMLStore, - documents_in_state_transitions: Vec, + extended_documents: Vec, document_transition: DocumentTransition, identity: Identity, } @@ -209,7 +209,7 @@ mod test { get_document_transitions_fixture([(Action::Create, vec![documents[0].clone()])]); TestData { - documents_in_state_transitions: documents, + extended_documents: documents, data_contract, top_level_identifier, sml_store, @@ -239,19 +239,18 @@ mod test { async fn should_return_an_error_if_percentage_greater_than_1000() { let TestData { mut document_transition, - documents_in_state_transitions, + extended_documents, sml_store, data_contract, top_level_identifier, .. } = setup_test(); - let documents = documents_in_state_transitions + let documents: Vec = extended_documents .clone() .into_iter() - .map(|dt| dt.try_into()) - .collect::, ProtocolError>>() - .expect("expected to convert to documents"); + .map(|dt| dt.document) + .collect(); let mut state_repository_mock = MockStateRepositoryLike::new(); state_repository_mock diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 814a5e1b73e..759fee17e34 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -293,7 +293,7 @@ impl Document { Self::from_json_value::>(raw_document) } - fn from_json_value(mut document_value: JsonValue) -> Result + pub fn from_json_value(mut document_value: JsonValue) -> Result where for<'de> S: Deserialize<'de> + TryInto, { @@ -354,31 +354,6 @@ impl fmt::Display for Document { } } -impl TryFrom for Document { - type Error = ProtocolError; - - fn try_from(value: ExtendedDocument) -> Result { - let ExtendedDocument { - id, - revision, - owner_id, - created_at, - updated_at, - data, - .. - } = value; - let value: Value = data.into(); - Ok(Document { - id: id.buffer, - owner_id: owner_id.buffer, - properties: value.into_btree_map()?, - revision: Some(revision), - created_at, - updated_at, - }) - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index a31f5f6fc0d..7adc0c62ce9 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -184,7 +184,7 @@ where } let is_the_same = - Self::is_ownership_the_same(flattened_documents_iter.clone().map(|d| &d.owner_id)); + Self::is_ownership_the_same(flattened_documents_iter.clone().map(|d| &d.owner_id())); if !is_the_same { return Err(DocumentError::MismatchOwnerIdsError { documents: documents.into_iter().flat_map(|(_, v)| v).collect(), @@ -196,7 +196,7 @@ where .clone() .next() .unwrap() - .owner_id + .owner_id() .to_owned(); for (action, documents) in documents { data_contracts.extend(documents.iter().map(|d| d.data_contract.clone())); @@ -303,11 +303,18 @@ where ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { - if document.revision != document_transition::INITIAL_REVISION { - return Err(DocumentError::InvalidInitialRevisionError { - document: Box::new(document), + if document.needs_revision() { + let Some(revision) = document.revision() else { + return Err(DocumentError::RevisionAbsentError { + document: Box::new(document), + }.into()); + }; + if revision != &document_transition::INITIAL_REVISION { + return Err(DocumentError::InvalidInitialRevisionError { + document: Box::new(document), + } + .into()); } - .into()); } let mut raw_document = document.to_object()?; @@ -335,7 +342,17 @@ where ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { - let document_revision = document.revision; + if !document.can_be_modified() { + return Err(DocumentError::TryingToReplaceImmutableDocument { + document: Box::new(document), + } + .into()); + } + let Some(document_revision) = document.revision() else { + return Err(DocumentError::RevisionAbsentError { + document: Box::new(document), + }.into()); + }; let mut raw_document = document.to_object()?; if let Some(map) = raw_document.as_object_mut() { @@ -369,8 +386,8 @@ where .map(|document| { json!({ PROPERTY_ACTION: Action::Delete, - PROPERTY_ID: document.id.buffer, - PROPERTY_TYPE: document.document_type, + PROPERTY_ID: document.id().buffer, + PROPERTY_TYPE: document.document_type_name, PROPERTY_DATA_CONTRACT_ID: document.data_contract_id.buffer}) }) .collect()) @@ -389,7 +406,7 @@ where mod test { use std::sync::Arc; - use crate::tests::fixtures::get_documents_in_state_transitions_fixture; + use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ assert_error_contains, state_repository::MockStateRepositoryLike, @@ -435,16 +452,19 @@ mod test { json!({ "name": name }), ) .expect("document creation shouldn't fail"); - assert_eq!(document_type, document.document_type); + assert_eq!(document_type, document.document_type_name); assert_eq!( name, document.get("name").expect("property 'name' should exist") ); assert_eq!(contract_id, document.data_contract_id); - assert_eq!(owner_id, document.owner_id); - assert_eq!(document_transition::INITIAL_REVISION, document.revision); - assert!(!document.id.to_string(Encoding::Base58).is_empty()); - assert!(document.created_at.is_some()); + assert_eq!(owner_id, document.owner_id()); + assert_eq!( + document_transition::INITIAL_REVISION, + *document.revision().unwrap() + ); + assert!(!document.id().to_string(Encoding::Base58).is_empty()); + assert!(document.created_at().is_some()); } #[test] @@ -463,7 +483,7 @@ mod test { #[test] fn create_transition_mismatch_user_id() { let data_contract = get_data_contract_fixture(None); - let mut documents = get_documents_in_state_transitions_fixture(data_contract).unwrap(); + let mut documents = get_extended_documents_fixture(data_contract).unwrap(); let factory = DocumentFactory::new( 1, @@ -471,7 +491,7 @@ mod test { DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())), None, ); - documents[0].owner_id = generate_random_identifier_struct(); + documents[0].document.owner_id = generate_random_identifier_struct().buffer; let result = factory.create_state_transition(vec![(Action::Create, documents)]); assert_error_contains!(result, "Documents have mixed owner ids") @@ -480,8 +500,8 @@ mod test { #[test] fn create_transition_invalid_initial_revision() { let data_contract = get_data_contract_fixture(None); - let mut documents = get_documents_in_state_transitions_fixture(data_contract).unwrap(); - documents[0].revision = 3; + let mut documents = get_extended_documents_fixture(data_contract).unwrap(); + documents[0].document.revision = Some(3); let factory = DocumentFactory::new( 1, @@ -496,7 +516,7 @@ mod test { #[test] fn create_transitions_with_passed_documents() { let data_contract = get_data_contract_fixture(None); - let documents = get_documents_in_state_transitions_fixture(data_contract).unwrap(); + let documents = get_extended_documents_fixture(data_contract).unwrap(); let factory = DocumentFactory::new( 1, get_document_validator_fixture(), diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 85fe602b5b9..aa28c0a26ae 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -106,7 +106,7 @@ mod test { use serde_json::Value as JsonValue; use test_case::test_case; - use crate::tests::fixtures::get_documents_in_state_transitions_fixture; + use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ codes::ErrorWithCode, consensus::{basic::JsonSchemaError, ConsensusError}, @@ -127,7 +127,7 @@ mod test { fn get_test_data() -> TestData { let data_contract = get_data_contract_fixture(None); - let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); + let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); let raw_document = documents .iter() .map(|d| d.to_object()) @@ -473,7 +473,7 @@ mod test { .. } = get_test_data(); - let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); + let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); let document = documents.get(8).unwrap(); let data = [0u8; 32]; diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index 1cb6acfb83f..8655848e555 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -27,9 +27,15 @@ pub enum DocumentError { errors: Vec, raw_document: Value, }, - #[error("Invalid Document initial revision '{}'", document.revision)] + #[error("Invalid Document initial revision '{}'", document.revision().map(|r| *r).unwrap_or_default())] InvalidInitialRevisionError { document: Box }, + #[error("Revision absent on mutable document")] + RevisionAbsentError { document: Box }, + + #[error("Trying To Replace Immutable Document")] + TryingToReplaceImmutableDocument { document: Box }, + #[error("Documents have mixed owner ids")] MismatchOwnerIdsError { documents: Vec }, diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 56ab1c43277..5deac433765 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -1,4 +1,4 @@ -use crate::data_contract::DataContract; +use crate::data_contract::{DataContract, DriveContractExt}; use crate::identifier::Identifier; use crate::metadata::Metadata; use crate::prelude::{Revision, TimestampMillis}; @@ -12,9 +12,12 @@ use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; +use crate::data_contract::document_type::DocumentType; +use crate::document::Document; +use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use std::collections::HashSet; +use std::collections::{BTreeMap, HashSet}; use std::convert::TryInto; pub mod property_names { @@ -39,23 +42,12 @@ pub const IDENTIFIER_FIELDS: [&str; 3] = [ pub struct ExtendedDocument { #[serde(rename = "$protocolVersion")] pub protocol_version: u32, - #[serde(rename = "$id")] - pub id: Identifier, #[serde(rename = "$type")] - pub document_type: String, - #[serde(rename = "$revision")] - pub revision: Revision, + pub document_type_name: String, #[serde(rename = "$dataContractId")] pub data_contract_id: Identifier, - #[serde(rename = "$ownerId")] - pub owner_id: Identifier, - #[serde(rename = "$createdAt", skip_serializing_if = "Option::is_none")] - pub created_at: Option, - #[serde(rename = "$updatedAt", skip_serializing_if = "Option::is_none")] - pub updated_at: Option, - // the serde_json::Value preserves the order (see .toml file) #[serde(flatten)] - pub data: JsonValue, + pub document: Document, #[serde(skip)] pub data_contract: DataContract, #[serde(skip)] @@ -83,6 +75,60 @@ impl ExtendedDocument { Ok(document) } + fn properties_as_json_data(&self) -> Result { + self.document + .properties + .try_into() + .map_err(ProtocolError::ValueError) + } + + pub fn get_optional_value(&self, key: &str) -> Option<&Value> { + self.document.properties.get(key) + } + + pub fn properties(&self) -> &BTreeMap { + &self.document.properties + } + + pub fn properties_as_mut(&mut self) -> &mut BTreeMap { + &mut self.document.properties + } + + pub fn id(&self) -> Identifier { + Identifier::new(self.document.id) + } + + pub fn owner_id(&self) -> Identifier { + Identifier::new(self.document.owner_id) + } + + pub fn document_type(&self) -> &DocumentType { + // We can unwrap because the Document can not be created without a valid Document Type + self.data_contract + .document_type_for_name(self.document_type_name.as_str()) + .unwrap() + } + + pub fn can_be_modified(&self) -> bool { + self.document_type().documents_mutable + } + + pub fn needs_revision(&self) -> bool { + self.document_type().documents_mutable + } + + pub fn revision(&self) -> Option<&Revision> { + self.document.revision.as_ref() + } + + pub fn created_at(&self) -> Option<&TimestampMillis> { + self.document.created_at.as_ref() + } + + pub fn updated_at(&self) -> Option<&TimestampMillis> { + self.document.updated_at.as_ref() + } + pub fn from_raw_document( raw_document: JsonValue, data_contract: DataContract, @@ -97,41 +143,24 @@ impl ExtendedDocument { where for<'de> S: Deserialize<'de> + TryInto, { - let mut document = Self { + let mut extended_document = Self { data_contract, ..Default::default() }; if let Ok(value) = document_value.remove(property_names::PROTOCOL_VERSION) { - document.protocol_version = serde_json::from_value(value)? - } - if let Ok(value) = document_value.remove(property_names::ID) { - let data: S = serde_json::from_value(value)?; - document.id = data.try_into()?; + extended_document.protocol_version = serde_json::from_value(value)? } + if let Ok(value) = document_value.remove(property_names::DOCUMENT_TYPE) { - document.document_type = serde_json::from_value(value)? + extended_document.document_type_name = serde_json::from_value(value)? } if let Ok(value) = document_value.remove(property_names::DATA_CONTRACT_ID) { let data: S = serde_json::from_value(value)?; - document.data_contract_id = data.try_into()? + extended_document.data_contract_id = data.try_into()? } - if let Ok(value) = document_value.remove(property_names::OWNER_ID) { - let data: S = serde_json::from_value(value)?; - document.owner_id = data.try_into()? - } - if let Ok(value) = document_value.remove(property_names::REVISION) { - document.revision = serde_json::from_value(value)? - } - if let Ok(value) = document_value.remove(property_names::CREATED_AT) { - document.created_at = serde_json::from_value(value)? - } - if let Ok(value) = document_value.remove(property_names::UPDATED_AT) { - document.updated_at = serde_json::from_value(value)? - } - - document.data = document_value; - Ok(document) + extended_document.document = Document::from_json_value(document_value)?; + Ok(extended_document) } pub fn to_json(&self) -> Result { @@ -139,7 +168,7 @@ impl ExtendedDocument { let (identifier_paths, binary_paths) = self .data_contract - .get_identifiers_and_binary_paths(&self.document_type)?; + .get_identifiers_and_binary_paths(&self.document_type_name)?; value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; @@ -189,13 +218,13 @@ impl ExtendedDocument { canonical_map.remove(property_names::PROTOCOL_VERSION); - if self.updated_at.is_none() { + if self.updated_at().is_none() { canonical_map.remove(property_names::UPDATED_AT); } let (identifier_paths, binary_paths) = self .data_contract - .get_identifiers_and_binary_paths(&self.document_type)?; + .get_identifiers_and_binary_paths(&self.document_type_name)?; // The static (part of structure) identifiers are being serialized to the String(base58) canonical_map.replace_values(IDENTIFIER_FIELDS, ReplaceWith::Bytes); @@ -235,11 +264,6 @@ impl ExtendedDocument { } } - /// Get the Document's data - pub fn get_data(&self) -> &JsonValue { - &self.data - } - /// Set the Document's data pub fn set_data(&mut self, data: JsonValue) { self.data = data; @@ -255,7 +279,7 @@ impl ExtendedDocument { ) -> Result<(HashSet<&str>, HashSet<&str>), ProtocolError> { let (mut identifiers_paths, binary_paths) = self .data_contract - .get_identifiers_and_binary_paths(&self.document_type)?; + .get_identifiers_and_binary_paths(&self.document_type_name)?; identifiers_paths.extend(IDENTIFIER_FIELDS); @@ -271,9 +295,11 @@ mod test { use crate::document::extended_document::{ExtendedDocument, IDENTIFIER_FIELDS}; use crate::data_contract::DataContract; + use crate::document::Document; use crate::identifier::Identifier; use crate::tests::utils::*; use crate::util::string_encoding::Encoding; + use platform_value::btreemap_extensions::BTreeValueMapHelper; use pretty_assertions::assert_eq; fn init() { @@ -313,10 +339,10 @@ mod test { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; let doc = serde_json::from_str::(&document_json)?; - assert_eq!(doc.document_type, "domain"); + assert_eq!(doc.document_type_name, "domain"); assert_eq!(doc.protocol_version, 0); assert_eq!( - doc.id.to_buffer(), + doc.id().to_buffer(), Identifier::from_string( "4veLBZPHDkaCPF9LfZ8fX3JZiS5q5iUVGhdBbaa9ga5E", Encoding::Base58 @@ -355,11 +381,11 @@ mod test { let doc = ExtendedDocument::from_buffer(buffer_document) .expect("document should be created from buffer"); - assert_eq!(init_doc.created_at, doc.created_at); - assert_eq!(init_doc.updated_at, doc.updated_at); - assert_eq!(init_doc.id, doc.id); + assert_eq!(init_doc.created_at(), doc.created_at()); + assert_eq!(init_doc.updated_at(), doc.updated_at()); + assert_eq!(init_doc.id(), doc.id()); assert_eq!(init_doc.data_contract_id, doc.data_contract_id); - assert_eq!(init_doc.owner_id, doc.owner_id); + assert_eq!(init_doc.owner_id(), doc.owner_id()); } #[test] @@ -407,13 +433,13 @@ mod test { assert_eq!(document.protocol_version, 1); assert_eq!( - document.id.to_buffer().to_vec(), + document.id().to_buffer().to_vec(), vec![ 113, 93, 61, 101, 117, 96, 36, 162, 222, 10, 177, 178, 187, 30, 131, 181, 239, 41, 123, 240, 198, 250, 97, 106, 173, 92, 136, 126, 79, 16, 222, 249 ] ); - assert_eq!(&document.document_type, "niceDocument"); + assert_eq!(&document.document_type_name, "niceDocument"); assert_eq!( document.data_contract_id.to_buffer().to_vec(), vec![ @@ -422,15 +448,15 @@ mod test { ] ); assert_eq!( - document.owner_id.to_buffer().to_vec(), + document.owner_id().to_buffer().to_vec(), vec![ 182, 191, 55, 77, 48, 47, 190, 43, 81, 27, 67, 226, 61, 3, 63, 150, 94, 46, 51, 160, 36, 199, 65, 157, 176, 117, 51, 212, 186, 125, 112, 142 ] ); - assert_eq!(document.revision, 1); - assert_eq!(document.created_at.unwrap(), 1656583332347); - assert_eq!(document.data.get("name").unwrap(), "Cutie"); + assert_eq!(document.revision(), Some(&1)); + assert_eq!(document.created_at().unwrap(), 1656583332347); + assert_eq!(document.properties().get_string("name").unwrap(), "Cutie"); Ok(()) } @@ -496,11 +522,14 @@ mod test { fn new_example_document() -> ExtendedDocument { ExtendedDocument { - id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), - owner_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), + document: Document { + id: generate_random_identifier(), + owner_id: generate_random_identifier(), + created_at: Some(1648013404492), + updated_at: Some(1648013404492), + ..Default::default() + }, data_contract_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), - created_at: Some(1648013404492), - updated_at: Some(1648013404492), ..Default::default() } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 6816c6407b0..91c32552d78 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -114,18 +114,8 @@ fn document_from_transition_replace( // TODO cloning is costly. Probably the [`Document`] should have properties of type `Cow<'a, K>` ExtendedDocument { protocol_version: state_transition.protocol_version, - id: document_replace_transition.base.id, - document_type: document_replace_transition.base.document_type.clone(), + document_type_name: document_replace_transition.base.document_type.clone(), data_contract_id: document_replace_transition.base.data_contract_id, - owner_id: state_transition.owner_id, - data: document_replace_transition - .data - .as_ref() - .unwrap_or(&serde_json::Value::Null) - .clone(), - updated_at: document_replace_transition.updated_at, - revision: document_replace_transition.revision, - created_at: Some(created_at), metadata: None, //? In the JS implementation the `data_contract` and `entropy` properties are completely omitted, what suggest we should make @@ -133,6 +123,19 @@ fn document_from_transition_replace( //? Also, the `getEntropy()` in JS API always returns `Buffer` data_contract: Default::default(), entropy: Default::default(), + document: Document { + id: document_replace_transition.base.id.buffer, + owner_id: state_transition.owner_id.buffer, + properties: document_replace_transition + .data + .as_ref() + .unwrap_or(&serde_json::Value::Null) + .clone() + .into(), + revision: Some(document_replace_transition.revision), + created_at: Some(created_at), + updated_at: document_replace_transition.updated_at, + }, } } @@ -142,7 +145,7 @@ mod test { use serde_json::{json, Value}; use crate::document::Document; - use crate::tests::fixtures::get_documents_in_state_transitions_fixture; + use crate::tests::fixtures::get_extended_documents_fixture; use crate::tests::utils::new_block_header; use crate::{ document::{ @@ -165,7 +168,7 @@ mod test { let owner_id = generate_random_identifier_struct(); let data_contract = get_data_contract_fixture(None); - let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); + let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); let documents_transitions = get_document_transitions_fixture([ (Action::Replace, documents), (Action::Create, vec![]), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index d7d6db418d2..be611ddacc1 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -416,7 +416,7 @@ mod test { use serde_json::json; - use crate::tests::fixtures::get_documents_in_state_transitions_fixture; + use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ document::{ document_factory::DocumentFactory, @@ -456,7 +456,7 @@ mod test { // 0 is niceDocument, // 1 and 2 are pretty documents, // 3 and 4 are indexed documents that do not have security level specified - let documents = get_documents_in_state_transitions_fixture(data_contract).unwrap(); + let documents = get_extended_documents_fixture(data_contract).unwrap(); let medium_security_document = documents.get(0).unwrap(); let master_security_document = documents.get(1).unwrap(); let no_security_level_document = documents.get(3).unwrap(); @@ -527,7 +527,7 @@ mod test { let mut data_contract = get_data_contract_fixture(Some(owner_id)); data_contract.id = data_contract_id; - let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); + let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); let mut document = documents.first().unwrap().to_owned(); document.entropy = entropy_bytes; diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index fc529183229..932dd9a534d 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -55,7 +55,7 @@ pub trait StateRepositoryLike: Sync { ) -> AnyResult<()>; /// Fetch Documents by Data Contract Id and type - /// By default, the method should return data as bytes (`Vec`), but the deserialization to [`ExtendedDocument`] should be also possible + /// By default, the method should return data as bytes (`Vec`), but the deserialization to [`Document`] should be also possible async fn fetch_documents( &self, contract_id: &Identifier, @@ -66,6 +66,18 @@ pub trait StateRepositoryLike: Sync { where T: for<'de> serde::de::Deserialize<'de> + 'static; + /// Fetch Documents by Data Contract Id and type + /// By default, the method should return data as bytes (`Vec`), but the deserialization to [`ExtendedDocument`] should be also possible + async fn fetch_extended_documents( + &self, + contract_id: &Identifier, + data_contract_type: &str, + where_query: JsonValue, + execution_context: &StateTransitionExecutionContext, + ) -> AnyResult> + where + T: for<'de> serde::de::Deserialize<'de> + 'static; + /// Create Document async fn create_document( &self, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 735bc2a17bd..b94f21be45d 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -27,12 +27,12 @@ use crate::{ }; use crate::document::{Document, ExtendedDocument}; use crate::identity::TimestampMillis; -use crate::tests::fixtures::get_documents_in_state_transitions_fixture; +use crate::tests::fixtures::get_extended_documents_fixture; struct TestData { owner_id: Identifier, data_contract: DataContract, - documents_in_state_transitions: Vec, + extended_documents: Vec, document_transitions: Vec, state_transition: DocumentsBatchTransition, state_repository_mock: MockStateRepositoryLike, @@ -48,7 +48,7 @@ fn setup_test() -> TestData { init(); let owner_id = generate_random_identifier_struct(); let data_contract = get_data_contract_fixture(Some(owner_id)); - let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); + let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); let document_transitions = get_document_transitions_fixture([(Action::Create, documents.clone())]); @@ -84,7 +84,7 @@ fn setup_test() -> TestData { owner_id, data_contract, document_transitions, - documents_in_state_transitions: documents, + extended_documents: documents, state_transition, state_repository_mock, } @@ -154,7 +154,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_delete_ let TestData { data_contract, owner_id, - documents_in_state_transitions: documents, + extended_documents: documents, mut state_repository_mock, .. } = setup_test(); @@ -201,20 +201,19 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let TestData { data_contract, owner_id, - documents_in_state_transitions, + extended_documents, mut state_repository_mock, .. } = setup_test(); - let mut documents = documents_in_state_transitions + let mut documents = extended_documents .clone() .into_iter() - .map(|dt| dt.try_into()) - .collect::, ProtocolError>>() - .expect("expected to convert to documents"); + .map(|extended_document| extended_document.document) + .collect::>(); let mut replace_document = ExtendedDocument::from_raw_document( - documents_in_state_transitions[0].to_object().unwrap(), + extended_documents[0].to_object().unwrap(), data_contract.clone(), ) .expect("document should be created"); @@ -268,7 +267,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let TestData { data_contract, owner_id, - documents_in_state_transitions: documents, + extended_documents: documents, mut state_repository_mock, .. } = setup_test(); @@ -343,7 +342,7 @@ async fn should_return_invalid_result_if_timestamps_mismatch() { let TestData { data_contract, owner_id, - documents_in_state_transitions: documents, + extended_documents: documents, mut state_repository_mock, .. } = setup_test(); @@ -394,7 +393,7 @@ async fn should_return_invalid_result_if_crated_at_has_violated_time_window() { let TestData { data_contract, owner_id, - documents_in_state_transitions: documents, + extended_documents: documents, mut state_repository_mock, .. } = setup_test(); @@ -447,7 +446,7 @@ async fn should_not_validate_time_in_block_window_on_dry_run() { let TestData { data_contract, owner_id, - documents_in_state_transitions: documents, + extended_documents: documents, mut state_repository_mock, .. } = setup_test(); @@ -492,7 +491,7 @@ async fn should_return_invalid_result_if_updated_at_has_violated_time_window() { let TestData { data_contract, owner_id, - documents_in_state_transitions: documents, + extended_documents: documents, mut state_repository_mock, .. } = setup_test(); @@ -545,7 +544,7 @@ async fn should_return_valid_result_if_document_transitions_are_valid() { let TestData { data_contract, owner_id, - documents_in_state_transitions: documents, + extended_documents: documents, mut state_repository_mock, .. } = setup_test(); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 8f1b88dafbe..5fefff6d8ab 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -13,20 +13,20 @@ use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ utils::generate_random_identifier_struct, }, util::string_encoding::Encoding, validation::ValidationResult}; use crate::document::{Document, ExtendedDocument}; -use crate::tests::fixtures::get_documents_in_state_transitions_fixture; +use crate::tests::fixtures::get_extended_documents_fixture; struct TestData { owner_id: Identifier, data_contract: DataContract, documents: Vec, - documents_in_state_transitions: Vec, + extended_documents: Vec, document_transitions: Vec, } fn setup_test() -> TestData { let owner_id = generate_random_identifier_struct(); let data_contract = get_data_contract_fixture(Some(owner_id)); - let documents = get_documents_in_state_transitions_fixture(data_contract.clone()).unwrap(); + let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); TestData { owner_id, @@ -38,10 +38,9 @@ fn setup_test() -> TestData { documents: documents .clone() .into_iter() - .map(|d| d.try_into()) - .collect::, ProtocolError>>() - .expect("expected to get documents"), - documents_in_state_transitions: documents, + .map(|extended_document| extended_document.document) + .collect(), + extended_documents: documents, } } @@ -50,7 +49,7 @@ async fn should_return_valid_result_if_documents_have_no_unique_indices() { let TestData { owner_id, data_contract, - documents_in_state_transitions, + extended_documents, .. } = setup_test(); let mut state_repository_mock = MockStateRepositoryLike::default(); @@ -58,10 +57,8 @@ async fn should_return_valid_result_if_documents_have_no_unique_indices() { .expect_fetch_documents::() .returning(|_, _, _, _| Ok(vec![])); - let document_transitions = get_document_transitions_fixture([( - Action::Create, - vec![documents_in_state_transitions[0].clone()], - )]); + let document_transitions = + get_document_transitions_fixture([(Action::Create, vec![extended_documents[0].clone()])]); let validation_result = validate_documents_uniqueness_by_indices( &state_repository_mock, &owner_id, @@ -79,18 +76,15 @@ async fn should_return_valid_result_if_document_has_unique_indices_and_there_are let TestData { owner_id, data_contract, - documents_in_state_transitions, + extended_documents, .. } = setup_test(); - let william_doc = documents_in_state_transitions[3].clone(); + let william_doc = extended_documents[3].clone(); let owner_id_base58 = owner_id.to_string(Encoding::Base58); let mut state_repository_mock = MockStateRepositoryLike::default(); let document_transitions = get_document_transitions_fixture([(Action::Create, vec![william_doc.clone()])]); - let expect_document: Document = william_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = william_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() @@ -107,10 +101,7 @@ async fn should_return_valid_result_if_document_has_unique_indices_and_there_are ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document: Document = william_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = william_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -143,11 +134,11 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a let TestData { owner_id, data_contract, - documents_in_state_transitions, + extended_documents, .. } = setup_test(); - let william_doc = documents_in_state_transitions[3].clone(); - let leon_doc = documents_in_state_transitions[4].clone(); + let william_doc = extended_documents[3].clone(); + let leon_doc = extended_documents[4].clone(); let owner_id_base58 = owner_id.to_string(Encoding::Base58); let mut state_repository_mock = MockStateRepositoryLike::default(); let document_transitions = get_document_transitions_fixture([( @@ -155,10 +146,7 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a vec![william_doc.clone(), leon_doc.clone()], )]); - let expect_document: Document = leon_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = leon_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -174,10 +162,7 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document: Document = leon_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = leon_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -193,10 +178,7 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document: Document = william_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = william_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -212,10 +194,7 @@ async fn should_return_invalid_result_if_document_has_unique_indices_and_there_a ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document: Document = william_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = william_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -263,11 +242,11 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an let TestData { owner_id, data_contract, - documents_in_state_transitions, + extended_documents, .. } = setup_test(); - let william_doc = documents_in_state_transitions[3].clone(); - let leon_doc = documents_in_state_transitions[4].clone(); + let william_doc = extended_documents[3].clone(); + let leon_doc = extended_documents[4].clone(); let owner_id_base58 = owner_id.to_string(Encoding::Base58); let mut state_repository_mock = MockStateRepositoryLike::default(); let document_transitions = get_document_transitions_fixture([( @@ -275,10 +254,7 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an vec![william_doc.clone(), leon_doc.clone()], )]); - let expect_document: Document = leon_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = leon_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -294,10 +270,7 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document: Document = leon_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = leon_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -313,10 +286,7 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document: Document = william_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = william_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -332,10 +302,7 @@ async fn should_return_valid_result_in_dry_run_if_document_has_unique_indices_an ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document: Document = william_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = william_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -371,19 +338,16 @@ async fn should_return_valid_result_if_document_has_undefined_field_from_index() let TestData { owner_id, data_contract, - documents_in_state_transitions, + extended_documents, .. } = setup_test(); - let indexed_document = documents_in_state_transitions[7].clone(); + let indexed_document = extended_documents[7].clone(); let document_transitions = get_document_transitions_fixture([(Action::Create, vec![indexed_document.clone()])]); let owner_id_base58 = owner_id.to_string(Encoding::Base58); let mut state_repository_mock = MockStateRepositoryLike::default(); - let expect_document: Document = indexed_document - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = indexed_document.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -399,10 +363,7 @@ async fn should_return_valid_result_if_document_has_undefined_field_from_index() ) .returning(move |_, _, _, _| Ok(vec![expect_document.clone()])); - let expect_document: Document = indexed_document - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = indexed_document.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -436,18 +397,15 @@ async fn should_return_valid_result_if_document_being_created_and_has_created_at let TestData { owner_id, data_contract, - documents_in_state_transitions, + extended_documents, .. } = setup_test(); - let unique_dates_doc = documents_in_state_transitions[6].clone(); + let unique_dates_doc = extended_documents[6].clone(); let document_transitions = get_document_transitions_fixture([(Action::Create, vec![unique_dates_doc.clone()])]); let mut state_repository_mock = MockStateRepositoryLike::default(); - let expect_document: Document = unique_dates_doc - .to_owned() - .try_into() - .expect("expected to convert to document"); + let expect_document: Document = unique_dates_doc.to_owned().document; state_repository_mock .expect_fetch_documents::() .with( @@ -455,8 +413,8 @@ async fn should_return_valid_result_if_document_being_created_and_has_created_at predicate::eq("uniqueDates"), predicate::eq(json!({ "where" : [ - ["$createdAt", "==", unique_dates_doc.created_at.expect("createdAt should be present") ], - ["$updatedAt", "==", unique_dates_doc.created_at.expect("createdAt should be present") ], + ["$createdAt", "==", unique_dates_doc.created_at().expect("createdAt should be present") ], + ["$updatedAt", "==", unique_dates_doc.created_at().expect("createdAt should be present") ], ], })), predicate::always(), diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 32aee188250..dd3fddb3b7c 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -1,4 +1,5 @@ use serde_json::{json, Value as JsonValue}; +use std::collections::BTreeMap; use crate::{ consensus::{basic::BasicError, ConsensusError}, @@ -14,7 +15,7 @@ use crate::{ validation::ValidationResult, }; use crate::document::ExtendedDocument; -use crate::tests::fixtures::get_documents_in_state_transitions_fixture; +use crate::tests::fixtures::get_extended_documents_fixture; struct TestData { data_contract: DataContract, @@ -23,8 +24,8 @@ struct TestData { fn setup_test() -> TestData { let data_contract = get_data_contract_fixture(None); - let documents = get_documents_in_state_transitions_fixture(data_contract.clone()) - .expect("documents should be created"); + let documents = + get_extended_documents_fixture(data_contract.clone()).expect("documents should be created"); TestData { data_contract, @@ -40,7 +41,7 @@ fn should_return_invalid_result_if_compound_index_contains_not_all_fields() { } = setup_test(); let mut document = documents.remove(9); document - .data + .properties_as_mut() .remove("lastName") .expect("lastName property should exist and be removed"); @@ -75,7 +76,7 @@ fn should_return_valid_result_if_compound_index_contains_nof_fields() { mut documents, } = setup_test(); let mut document = documents.remove(8); - document.data = json!({}); + document.properties_as_mut() = *BTreeMap::new(); let documents_for_transition = vec![document]; let raw_document_transitions: Vec = diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index eef8d036078..c6ccfa85343 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -8,7 +8,7 @@ use crate::document::{ document_transition::{Action, DocumentTransition}, }; use crate::state_repository::MockStateRepositoryLike; -use crate::tests::fixtures::get_documents_in_state_transitions_fixture; +use crate::tests::fixtures::get_extended_documents_fixture; use crate::version::LATEST_VERSION; use super::{get_data_contract_fixture, get_document_validator_fixture}; @@ -28,7 +28,7 @@ pub fn get_document_transitions_fixture( let create_documents = documents_collected .remove(&Action::Create) .unwrap_or_else(|| { - get_documents_in_state_transitions_fixture(get_data_contract_fixture(None)).unwrap() + get_extended_documents_fixture(get_data_contract_fixture(None)).unwrap() }); let replace_documents = documents_collected .remove(&Action::Replace) diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index f713ddfb5b3..7862fa315e1 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -35,17 +35,17 @@ pub fn get_documents_fixture_with_owner_id_from_contract( ); let owner_id = data_contract.owner_id.clone(); - get_documents_in_state_transitions(factory, data_contract, owner_id) + get_extended_documents(factory, data_contract, owner_id) } pub fn get_documents_fixture(data_contract: DataContract) -> Result, ProtocolError> { - get_documents_in_state_transitions_fixture(data_contract)? + get_extended_documents_fixture(data_contract)? .into_iter() - .map(|dt| dt.try_into()) + .map(|extended_document| extended_document.document) .collect() } -pub fn get_documents_in_state_transitions_fixture( +pub fn get_extended_documents_fixture( data_contract: DataContract, ) -> Result, ProtocolError> { let data_contract_fetcher_and_validator = @@ -58,10 +58,10 @@ pub fn get_documents_in_state_transitions_fixture( ); let owner_id = gen_owner_id(); - get_documents_in_state_transitions(factory, data_contract, owner_id) + get_extended_documents(factory, data_contract, owner_id) } -fn get_documents_in_state_transitions( +fn get_extended_documents( factory: DocumentFactory, data_contract: DataContract, owner_id: Identifier, diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 5ecb694932c..d4ed284e385 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -209,7 +209,7 @@ impl Platform { let document = ExtendedDocument { protocol_version: PROTOCOL_VERSION, id: Identifier::new(DPNS_DASH_TLD_DOCUMENT_ID), - document_type: "domain".to_string(), + document_type_name: "domain".to_string(), revision: 0, data_contract_id: contract.id, owner_id: contract.owner_id, diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index b8c57295885..f8f1c42ed57 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -1,4 +1,4 @@ -use serde_json::Value as JsonValue; +use serde_json::{Map, Value as JsonValue}; use std::borrow::Borrow; use std::convert::TryFrom; use std::iter::FromIterator; @@ -115,6 +115,7 @@ pub trait BTreeValueMapHelper { fn remove_system_bytes(&mut self, key: &str) -> Result, Error>; fn get_optional_bytes(&self, key: &str) -> Result>, Error>; fn get_bytes(&self, key: &str) -> Result, Error>; + fn to_json_value(&self) -> Result; } impl BTreeValueMapHelper for BTreeMap @@ -504,4 +505,12 @@ where self.get_optional_float(key)? .ok_or_else(|| Error::StructureError(format!("unable to get float property {key}"))) } + + fn to_json_value(&self) -> Result { + Ok(JsonValue::Object( + self.iter() + .map(|(key, value)| Ok((key.to_string(), value.borrow().clone().try_into()?))) + .collect::, Error>>()?, + )) + } } diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 58e4d6a0b4e..aa4820ac5a0 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -1,5 +1,6 @@ use crate::{Error, Value}; use serde_json::{Map, Number, Value as JsonValue}; +use std::collections::BTreeMap; impl Value { pub fn convert_from_serde_json_map(map: I) -> R @@ -89,3 +90,17 @@ impl TryInto for Value { }) } } + +pub trait BTreeValueJsonConverter { + fn into_json_value(self) -> Result; +} + +impl BTreeValueJsonConverter for BTreeMap { + fn into_json_value(self) -> Result { + Ok(JsonValue::Object( + self.into_iter() + .map(|(key, value)| Ok((key, value.try_into()?))) + .collect::, Error>>()?, + )) + } +} diff --git a/packages/wasm-dpp/src/document/document_in_state_transition.rs b/packages/wasm-dpp/src/document/document_in_state_transition.rs index de22903a7aa..f1bb2fae6a3 100644 --- a/packages/wasm-dpp/src/document/document_in_state_transition.rs +++ b/packages/wasm-dpp/src/document/document_in_state_transition.rs @@ -1,7 +1,6 @@ use dpp::dashcore::anyhow::Context; use dpp::document::{ - document_in_state_transition_property_names, ExtendedDocument, - DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS, + extended_document_property_names, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, }; use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; @@ -35,7 +34,7 @@ impl DocumentInStateTransitionWasm { let mut raw_document = with_serde_to_json_value(&js_raw_document)?; let document_type = raw_document - .get_string(document_in_state_transition_property_names::DOCUMENT_TYPE) + .get_string(extended_document_property_names::DOCUMENT_TYPE) .with_js_error()?; let (identifier_paths, _) = js_data_contract @@ -50,7 +49,7 @@ impl DocumentInStateTransitionWasm { .replace_identifier_paths( identifier_paths .into_iter() - .chain(DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS), + .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS), ReplaceWith::Bytes, ) .with_js_error(); @@ -80,7 +79,7 @@ impl DocumentInStateTransitionWasm { #[wasm_bindgen(js_name=getType)] pub fn get_type(&self) -> String { - self.0.document_type.clone() + self.0.document_type_name.clone() } #[wasm_bindgen(js_name=getDataContractId)] @@ -262,7 +261,7 @@ impl DocumentInStateTransitionWasm { for path in identifiers_paths .into_iter() - .chain(DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS) + .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS) { if let Ok(bytes) = value.remove_path_into::>(path) { if !options.skip_identifiers_conversion { @@ -317,7 +316,7 @@ impl DocumentInStateTransitionWasm { let maybe_binary_properties = self .0 .data_contract - .get_binary_properties(&self.0.document_type); + .get_binary_properties(&self.0.document_type_name); if let Ok(binary_properties) = maybe_binary_properties { if let Some(data) = binary_properties.get(path) { diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 4bd2b34391c..3b7077aa250 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -1,10 +1,10 @@ use std::sync::Arc; -use dpp::document::document_transition::extended_document; use dpp::{ document::{ document_factory::{DocumentFactory, FactoryOptions}, document_transition::Action, + extended_document, fetch_and_validate_data_contract::DataContractFetcherAndValidator, }, util::json_value::{JsonValueExt, ReplaceWith}, diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index a77505a2494..fd56cce0b2f 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -27,8 +27,7 @@ pub use document_batch_transition::{DocumentsBatchTransitionWASM, DocumentsConta pub use document_in_state_transition::DocumentInStateTransitionWasm; use dpp::data_contract::DriveContractExt; use dpp::document::{ - document_in_state_transition_property_names, Document, - DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS, + extended_document_property_names, Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, }; use dpp::identity::TimestampMillis; @@ -64,7 +63,7 @@ impl DocumentWasm { let mut raw_document = with_serde_to_json_value(&js_raw_document)?; let document_type = raw_document - .get_string(document_in_state_transition_property_names::DOCUMENT_TYPE) + .get_string(extended_document_property_names::DOCUMENT_TYPE) .with_js_error()?; let (identifier_paths, _) = js_data_contract @@ -79,7 +78,7 @@ impl DocumentWasm { .replace_identifier_paths( identifier_paths .into_iter() - .chain(DOCUMENT_IN_STATE_TRANSITION_IDENTIFIER_FIELDS), + .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS), ReplaceWith::Bytes, ) .with_js_error(); From 927a66029f0a5ebf2468618551e1e99887db84f8 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 28 Feb 2023 22:43:02 +0700 Subject: [PATCH 019/228] added path searching --- .../document/DocumentRepository.spec.js | 14 +- .../src/data_contract/errors/structure.rs | 2 +- .../src/btreemap_extensions.rs | 7 +- .../src/btreemap_path_extensions.rs | 583 ++++++++++++++++++ packages/rs-platform-value/src/error.rs | 5 +- packages/rs-platform-value/src/lib.rs | 3 +- packages/rs-platform-value/src/value_map.rs | 41 +- 7 files changed, 639 insertions(+), 16 deletions(-) create mode 100644 packages/rs-platform-value/src/btreemap_path_extensions.rs diff --git a/packages/js-drive/test/integration/document/DocumentRepository.spec.js b/packages/js-drive/test/integration/document/DocumentRepository.spec.js index 0f0f3056a87..fefad588c89 100644 --- a/packages/js-drive/test/integration/document/DocumentRepository.spec.js +++ b/packages/js-drive/test/integration/document/DocumentRepository.spec.js @@ -1511,7 +1511,7 @@ describe('DocumentRepository', function main() { expect.fail('should throw an error'); } catch (e) { expect(e).to.be.instanceOf(InvalidQueryError); - expect(e.message).to.equal('value error: structure Error: value is not a float'); + expect(e.message).to.equal('value error: structure error: value is not a float'); } }); }); @@ -1851,7 +1851,7 @@ describe('DocumentRepository', function main() { expect.fail('should throw an error'); } catch (e) { - expect(e.message).to.equal('value error: structure Error: value is not a float'); + expect(e.message).to.equal('value error: structure error: value is not a float'); expect(e).to.be.instanceOf(InvalidQueryError); } }); @@ -1866,7 +1866,7 @@ describe('DocumentRepository', function main() { } catch (e) { expect(e).to.be.instanceOf(InvalidQueryError); expect(e.message).to.equal( - 'value error: structure Error: value is not a float', + 'value error: structure error: value is not a float', ); } }); @@ -1984,7 +1984,7 @@ describe('DocumentRepository', function main() { expect.fail('should throw an error'); } catch (e) { expect(e).to.be.instanceOf(InvalidQueryError); - expect(e.message).to.equal('value error: structure Error: value is not a float'); + expect(e.message).to.equal('value error: structure error: value is not a float'); } }); }); @@ -2607,7 +2607,7 @@ describe('DocumentRepository', function main() { expect.fail('should throw an error'); } catch (e) { expect(e).to.be.instanceOf(InvalidQueryError); - expect(e.message).to.equal('value error: structure Error: value is not an integer'); + expect(e.message).to.equal('value error: structure error: value is not an integer'); } }); @@ -2625,7 +2625,7 @@ describe('DocumentRepository', function main() { expect.fail('should throw an error'); } catch (e) { expect(e).to.be.instanceOf(InvalidQueryError); - expect(e.message).to.equal('value error: structure Error: value is not an integer'); + expect(e.message).to.equal('value error: structure error: value is not an integer'); } }); }); @@ -2799,7 +2799,7 @@ describe('DocumentRepository', function main() { expect.fail('should throw an error'); } catch (e) { expect(e).to.be.instanceOf(InvalidQueryError); - expect(e.message).to.equal('value error: structure Error: value are not bytes, a string, or an array of values representing bytes'); + expect(e.message).to.equal('value error: structure error: value are not bytes, a string, or an array of values representing bytes'); } }); }); diff --git a/packages/rs-dpp/src/data_contract/errors/structure.rs b/packages/rs-dpp/src/data_contract/errors/structure.rs index 8b39ee64125..4b12a165acd 100644 --- a/packages/rs-dpp/src/data_contract/errors/structure.rs +++ b/packages/rs-dpp/src/data_contract/errors/structure.rs @@ -1,4 +1,4 @@ -/// Structure errors +/// structure errors #[derive(Debug, thiserror::Error)] pub enum StructureError { /// Invalid protocol version error diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index f8f1c42ed57..526bb99c0c8 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -4,7 +4,7 @@ use std::convert::TryFrom; use std::iter::FromIterator; use std::{collections::BTreeMap, convert::TryInto}; -use crate::{Error, Value}; +use crate::{Error, Value, ValueMap}; pub trait BTreeValueMapHelper { fn get_optional_identifier(&self, key: &str) -> Result, Error>; @@ -322,10 +322,7 @@ where }) } - fn get_optional_inner_borrowed_map( - &self, - key: &str, - ) -> Result>, Error> { + fn get_optional_inner_borrowed_map(&self, key: &str) -> Result, Error> { self.get(key) .map(|v| { v.borrow() diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_path_extensions.rs new file mode 100644 index 00000000000..5f7c4c1ea60 --- /dev/null +++ b/packages/rs-platform-value/src/btreemap_path_extensions.rs @@ -0,0 +1,583 @@ +use serde_json::{Map, Value as JsonValue}; +use std::borrow::Borrow; +use std::convert::TryFrom; +use std::iter::FromIterator; +use std::path::Path; +use std::{collections::BTreeMap, convert::TryInto}; + +use crate::btreemap_extensions::BTreeValueMapHelper; +use crate::value_map::ValueMapHelper; +use crate::{Error, Value}; + +pub trait BTreeValueMapPathHelper { + fn get_at_path(&self, path: &str) -> Result<&Value, Error>; + fn get_optional_at_path(&self, path: &str) -> Result, Error>; + fn get_optional_identifier_at_path(&self, path: &str) -> Result, Error>; + fn get_identifier_at_path(&self, path: &str) -> Result<[u8; 32], Error>; + fn get_optional_string_at_path(&self, path: &str) -> Result, Error>; + fn get_string_at_path(&self, path: &str) -> Result; + fn get_optional_str_at_path(&self, path: &str) -> Result, Error>; + fn get_str_at_path(&self, path: &str) -> Result<&str, Error>; + fn get_optional_float_at_path(&self, path: &str) -> Result, Error>; + fn get_float_at_path(&self, path: &str) -> Result; + fn get_optional_integer_at_path(&self, path: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom; + fn get_integer_at_path(&self, path: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom; + fn get_optional_bool_at_path(&self, path: &str) -> Result, Error>; + fn get_bool_at_path(&self, path: &str) -> Result; + fn get_optional_inner_value_array_at_path<'a, I: FromIterator<&'a Value>>( + &'a self, + path: &str, + ) -> Result, Error>; + fn get_inner_value_array_at_path<'a, I: FromIterator<&'a Value>>( + &'a self, + path: &str, + ) -> Result; + fn get_optional_inner_string_array_at_path>( + &self, + path: &str, + ) -> Result, Error>; + fn get_inner_string_array_at_path>( + &self, + path: &str, + ) -> Result; + fn get_optional_inner_borrowed_map_at_path( + &self, + path: &str, + ) -> Result>, Error>; + fn get_optional_inner_borrowed_str_value_map_at_path<'a, I: FromIterator<(String, &'a Value)>>( + &'a self, + path: &str, + ) -> Result, Error>; + fn get_inner_borrowed_str_value_map_at_path<'a, I: FromIterator<(String, &'a Value)>>( + &'a self, + path: &str, + ) -> Result; + fn get_optional_inner_str_json_value_map_at_path>( + &self, + path: &str, + ) -> Result, Error>; + fn get_inner_str_json_value_map_at_path>( + &self, + path: &str, + ) -> Result; + fn get_optional_system_hash256_bytes_at_path( + &self, + path: &str, + ) -> Result, Error>; + fn get_system_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error>; + fn get_optional_system_bytes_at_path(&self, path: &str) -> Result>, Error>; + fn get_system_bytes_at_path(&self, path: &str) -> Result, Error>; + fn remove_optional_string_at_path(&mut self, path: &str) -> Result, Error>; + fn remove_string_at_path(&mut self, path: &str) -> Result; + fn remove_optional_float_at_path(&mut self, path: &str) -> Result, Error>; + fn remove_float_at_path(&mut self, path: &str) -> Result; + fn remove_optional_integer_at_path(&mut self, path: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom; + fn remove_integer_at_path(&mut self, path: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom; + fn remove_optional_system_hash256_bytes_at_path( + &mut self, + path: &str, + ) -> Result, Error>; + fn remove_system_hash256_bytes_at_path(&mut self, path: &str) -> Result<[u8; 32], Error>; + fn remove_optional_system_bytes_at_path( + &mut self, + path: &str, + ) -> Result>, Error>; + fn remove_system_bytes_at_path(&mut self, path: &str) -> Result, Error>; + fn get_optional_bytes_at_path(&self, path: &str) -> Result>, Error>; + fn get_bytes_at_path(&self, path: &str) -> Result, Error>; +} + +impl BTreeValueMapPathHelper for BTreeMap +where + V: Borrow, +{ + fn get_at_path(&self, path: &str) -> Result<&Value, Error> { + let mut split = path.split("."); + let first = split.next(); + let Some(first_path_component) = first else { + return Err(Error::PathError("path was empty".to_string())); + }; + let mut current_value = self + .get(first_path_component) + .ok_or_else(|| { + Error::StructureError(format!( + "unable to get property {first_path_component} in {path}" + )) + })? + .borrow(); + while let Some(path_component) = split.next() { + let map = current_value.to_map_ref()?; + current_value = map.get_key(path_component).ok_or_else(|| { + Error::StructureError(format!("unable to get property {path_component} in {path}")) + })?; + } + Ok(current_value) + } + + fn get_optional_at_path(&self, path: &str) -> Result, Error> { + let mut split = path.split("."); + let first = split.next(); + let Some(first_path_component) = first else { + return Err(Error::PathError("path was empty".to_string())); + }; + let Some(mut current_value) = self.get(first_path_component).map(|v| v.borrow()) else { + return Ok(None); + }; + while let Some(path_component) = split.next() { + let map = current_value.to_map_ref()?; + let Some(new_value) = map.get_key(path_component) else { + return Ok(None); + }; + current_value = new_value; + } + Ok(Some(current_value)) + } + + fn get_optional_identifier_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_at_path(path)? + .map(|v| v.borrow().to_system_hash256()) + .transpose() + } + + fn get_identifier_at_path(&self, path: &str) -> Result<[u8; 32], Error> { + self.get_optional_identifier_at_path(path)?.ok_or_else(|| { + Error::StructureError(format!("unable to get identifier property {path}")) + }) + } + + fn get_optional_string_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_at_path(path)? + .map(|v| { + v.borrow() + .as_text() + .map(|str| str.to_string()) + .ok_or_else(|| Error::StructureError(format!("{path} must be a string"))) + }) + .transpose() + } + + fn get_string_at_path(&self, path: &str) -> Result { + self.get_optional_string_at_path(path)? + .ok_or_else(|| Error::StructureError(format!("unable to get string property {path}"))) + } + + fn get_optional_str_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_at_path(path)? + .map(|v| { + v.borrow() + .as_text() + .ok_or_else(|| Error::StructureError(format!("{path} must be a string"))) + }) + .transpose() + } + + fn get_str_at_path(&self, path: &str) -> Result<&str, Error> { + self.get_optional_str_at_path(path)? + .ok_or_else(|| Error::StructureError(format!("unable to get str property {path}"))) + } + + fn get_optional_integer_at_path(&self, path: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + self.get_optional_at_path(path)? + .and_then(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_integer()) + } + }) + .transpose() + } + + fn get_integer_at_path(&self, path: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + self.get_optional_integer_at_path(path)? + .ok_or_else(|| Error::StructureError(format!("unable to get integer property {path}"))) + } + + fn remove_optional_integer_at_path(&mut self, path: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + self.remove(path) + .and_then(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_integer()) + } + }) + .transpose() + } + + fn remove_integer_at_path(&mut self, path: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + self.remove_optional_integer_at_path(path)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove integer property {path}")) + }) + } + + fn get_optional_bool_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_at_path(path)? + .and_then(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_bool()) + } + }) + .transpose() + } + + fn get_bool_at_path(&self, path: &str) -> Result { + self.get_optional_bool_at_path(path)? + .ok_or_else(|| Error::StructureError(format!("unable to get bool property {path}"))) + } + + fn get_optional_inner_value_array_at_path<'a, I: FromIterator<&'a Value>>( + &'a self, + path: &str, + ) -> Result, Error> { + self.get_optional_at_path(path)? + .map(|v| { + v.borrow() + .as_array() + .map(|vec| vec.iter().collect()) + .ok_or_else(|| Error::StructureError(format!("{path} must be a bool"))) + }) + .transpose() + } + + fn get_inner_value_array_at_path<'a, I: FromIterator<&'a Value>>( + &'a self, + path: &str, + ) -> Result { + self.get_optional_inner_value_array_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!("unable to get inner value array property {path}")) + }) + } + + fn get_optional_inner_string_array_at_path>( + &self, + path: &str, + ) -> Result, Error> { + self.get_optional_at_path(path)? + .map(|v| { + v.borrow() + .as_array() + .map(|inner| { + inner + .iter() + .map(|v| { + let Some(str) = v.as_text() else { + return Err(Error::StructureError(format!("{path} must be an string"))) + }; + Ok(str.to_string()) + }) + .collect::>() + }) + .transpose()? + .ok_or_else(|| Error::StructureError(format!("{path} must be a bool"))) + }) + .transpose() + } + + fn get_inner_string_array_at_path>( + &self, + path: &str, + ) -> Result { + self.get_optional_inner_string_array_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!("unable to get inner string property {path}")) + }) + } + + fn get_optional_inner_borrowed_map_at_path( + &self, + path: &str, + ) -> Result>, Error> { + self.get_optional_at_path(path)? + .map(|v| { + v.borrow() + .as_map() + .ok_or_else(|| Error::StructureError(format!("{path} must be a map"))) + }) + .transpose() + } + + fn get_optional_inner_borrowed_str_value_map_at_path< + 'a, + I: FromIterator<(String, &'a Value)>, + >( + &'a self, + path: &str, + ) -> Result, Error> { + self.get_optional_at_path(path)? + .map(|v| { + v.borrow() + .as_map() + .map(|inner| { + inner + .iter() + .map(|(k, v)| Ok((k.to_text()?, v))) + .collect::>() + }) + .transpose()? + .ok_or_else(|| Error::StructureError(format!("{path} must be a bool"))) + }) + .transpose() + } + + fn get_inner_borrowed_str_value_map_at_path<'a, I: FromIterator<(String, &'a Value)>>( + &'a self, + path: &str, + ) -> Result { + self.get_optional_inner_borrowed_str_value_map_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!( + "unable to get borrowed str value map property {path}" + )) + }) + } + + fn get_optional_inner_str_json_value_map_at_path>( + &self, + path: &str, + ) -> Result, Error> { + self.get_optional_at_path(path)? + .map(|v| { + v.borrow() + .as_map() + .map(|inner| { + inner + .iter() + .map(|(k, v)| Ok((k.to_text()?, v.clone().try_into()?))) + .collect::>() + }) + .transpose()? + .ok_or_else(|| Error::StructureError(format!("{path} must be a bool"))) + }) + .transpose() + } + + fn get_inner_str_json_value_map_at_path>( + &self, + path: &str, + ) -> Result { + self.get_optional_inner_str_json_value_map_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!( + "unable to get borrowed str json value map property {path}" + )) + }) + } + + fn get_optional_system_hash256_bytes_at_path( + &self, + path: &str, + ) -> Result, Error> { + self.get_optional_at_path(path)? + .map(|v| v.borrow().to_system_hash256()) + .transpose() + } + + fn get_system_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error> { + self.get_optional_system_hash256_bytes_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!("unable to get system hash256 property {path}")) + }) + } + + fn get_optional_bytes_at_path(&self, path: &str) -> Result>, Error> { + self.get_optional_at_path(path)? + .map(|v| v.borrow().to_bytes()) + .transpose() + } + + fn get_bytes_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_bytes_at_path(path)?.ok_or_else(|| { + Error::StructureError(format!("unable to get system bytes property {path}")) + }) + } + + fn get_optional_system_bytes_at_path(&self, path: &str) -> Result>, Error> { + self.get_optional_at_path(path)? + .map(|v| v.borrow().to_system_bytes()) + .transpose() + } + + fn get_system_bytes_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_system_bytes_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!("unable to get system bytes property {path}")) + }) + } + + fn remove_optional_system_hash256_bytes_at_path( + &mut self, + path: &str, + ) -> Result, Error> { + self.remove(path) + .map(|v| v.borrow().to_system_hash256()) + .transpose() + } + + fn remove_system_hash256_bytes_at_path(&mut self, path: &str) -> Result<[u8; 32], Error> { + self.remove_optional_system_hash256_bytes_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!("unable to remove system hash256 property {path}")) + }) + } + + fn remove_optional_system_bytes_at_path( + &mut self, + path: &str, + ) -> Result>, Error> { + self.remove(path) + .map(|v| v.borrow().to_system_bytes()) + .transpose() + } + + fn remove_system_bytes_at_path(&mut self, path: &str) -> Result, Error> { + self.remove_optional_system_bytes_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!("unable to remove system bytes property {path}")) + }) + } + + fn remove_optional_string_at_path(&mut self, path: &str) -> Result, Error> { + self.remove(path).map(|v| v.borrow().to_text()).transpose() + } + + fn remove_string_at_path(&mut self, path: &str) -> Result { + self.remove_optional_string_at_path(path)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove string property {path}")) + }) + } + + fn remove_optional_float_at_path(&mut self, path: &str) -> Result, Error> { + self.remove(path) + .and_then(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_float()) + } + }) + .transpose() + } + + fn remove_float_at_path(&mut self, path: &str) -> Result { + self.remove_optional_float_at_path(path)? + .ok_or_else(|| Error::StructureError(format!("unable to remove float property {path}"))) + } + + fn get_optional_float_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_at_path(path)? + .and_then(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_float()) + } + }) + .transpose() + } + + fn get_float_at_path(&self, path: &str) -> Result { + self.get_optional_float_at_path(path)? + .ok_or_else(|| Error::StructureError(format!("unable to get float property {path}"))) + } +} diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index ea1441782d2..fafc6f6b22e 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -5,9 +5,12 @@ pub enum Error { #[error("unsupported: {0}")] Unsupported(String), - #[error("structure Error: {0}")] + #[error("structure error: {0}")] StructureError(String), + #[error("path error: {0}")] + PathError(String), + #[error("integer out of bounds")] IntegerSizeError, } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 3e2b0a1238f..7276d75c952 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -6,6 +6,7 @@ //! //! pub mod btreemap_extensions; +pub mod btreemap_path_extensions; pub mod converter; pub mod display; mod error; @@ -14,11 +15,11 @@ mod integer; pub mod system_bytes; pub mod value_map; +use crate::value_map::ValueMap; pub use error::Error; pub use integer::Integer; use serde::{Deserialize, Serialize}; -pub type ValueMap = Vec<(Value, Value)>; pub type Hash256 = [u8; 32]; /// A representation of a dynamic value that can handled dynamically diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 6372a93be83..4215ee3c717 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,6 +1,45 @@ -use crate::{Error, Value, ValueMap}; +use crate::{Error, Value}; use std::collections::BTreeMap; +pub type ValueMap = Vec<(Value, Value)>; + +pub trait ValueMapHelper { + fn get_key(&self, key: &str) -> Option<&Value>; + fn remove_key(&mut self, key: &str) -> Option; +} + +impl ValueMapHelper for ValueMap { + fn get_key(&self, search_key: &str) -> Option<&Value> { + self.iter().find_map(|(key, value)| { + if let Value::Text(text) = key { + if text == search_key { + Some(value) + } else { + None + } + } else { + None + } + }) + } + + fn remove_key(&mut self, search_key: &str) -> Option { + self.iter() + .position(|(key, _)| { + if let Value::Text(text) = key { + if text == search_key { + true + } else { + false + } + } else { + false + } + }) + .map(|pos| self.remove(pos).1) + } +} + impl Value { /// If the `Value` is a `Map`, returns a the associated `BTreeMap` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. From 8138ca214a32bfa9d4cb22c179c5a42fbc51ef1b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 28 Feb 2023 23:55:24 +0700 Subject: [PATCH 020/228] insertion methods --- .../rs-dpp/src/document/document_factory.rs | 6 ++- .../rs-dpp/src/document/extended_document.rs | 19 +++----- ...e_documents_batch_transition_state_spec.rs | 6 +-- .../tests/fixtures/get_documents_fixture.rs | 4 +- .../src/btreemap_path_insertion_extensions.rs | 44 +++++++++++++++++++ packages/rs-platform-value/src/lib.rs | 25 +++++++++++ packages/rs-platform-value/src/value_map.rs | 41 +++++++++++++++++ 7 files changed, 126 insertions(+), 19 deletions(-) create mode 100644 packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 7adc0c62ce9..721c946814e 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -404,6 +404,7 @@ where #[cfg(test)] mod test { + use platform_value::btreemap_extensions::BTreeValueMapHelper; use std::sync::Arc; use crate::tests::fixtures::get_extended_documents_fixture; @@ -455,7 +456,10 @@ mod test { assert_eq!(document_type, document.document_type_name); assert_eq!( name, - document.get("name").expect("property 'name' should exist") + document + .properties() + .get_str("name") + .expect("property 'name' should exist") ); assert_eq!(contract_id, document.data_contract_id); assert_eq!(owner_id, document.owner_id()); diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 5deac433765..2244b9754e8 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -14,6 +14,7 @@ use integer_encoding::VarInt; use crate::data_contract::document_type::DocumentType; use crate::document::Document; +use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -252,21 +253,13 @@ impl ExtendedDocument { /// Set the value under given path. /// The path supports syntax from `lodash` JS lib. Example: "root.people[0].name". /// If parents are not present they will be automatically created - pub fn set(&mut self, path: &str, value: JsonValue) -> Result<(), ProtocolError> { - Ok(self.data.insert_with_path(path, value)?) + pub fn set(&mut self, path: &str, value: Value) -> Result<(), ProtocolError> { + Ok(self.document.properties.insert_with_path(path, value)?) } /// Retrieves field specified by path - pub fn get(&self, path: &str) -> Option<&JsonValue> { - match self.data.get_value(path) { - Ok(v) => Some(v), - Err(_) => None, - } - } - - /// Set the Document's data - pub fn set_data(&mut self, data: JsonValue) { - self.data = data; + pub fn get(&self, path: &str) -> Option<&Value> { + self.properties().get_optional_at_path(path).ok().flatten() } /// Get entropy @@ -455,7 +448,7 @@ mod test { ] ); assert_eq!(document.revision(), Some(&1)); - assert_eq!(document.created_at().unwrap(), 1656583332347); + assert_eq!(document.created_at().unwrap(), &1656583332347); assert_eq!(document.properties().get_string("name").unwrap(), "Cutie"); Ok(()) diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index b94f21be45d..86e04151fb8 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -217,9 +217,9 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace data_contract.clone(), ) .expect("document should be created"); - replace_document.revision = 3; + replace_document.document.revision = Some(3); - documents[0].created_at = replace_document.created_at; + documents[0].created_at = replace_document.created_at().copied(); let document_transitions = get_document_transitions_fixture([ (Action::Create, vec![]), @@ -276,7 +276,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace data_contract.clone(), ) .expect("document should be created"); - replace_document.revision = 1; + replace_document.document.revision = Some(1); let mut fetched_document = Document::from_raw_json_document(documents[0].to_object().unwrap()) .expect("document should be created"); diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 7862fa315e1..c29aaebfd8f 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -39,10 +39,10 @@ pub fn get_documents_fixture_with_owner_id_from_contract( } pub fn get_documents_fixture(data_contract: DataContract) -> Result, ProtocolError> { - get_extended_documents_fixture(data_contract)? + Ok(get_extended_documents_fixture(data_contract)? .into_iter() .map(|extended_document| extended_document.document) - .collect() + .collect()) } pub fn get_extended_documents_fixture( diff --git a/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs b/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs new file mode 100644 index 00000000000..2862c68c1c5 --- /dev/null +++ b/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs @@ -0,0 +1,44 @@ +use crate::value_map::{ValueMap, ValueMapHelper}; +use crate::{Error, Value}; +use std::collections::BTreeMap; + +pub trait BTreeValueMapInsertionPathHelper { + fn insert_at_path(&mut self, path: &str, value: Value) -> Result<(), Error>; +} + +impl BTreeValueMapInsertionPathHelper for BTreeMap { + fn insert_at_path(&mut self, path: &str, value: Value) -> Result<(), Error> { + let mut split = path.split(".").peekable(); + let first = split.next(); + let Some(first_path_component) = first else { + return Err(Error::PathError("path was empty".to_string())); + }; + if split.peek().is_none() { + self.insert(first_path_component.to_string(), value); + } else { + let mut current_value = self + .entry(first_path_component.to_string()) + .or_insert(Value::Map(ValueMap::new())); + let mut last_path_component = None; + while let Some(path_component) = split.next() { + if split.peek().is_some() { + let map = current_value.as_map_mut_ref()?; + current_value = + map.get_key_mut_or_insert(path_component, Value::Map(ValueMap::new())); + } else { + last_path_component = Some(path_component) + } + } + if let Some(last_path_component) = last_path_component { + let map = current_value.as_map_mut_ref()?; + if let Some(mut new_value) = map.get_key_mut(last_path_component) { + *new_value = value; + } else { + map.push((Value::Text(last_path_component.to_string()), value)); + } + } + } + + Ok(()) + } +} diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 7276d75c952..f009d2e1aa7 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -7,6 +7,7 @@ //! pub mod btreemap_extensions; pub mod btreemap_path_extensions; +pub mod btreemap_path_insertion_extensions; pub mod converter; pub mod display; mod error; @@ -929,6 +930,30 @@ impl Value { _other => Err(Error::StructureError("value is not a map".to_string())), } } + + /// If the `Value` is a `Map`, returns the associated ValueMap ref which is a `&Vec<(Value, Value)>` + /// data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Value}; + /// # + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("key")), Value::Float(18.)), + /// ] + /// ); + /// assert_eq!(value.as_map_mut_ref(), Ok(&mut vec![(Value::Text(String::from("key")), Value::Float(18.))])); + /// + /// let mut value = Value::Bool(true); + /// assert_eq!(value.as_map_mut_ref(), Err(Error::StructureError("value is not a map".to_string()))) + /// ``` + pub fn as_map_mut_ref(&mut self) -> Result<&mut ValueMap, Error> { + match self { + Value::Map(map) => Ok(map), + _other => Err(Error::StructureError("value is not a map".to_string())), + } + } } macro_rules! implfrom { diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 4215ee3c717..16c26a1569f 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -5,6 +5,8 @@ pub type ValueMap = Vec<(Value, Value)>; pub trait ValueMapHelper { fn get_key(&self, key: &str) -> Option<&Value>; + fn get_key_mut(&mut self, key: &str) -> Option<&mut Value>; + fn get_key_mut_or_insert(&mut self, key: &str, value: Value) -> &mut Value; fn remove_key(&mut self, key: &str) -> Option; } @@ -23,6 +25,45 @@ impl ValueMapHelper for ValueMap { }) } + fn get_key_mut(&mut self, search_key: &str) -> Option<&mut Value> { + self.iter_mut().find_map(|(key, value)| { + if let Value::Text(text) = key { + if text == search_key { + Some(value) + } else { + None + } + } else { + None + } + }) + } + + fn get_key_mut_or_insert(&mut self, search_key: &str, value: Value) -> &mut Value { + let found = self.iter().position(|(key, _)| { + if let Value::Text(text) = key { + if text == search_key { + true + } else { + false + } + } else { + false + } + }); + match found { + None => { + self.push((Value::Text(search_key.to_string()), value)); + let (_, value) = self.last_mut().unwrap(); + value + } + Some(pos) => { + let (_, value) = self.get_mut(pos).unwrap(); + value + } + } + } + fn remove_key(&mut self, search_key: &str) -> Option { self.iter() .position(|(key, _)| { From 7e68b240f197382fc29168c4e24161e6ef8572e1 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 1 Mar 2023 01:58:36 +0700 Subject: [PATCH 021/228] more work --- .../rs-dpp/src/document/document_factory.rs | 9 +- .../rs-dpp/src/document/extended_document.rs | 85 ++++++++++++------- packages/rs-dpp/src/document/serialize.rs | 25 ++++-- ...pply_documents_batch_transition_factory.rs | 22 +++-- .../validate_partial_compound_indices_spec.rs | 2 +- packages/rs-drive-abci/src/state/genesis.rs | 28 +++--- .../rs-platform-value/src/converter/mod.rs | 4 +- .../src/converter/serde_json.rs | 8 ++ .../errors/invalid_initial_revision_error.rs | 8 +- .../errors/mismatch_owners_ids_error.rs | 6 +- ...ate_transition.rs => extended_document.rs} | 40 +++++---- packages/wasm-dpp/src/document/factory.rs | 21 +++-- packages/wasm-dpp/src/document/mod.rs | 4 +- .../document_batch_transition/mod.rs | 8 +- 14 files changed, 165 insertions(+), 105 deletions(-) rename packages/wasm-dpp/src/document/{document_in_state_transition.rs => extended_document.rs} (89%) diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 721c946814e..b4917f099a1 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -183,8 +183,11 @@ where return Err(DocumentError::NoDocumentsSuppliedError.into()); } - let is_the_same = - Self::is_ownership_the_same(flattened_documents_iter.clone().map(|d| &d.owner_id())); + let is_the_same = Self::is_ownership_the_same( + flattened_documents_iter + .clone() + .map(|extended_document| &extended_document.document.owner_id), + ); if !is_the_same { return Err(DocumentError::MismatchOwnerIdsError { documents: documents.into_iter().flat_map(|(_, v)| v).collect(), @@ -397,7 +400,7 @@ where data.into_iter().next().is_none() } - fn is_ownership_the_same<'a>(ids: impl IntoIterator) -> bool { + fn is_ownership_the_same<'a>(ids: impl IntoIterator) -> bool { ids.into_iter().all_equal() } } diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 2244b9754e8..48d3158d8c7 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -14,7 +14,9 @@ use integer_encoding::VarInt; use crate::data_contract::document_type::DocumentType; use crate::document::Document; +use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -64,22 +66,21 @@ impl ExtendedDocument { json_document: JsonValue, data_contract: DataContract, ) -> Result { - let mut document = Self::from_value::(json_document, data_contract)?; - let mut document_data = document.data.take(); + let mut document = Self::from_json_value::(json_document, data_contract)?; + // let mut properties = document.properties_as_mut(); // replace only the dynamic data - let (identifier_paths, binary_paths) = document.get_identifiers_and_binary_paths()?; - document_data.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - document_data.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; - - document.data = document_data; + //todo: not sure if this is needed anymore + // let (identifier_paths, binary_paths) = document.get_identifiers_and_binary_paths()?; + // properties.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; + // properties.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; Ok(document) } fn properties_as_json_data(&self) -> Result { self.document .properties - .try_into() + .to_json_value() .map_err(ProtocolError::ValueError) } @@ -134,10 +135,10 @@ impl ExtendedDocument { raw_document: JsonValue, data_contract: DataContract, ) -> Result { - Self::from_value::>(raw_document, data_contract) + Self::from_json_value::>(raw_document, data_contract) } - fn from_value( + fn from_json_value( mut document_value: JsonValue, data_contract: DataContract, ) -> Result @@ -160,7 +161,7 @@ impl ExtendedDocument { let data: S = serde_json::from_value(value)?; extended_document.data_contract_id = data.try_into()? } - extended_document.document = Document::from_json_value(document_value)?; + extended_document.document = Document::from_json_value::(document_value)?; Ok(extended_document) } @@ -184,17 +185,30 @@ impl ExtendedDocument { .. } = deserializer::split_protocol_version(cbor_bytes.as_ref())?; - let cbor_value: CborValue = ciborium::de::from_reader(document_cbor_bytes) - .map_err(|e| ProtocolError::EncodingError(format!("{}", e)))?; + let document_cbor_map: BTreeMap = + ciborium::de::from_reader(document_cbor_bytes) + .map_err(|e| ProtocolError::EncodingError(format!("{}", e)))?; + + let mut document_map: BTreeMap = + Value::convert_from_cbor_map(document_cbor_map); - let mut json_value = cbor_value::cbor_value_to_json_value(&cbor_value)?; + let data_contract_id = Identifier::new( + document_map + .remove_system_hash256_bytes(property_names::DATA_CONTRACT_ID) + .map_err(ProtocolError::ValueError)?, + ); - json_value.add_protocol_version(property_names::PROTOCOL_VERSION, protocol_version)?; - json_value.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Base58)?; + let document_type_name = document_map.remove_string(property_names::DOCUMENT_TYPE)?; - let document: Self = serde_json::from_value(json_value)?; + let document = Document::from_map(document_map, None, None)?; - Ok(document) + Ok(ExtendedDocument { + protocol_version, + document_type_name, + data_contract_id, + document, + ..Default::default() + }) } // The skipIdentifierConversion option is removed as it doesn't make sense in the case of @@ -254,7 +268,7 @@ impl ExtendedDocument { /// The path supports syntax from `lodash` JS lib. Example: "root.people[0].name". /// If parents are not present they will be automatically created pub fn set(&mut self, path: &str, value: Value) -> Result<(), ProtocolError> { - Ok(self.document.properties.insert_with_path(path, value)?) + Ok(self.document.properties.insert_at_path(path, value)?) } /// Retrieves field specified by path @@ -283,7 +297,7 @@ impl ExtendedDocument { #[cfg(test)] mod test { use anyhow::Result; - use serde_json::{json, Value}; + use serde_json::{json, Value as JsonValue}; use crate::document::extended_document::{ExtendedDocument, IDENTIFIER_FIELDS}; @@ -293,6 +307,8 @@ mod test { use crate::tests::utils::*; use crate::util::string_encoding::Encoding; use platform_value::btreemap_extensions::BTreeValueMapHelper; + use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; + use platform_value::Value; use pretty_assertions::assert_eq; fn init() { @@ -353,14 +369,23 @@ mod test { .to_buffer() ); - assert_eq!(doc.data["label"], Value::String("user-9999".to_string())); assert_eq!( - doc.data["records"]["dashUniqueIdentityId"], - Value::String("HBNMY5QWuBVKNFLhgBTC1VmpEnscrmqKPMXpnYSHwhfn".to_string()) + doc.properties() + .get("label") + .expect("expected to get label"), + &Value::Text("user-9999".to_string()) + ); + assert_eq!( + doc.properties() + .get_at_path("records.dashUniqueIdentityId") + .expect("expected to get value"), + &Value::Text("HBNMY5QWuBVKNFLhgBTC1VmpEnscrmqKPMXpnYSHwhfn".to_string()) ); assert_eq!( - doc.data["subdomainRules"]["allowSubdomains"], - Value::Bool(false) + doc.properties() + .get_at_path("subdomainRules.allowSubdomains") + .expect("expected to get value"), + &Value::Bool(false) ); Ok(()) } @@ -489,23 +514,23 @@ mod test { assert_eq!( json_document["$id"], - Value::String(bs58::encode(&id).into_string()) + JsonValue::String(bs58::encode(&id).into_string()) ); assert_eq!( json_document["$ownerId"], - Value::String(bs58::encode(&owner_id).into_string()) + JsonValue::String(bs58::encode(&owner_id).into_string()) ); assert_eq!( json_document["$dataContractId"], - Value::String(bs58::encode(&data_contract_id).into_string()) + JsonValue::String(bs58::encode(&data_contract_id).into_string()) ); assert_eq!( json_document["alphaBinary"], - Value::String(base64::encode(&alpha_value)) + JsonValue::String(base64::encode(&alpha_value)) ); assert_eq!( json_document["alphaIdentifier"], - Value::String(bs58::encode(&alpha_value).into_string()) + JsonValue::String(bs58::encode(&alpha_value).into_string()) ); } diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 7240d8ece41..24d3ffe87aa 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -338,37 +338,46 @@ impl Document { // first we need to deserialize the document and contract indices // we would need dedicated deserialization functions based on the document type - let document_cbor: BTreeMap = + let document_cbor_map: BTreeMap = ciborium::de::from_reader(read_document_cbor).map_err(|_| { ProtocolError::StructureError(StructureError::InvalidCBOR( "unable to decode document for document call", )) })?; + let document_map: BTreeMap = Value::convert_from_cbor_map(document_cbor_map); - let mut document: BTreeMap = Value::convert_from_cbor_map(document_cbor); + Self::from_map(document_map, document_id, owner_id) + } + /// Reads a CBOR-serialized document and creates a Document from it. + /// If Document and Owner IDs are provided, they are used, otherwise they are created. + pub fn from_map( + mut document_map: BTreeMap, + document_id: Option<[u8; 32]>, + owner_id: Option<[u8; 32]>, + ) -> Result { let owner_id = match owner_id { - None => document + None => document_map .remove_system_hash256_bytes(property_names::OWNER_ID) .map_err(ProtocolError::ValueError)?, Some(owner_id) => owner_id, }; let id = match document_id { - None => document + None => document_map .remove_system_hash256_bytes(property_names::ID) .map_err(ProtocolError::ValueError)?, Some(document_id) => document_id, }; - let revision = document.remove_optional_integer(property_names::REVISION)?; + let revision = document_map.remove_optional_integer(property_names::REVISION)?; - let created_at = document.remove_optional_integer(property_names::CREATED_AT)?; - let updated_at = document.remove_optional_integer(property_names::UPDATED_AT)?; + let created_at = document_map.remove_optional_integer(property_names::CREATED_AT)?; + let updated_at = document_map.remove_optional_integer(property_names::UPDATED_AT)?; // dev-note: properties is everything other than the id and owner id Ok(Document { - properties: document, + properties: document_map, owner_id, id, revision, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 91c32552d78..019f47c2487 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -1,3 +1,4 @@ +use platform_value::Value; use std::collections::HashMap; use crate::document::{Document, ExtendedDocument}; @@ -110,9 +111,15 @@ fn document_from_transition_replace( document_replace_transition: &DocumentReplaceTransition, state_transition: &DocumentsBatchTransition, created_at: TimestampMillis, -) -> ExtendedDocument { +) -> Result { // TODO cloning is costly. Probably the [`Document`] should have properties of type `Cow<'a, K>` - ExtendedDocument { + let property_value: Value = document_replace_transition + .data + .as_ref() + .unwrap_or(&serde_json::Value::Null) + .clone() + .into(); + Ok(ExtendedDocument { protocol_version: state_transition.protocol_version, document_type_name: document_replace_transition.base.document_type.clone(), data_contract_id: document_replace_transition.base.data_contract_id, @@ -126,17 +133,14 @@ fn document_from_transition_replace( document: Document { id: document_replace_transition.base.id.buffer, owner_id: state_transition.owner_id.buffer, - properties: document_replace_transition - .data - .as_ref() - .unwrap_or(&serde_json::Value::Null) - .clone() - .into(), + properties: property_value + .into_btree_map() + .map_err(ProtocolError::ValueError)?, revision: Some(document_replace_transition.revision), created_at: Some(created_at), updated_at: document_replace_transition.updated_at, }, - } + }) } #[cfg(test)] diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index dd3fddb3b7c..1a70bed3a7a 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -76,7 +76,7 @@ fn should_return_valid_result_if_compound_index_contains_nof_fields() { mut documents, } = setup_test(); let mut document = documents.remove(8); - document.properties_as_mut() = *BTreeMap::new(); + document.properties_as_mut().clear(); let documents_for_transition = vec![document]; let raw_document_transitions: Vec = diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index d4ed284e385..26531700ccd 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -31,6 +31,7 @@ use crate::error::execution::ExecutionError; use crate::error::Error; use crate::platform::Platform; use ciborium::{cbor, Value as CborValue}; +use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; use dpp::platform_value::Value; use dpp::ProtocolError; use drive::contract::DataContract; @@ -206,16 +207,7 @@ impl Platform { // TODO: Add created and updated at to DPNS contract - let document = ExtendedDocument { - protocol_version: PROTOCOL_VERSION, - id: Identifier::new(DPNS_DASH_TLD_DOCUMENT_ID), - document_type_name: "domain".to_string(), - revision: 0, - data_contract_id: contract.id, - owner_id: contract.owner_id, - created_at: None, - updated_at: None, - data: json!({ + let properties_json = json!({ "label": domain, "normalizedLabel": domain, "normalizedParentDomainName": "", @@ -226,10 +218,24 @@ impl Platform { "subdomainRules": { "allowSubdomains": true, } - }), + }); + + let document = ExtendedDocument { + protocol_version: PROTOCOL_VERSION, + document_type_name: "domain".to_string(), + data_contract_id: contract.id, data_contract: contract.clone(), metadata: None, entropy: [0; 32], + document: Document { + id: DPNS_DASH_TLD_DOCUMENT_ID, + revision: None, + owner_id: contract.owner_id.to_buffer(), + created_at: None, + updated_at: None, + properties: BTreeMap::from_json_value(properties_json) + .map_err(ProtocolError::ValueError)?, + }, }; let document_stub_properties_value: Value = cbor!({ diff --git a/packages/rs-platform-value/src/converter/mod.rs b/packages/rs-platform-value/src/converter/mod.rs index 47a42d020a8..02cf95f907a 100644 --- a/packages/rs-platform-value/src/converter/mod.rs +++ b/packages/rs-platform-value/src/converter/mod.rs @@ -1,2 +1,2 @@ -mod ciborium; -mod serde_json; +pub mod ciborium; +pub mod serde_json; diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index aa4820ac5a0..a9a6d2bb274 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -93,6 +93,9 @@ impl TryInto for Value { pub trait BTreeValueJsonConverter { fn into_json_value(self) -> Result; + fn from_json_value(value: JsonValue) -> Result + where + Self: Sized; } impl BTreeValueJsonConverter for BTreeMap { @@ -103,4 +106,9 @@ impl BTreeValueJsonConverter for BTreeMap { .collect::, Error>>()?, )) } + + fn from_json_value(value: JsonValue) -> Result { + let platform_value: Value = value.into(); + platform_value.into_btree_map() + } } diff --git a/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs b/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs index c0224df3ad4..b973f0fe3f5 100644 --- a/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs +++ b/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs @@ -1,4 +1,4 @@ -use crate::DocumentInStateTransitionWasm; +use crate::ExtendedDocumentWasm; use thiserror::Error; use super::*; @@ -7,18 +7,18 @@ use super::*; #[derive(Error, Debug)] #[error("Invalid Document Initial revision '{}'", document.get_revision())] pub struct InvalidInitialRevisionError { - document: DocumentInStateTransitionWasm, + document: ExtendedDocumentWasm, } #[wasm_bindgen] impl InvalidInitialRevisionError { #[wasm_bindgen(constructor)] - pub fn new(document: DocumentInStateTransitionWasm) -> InvalidInitialRevisionError { + pub fn new(document: ExtendedDocumentWasm) -> InvalidInitialRevisionError { Self { document } } #[wasm_bindgen(js_name=getDocument)] - pub fn get_document_transition(&self) -> DocumentInStateTransitionWasm { + pub fn get_document_transition(&self) -> ExtendedDocumentWasm { self.document.clone() } } diff --git a/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs b/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs index ec509bf3688..8c94ba91448 100644 --- a/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs +++ b/packages/wasm-dpp/src/document/errors/mismatch_owners_ids_error.rs @@ -1,4 +1,4 @@ -use crate::DocumentInStateTransitionWasm; +use crate::ExtendedDocumentWasm; use dpp::document::ExtendedDocument; use itertools::Itertools; use thiserror::Error; @@ -9,7 +9,7 @@ use super::*; #[derive(Error, Debug)] #[error("Documents have mixed owner ids")] pub struct MismatchOwnerIdsError { - documents: Vec, + documents: Vec, } #[wasm_bindgen] @@ -32,7 +32,7 @@ impl MismatchOwnerIdsError { Self { documents: documents .into_iter() - .map(DocumentInStateTransitionWasm::from) + .map(ExtendedDocumentWasm::from) .collect_vec(), } } diff --git a/packages/wasm-dpp/src/document/document_in_state_transition.rs b/packages/wasm-dpp/src/document/extended_document.rs similarity index 89% rename from packages/wasm-dpp/src/document/document_in_state_transition.rs rename to packages/wasm-dpp/src/document/extended_document.rs index f1bb2fae6a3..887b20cca00 100644 --- a/packages/wasm-dpp/src/document/document_in_state_transition.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -1,11 +1,14 @@ use dpp::dashcore::anyhow::Context; +use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::document::{ extended_document_property_names, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, }; +use dpp::platform_value::Value; use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::{JsonValueExt, ReplaceWith}; use dpp::util::string_encoding::Encoding; +use dpp::ProtocolError; use serde::{Deserialize, Serialize}; use std::convert::TryInto; use wasm_bindgen::prelude::*; @@ -22,15 +25,15 @@ use crate::{DataContractWasm, MetadataWasm}; #[wasm_bindgen(js_name=DocumentInStateTransition)] #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DocumentInStateTransitionWasm(pub(crate) ExtendedDocument); +pub struct ExtendedDocumentWasm(pub(crate) ExtendedDocument); #[wasm_bindgen(js_class=DocumentInStateTransition)] -impl DocumentInStateTransitionWasm { +impl ExtendedDocumentWasm { #[wasm_bindgen(constructor)] pub fn new( js_raw_document: JsValue, js_data_contract: &DataContractWasm, - ) -> Result { + ) -> Result { let mut raw_document = with_serde_to_json_value(&js_raw_document)?; let document_type = raw_document @@ -160,9 +163,9 @@ impl DocumentInStateTransitionWasm { return self.0.set(&path, new_value).with_js_error(); } else if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - let mut value = js_value_to_set.with_serde_to_json_value()?; + let mut value: Value = js_value_to_set.with_serde_to_json_value()?.into(); - if value.get_value(suffix).is_ok() { + if value(suffix).is_ok() { let id_string = value .remove_path_into::(suffix) .with_context(|| format!("unable convert `{path}` into string")) @@ -179,7 +182,7 @@ impl DocumentInStateTransitionWasm { } } - let value = js_value_to_set.with_serde_to_json_value()?; + let value: Value = js_value_to_set.with_serde_to_json_value()?.into(); self.0.set(&path, value).with_js_error() } @@ -190,21 +193,24 @@ impl DocumentInStateTransitionWasm { if let Some(value) = self.0.get(&path) { match binary_type { BinaryType::Identifier => { - if let Ok(bytes) = serde_json::from_value::>(value.to_owned()) { + if let Ok(bytes) = value.to_system_bytes() { let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); return id.into(); } } BinaryType::Buffer => { - if let Ok(bytes) = serde_json::from_value::>(value.to_owned()) { + if let Ok(bytes) = value.to_system_bytes() { return Buffer::from_bytes(&bytes).into(); } } BinaryType::None => { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - if let Ok(js_value) = value.serialize(&serializer) { - return js_value; + let json_value: Option = value.clone().try_into().ok(); + if let Some(json_value) = json_value { + if let Ok(js_value) = json_value.serialize(&serializer) { + return js_value; + } } } } @@ -215,22 +221,22 @@ impl DocumentInStateTransitionWasm { #[wasm_bindgen(js_name=setCreatedAt)] pub fn set_created_at(&mut self, ts: f64) { - self.0.created_at = Some(ts as u64); + self.0.document.created_at = Some(ts as u64); } #[wasm_bindgen(js_name=setUpdatedAt)] pub fn set_updated_at(&mut self, ts: f64) { - self.0.updated_at = Some(ts as u64); + self.0.document.updated_at = Some(ts as u64); } #[wasm_bindgen(js_name=getCreatedAt)] pub fn get_created_at(&self) -> Option { - self.0.created_at.map(|v| v as f64) + self.0.document.created_at.map(|v| v as f64) } #[wasm_bindgen(js_name=getUpdatedAt)] pub fn get_updated_at(&self) -> Option { - self.0.updated_at.map(|v| v as f64) + self.0.document.updated_at.map(|v| v as f64) } #[wasm_bindgen(js_name=getMetadata)] @@ -311,7 +317,7 @@ impl DocumentInStateTransitionWasm { } } -impl DocumentInStateTransitionWasm { +impl ExtendedDocumentWasm { fn get_binary_type_of_path(&self, path: &String) -> BinaryType { let maybe_binary_properties = self .0 @@ -330,8 +336,8 @@ impl DocumentInStateTransitionWasm { } } -impl From for DocumentInStateTransitionWasm { +impl From for ExtendedDocumentWasm { fn from(d: ExtendedDocument) -> Self { - DocumentInStateTransitionWasm(d) + ExtendedDocumentWasm(d) } } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 3b7077aa250..c41581ce371 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -15,8 +15,7 @@ use crate::{ identifier::identifier_from_js_value, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, utils::{ToSerdeJSONExt, WithJsError}, - DataContractWasm, DocumentInStateTransitionWasm, DocumentsBatchTransitionWASM, - DocumentsContainer, + DataContractWasm, DocumentsBatchTransitionWASM, DocumentsContainer, ExtendedDocumentWasm, }; use super::validator::DocumentValidatorWasm; @@ -24,9 +23,9 @@ use super::validator::DocumentValidatorWasm; #[wasm_bindgen(js_name=DocumentTransitions)] #[derive(Debug, Default)] pub struct DocumentTransitions { - create: Vec, - replace: Vec, - delete: Vec, + create: Vec, + replace: Vec, + delete: Vec, } #[wasm_bindgen(js_class=DocumentTransitions)] @@ -37,17 +36,17 @@ impl DocumentTransitions { } #[wasm_bindgen(js_name = "addTransitionCreate")] - pub fn add_transition_create(&mut self, transition: DocumentInStateTransitionWasm) { + pub fn add_transition_create(&mut self, transition: ExtendedDocumentWasm) { self.create.push(transition) } #[wasm_bindgen(js_name = "addTransitionReplace")] - pub fn add_transition_replace(&mut self, transition: DocumentInStateTransitionWasm) { + pub fn add_transition_replace(&mut self, transition: ExtendedDocumentWasm) { self.replace.push(transition) } #[wasm_bindgen(js_name = "addTransitionDelete")] - pub fn add_transition_delete(&mut self, transition: DocumentInStateTransitionWasm) { + pub fn add_transition_delete(&mut self, transition: ExtendedDocumentWasm) { self.delete.push(transition) } } @@ -83,7 +82,7 @@ impl DocumentFactoryWASM { js_owner_id: &JsValue, document_type: &str, data: &JsValue, - ) -> Result { + ) -> Result { let owner_id = identifier_from_js_value(js_owner_id)?; let dynamic_data = data.with_serde_to_json_value()?; let document = self @@ -126,7 +125,7 @@ impl DocumentFactoryWASM { &self, raw_document_js: JsValue, options: JsValue, - ) -> Result { + ) -> Result { let mut raw_document = raw_document_js.with_serde_to_json_value()?; let options: FactoryOptions = if !options.is_undefined() && options.is_object() { let raw_options = options.with_serde_to_json_value()?; @@ -169,7 +168,7 @@ impl DocumentFactoryWASM { &self, buffer: Vec, options: &JsValue, - ) -> Result { + ) -> Result { let options: FactoryOptions = if !options.is_undefined() && options.is_object() { let raw_options = options.with_serde_to_json_value()?; serde_json::from_value(raw_options).with_js_error()? diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index fd56cce0b2f..1d2710fe925 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -17,19 +17,19 @@ use crate::DataContractWasm; pub mod errors; pub use state_transition::*; -mod document_in_state_transition; +mod extended_document; mod factory; pub mod fetch_and_validate_data_contract; pub mod state_transition; mod validator; pub use document_batch_transition::{DocumentsBatchTransitionWASM, DocumentsContainer}; -pub use document_in_state_transition::DocumentInStateTransitionWasm; use dpp::data_contract::DriveContractExt; use dpp::document::{ extended_document_property_names, Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, }; use dpp::identity::TimestampMillis; +pub use extended_document::ExtendedDocumentWasm; use dpp::ProtocolError; pub use factory::DocumentFactoryWASM; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 0d24696c430..595fe1e39db 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -23,7 +23,7 @@ use crate::{ identifier::IdentifierWrapper, lodash::lodash_set, utils::{ToSerdeJSONExt, WithJsError}, - DocumentInStateTransitionWasm, IdentityPublicKeyWasm, + ExtendedDocumentWasm, IdentityPublicKeyWasm, }; pub mod document_transition; @@ -63,17 +63,17 @@ impl DocumentsContainer { } #[wasm_bindgen(js_name=pushDocumentCreate)] - pub fn push_document_create(&mut self, d: DocumentInStateTransitionWasm) { + pub fn push_document_create(&mut self, d: ExtendedDocumentWasm) { self.create.push(d.0); } #[wasm_bindgen(js_name=pushDocumentReplace)] - pub fn push_document_replace(&mut self, d: DocumentInStateTransitionWasm) { + pub fn push_document_replace(&mut self, d: ExtendedDocumentWasm) { self.replace.push(d.0); } #[wasm_bindgen(js_name=pushDocumentDelete)] - pub fn push_document_delete(&mut self, d: DocumentInStateTransitionWasm) { + pub fn push_document_delete(&mut self, d: ExtendedDocumentWasm) { self.delete.push(d.0); } } From c255b7e2a0b3f06b9249d10b041e222cfe49f13c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 1 Mar 2023 11:31:17 +0700 Subject: [PATCH 022/228] more work --- Cargo.lock | 1 + .../rs-drive/src/drive/document/update.rs | 5 +- packages/rs-platform-value/Cargo.toml | 1 + .../src/btreemap_field_replacement.rs | 78 +++++++++++++++++++ packages/rs-platform-value/src/lib.rs | 2 + .../src/document/extended_document.rs | 32 ++++---- packages/wasm-dpp/src/document/factory.rs | 11 ++- 7 files changed, 111 insertions(+), 19 deletions(-) create mode 100644 packages/rs-platform-value/src/btreemap_field_replacement.rs diff --git a/Cargo.lock b/Cargo.lock index c165219faa3..e3f1f6e05f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2216,6 +2216,7 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" name = "platform-value" version = "0.1.0" dependencies = [ + "base64 0.13.1", "bs58", "ciborium", "hex", diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index a49698d3f96..0c4e565019d 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -684,12 +684,13 @@ mod tests { use dpp::document::document_factory::DocumentFactory; use dpp::document::document_validator::DocumentValidator; + use dpp::platform_value::Value; use dpp::prelude::DataContract; use dpp::util::serializer; use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; use rand::Rng; use serde::{Deserialize, Serialize}; - use serde_json::{json, Value}; + use serde_json::{json, Value as JsonValue}; use tempfile::TempDir; use super::*; @@ -2455,7 +2456,7 @@ mod tests { // Update the document in a second document - .set("name", Value::String("Ivaaaaaaaaaan!".to_string())) + .set("name", Value::Text("Ivaaaaaaaaaan!".to_string())) .expect("should change name"); let document_cbor = document.to_buffer().expect("should encode to buffer"); diff --git a/packages/rs-platform-value/Cargo.toml b/packages/rs-platform-value/Cargo.toml index 7bf90ca00e4..c99d1a86daa 100644 --- a/packages/rs-platform-value/Cargo.toml +++ b/packages/rs-platform-value/Cargo.toml @@ -10,6 +10,7 @@ private = true ciborium = { git="https://github.com/qrayven/ciborium", branch="feat-ser-null-as-undefined"} thiserror = "1.0.30" bs58 = "0.4.0" +base64 = "0.13.0" hex = "0.4.3" serde = { version = "1.0.152", features = ["derive"] } serde_json = { version="1.0", features=["preserve_order"] } \ No newline at end of file diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs new file mode 100644 index 00000000000..c61c3cf5b03 --- /dev/null +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -0,0 +1,78 @@ +use crate::btreemap_path_extensions::BTreeValueMapPathHelper; +use crate::value_map::{ValueMap, ValueMapHelper}; +use crate::{Error, Value}; +use std::collections::{BTreeMap, HashMap}; + +#[derive(Debug, Clone, Copy)] +pub enum ReplacementType { + Bytes, + TextBase58, + TextBase64, +} + +impl ReplacementType { + pub fn replace_for_bytes(&self, bytes: Vec) -> Value { + match self { + ReplacementType::Bytes => Value::Bytes(bytes), + ReplacementType::TextBase58 => Value::Text(bs58::encode(bytes).into_string()), + ReplacementType::TextBase64 => Value::Text(base64::encode(bytes)), + } + } +} + +pub trait BTreeValueMapInsertionPathHelper { + fn replace_at_path( + &mut self, + path: &str, + replacement_type: ReplacementType, + ) -> Result; + fn replace_at_paths<'a, I: IntoIterator>( + &mut self, + paths: I, + replacement_type: ReplacementType, + ) -> Result, Error>; +} + +impl BTreeValueMapInsertionPathHelper for BTreeMap { + fn replace_at_path( + &mut self, + path: &str, + replacement_type: ReplacementType, + ) -> Result { + let mut split = path.split(".").peekable(); + let first = split.next(); + let Some(first_path_component) = first else { + return Err(Error::PathError("path was empty".to_string())); + }; + let Some(mut current_value) = self.get_mut(first_path_component) else { + return Ok(false); + }; + while let Some(path_component) = split.next() { + let map = current_value.as_map_mut_ref()?; + let Some(mut new_value) = map.get_key_mut(path_component) else { + return Ok(false); + }; + current_value = new_value; + if split.peek().is_none() { + let bytes = current_value.to_system_bytes()?; + new_value = &mut replacement_type.replace_for_bytes(bytes); + return Ok(true); + } + } + Ok(false) + } + + fn replace_at_paths<'a, I: IntoIterator>( + &mut self, + paths: I, + replacement_type: ReplacementType, + ) -> Result, Error> { + paths + .into_iter() + .map(|path| { + let success = self.replace_at_path(path, replacement_type)?; + Ok((path, success)) + }) + .collect() + } +} diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index f009d2e1aa7..4dd3d6503f7 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -6,6 +6,7 @@ //! //! pub mod btreemap_extensions; +mod btreemap_field_replacement; pub mod btreemap_path_extensions; pub mod btreemap_path_insertion_extensions; pub mod converter; @@ -22,6 +23,7 @@ pub use integer::Integer; use serde::{Deserialize, Serialize}; pub type Hash256 = [u8; 32]; +pub use btreemap_field_replacement::ReplacementType; /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 887b20cca00..edd8d251bda 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -3,6 +3,7 @@ use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::document::{ extended_document_property_names, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, }; +use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use dpp::platform_value::Value; use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; @@ -72,12 +73,12 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=getId)] pub fn get_id(&self) -> IdentifierWrapper { - self.0.id.into() + self.0.document.id.into() } #[wasm_bindgen(js_name=setId)] pub fn set_id(&mut self, js_id: IdentifierWrapper) { - self.0.id = js_id.inner(); + self.0.document.id = js_id.inner().buffer; } #[wasm_bindgen(js_name=getType)] @@ -97,24 +98,24 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=setOwnerId)] pub fn set_owner_id(&mut self, owner_id: IdentifierWrapper) { - self.0.owner_id = owner_id.inner(); + self.0.document.owner_id = owner_id.inner().buffer; } #[wasm_bindgen(js_name=getOwnerId)] pub fn get_owner_id(&self) -> IdentifierWrapper { - self.0.owner_id.into() + self.0.document.owner_id.into() } #[wasm_bindgen(js_name=setRevision)] - pub fn set_revision(&mut self, rev: u32) { + pub fn set_revision(&mut self, rev: Option) { // TODO: js feeds Number (u32). Is casting revision to u64 safe? - self.0.revision = rev as Revision; + self.0.document.revision = rev.map(|r| r as Revision); } #[wasm_bindgen(js_name=getRevision)] - pub fn get_revision(&self) -> u32 { + pub fn get_revision(&self) -> Option { // TODO: js expects Number (u32). Is casting revision to u32 safe? - self.0.revision as u32 + self.0.document.revision.map(|r| r as u32) } #[wasm_bindgen(js_name=setEntropy)] @@ -136,7 +137,7 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=setData)] pub fn set_data(&mut self, d: JsValue) -> Result<(), JsValue> { - self.0.data = with_js_error!(serde_wasm_bindgen::from_value(d))?; + self.0.document.properties = with_js_error!(serde_wasm_bindgen::from_value(d))?; Ok(()) } @@ -144,7 +145,11 @@ impl ExtendedDocumentWasm { pub fn get_data(&mut self) -> Result { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - Ok(with_js_error!(self.0.data.serialize(&serializer))?) + Ok(with_js_error!(self + .0 + .document + .properties + .serialize(&serializer))?) } #[wasm_bindgen(js_name=set)] @@ -159,13 +164,14 @@ impl ExtendedDocumentWasm { .with_js_error()?; let id = Identifier::from_string(id_string, Encoding::Base58).with_js_error()?; let new_value = serde_json::to_value(id.as_bytes()).with_js_error()?; + let mut value: Value = new_value.into(); - return self.0.set(&path, new_value).with_js_error(); + return self.0.set(&path, value).with_js_error(); } else if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); let mut value: Value = js_value_to_set.with_serde_to_json_value()?.into(); - - if value(suffix).is_ok() { + let map = value.to_btree_ref_map()?; + if map.get_at_path(suffix).is_ok() { let id_string = value .remove_path_into::(suffix) .with_context(|| format!("unable convert `{path}` into string")) diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index c41581ce371..bbef504786d 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use dpp::platform_value::ReplacementType; use dpp::{ document::{ document_factory::{DocumentFactory, FactoryOptions}, @@ -8,6 +9,7 @@ use dpp::{ fetch_and_validate_data_contract::DataContractFetcherAndValidator, }, util::json_value::{JsonValueExt, ReplaceWith}, + ProtocolError, }; use wasm_bindgen::prelude::*; @@ -148,17 +150,18 @@ impl DocumentFactoryWASM { .with_js_error()?; // When data contract is available, replace remaining dynamic paths - let mut document_data = document.data.take(); + let mut document_data = document.properties_as_mut(); let (identifier_paths, binary_paths) = document .get_identifiers_and_binary_paths() .with_js_error()?; document_data - .replace_identifier_paths(identifier_paths, ReplaceWith::Bytes) + .replace_at_paths(identifier_paths, ReplacementType::Bytes) + .map_err(ProtocolError::ValueError) .with_js_error()?; document_data - .replace_binary_paths(binary_paths, ReplaceWith::Bytes) + .replace_at_paths(binary_paths, ReplacementType::Bytes) + .map_err(ProtocolError::ValueError) .with_js_error()?; - document.data = document_data; Ok(document.into()) } From 83535d0c803632e4f237ab553a7ffbc0e136fb8d Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 1 Mar 2023 15:31:01 +0700 Subject: [PATCH 023/228] more work --- .../rs-dpp/src/data_contract/data_contract.rs | 25 ++++++++ .../rs-dpp/src/document/extended_document.rs | 12 ++++ .../src/btreemap_field_replacement.rs | 15 +++-- packages/rs-platform-value/src/lib.rs | 41 ++++++++++++- packages/rs-platform-value/src/value_map.rs | 4 +- .../errors/invalid_initial_revision_error.rs | 2 +- packages/wasm-dpp/src/document/errors/mod.rs | 10 ++++ .../document/errors/revision_absent_error.rs | 24 ++++++++ ...ing_to_replace_immutable_document_error.rs | 19 +++++++ .../src/document/extended_document.rs | 57 ++++++++----------- packages/wasm-dpp/src/document/factory.rs | 9 +-- packages/wasm-dpp/src/state_repository.rs | 14 +++++ 12 files changed, 184 insertions(+), 48 deletions(-) create mode 100644 packages/wasm-dpp/src/document/errors/revision_absent_error.rs create mode 100644 packages/wasm-dpp/src/document/errors/trying_to_replace_immutable_document_error.rs diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index c5982e456ef..fbfcc86a105 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -292,6 +292,31 @@ impl DataContract { }; Ok((identifiers_paths, binary_paths)) } + + pub fn get_identifiers_and_binary_paths_owned( + &self, + document_type: &str, + ) -> Result<(HashSet, HashSet), ProtocolError> { + let binary_properties = self.get_optional_binary_properties(document_type)?; + + // At this point we don't bother about returned error from `get_binary_properties`. + // If document of given type isn't found, then empty vectors will be returned. + let (binary_paths, identifiers_paths) = match binary_properties { + None => (HashSet::new(), HashSet::new()), + Some(binary_properties) => binary_properties.iter().partition_map(|(path, v)| { + if let Some(JsonValue::String(content_type)) = v.get("contentMediaType") { + if content_type == identifier::MEDIA_TYPE { + Either::Right(path.clone()) + } else { + Either::Left(path.clone()) + } + } else { + Either::Left(path.clone()) + } + }), + }; + Ok((identifiers_paths, binary_paths)) + } } impl TryFrom for DataContract { diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 48d3158d8c7..1296c397df2 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -292,6 +292,18 @@ impl ExtendedDocument { Ok((identifiers_paths, binary_paths)) } + + pub fn get_identifiers_and_binary_paths_owned( + &self, + ) -> Result<(HashSet, HashSet), ProtocolError> { + let (mut identifiers_paths, binary_paths) = self + .data_contract + .get_identifiers_and_binary_paths_owned(&self.document_type_name)?; + + identifiers_paths.extend(IDENTIFIER_FIELDS.map(|str| str.to_string())); + + Ok((identifiers_paths, binary_paths)) + } } #[cfg(test)] diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index c61c3cf5b03..edd50bf2cbd 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -18,6 +18,11 @@ impl ReplacementType { ReplacementType::TextBase64 => Value::Text(base64::encode(bytes)), } } + + pub fn replace_consume_value(&self, value: Value) -> Result { + let bytes = value.into_system_bytes()?; + Ok(self.replace_for_bytes(bytes)) + } } pub trait BTreeValueMapInsertionPathHelper { @@ -26,11 +31,11 @@ pub trait BTreeValueMapInsertionPathHelper { path: &str, replacement_type: ReplacementType, ) -> Result; - fn replace_at_paths<'a, I: IntoIterator>( + fn replace_at_paths>( &mut self, paths: I, replacement_type: ReplacementType, - ) -> Result, Error>; + ) -> Result, Error>; } impl BTreeValueMapInsertionPathHelper for BTreeMap { @@ -62,15 +67,15 @@ impl BTreeValueMapInsertionPathHelper for BTreeMap { Ok(false) } - fn replace_at_paths<'a, I: IntoIterator>( + fn replace_at_paths>( &mut self, paths: I, replacement_type: ReplacementType, - ) -> Result, Error> { + ) -> Result, Error> { paths .into_iter() .map(|path| { - let success = self.replace_at_path(path, replacement_type)?; + let success = self.replace_at_path(path.as_str(), replacement_type)?; Ok((path, success)) }) .collect() diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 4dd3d6503f7..efb2088aa5d 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -6,7 +6,7 @@ //! //! pub mod btreemap_extensions; -mod btreemap_field_replacement; +pub mod btreemap_field_replacement; pub mod btreemap_path_extensions; pub mod btreemap_path_insertion_extensions; pub mod converter; @@ -17,10 +17,11 @@ mod integer; pub mod system_bytes; pub mod value_map; -use crate::value_map::ValueMap; +use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; pub use integer::Integer; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; pub type Hash256 = [u8; 32]; pub use btreemap_field_replacement::ReplacementType; @@ -956,6 +957,42 @@ impl Value { _other => Err(Error::StructureError("value is not a map".to_string())), } } + + pub fn replace_at_path( + &mut self, + path: &str, + replacement_type: ReplacementType, + ) -> Result { + let mut split = path.split(".").peekable(); + let mut current_value = self; + while let Some(path_component) = split.next() { + let map = current_value.as_map_mut_ref()?; + let Some(mut new_value) = map.get_key_mut(path_component) else { + return Ok(false); + }; + current_value = new_value; + if split.peek().is_none() { + let bytes = current_value.to_system_bytes()?; + new_value = &mut replacement_type.replace_for_bytes(bytes); + return Ok(true); + } + } + Ok(false) + } + + pub fn replace_at_paths<'a, I: IntoIterator>( + &mut self, + paths: I, + replacement_type: ReplacementType, + ) -> Result, Error> { + paths + .into_iter() + .map(|path| { + let success = self.replace_at_path(path, replacement_type)?; + Ok((path, success)) + }) + .collect() + } } macro_rules! implfrom { diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 16c26a1569f..12535ab7357 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,5 +1,5 @@ -use crate::{Error, Value}; -use std::collections::BTreeMap; +use crate::{Error, ReplacementType, Value}; +use std::collections::{BTreeMap, HashMap}; pub type ValueMap = Vec<(Value, Value)>; diff --git a/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs b/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs index b973f0fe3f5..fd8893caef5 100644 --- a/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs +++ b/packages/wasm-dpp/src/document/errors/invalid_initial_revision_error.rs @@ -5,7 +5,7 @@ use super::*; #[wasm_bindgen] #[derive(Error, Debug)] -#[error("Invalid Document Initial revision '{}'", document.get_revision())] +#[error("Invalid Document Initial revision '{}'", document.get_revision().unwrap_or_default())] pub struct InvalidInitialRevisionError { document: ExtendedDocumentWasm, } diff --git a/packages/wasm-dpp/src/document/errors/mod.rs b/packages/wasm-dpp/src/document/errors/mod.rs index 4b92bd5e2f9..32fc15a73cb 100644 --- a/packages/wasm-dpp/src/document/errors/mod.rs +++ b/packages/wasm-dpp/src/document/errors/mod.rs @@ -2,6 +2,8 @@ use serde::Serialize; use wasm_bindgen::prelude::*; use crate::document::errors::document_no_revision_error::DocumentNoRevisionError; +use crate::document::errors::revision_absent_error::RevisionAbsentError; +use crate::document::errors::trying_to_replace_immutable_document_error::TryingToReplaceImmutableDocumentError; pub use document_already_exists_error::*; pub use document_not_provided_error::*; use dpp::document::errors::DocumentError; @@ -24,6 +26,8 @@ mod invalid_document_error; mod invalid_initial_revision_error; mod mismatch_owners_ids_error; mod no_documents_supplied_error; +mod revision_absent_error; +mod trying_to_replace_immutable_document_error; pub fn from_document_to_js_error(e: DocumentError) -> JsValue { match e { @@ -60,5 +64,11 @@ pub fn from_document_to_js_error(e: DocumentError) -> JsValue { DocumentError::DocumentNoRevisionError { document } => { DocumentNoRevisionError::new((*document).into()).into() } + DocumentError::RevisionAbsentError { document } => { + RevisionAbsentError::new((*document).into()).into() + } + DocumentError::TryingToReplaceImmutableDocument { document } => { + TryingToReplaceImmutableDocumentError::new((*document).into()).into() + } } } diff --git a/packages/wasm-dpp/src/document/errors/revision_absent_error.rs b/packages/wasm-dpp/src/document/errors/revision_absent_error.rs new file mode 100644 index 00000000000..b04eb8c3c60 --- /dev/null +++ b/packages/wasm-dpp/src/document/errors/revision_absent_error.rs @@ -0,0 +1,24 @@ +use crate::ExtendedDocumentWasm; +use thiserror::Error; + +use super::*; + +#[wasm_bindgen] +#[derive(Error, Debug)] +#[error("The revision was absent, but was needed")] +pub struct RevisionAbsentError { + extended_document: ExtendedDocumentWasm, +} + +#[wasm_bindgen] +impl RevisionAbsentError { + #[wasm_bindgen(constructor)] + pub fn new(extended_document: ExtendedDocumentWasm) -> RevisionAbsentError { + Self { extended_document } + } + + #[wasm_bindgen(js_name=getDocument)] + pub fn get_document_transition(&self) -> ExtendedDocumentWasm { + self.extended_document.clone() + } +} diff --git a/packages/wasm-dpp/src/document/errors/trying_to_replace_immutable_document_error.rs b/packages/wasm-dpp/src/document/errors/trying_to_replace_immutable_document_error.rs new file mode 100644 index 00000000000..ef3a206fd87 --- /dev/null +++ b/packages/wasm-dpp/src/document/errors/trying_to_replace_immutable_document_error.rs @@ -0,0 +1,19 @@ +use crate::ExtendedDocumentWasm; +use thiserror::Error; + +use super::*; + +#[wasm_bindgen] +#[derive(Error, Debug)] +#[error("Trying to update an immutable document")] +pub struct TryingToReplaceImmutableDocumentError { + extended_document: ExtendedDocumentWasm, +} + +#[wasm_bindgen] +impl TryingToReplaceImmutableDocumentError { + #[wasm_bindgen(constructor)] + pub fn new(extended_document: ExtendedDocumentWasm) -> Self { + TryingToReplaceImmutableDocumentError { extended_document } + } +} diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index edd8d251bda..a12d35bee13 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -4,7 +4,7 @@ use dpp::document::{ extended_document_property_names, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, }; use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; -use dpp::platform_value::Value; +use dpp::platform_value::{ReplacementType, Value}; use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::{JsonValueExt, ReplaceWith}; @@ -155,40 +155,29 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=set)] pub fn set(&mut self, path: String, js_value_to_set: JsValue) -> Result<(), JsValue> { let (identifier_paths, _) = self.0.get_identifiers_and_binary_paths().with_js_error()?; - for property_path in identifier_paths { - if property_path == path { - let id_value = js_value_to_set.with_serde_to_json_value()?; - let id_string = id_value - .as_str() - .context("the value must be a string") - .with_js_error()?; - let id = Identifier::from_string(id_string, Encoding::Base58).with_js_error()?; - let new_value = serde_json::to_value(id.as_bytes()).with_js_error()?; - let mut value: Value = new_value.into(); - - return self.0.set(&path, value).with_js_error(); - } else if property_path.starts_with(&path) { - let (_, suffix) = property_path.split_at(path.len() + 1); - let mut value: Value = js_value_to_set.with_serde_to_json_value()?.into(); - let map = value.to_btree_ref_map()?; - if map.get_at_path(suffix).is_ok() { - let id_string = value - .remove_path_into::(suffix) - .with_context(|| format!("unable convert `{path}` into string")) - .map_err(|e| format!("{e:#}"))?; - let id: IdentifierWrapper = - Identifier::from_string(&id_string, Encoding::Base58) - .with_js_error()? - .into(); - let new_value = serde_json::to_value(id.inner().as_bytes()).with_js_error()?; - value.insert_with_path(suffix, new_value).with_js_error()?; - - return self.0.set(&path, value).with_js_error(); - } - } + let mut value: Value = js_value_to_set.with_serde_to_json_value()?.into(); + if identifier_paths.contains(path.as_str()) { + let identifier_value = ReplacementType::Bytes + .replace_consume_value(value) + .map_err(ProtocolError::ValueError) + .with_js_error()?; + return self.0.set(&path, identifier_value).with_js_error(); + } else { + identifier_paths + .into_iter() + .try_for_each(|identifier_path| { + if identifier_path.starts_with(path.as_str()) { + let (_, suffix) = identifier_path.split_at(path.len() + 1); + value + .replace_at_path(suffix, ReplacementType::Bytes) + .map_err(ProtocolError::ValueError) + .map(|_| ()) + .with_js_error() + } else { + Ok(()) + } + })?; } - - let value: Value = js_value_to_set.with_serde_to_json_value()?.into(); self.0.set(&path, value).with_js_error() } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index bbef504786d..600cfa1a854 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -1,5 +1,7 @@ +use std::collections::HashSet; use std::sync::Arc; +use dpp::platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; use dpp::platform_value::ReplacementType; use dpp::{ document::{ @@ -148,12 +150,11 @@ impl DocumentFactoryWASM { .create_from_object(raw_document, options) .await .with_js_error()?; - - // When data contract is available, replace remaining dynamic paths - let mut document_data = document.properties_as_mut(); let (identifier_paths, binary_paths) = document - .get_identifiers_and_binary_paths() + .get_identifiers_and_binary_paths_owned() .with_js_error()?; + // When data contract is available, replace remaining dynamic paths + let mut document_data = document.properties_as_mut(); document_data .replace_at_paths(identifier_paths, ReplacementType::Bytes) .map_err(ProtocolError::ValueError) diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 355419b9f2b..00716033b87 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -22,6 +22,7 @@ use dpp::{ }; use js_sys::Uint8Array; use js_sys::{Array, Number}; +use serde_json::Value; use wasm_bindgen::__rt::Ref; use dpp::document::Document; @@ -279,6 +280,19 @@ impl StateRepositoryLike for ExternalStateRepositoryLikeWrapper { todo!() } + async fn fetch_extended_documents( + &self, + _contract_id: &Identifier, + _data_contract_type: &str, + _where_query: serde_json::Value, + _execution_context: &StateTransitionExecutionContext, + ) -> Result> + where + T: for<'de> serde::de::Deserialize<'de> + 'static, + { + todo!() + } + async fn create_document( &self, _document: &Document, From 65ba3be9bf3ddf0a2d536a5218550ef2ccccb2a3 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 1 Mar 2023 17:31:51 +0700 Subject: [PATCH 024/228] added identifier to platform value --- .../rs-platform-value/src/converter/ciborium.rs | 1 + .../src/converter/serde_json.rs | 3 +++ packages/rs-platform-value/src/display.rs | 4 ++++ packages/rs-platform-value/src/lib.rs | 10 +++++++--- packages/rs-platform-value/src/system_bytes.rs | 16 ++++++++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 4a25069e09f..8a2d2f48044 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -100,6 +100,7 @@ impl TryInto for Value { .map(|(k, v)| Ok((k.try_into()?, v.try_into()?))) .collect::, Error>>()?, ), + Value::Identifier(bytes) => CborValue::Bytes(bytes.to_vec()), }) } } diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index a9a6d2bb274..e2d0b406973 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -87,6 +87,9 @@ impl TryInto for Value { }) .collect::, Error>>()?, ), + Value::Identifier(bytes) => { + JsonValue::String(bs58::encode(bytes.as_slice()).into_string()) + } }) } } diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index dd9c444bf8c..c0d44049dbf 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -47,6 +47,10 @@ impl Value { Value::I16(i) => format!("(i16){}", i), Value::U8(i) => format!("(u8){}", i), Value::I8(i) => format!("(i8){}", i), + Value::Identifier(identifier) => format!( + "identifier {}", + bs58::encode(identifier.as_slice()).into_string() + ), } } } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index efb2088aa5d..aed1971655b 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -60,12 +60,14 @@ pub enum Value { /// A i8 integer I8(i8), - // Todo: add this in - // /// A 256 bit hash - // Hash256(Hash256), /// Bytes Bytes(Vec), + /// Identifier + /// The identifier is very similar to bytes, however it is serialized to Base58 when converted + /// to a JSON Value + Identifier(Hash256), + /// A float Float(f64), @@ -1023,6 +1025,8 @@ implfrom! { Bytes(Vec), Bytes(&[u8]), + Identifier(Hash256), + Float(f64), Float(f32), diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index 5f62a96c054..140b39b4c60 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -17,6 +17,9 @@ impl Value { /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108)]); /// assert_eq!(value.into_system_bytes(), Ok(vec![104, 101, 108])); /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.into_system_bytes(), Ok(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// /// let value = Value::Bool(true); /// assert_eq!(value.into_system_bytes(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); /// ``` @@ -35,6 +38,7 @@ impl Value { }) .collect::, Error>>(), Value::Bytes(vec) => Ok(vec), + Value::Identifier(identifier) => Ok(Vec::from(identifier)), _other => Err(Error::StructureError( "value are not bytes, a string, or an array of values representing bytes" .to_string(), @@ -58,6 +62,9 @@ impl Value { /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108)]); /// assert_eq!(value.to_system_bytes(), Ok(vec![104, 101, 108])); /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.to_system_bytes(), Ok(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// /// let value = Value::Bool(true); /// assert_eq!(value.to_system_bytes(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); /// ``` @@ -76,6 +83,7 @@ impl Value { }) .collect::, Error>>(), Value::Bytes(vec) => Ok(vec.clone()), + Value::Identifier(identifier) => Ok(Vec::from(identifier.as_slice())), _other => Err(Error::StructureError( "value are not bytes, a string, or an array of values representing bytes" .to_string(), @@ -105,6 +113,9 @@ impl Value { /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); /// assert_eq!(value.into_system_hash256(), Ok([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101])); /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.into_system_hash256(), Ok([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// /// let value = Value::Bool(true); /// assert_eq!(value.into_system_hash256(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); /// ``` @@ -133,6 +144,7 @@ impl Value { vec.try_into() .map_err(|_| Error::StructureError("value was bytes, but was not 32 bytes long".to_string())) }, + Value::Identifier(identifier) => Ok(identifier), _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), } } @@ -159,6 +171,9 @@ impl Value { /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); /// assert_eq!(value.to_system_hash256(), Ok([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101])); /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.to_system_hash256(), Ok([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// /// let value = Value::Bool(true); /// assert_eq!(value.to_system_hash256(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); /// ``` @@ -182,6 +197,7 @@ impl Value { vec.clone().try_into() .map_err(|_| Error::StructureError("value was bytes, but was not 32 bytes long".to_string())) }, + Value::Identifier(identifier) => Ok(identifier.to_owned()), _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), } } From f6390a4ac71ef6b268627aa89ae16786af16ac3e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 1 Mar 2023 20:58:48 +0700 Subject: [PATCH 025/228] more work --- .../reward_share_data_triggers/mod.rs | 40 +++++---- .../rs-dpp/src/document/document_factory.rs | 89 +++++++++++-------- .../tests/fixtures/get_documents_fixture.rs | 20 ++--- .../fixtures/get_dpns_document_fixture.rs | 2 +- ...ternode_reward_shares_documents_fixture.rs | 4 +- .../rs-drive/src/drive/document/update.rs | 2 +- packages/wasm-dpp/src/document/factory.rs | 2 +- 7 files changed, 92 insertions(+), 67 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index b5ea4f6c090..025c9080bc3 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -1,5 +1,6 @@ use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; use serde_json::json; use crate::document::Document; @@ -32,22 +33,29 @@ where let is_dry_run = context.state_transition_execution_context.is_dry_run(); let owner_id = context.owner_id.to_string(Encoding::Base58); - let dt_create = match document_transition { - DocumentTransition::Create(d) => d, + let document_create_transition = match document_transition { + DocumentTransition::Create(document_create_transition) => document_create_transition, _ => bail!( "the Document Transition {} isn't 'CREATE'", get_from_transition!(document_transition, id) ), }; - let data = dt_create.data.as_ref().ok_or_else(|| { - anyhow!( - "data isn't defined in Data Transition '{}'", - dt_create.base.id - ) - })?; - - let pay_to_id_bytes = data.get_bytes(PROPERTY_PAY_TO_ID)?; - let percentage = data.get_u64(PROPERTY_PERCENTAGE)?; + let data: Value = document_create_transition + .data + .as_ref() + .ok_or_else(|| { + anyhow!( + "data isn't defined in Data Transition '{}'", + document_create_transition.base.id + ) + })? + .clone() + .into(); + + let properties = data.into_btree_map()?; + + let pay_to_id_bytes = properties.get_bytes(PROPERTY_PAY_TO_ID)?; + let percentage = properties.get_integer(PROPERTY_PERCENTAGE)?; if !is_dry_run { // Do not allow creating document if ownerId is not in SML @@ -63,7 +71,7 @@ where if !owner_id_in_sml { let err = create_error( context, - dt_create, + document_create_transition, "Only masternode identities can share rewards".to_string(), ); result.add_error(err.into()); @@ -83,7 +91,7 @@ where if !is_dry_run && maybe_identity.is_none() { let err = create_error( context, - dt_create, + document_create_transition, format!("Identity '{}' doesn't exist", pay_to_identifier), ); result.add_error(err.into()) @@ -93,7 +101,7 @@ where .state_repository .fetch_documents( &context.data_contract.id, - &dt_create.base.document_type, + &document_create_transition.base.document_type, json!({ "where" : [ [ "$owner_id", "==", owner_id ]] }), @@ -108,7 +116,7 @@ where if documents.len() >= MAX_DOCUMENTS { let err = create_error( context, - dt_create, + document_create_transition, format!( "Reward shares cannot contain more than {} identities", MAX_DOCUMENTS @@ -126,7 +134,7 @@ where if total_percent > MAX_PERCENTAGE { let err = create_error( context, - dt_create, + document_create_transition, format!("Percentage can not be more than {}", MAX_PERCENTAGE), ); result.add_error(err.into()); diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index b4917f099a1..939a03f9299 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -1,8 +1,10 @@ use anyhow::Context; use chrono::Utc; +use std::collections::BTreeMap; use itertools::Itertools; +use platform_value::Value; use rand::rngs::StdRng; use rand::SeedableRng; use serde::{Deserialize, Serialize}; @@ -10,6 +12,10 @@ use serde_json::{json, Value as JsonValue}; use crate::document::extended_document::{property_names, ExtendedDocument}; +use crate::data_contract::DriveContractExt; +use crate::document::document_transition::INITIAL_REVISION; +use crate::document::{extended_document, Document}; +use crate::identity::TimestampMillis; use crate::{ data_contract::{errors::DataContractError, DataContract}, decode_protocol_entity_factory::DecodeProtocolEntity, @@ -104,12 +110,12 @@ where &self, data_contract: DataContract, owner_id: Identifier, - document_type: String, - data: JsonValue, + document_type_name: String, + data: Value, ) -> Result { - if !data_contract.is_document_defined(&document_type) { + if !data_contract.is_document_defined(&document_type_name) { return Err(DataContractError::InvalidDocumentTypeError { - doc_type: document_type, + doc_type: document_type_name, data_contract, } .into()); @@ -117,57 +123,68 @@ where let document_entropy = entropy_generator::generate()?; // TODO use EntropyGenerator - let document_required_fields = data_contract - .get_document_schema(&document_type)? - .get_schema_required_fields()?; - let document_id = generate_document_id( &data_contract.id, &owner_id, - &document_type, + &document_type_name, &document_entropy, ); - let mut raw_document = json!({ - PROPERTY_DOCUMENT_PROTOCOL_VERSION: self.protocol_version, - PROPERTY_ID: document_id.to_buffer(), - PROPERTY_DOCUMENT_TYPE: document_type, - PROPERTY_DATA_CONTRACT_ID: data_contract.id.to_buffer(), - PROPERTY_DOCUMENT_OWNER_ID: owner_id.to_buffer(), - PROPERTY_REVISION: document_transition::INITIAL_REVISION, - }); + let document_type = data_contract.document_type_for_name(document_type_name.as_str())?; + let revision = if document_type.documents_mutable { + Some(INITIAL_REVISION) + } else { + None + }; - if let JsonValue::Object(ref mut raw_document_map) = raw_document { - if let JsonValue::Object(data_map) = data { - raw_document_map.extend(data_map) - } - } + let contains_created_at = document_type.required_fields.contains(PROPERTY_CREATED_AT); + let contains_updated_at = document_type.required_fields.contains(PROPERTY_UPDATED_AT); - let creation_time = Utc::now().timestamp_millis(); - if document_required_fields.contains(&PROPERTY_CREATED_AT) { - raw_document.insert(PROPERTY_CREATED_AT.to_string(), json!(Some(creation_time)))?; - } + let (created_at, updated_at) = if contains_created_at || contains_updated_at { + //we want only one call to get current time + let now = Utc::now().timestamp_millis() as TimestampMillis; + let created_at = if contains_created_at { Some(now) } else { None }; - if document_required_fields.contains(&PROPERTY_UPDATED_AT) { - raw_document.insert(PROPERTY_UPDATED_AT.to_string(), json!(Some(creation_time)))?; - } + let updated_at = if contains_updated_at { Some(now) } else { None }; + (created_at, updated_at) + } else { + (None, None) + }; + + let mut extended_document = ExtendedDocument { + protocol_version: self.protocol_version, + document_type_name, + data_contract_id: data_contract.id.clone(), + document: Document { + id: document_id.to_buffer(), + owner_id: owner_id.to_buffer(), + properties: data.into_btree_map().map_err(ProtocolError::ValueError)?, + revision, + created_at, + updated_at, + }, + data_contract: DataContract::default(), + metadata: None, + entropy: document_entropy, + }; + let json_value = extended_document.to_json()?; let validation_result = self .document_validator - .validate(&raw_document, &data_contract)?; + .validate(&json_value, &data_contract)?; + + extended_document.data_contract = data_contract; + if !validation_result.is_valid() { return Err(ProtocolError::Document(Box::new( DocumentError::InvalidDocumentError { errors: validation_result.errors, - raw_document, + raw_document: json_value, }, ))); } - let mut document = ExtendedDocument::from_raw_document(raw_document, data_contract)?; - document.entropy = document_entropy; - - Ok(document) + Ok(extended_document) } pub fn create_state_transition( @@ -453,7 +470,7 @@ mod test { data_contract, owner_id, document_type.to_string(), - json!({ "name": name }), + json!({ "name": name }).into(), ) .expect("document creation shouldn't fail"); assert_eq!(document_type, document.document_type_name); diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index c29aaebfd8f..40502cd5840 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -71,56 +71,56 @@ fn get_extended_documents( data_contract.clone(), owner_id, "niceDocument".to_string(), - json!({ "name": "Cutie" }), + json!({ "name": "Cutie" }).into(), )?, factory.create_document_for_state_transition( data_contract.clone(), owner_id, "prettyDocument".to_string(), - json!({ "lastName": "Shiny" }), + json!({ "lastName": "Shiny" }).into(), )?, factory.create_document_for_state_transition( data_contract.clone(), owner_id, "prettyDocument".to_string(), - json!({ "lastName": "Sweety" }), + json!({ "lastName": "Sweety" }).into(), )?, factory.create_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - json!( { "firstName": "William", "lastName": "Birkin" }), + json!( { "firstName": "William", "lastName": "Birkin" }).into(), )?, factory.create_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - json!( { "firstName": "Leon", "lastName": "Kennedy" }), + json!( { "firstName": "Leon", "lastName": "Kennedy" }).into(), )?, factory.create_document_for_state_transition( data_contract.clone(), owner_id, "noTimeDocument".to_string(), - json!({ "name": "ImOutOfTime" }), + json!({ "name": "ImOutOfTime" }).into(), )?, factory.create_document_for_state_transition( data_contract.clone(), owner_id, "uniqueDates".to_string(), - json!({ "firstName": "John" }), + json!({ "firstName": "John" }).into(), )?, factory.create_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - json!( { "firstName": "Bill", "lastName": "Gates" }), + json!( { "firstName": "Bill", "lastName": "Gates" }).into(), )?, - factory.create_document_for_state_transition(data_contract.clone(), owner_id, "withByteArrays".to_string(), json!( { "byteArrayField": get_random_10_bytes(), "identifierField": gen_owner_id().to_buffer() }),)?, + factory.create_document_for_state_transition(data_contract.clone(), owner_id, "withByteArrays".to_string(), json!( { "byteArrayField": get_random_10_bytes(), "identifierField": gen_owner_id().to_buffer() }).into())?, factory.create_document_for_state_transition( data_contract, owner_id, "optionalUniqueIndexedDocument".to_string(), - json!({ "firstName": "Jacques-Yves", "lastName": "Cousteau" }), + json!({ "firstName": "Jacques-Yves", "lastName": "Cousteau" }).into() )?, ]; diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs index 9e9e14e1e39..72716d9e55d 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs @@ -62,7 +62,7 @@ pub fn get_dpns_parent_document_fixture(options: ParentDocumentOptions) -> Exten data_contract, options.owner_id, String::from("domain"), - data, + data.into(), ) .expect("DPNS document should be created") } diff --git a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs index ded9ff2a7b2..71cb2af28ab 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs @@ -41,8 +41,8 @@ pub fn get_masternode_reward_shares_documents_fixture() -> (Vec Date: Thu, 2 Mar 2023 11:03:47 +0700 Subject: [PATCH 026/228] more work --- .../rs-dpp/schema/document/documentBase.json | 26 ++----- .../schema/document/documentExtended.json | 55 ++++++++++++++ .../reward_share_data_triggers/mod.rs | 8 +-- packages/rs-dpp/src/document/document.rs | 57 ++++++++++++--- .../rs-dpp/src/document/document_factory.rs | 40 ++++++----- .../rs-dpp/src/document/document_validator.rs | 72 +++++++++++++++---- .../rs-dpp/src/document/extended_document.rs | 32 ++++++++- .../src/converter/serde_json.rs | 22 +++++- packages/wasm-dpp/src/document/mod.rs | 7 +- 9 files changed, 241 insertions(+), 78 deletions(-) create mode 100644 packages/rs-dpp/schema/document/documentExtended.json diff --git a/packages/rs-dpp/schema/document/documentBase.json b/packages/rs-dpp/schema/document/documentBase.json index 12aba140b5e..6ddb9aa33c2 100644 --- a/packages/rs-dpp/schema/document/documentBase.json +++ b/packages/rs-dpp/schema/document/documentBase.json @@ -2,10 +2,6 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { - "$protocolVersion": { - "type": "integer", - "$comment": "Maximum is the latest protocol version" - }, "$id": { "type": "array", "byteArray": true, @@ -13,20 +9,6 @@ "maxItems": 32, "contentMediaType": "application/x.dash.dpp.identifier" }, - "$type": { - "type": "string" - }, - "$revision": { - "type": "integer", - "minimum": 1 - }, - "$dataContractId": { - "type": "array", - "byteArray": true, - "minItems": 32, - "maxItems": 32, - "contentMediaType": "application/x.dash.dpp.identifier" - }, "$ownerId": { "type": "array", "byteArray": true, @@ -34,6 +16,10 @@ "maxItems": 32, "contentMediaType": "application/x.dash.dpp.identifier" }, + "$revision": { + "type": "integer", + "minimum": 1 + }, "$createdAt": { "type": "integer", "minimum": 0 @@ -44,11 +30,7 @@ } }, "required": [ - "$protocolVersion", "$id", - "$type", - "$revision", - "$dataContractId", "$ownerId" ], "additionalProperties": false diff --git a/packages/rs-dpp/schema/document/documentExtended.json b/packages/rs-dpp/schema/document/documentExtended.json new file mode 100644 index 00000000000..acff4cd2cfa --- /dev/null +++ b/packages/rs-dpp/schema/document/documentExtended.json @@ -0,0 +1,55 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "properties": { + "$protocolVersion": { + "type": "integer", + "$comment": "Maximum is the latest protocol version" + }, + "$id": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "contentMediaType": "application/x.dash.dpp.identifier" + }, + "$type": { + "type": "string" + }, + "$revision": { + "type": "integer", + "minimum": 1 + }, + "$dataContractId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "contentMediaType": "application/x.dash.dpp.identifier" + }, + "$ownerId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "contentMediaType": "application/x.dash.dpp.identifier" + }, + "$createdAt": { + "type": "integer", + "minimum": 0 + }, + "$updatedAt": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "$protocolVersion", + "$id", + "$type", + "$revision", + "$dataContractId", + "$ownerId" + ], + "additionalProperties": false +} \ No newline at end of file diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 025c9080bc3..3992da0b69f 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -40,6 +40,7 @@ where get_from_transition!(document_transition, id) ), }; + dbg!(&document_create_transition.data); let data: Value = document_create_transition .data .as_ref() @@ -53,8 +54,7 @@ where .into(); let properties = data.into_btree_map()?; - - let pay_to_id_bytes = properties.get_bytes(PROPERTY_PAY_TO_ID)?; + let pay_to_id = properties.get_system_hash256_bytes(PROPERTY_PAY_TO_ID)?; let percentage = properties.get_integer(PROPERTY_PERCENTAGE)?; if !is_dry_run { @@ -79,7 +79,7 @@ where } // payToId identity exists - let pay_to_identifier = Identifier::from_bytes(&pay_to_id_bytes)?; + let pay_to_identifier = Identifier::from(pay_to_id); let maybe_identity = context .state_repository .fetch_identity( @@ -215,7 +215,7 @@ mod test { }; let document_transitions = get_document_transitions_fixture([(Action::Create, vec![documents[0].clone()])]); - + dbg!(&document_transitions); TestData { extended_documents: documents, data_contract, diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 759fee17e34..cc90c4eb07f 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -38,7 +38,7 @@ use std::convert::{TryFrom, TryInto}; use std::fmt; use itertools::Itertools; -use serde_json::Value as JsonValue; +use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; use platform_value::Value; @@ -245,7 +245,6 @@ impl Document { } pub fn get_identifiers_and_binary_paths<'a>( - &'a self, data_contract: &'a DataContract, document_type_name: &'a str, ) -> Result<(HashSet<&'a str>, HashSet<&'a str>), ProtocolError> { @@ -256,20 +255,56 @@ impl Document { Ok((identifiers_paths, binary_paths)) } - pub fn to_json( - &self, + pub fn to_json(&self) -> Result { + let mut value = json!({ + property_names::ID: self.id, + property_names::OWNER_ID: self.owner_id, + }); + let value_mut = value.as_object_mut().unwrap(); + if let Some(created_at) = self.created_at { + value_mut.insert( + property_names::CREATED_AT.to_string(), + JsonValue::Number(created_at.into()), + ); + } + if let Some(updated_at) = self.updated_at { + value_mut.insert( + property_names::UPDATED_AT.to_string(), + JsonValue::Number(updated_at.into()), + ); + } + if let Some(revision) = self.revision { + value_mut.insert( + property_names::REVISION.to_string(), + JsonValue::Number(revision.into()), + ); + } + + self.properties + .iter() + .try_for_each(|(key, property_value)| { + let serde_value: JsonValue = property_value + .clone() + .try_into() + .map_err(ProtocolError::ValueError)?; + value_mut.insert(key.to_string(), serde_value); + Ok::<(), ProtocolError>(()) + })?; + + Ok(value) + } + + pub fn replace_fields( + value: &mut JsonValue, data_contract: &DataContract, document_type_name: &str, - ) -> Result { - let mut value = serde_json::to_value(self)?; - + ) -> Result<(), ProtocolError> { let (identifier_paths, binary_paths) = - self.get_identifiers_and_binary_paths(data_contract, document_type_name)?; + Self::get_identifiers_and_binary_paths(data_contract, document_type_name)?; value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - - Ok(value) + Ok(()) } // The skipIdentifierConversion option is removed as it doesn't make sense in the case of @@ -282,7 +317,7 @@ impl Document { let mut json_object = serde_json::to_value(self)?; let (identifier_paths, binary_paths) = - self.get_identifiers_and_binary_paths(data_contract, document_type_name)?; + Self::get_identifiers_and_binary_paths(data_contract, document_type_name)?; let _ = json_object.replace_identifier_paths(identifier_paths, ReplaceWith::Bytes); let _ = json_object.replace_binary_paths(binary_paths, ReplaceWith::Bytes); diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 939a03f9299..e7570c337c1 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -151,30 +151,32 @@ where (None, None) }; + let document = Document { + id: document_id.to_buffer(), + owner_id: owner_id.to_buffer(), + properties: data.into_btree_map().map_err(ProtocolError::ValueError)?, + revision, + created_at, + updated_at, + }; + + let mut json_value = document.to_json()?; + let validation_result = + self.document_validator + .validate(&json_value, &data_contract, document_type)?; + + Document::replace_fields(&mut json_value, &data_contract, document_type.name.as_str())?; + let mut extended_document = ExtendedDocument { protocol_version: self.protocol_version, document_type_name, data_contract_id: data_contract.id.clone(), - document: Document { - id: document_id.to_buffer(), - owner_id: owner_id.to_buffer(), - properties: data.into_btree_map().map_err(ProtocolError::ValueError)?, - revision, - created_at, - updated_at, - }, - data_contract: DataContract::default(), + document, + data_contract, metadata: None, entropy: document_entropy, }; - let json_value = extended_document.to_json()?; - let validation_result = self - .document_validator - .validate(&json_value, &data_contract)?; - - extended_document.data_contract = data_contract; - if !validation_result.is_valid() { return Err(ProtocolError::Document(Box::new( DocumentError::InvalidDocumentError { @@ -273,13 +275,13 @@ where options: FactoryOptions, ) -> Result { let data_contract = self - .validate_data_contract_for_document(&raw_document, options) + .validate_data_contract_for_extended_document(&raw_document, options) .await?; ExtendedDocument::from_raw_document(raw_document, data_contract) } - async fn validate_data_contract_for_document( + async fn validate_data_contract_for_extended_document( &self, raw_document: &JsonValue, options: FactoryOptions, @@ -304,7 +306,7 @@ where if !options.skip_validation { let result = self .document_validator - .validate(raw_document, &data_contract)?; + .validate_extended(raw_document, &data_contract)?; if !result.is_valid() { return Err(ProtocolError::Document(Box::new( DocumentError::InvalidDocumentError { diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index aa28c0a26ae..8ce660d5832 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -4,6 +4,7 @@ use anyhow::anyhow; use lazy_static::lazy_static; use serde_json::Value as JsonValue; +use crate::data_contract::document_type::DocumentType; use crate::{ consensus::basic::BasicError, data_contract::{ @@ -24,6 +25,11 @@ lazy_static! { serde_json::from_str(include_str!("../../schema/document/documentBase.json")).unwrap(); } +lazy_static! { + static ref EXTENDED_DOCUMENT_SCHEMA: JsonValue = + serde_json::from_str(include_str!("../../schema/document/documentExtended.json")).unwrap(); +} + pub struct DocumentValidator { protocol_version_validator: Arc, } @@ -39,6 +45,44 @@ impl DocumentValidator { &self, raw_document: &JsonValue, data_contract: &DataContract, + document_type: &DocumentType, + ) -> Result, ProtocolError> { + let mut result = ValidationResult::default(); + let enriched_data_contract = enrich_data_contract_with_base_schema( + data_contract, + &BASE_DOCUMENT_SCHEMA, + PREFIX_BYTE_0, + &[], + )?; + + //todo: maybe we should validate on the document type instead as it already has all the + //information needed + let document_schema = enriched_data_contract + .get_document_schema(document_type.name.as_str())? + .to_owned(); + + let json_schema_validator = if let Some(defs) = &data_contract.defs { + JsonSchemaValidator::new_with_definitions(document_schema, defs.iter()) + } else { + JsonSchemaValidator::new(document_schema) + } + .map_err(|e| anyhow!("unable to process the contract: {}", e))?; + + let json_schema_validation_result = json_schema_validator.validate(raw_document)?; + result.merge(json_schema_validation_result); + + if !result.is_valid() { + return Ok(result); + } + //todo: validate the version + + Ok(result) + } + + pub fn validate_extended( + &self, + raw_document: &JsonValue, + data_contract: &DataContract, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); @@ -65,7 +109,7 @@ impl DocumentValidator { let enriched_data_contract = enrich_data_contract_with_base_schema( data_contract, - &BASE_DOCUMENT_SCHEMA, + &EXTENDED_DOCUMENT_SCHEMA, PREFIX_BYTE_0, &[], )?; @@ -165,7 +209,7 @@ mod test { .unwrap_or_else(|_| panic!("the {} should exist and be removed", property_name)); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -192,7 +236,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -229,7 +273,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -267,7 +311,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -298,7 +342,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -328,7 +372,7 @@ mod test { .expect("the '$type' should exist and be removed"); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let validation_error = result.errors.get(0).expect("should return an error"); assert!( @@ -349,7 +393,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let validation_error = result.errors.get(0).expect("the error should exist"); assert_eq!(1024, validation_error.get_code()); @@ -368,7 +412,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -394,7 +438,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -421,7 +465,7 @@ mod test { raw_document.insert(String::from("name"), json!(1)).unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -450,7 +494,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -483,7 +527,7 @@ mod test { .unwrap(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); let schema_error = get_first_schema_error(&result); @@ -507,7 +551,7 @@ mod test { } = get_test_data(); let result = document_validator - .validate(&raw_document, &data_contract) + .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); assert!(result.is_valid()) diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 1296c397df2..4705b5cd6cc 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -19,7 +19,7 @@ use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; -use serde_json::Value as JsonValue; +use serde_json::{json, Value as JsonValue}; use std::collections::{BTreeMap, HashSet}; use std::convert::TryInto; @@ -166,7 +166,20 @@ impl ExtendedDocument { } pub fn to_json(&self) -> Result { - let mut value = serde_json::to_value(self)?; + let mut value = self.document.to_json()?; + let value_mut = value.as_object_mut().unwrap(); + value_mut.insert( + property_names::PROTOCOL_VERSION.to_string(), + JsonValue::Number(self.protocol_version.into()), + ); + value_mut.insert( + property_names::DOCUMENT_TYPE.to_string(), + JsonValue::String(self.document_type_name.clone()), + ); + value_mut.insert( + property_names::DATA_CONTRACT_ID.to_string(), + json!(self.data_contract.id), + ); let (identifier_paths, binary_paths) = self .data_contract @@ -214,7 +227,20 @@ impl ExtendedDocument { // The skipIdentifierConversion option is removed as it doesn't make sense in the case of // of Rust. Rust doesn't distinguish between `Buffer` and `Identifier` pub fn to_object(&self) -> Result { - let mut json_object = serde_json::to_value(self)?; + let mut json_object = self.document.to_json()?; + let value_mut = json_object.as_object_mut().unwrap(); + value_mut.insert( + property_names::PROTOCOL_VERSION.to_string(), + JsonValue::Number(self.protocol_version.into()), + ); + value_mut.insert( + property_names::DOCUMENT_TYPE.to_string(), + JsonValue::String(self.document_type_name.clone()), + ); + value_mut.insert( + property_names::DATA_CONTRACT_ID.to_string(), + json!(self.data_contract.id), + ); let (identifier_paths, binary_paths) = self.get_identifiers_and_binary_paths()?; let _ = json_object.replace_identifier_paths(identifier_paths, ReplaceWith::Bytes); diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index e2d0b406973..1a629211ba8 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -30,7 +30,27 @@ impl From for Value { unreachable!("this shouldn't be reachable") } JsonValue::String(string) => Self::Text(string), - JsonValue::Array(array) => Self::Array(array.into_iter().map(|v| v.into()).collect()), + JsonValue::Array(array) => { + let u8_max = u8::MAX as u64; + if !array.is_empty() + && array.iter().all(|v| { + let Some(int) = v.as_u64() else { + return false; + }; + int.le(&u8_max) + }) + { + //this is an array of bytes + Self::Bytes( + array + .into_iter() + .map(|v| v.as_u64().unwrap() as u8) + .collect(), + ) + } else { + Self::Array(array.into_iter().map(|v| v.into()).collect()) + } + } JsonValue::Object(map) => { Self::Map(map.into_iter().map(|(k, v)| (k.into(), v.into())).collect()) } diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 1d2710fe925..b2888d8614a 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -217,10 +217,9 @@ impl DocumentWasm { .to_object(&data_contract.0, document_type_name) .with_js_error()?; - let (identifiers_paths, binary_paths) = self - .0 - .get_identifiers_and_binary_paths(&data_contract.0, document_type_name) - .with_js_error()?; + let (identifiers_paths, binary_paths) = + Document::get_identifiers_and_binary_paths(&data_contract.0, document_type_name) + .with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_value = value.serialize(&serializer)?; From 2f60d15c56ba29f9a3d94016ee104a26204ded2d Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 Mar 2023 11:06:03 +0700 Subject: [PATCH 027/228] more work --- .../src/data_contract/get_property_definition_by_path.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/get_property_definition_by_path.rs b/packages/rs-dpp/src/data_contract/get_property_definition_by_path.rs index 3d4ae123c62..b1395a9336a 100644 --- a/packages/rs-dpp/src/data_contract/get_property_definition_by_path.rs +++ b/packages/rs-dpp/src/data_contract/get_property_definition_by_path.rs @@ -8,8 +8,8 @@ use crate::errors::ProtocolError; use crate::util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}; lazy_static! { - static ref BASE_DOCUMENT_SCHEMA: JsonValue = - serde_json::from_str(include_str!("../../schema/document/documentBase.json")).unwrap(); + static ref EXTENDED_DOCUMENT_SCHEMA: JsonValue = + serde_json::from_str(include_str!("../../schema/document/documentExtended.json")).unwrap(); } // Get user property definition pub fn get_property_definition_by_path<'a>( @@ -18,7 +18,7 @@ pub fn get_property_definition_by_path<'a>( ) -> Result<&'a JsonValue, ProtocolError> { // Return system properties schema if path.starts_with('$') { - return Ok(BASE_DOCUMENT_SCHEMA.get_value(&format!("properties.{}", path))?); + return Ok(EXTENDED_DOCUMENT_SCHEMA.get_value(&format!("properties.{}", path))?); } let mut path_components = path.split('.'); From 08c5e36390636e2693f76bec071ed0c645ba6595 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 Mar 2023 12:00:51 +0700 Subject: [PATCH 028/228] more fixes --- packages/rs-dpp/src/document/document.rs | 61 ++++++++++++++++++- .../rs-dpp/src/document/document_factory.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 43 +++++++++---- 3 files changed, 92 insertions(+), 14 deletions(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index cc90c4eb07f..25318b6fd7d 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -36,6 +36,7 @@ use chrono::{DateTime, NaiveDateTime, Utc}; use std::collections::{BTreeMap, HashSet}; use std::convert::{TryFrom, TryInto}; use std::fmt; +use std::process::id; use itertools::Itertools; use serde_json::{json, Value as JsonValue}; @@ -294,7 +295,52 @@ impl Document { Ok(value) } - pub fn replace_fields( + pub fn to_pretty_json( + &self, + data_contract: &DataContract, + document_type_name: &str, + ) -> Result { + let mut value = json!({ + property_names::ID: bs58::encode(self.id).into_string(), + property_names::OWNER_ID: bs58::encode(self.owner_id).into_string(), + }); + let value_mut = value.as_object_mut().unwrap(); + if let Some(created_at) = self.created_at { + value_mut.insert( + property_names::CREATED_AT.to_string(), + JsonValue::Number(created_at.into()), + ); + } + if let Some(updated_at) = self.updated_at { + value_mut.insert( + property_names::UPDATED_AT.to_string(), + JsonValue::Number(updated_at.into()), + ); + } + if let Some(revision) = self.revision { + value_mut.insert( + property_names::REVISION.to_string(), + JsonValue::Number(revision.into()), + ); + } + + self.properties + .iter() + .try_for_each(|(key, property_value)| { + let serde_value: JsonValue = property_value + .clone() + .try_into() + .map_err(ProtocolError::ValueError)?; + value_mut.insert(key.to_string(), serde_value); + Ok::<(), ProtocolError>(()) + })?; + + Self::replace_property_fields(&mut value, data_contract, document_type_name)?; + + Ok(value) + } + + pub fn replace_all_fields( value: &mut JsonValue, data_contract: &DataContract, document_type_name: &str, @@ -307,6 +353,19 @@ impl Document { Ok(()) } + pub fn replace_property_fields( + value: &mut JsonValue, + data_contract: &DataContract, + document_type_name: &str, + ) -> Result<(), ProtocolError> { + let (identifier_paths, binary_paths) = + data_contract.get_identifiers_and_binary_paths(document_type_name)?; + + value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; + value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; + Ok(()) + } + // The skipIdentifierConversion option is removed as it doesn't make sense in the case of // of Rust. Rust doesn't distinguish between `Buffer` and `Identifier` pub fn to_object( diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index e7570c337c1..b3264542b80 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -165,7 +165,7 @@ where self.document_validator .validate(&json_value, &data_contract, document_type)?; - Document::replace_fields(&mut json_value, &data_contract, document_type.name.as_str())?; + Document::replace_all_fields(&mut json_value, &data_contract, document_type.name.as_str())?; let mut extended_document = ExtendedDocument { protocol_version: self.protocol_version, diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 4705b5cd6cc..e5a2c238853 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -131,6 +131,13 @@ impl ExtendedDocument { self.document.updated_at.as_ref() } + pub fn from_json_string(string: &str) -> Result { + let json_value: JsonValue = serde_json::from_str(string).map_err(|_| { + ProtocolError::StringDecodeError("error decoding from json string".to_string()) + })?; + Self::from_json_document(json_value, DataContract::new()) + } + pub fn from_raw_document( raw_document: JsonValue, data_contract: DataContract, @@ -180,14 +187,26 @@ impl ExtendedDocument { property_names::DATA_CONTRACT_ID.to_string(), json!(self.data_contract.id), ); + Ok(value) + } - let (identifier_paths, binary_paths) = self - .data_contract - .get_identifiers_and_binary_paths(&self.document_type_name)?; - - value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; - value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - + pub fn to_pretty_json(&self) -> Result { + let mut value = self + .document + .to_pretty_json(&self.data_contract, &self.document_type_name)?; + let value_mut = value.as_object_mut().unwrap(); + value_mut.insert( + property_names::PROTOCOL_VERSION.to_string(), + JsonValue::Number(self.protocol_version.into()), + ); + value_mut.insert( + property_names::DOCUMENT_TYPE.to_string(), + JsonValue::String(self.document_type_name.clone()), + ); + value_mut.insert( + property_names::DATA_CONTRACT_ID.to_string(), + JsonValue::String(bs58::encode(self.data_contract_id.to_buffer()).into_string()), + ); Ok(value) } @@ -385,7 +404,7 @@ mod test { fn test_document_deserialize() -> Result<()> { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - let doc = serde_json::from_str::(&document_json)?; + let doc = ExtendedDocument::from_json_string(&document_json)?; assert_eq!(doc.document_type_name, "domain"); assert_eq!(doc.protocol_version, 0); assert_eq!( @@ -448,7 +467,7 @@ mod test { fn test_to_object() { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json").unwrap(); - let document = serde_json::from_str::(&document_json).unwrap(); + let document = ExtendedDocument::from_json_string(&document_json).unwrap(); let document_object = document.to_object().unwrap(); for property in IDENTIFIER_FIELDS { @@ -466,7 +485,7 @@ mod test { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - let document = serde_json::from_str::(&document_json)?; + let document = ExtendedDocument::from_json_string(&document_json)?; serde_json::to_string(&document)?; Ok(()) @@ -477,7 +496,7 @@ mod test { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - serde_json::from_str::(&document_json)?; + ExtendedDocument::from_json_string(&document_json)?; Ok(()) } @@ -548,7 +567,7 @@ mod test { }); let document = ExtendedDocument::from_raw_document(raw_document, data_contract).unwrap(); - let json_document = document.to_json().expect("no errors"); + let json_document = document.to_pretty_json().expect("no errors"); assert_eq!( json_document["$id"], From f662caf1f014aeb56b2660028e4969826ad0e03b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 Mar 2023 19:56:31 +0700 Subject: [PATCH 029/228] fixed issue --- packages/rs-dpp/src/document/document.rs | 45 +++++++++++++++++++ .../rs-dpp/src/document/extended_document.rs | 35 +++++---------- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 25318b6fd7d..baaba94a5d6 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -38,6 +38,7 @@ use std::convert::{TryFrom, TryInto}; use std::fmt; use std::process::id; +use ciborium::{cbor, Value as CborValue}; use itertools::Itertools; use serde_json::{json, Value as JsonValue}; @@ -295,6 +296,50 @@ impl Document { Ok(value) } + pub fn to_cbor_value(&self) -> Result { + let mut value = CborValue::Map(vec![]); + let value_mut = value.as_map_mut().unwrap(); + value_mut.push(( + CborValue::Text(property_names::ID.to_string()), + CborValue::Bytes(self.id.to_vec()), + )); + value_mut.push(( + CborValue::Text(property_names::OWNER_ID.to_string()), + CborValue::Bytes(self.owner_id.to_vec()), + )); + if let Some(created_at) = self.created_at { + value_mut.push(( + CborValue::Text(property_names::CREATED_AT.to_string()), + CborValue::Integer(created_at.into()), + )); + } + if let Some(updated_at) = self.updated_at { + value_mut.push(( + CborValue::Text(property_names::UPDATED_AT.to_string()), + CborValue::Integer(updated_at.into()), + )); + } + if let Some(revision) = self.revision { + value_mut.push(( + CborValue::Text(property_names::REVISION.to_string()), + CborValue::Integer(revision.into()), + )); + } + + self.properties + .iter() + .try_for_each(|(key, property_value)| { + let cbor_value: CborValue = property_value + .clone() + .try_into() + .map_err(ProtocolError::ValueError)?; + value_mut.push((CborValue::Text(key.clone()), cbor_value)); + Ok::<(), ProtocolError>(()) + })?; + + Ok(value) + } + pub fn to_pretty_json( &self, data_contract: &DataContract, diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index e5a2c238853..e96647f81e5 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -233,7 +233,6 @@ impl ExtendedDocument { let document_type_name = document_map.remove_string(property_names::DOCUMENT_TYPE)?; let document = Document::from_map(document_map, None, None)?; - Ok(ExtendedDocument { protocol_version, document_type_name, @@ -271,30 +270,20 @@ impl ExtendedDocument { pub fn to_buffer(&self) -> Result, ProtocolError> { let mut result_buf = self.protocol_version.encode_var_vec(); - let map = CborValue::serialized(&self) - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - - let mut canonical_map: CborCanonicalMap = map.try_into()?; - - canonical_map.remove(property_names::PROTOCOL_VERSION); + let mut cbor_value = self.document.to_cbor_value()?; + let value_mut = cbor_value.as_map_mut().unwrap(); - if self.updated_at().is_none() { - canonical_map.remove(property_names::UPDATED_AT); - } + value_mut.push(( + CborValue::Text(property_names::DOCUMENT_TYPE.to_string()), + CborValue::Text(self.document_type_name.clone()), + )); - let (identifier_paths, binary_paths) = self - .data_contract - .get_identifiers_and_binary_paths(&self.document_type_name)?; + value_mut.push(( + CborValue::Text(property_names::DATA_CONTRACT_ID.to_string()), + CborValue::Bytes(self.data_contract_id.to_buffer_vec()), + )); - // The static (part of structure) identifiers are being serialized to the String(base58) - canonical_map.replace_values(IDENTIFIER_FIELDS, ReplaceWith::Bytes); - // The DYNAMIC identifiers and binary fields are being serialized to the ArrayInt, therefore - // they both need to be converted to the the CborValue::Bytes - canonical_map.replace_paths( - identifier_paths.into_iter().chain(binary_paths), - FieldType::ArrayInt, - FieldType::Bytes, - ); + let mut canonical_map: CborCanonicalMap = cbor_value.try_into()?; let mut document_buffer = canonical_map .to_bytes() @@ -543,7 +532,7 @@ mod test { let buffer = document.to_buffer()?; - assert_eq!(document_cbor, buffer); + assert_eq!(hex::encode(document_cbor), hex::encode(buffer)); Ok(()) } From 1f32e76c19c16ed91fa75a644c42696f566cf33a Mon Sep 17 00:00:00 2001 From: Evgeny Fomin Date: Thu, 2 Mar 2023 20:25:11 +0100 Subject: [PATCH 030/228] fixed another issue --- packages/rs-platform-value/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index aed1971655b..e421d728818 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -29,6 +29,7 @@ pub use btreemap_field_replacement::ReplacementType; /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)] +#[serde(untagged)] pub enum Value { /// A u128 integer U128(u128), From 385e22f4b28e82257df871fe6e523bf8f911bec9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Mar 2023 11:00:49 +0700 Subject: [PATCH 031/228] tests passing --- packages/rs-drive-abci/src/state/genesis.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 26531700ccd..cad7b57586b 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -315,8 +315,8 @@ mod tests { assert_eq!( root_hash, [ - 59, 16, 30, 145, 9, 47, 66, 85, 133, 88, 194, 109, 241, 15, 226, 214, 163, 196, - 146, 107, 122, 145, 111, 45, 251, 242, 250, 157, 153, 43, 219, 184 + 111, 88, 10, 143, 94, 71, 51, 8, 40, 196, 201, 45, 155, 81, 130, 150, 9, 253, + 0, 184, 61, 2, 173, 157, 131, 24, 71, 199, 114, 11, 16, 44 ] ) } From 7324cb09aaf7a5209ba66360ca2422cb8367bc3b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Mar 2023 18:30:12 +0700 Subject: [PATCH 032/228] fixes --- packages/rs-dpp/src/data_contract/data_contract.rs | 11 ++++++----- .../rs-dpp/src/data_trigger/dpns_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/document.rs | 8 ++++---- packages/rs-dpp/src/document/document_facade.rs | 3 +-- packages/rs-dpp/src/document/document_factory.rs | 8 ++++---- packages/rs-dpp/src/document/extended_document.rs | 8 ++++---- .../src/tests/fixtures/get_documents_fixture.rs | 2 +- packages/rs-drive/src/drive/document/update.rs | 2 +- .../src/btreemap_field_replacement.rs | 4 ++-- .../src/btreemap_path_extensions.rs | 6 +++--- .../src/btreemap_path_insertion_extensions.rs | 2 +- packages/rs-platform-value/src/value_map.rs | 4 ++-- .../data_contract_update_transition/mod.rs | 2 +- packages/wasm-dpp/src/document/document_facade.rs | 2 +- .../wasm-dpp/src/document/extended_document.rs | 6 +++--- packages/wasm-dpp/src/document/factory.rs | 9 ++++----- packages/wasm-dpp/src/document/mod.rs | 14 +++++++------- .../document_batch_transition/mod.rs | 7 +++---- packages/wasm-dpp/src/state_repository.rs | 3 +-- packages/wasm-dpp/src/utils.rs | 1 - 20 files changed, 50 insertions(+), 54 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index fbfcc86a105..4542f38f879 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -2,8 +2,8 @@ use std::collections::{BTreeMap, HashSet}; use std::convert::TryFrom; use anyhow::anyhow; -use ciborium::value::Value as CborValue; -use integer_encoding::VarInt; + + use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; @@ -18,9 +18,9 @@ use crate::data_contract::contract_config::{ }; use crate::data_contract::get_binary_properties_from_schema::get_binary_properties; -use crate::util::cbor_value::{CborBTreeMapHelper, CborCanonicalMap}; -use crate::util::deserializer; -use crate::util::deserializer::SplitProtocolVersionOutcome; +use crate::util::cbor_value::{CborBTreeMapHelper}; + + use crate::util::json_value::{JsonValueExt, ReplaceWith}; use crate::util::string_encoding::Encoding; use crate::{ @@ -454,6 +454,7 @@ pub fn get_definitions( #[cfg(test)] mod test { use anyhow::Result; + use integer_encoding::VarInt; use crate::{ assert_error_contains, diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 5b42565d1db..59b95e31b0e 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -5,7 +5,7 @@ use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use serde_json::{json, Value as JsonValue}; -use crate::document::{Document, ExtendedDocument}; +use crate::document::{Document}; use crate::util::hash::hash; use crate::util::string_encoding::Encoding; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 7ac475667d9..46e672f86c8 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -34,11 +34,11 @@ use chrono::{DateTime, NaiveDateTime, Utc}; use std::collections::{BTreeMap, HashSet}; -use std::convert::{TryFrom, TryInto}; +use std::convert::{TryInto}; use std::fmt; -use std::process::id; -use ciborium::{cbor, Value as CborValue}; + +use ciborium::{Value as CborValue}; use itertools::Itertools; use serde_json::{json, Value as JsonValue}; @@ -50,7 +50,7 @@ use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType} use crate::data_contract::errors::DataContractError; use crate::document::errors::DocumentError; -use crate::document::ExtendedDocument; + use crate::identifier::Identifier; use crate::identity::TimestampMillis; use crate::prelude::Revision; diff --git a/packages/rs-dpp/src/document/document_facade.rs b/packages/rs-dpp/src/document/document_facade.rs index f7426834c01..b51f73de509 100644 --- a/packages/rs-dpp/src/document/document_facade.rs +++ b/packages/rs-dpp/src/document/document_facade.rs @@ -13,8 +13,7 @@ use super::{ document_factory::{DocumentFactory, FactoryOptions}, document_transition::Action, document_validator::DocumentValidator, - fetch_and_validate_data_contract::DataContractFetcherAndValidator, - Document, DocumentsBatchTransition, + fetch_and_validate_data_contract::DataContractFetcherAndValidator, DocumentsBatchTransition, }; pub struct DocumentFacade { diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index c478ca22c69..84ba8a296b2 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -1,6 +1,6 @@ use anyhow::Context; use chrono::Utc; -use std::collections::BTreeMap; + use itertools::Itertools; @@ -14,7 +14,7 @@ use crate::document::extended_document::{property_names, ExtendedDocument}; use crate::data_contract::DriveContractExt; use crate::document::document_transition::INITIAL_REVISION; -use crate::document::{extended_document, Document}; +use crate::document::{Document}; use crate::identity::TimestampMillis; use crate::{ data_contract::{errors::DataContractError, DataContract}, @@ -22,7 +22,7 @@ use crate::{ prelude::Identifier, state_repository::StateRepositoryLike, util::entropy_generator, - util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, + util::{json_value::JsonValueExt}, ProtocolError, }; @@ -167,7 +167,7 @@ where Document::replace_all_fields(&mut json_value, &data_contract, document_type.name.as_str())?; - let mut extended_document = ExtendedDocument { + let extended_document = ExtendedDocument { protocol_version: self.protocol_version, document_type_name, data_contract_id: data_contract.id.clone(), diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index e96647f81e5..082b7eedb6c 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -2,12 +2,12 @@ use crate::data_contract::{DataContract, DriveContractExt}; use crate::identifier::Identifier; use crate::metadata::Metadata; use crate::prelude::{Revision, TimestampMillis}; -use crate::util::cbor_value::{CborCanonicalMap, FieldType}; +use crate::util::cbor_value::{CborCanonicalMap}; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::util::hash::hash; use crate::util::json_value::JsonValueExt; use crate::util::json_value::ReplaceWith; -use crate::util::{cbor_value, deserializer}; +use crate::util::{deserializer}; use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; @@ -66,7 +66,7 @@ impl ExtendedDocument { json_document: JsonValue, data_contract: DataContract, ) -> Result { - let mut document = Self::from_json_value::(json_document, data_contract)?; + let document = Self::from_json_value::(json_document, data_contract)?; // let mut properties = document.properties_as_mut(); // replace only the dynamic data @@ -283,7 +283,7 @@ impl ExtendedDocument { CborValue::Bytes(self.data_contract_id.to_buffer_vec()), )); - let mut canonical_map: CborCanonicalMap = cbor_value.try_into()?; + let canonical_map: CborCanonicalMap = cbor_value.try_into()?; let mut document_buffer = canonical_map .to_bytes() diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 40502cd5840..424d47b8193 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -1,6 +1,6 @@ use rand::rngs::StdRng; use rand::SeedableRng; -use std::convert::TryInto; + use std::sync::Arc; use platform_value::Value; diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index b6df49c075a..bfdbd352e53 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -690,7 +690,7 @@ mod tests { use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; use rand::Rng; use serde::{Deserialize, Serialize}; - use serde_json::{json, Value as JsonValue}; + use serde_json::{json}; use tempfile::TempDir; use super::*; diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index edd50bf2cbd..f0268d60cb8 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -1,5 +1,5 @@ -use crate::btreemap_path_extensions::BTreeValueMapPathHelper; -use crate::value_map::{ValueMap, ValueMapHelper}; + +use crate::value_map::{ValueMapHelper}; use crate::{Error, Value}; use std::collections::{BTreeMap, HashMap}; diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_path_extensions.rs index 5f7c4c1ea60..91a2f796c86 100644 --- a/packages/rs-platform-value/src/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_extensions.rs @@ -1,11 +1,11 @@ -use serde_json::{Map, Value as JsonValue}; +use serde_json::{Value as JsonValue}; use std::borrow::Borrow; use std::convert::TryFrom; use std::iter::FromIterator; -use std::path::Path; + use std::{collections::BTreeMap, convert::TryInto}; -use crate::btreemap_extensions::BTreeValueMapHelper; + use crate::value_map::ValueMapHelper; use crate::{Error, Value}; diff --git a/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs b/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs index 2862c68c1c5..5697119aac5 100644 --- a/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs @@ -31,7 +31,7 @@ impl BTreeValueMapInsertionPathHelper for BTreeMap { } if let Some(last_path_component) = last_path_component { let map = current_value.as_map_mut_ref()?; - if let Some(mut new_value) = map.get_key_mut(last_path_component) { + if let Some(new_value) = map.get_key_mut(last_path_component) { *new_value = value; } else { map.push((Value::Text(last_path_component.to_string()), value)); diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 12535ab7357..6a52884fd8d 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,5 +1,5 @@ -use crate::{Error, ReplacementType, Value}; -use std::collections::{BTreeMap, HashMap}; +use crate::{Error, Value}; +use std::collections::{BTreeMap}; pub type ValueMap = Vec<(Value, Value)>; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index f032bed3f67..61e47acdcf7 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; -use dpp::identity::KeyID; + use dpp::{ data_contract::state_transition::DataContractUpdateTransition, state_transition::{ diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index 076497647e5..dfca7493305 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -6,7 +6,7 @@ use crate::{ fetch_and_validate_data_contract::DataContractFetcherAndValidatorWasm, utils::{get_class_name, IntoWasm}, validation::ValidationResultWasm, - DataContractWasm, DocumentFactoryWASM, DocumentValidatorWasm, DocumentWasm, + DataContractWasm, DocumentFactoryWASM, DocumentValidatorWasm, DocumentsBatchTransitionWASM, ExtendedDocumentWasm, }; diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index c66fc660860..698c6508351 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -1,14 +1,14 @@ -use dpp::dashcore::anyhow::Context; + use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::document::{ extended_document_property_names, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, }; -use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; + use dpp::platform_value::{ReplacementType, Value}; use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::{JsonValueExt, ReplaceWith}; -use dpp::util::string_encoding::Encoding; + use dpp::ProtocolError; use serde::{Deserialize, Serialize}; use std::convert::TryInto; diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 98247289b78..d7c296ab170 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -1,8 +1,8 @@ use anyhow::anyhow; -use std::collections::{HashMap, HashSet}; +use std::collections::{HashMap}; use std::sync::Arc; -use dpp::document::Document; + use dpp::platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; use dpp::platform_value::ReplacementType; use dpp::{ @@ -21,11 +21,10 @@ use dpp::prelude::ExtendedDocument; use std::convert::TryFrom; use crate::{ - document::document_data_to_bytes, identifier::identifier_from_js_value, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, utils::{ToSerdeJSONExt, WithJsError}, - DataContractWasm, DocumentWasm, DocumentsBatchTransitionWASM, ExtendedDocumentWasm, + DataContractWasm, DocumentsBatchTransitionWASM, ExtendedDocumentWasm, }; use super::validator::DocumentValidatorWasm; @@ -168,7 +167,7 @@ impl DocumentFactoryWASM { .get_identifiers_and_binary_paths_owned() .with_js_error()?; // When data contract is available, replace remaining dynamic paths - let mut document_data = document.properties_as_mut(); + let document_data = document.properties_as_mut(); document_data .replace_at_paths(identifier_paths, ReplacementType::Bytes) .map_err(ProtocolError::ValueError) diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 16ff16ada1d..e3e1715357b 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -1,18 +1,18 @@ use dpp::dashcore::anyhow::Context; -use dpp::prelude::{DataContract, Identifier, Revision}; +use dpp::prelude::{DataContract, Identifier}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::{JsonValueExt, ReplaceWith}; use anyhow::anyhow; use serde::{Deserialize, Serialize}; use serde_json::Value; -use std::convert::{self, TryInto}; +use std::convert::{TryInto}; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; -use crate::errors::RustConversionError; -use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; + +use crate::identifier::{IdentifierWrapper}; use crate::lodash::lodash_set; use crate::utils::{ replace_identifiers_with_bytes_without_failing, with_serde_to_json_value, ToSerdeJSONExt, @@ -33,13 +33,13 @@ mod validator; pub use document_batch_transition::DocumentsBatchTransitionWASM; use dpp::data_contract::DriveContractExt; use dpp::document::{ - extended_document_property_names, Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, + Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, IDENTIFIER_FIELDS, }; -use dpp::identity::TimestampMillis; + pub use extended_document::ExtendedDocumentWasm; -use dpp::data_contract::document_type::DocumentType; + use dpp::document::extended_document::property_names; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; use dpp::platform_value::ReplacementType; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 95402899f06..6f000fce2de 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,4 +1,4 @@ -use dpp::document::ExtendedDocument; + use dpp::identity::KeyID; use dpp::{ document::{ @@ -11,7 +11,7 @@ use dpp::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::json_value::{JsonValueExt, ReplaceWith}, + util::json_value::{JsonValueExt}, }; use js_sys::{Array, Reflect}; use serde::{Deserialize, Serialize}; @@ -26,8 +26,7 @@ use crate::{ lodash::lodash_set, utils::{ replace_identifiers_with_bytes_without_failing, IntoWasm, ToSerdeJSONExt, WithJsError, - }, - ExtendedDocumentWasm, IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, + }, IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, }; pub mod apply_document_batch_transition; pub mod document_transition; diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 714651e721e..6c421d98e77 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -17,11 +17,10 @@ use dpp::{ FetchTransactionResponse as FetchTransactionResponseDPP, StateRepositoryLike, }, state_transition::state_transition_execution_context::StateTransitionExecutionContext, - ProtocolError, }; use js_sys::Uint8Array; use js_sys::{Array, Number}; -use serde_json::Value; + use wasm_bindgen::__rt::Ref; use dpp::document::Document; diff --git a/packages/wasm-dpp/src/utils.rs b/packages/wasm-dpp/src/utils.rs index 5f9684a5d19..244bb44216e 100644 --- a/packages/wasm-dpp/src/utils.rs +++ b/packages/wasm-dpp/src/utils.rs @@ -14,7 +14,6 @@ use serde_json::Value as JsonValue; use wasm_bindgen::{convert::RefFromWasmAbi, prelude::*}; use crate::{ - bail_js, errors::{from_dpp_err, RustConversionError}, }; From 1c5d05b6cf572868d4ea8fcab7d82be8980fde1f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Mar 2023 18:31:13 +0700 Subject: [PATCH 033/228] more fixes --- packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs | 2 +- .../rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs | 4 ++-- .../apply_documents_batch_transition_factory.rs | 4 ++-- .../validate_documents_batch_transition_state_spec.rs | 4 ++-- .../validate_documents_uniqueness_by_indices_spec.rs | 4 ++-- .../validation/validate_partial_compound_indices_spec.rs | 4 ++-- packages/rs-drive-abci/src/state/genesis.rs | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 59b95e31b0e..76dda3133fb 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -232,7 +232,7 @@ where #[cfg(test)] mod test { - use crate::document::Document; + use crate::{ data_trigger::DataTriggerExecutionContext, document::document_transition::Action, diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 871765f8476..3dbce05048b 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -154,7 +154,7 @@ mod test { use super::*; use itertools::Itertools; use serde_json::json; - use std::convert::TryInto; + use crate::document::{Document, ExtendedDocument}; use crate::identity::Identity; @@ -172,7 +172,7 @@ mod test { }, utils::generate_random_identifier_struct, }, - DataTriggerError, ProtocolError, StateError, + DataTriggerError, StateError, }; struct TestData { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 05483d9721f..77592830e94 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -146,9 +146,9 @@ fn document_from_transition_replace( mod test { use serde_json::{json, Value}; - use crate::document::Document; + use crate::tests::fixtures::get_extended_documents_fixture; - use crate::tests::utils::new_block_header; + use crate::{ document::{ document_transition::{Action, DocumentTransitionObjectLike}, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index b40178909cc..35658900c49 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -1,4 +1,4 @@ -use std::convert::TryInto; + use std::time::Duration; use chrono::Utc; @@ -21,7 +21,7 @@ use crate::{ fixtures::{ get_data_contract_fixture, get_document_transitions_fixture, }, - utils::{generate_random_identifier_struct, new_block_header}, + utils::{generate_random_identifier_struct}, }, validation::ValidationResult, }; use crate::document::{Document, ExtendedDocument}; diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 665a575b191..0e011e8e4be 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -1,12 +1,12 @@ use futures::StreamExt; use mockall::predicate; use serde_json::json; -use std::convert::TryInto; + use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ document_transition::{Action, DocumentTransition}, state_transition::documents_batch_transition::validation::state::validate_documents_uniqueness_by_indices::*, -}, prelude::Identifier, ProtocolError, state_repository::MockStateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, StateError, tests::{ +}, prelude::Identifier, state_repository::MockStateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, StateError, tests::{ fixtures::{ get_data_contract_fixture, get_document_transitions_fixture, }, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 1a70bed3a7a..57ac4c411a9 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -1,5 +1,5 @@ -use serde_json::{json, Value as JsonValue}; -use std::collections::BTreeMap; +use serde_json::{Value as JsonValue}; + use crate::{ consensus::{basic::BasicError, ConsensusError}, diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index cad7b57586b..0a0f7789241 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -41,7 +41,7 @@ use drive::dpp::document::ExtendedDocument; use drive::dpp::identity::{ Identity, IdentityPublicKey, KeyType, Purpose, SecurityLevel, TimestampMillis, }; -use drive::dpp::prelude::Identifier; + use drive::dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use drive::dpp::util::string_encoding::{encode, Encoding}; use drive::drive::batch::{ From 5a0ac64db36f45952fc047c1a75d42ce102483ff Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Mar 2023 18:32:17 +0700 Subject: [PATCH 034/228] last fixes --- packages/rs-dpp/src/document/document.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 46e672f86c8..ae47b6231d8 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -39,7 +39,6 @@ use std::fmt; use ciborium::{Value as CborValue}; -use itertools::Itertools; use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; From 417c80f53c40301ca6cf1e7b798816e05d06e4dd Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Mar 2023 18:34:49 +0700 Subject: [PATCH 035/228] clippy fixes --- packages/rs-dpp/src/data_contract/data_contract.rs | 4 +--- ...lidate_data_contract_create_transition_state.rs | 2 +- .../rs-dpp/src/data_trigger/dpns_triggers/mod.rs | 4 ++-- .../data_trigger/reward_share_data_triggers/mod.rs | 1 - .../data_trigger/withdrawals_data_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/document.rs | 5 ++--- packages/rs-dpp/src/document/document_facade.rs | 3 ++- packages/rs-dpp/src/document/document_factory.rs | 7 +++---- packages/rs-dpp/src/document/errors.rs | 2 +- packages/rs-dpp/src/document/extended_document.rs | 4 ++-- .../apply_documents_batch_transition_factory.rs | 3 +-- .../validation/validate_state_transition_fee.rs | 10 +++++----- ...e_data_contract_update_transition_basic_spec.rs | 2 +- ...lidate_documents_batch_transition_state_spec.rs | 1 - ...alidate_documents_uniqueness_by_indices_spec.rs | 1 - .../validate_partial_compound_indices_spec.rs | 3 +-- .../src/tests/fixtures/get_documents_fixture.rs | 2 +- packages/rs-drive/src/drive/document/update.rs | 2 +- .../src/btreemap_field_replacement.rs | 5 ++--- .../src/btreemap_path_extensions.rs | 11 +++++------ .../src/btreemap_path_insertion_extensions.rs | 2 +- packages/rs-platform-value/src/lib.rs | 2 +- packages/rs-platform-value/src/value_map.rs | 14 +++----------- .../data_contract_update_transition/mod.rs | 1 - packages/wasm-dpp/src/document/document_facade.rs | 4 ++-- .../wasm-dpp/src/document/extended_document.rs | 1 - packages/wasm-dpp/src/document/factory.rs | 3 +-- packages/wasm-dpp/src/document/mod.rs | 11 +++-------- .../document_batch_transition/mod.rs | 6 +++--- packages/wasm-dpp/src/document/validator.rs | 2 +- packages/wasm-dpp/src/utils.rs | 4 +--- 31 files changed, 48 insertions(+), 76 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 4542f38f879..9647c98fbc1 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -3,7 +3,6 @@ use std::convert::TryFrom; use anyhow::anyhow; - use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; @@ -18,8 +17,7 @@ use crate::data_contract::contract_config::{ }; use crate::data_contract::get_binary_properties_from_schema::get_binary_properties; -use crate::util::cbor_value::{CborBTreeMapHelper}; - +use crate::util::cbor_value::CborBTreeMapHelper; use crate::util::json_value::{JsonValueExt, ReplaceWith}; use crate::util::string_encoding::Encoding; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs index 947fe3af7d7..ac7724e9633 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs @@ -89,7 +89,7 @@ mod test { let mut state_repository_mock = MockStateRepositoryLike::new(); let data_contract = get_data_contract_fixture(None); let state_transition = &DataContractCreateTransition { - entropy: data_contract.entropy.clone(), + entropy: data_contract.entropy, data_contract, ..Default::default() }; diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 76dda3133fb..8101d4747cf 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -5,7 +5,7 @@ use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use serde_json::{json, Value as JsonValue}; -use crate::document::{Document}; +use crate::document::Document; use crate::util::hash::hash; use crate::util::string_encoding::Encoding; use crate::ProtocolError; @@ -232,7 +232,7 @@ where #[cfg(test)] mod test { - + use crate::{ data_trigger::DataTriggerExecutionContext, document::document_transition::Action, diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 3dbce05048b..894a9dfb24a 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -154,7 +154,6 @@ mod test { use super::*; use itertools::Itertools; use serde_json::json; - use crate::document::{Document, ExtendedDocument}; use crate::identity::Identity; diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index c217bba23b2..56f865e2d7d 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -133,7 +133,7 @@ mod tests { let data_contract = load_system_data_contract(data_contracts::SystemDataContract::Withdrawals) .expect("to load system data contract"); - let owner_id = data_contract.owner_id.clone(); + let owner_id = data_contract.owner_id; let document = get_withdrawal_document_fixture( &data_contract, diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index ae47b6231d8..9a2be750978 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -34,11 +34,10 @@ use chrono::{DateTime, NaiveDateTime, Utc}; use std::collections::{BTreeMap, HashSet}; -use std::convert::{TryInto}; +use std::convert::TryInto; use std::fmt; - -use ciborium::{Value as CborValue}; +use ciborium::Value as CborValue; use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; diff --git a/packages/rs-dpp/src/document/document_facade.rs b/packages/rs-dpp/src/document/document_facade.rs index b51f73de509..e81ad53be90 100644 --- a/packages/rs-dpp/src/document/document_facade.rs +++ b/packages/rs-dpp/src/document/document_facade.rs @@ -13,7 +13,8 @@ use super::{ document_factory::{DocumentFactory, FactoryOptions}, document_transition::Action, document_validator::DocumentValidator, - fetch_and_validate_data_contract::DataContractFetcherAndValidator, DocumentsBatchTransition, + fetch_and_validate_data_contract::DataContractFetcherAndValidator, + DocumentsBatchTransition, }; pub struct DocumentFacade { diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 84ba8a296b2..7ab4135442f 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -1,7 +1,6 @@ use anyhow::Context; use chrono::Utc; - use itertools::Itertools; use platform_value::Value; @@ -14,7 +13,7 @@ use crate::document::extended_document::{property_names, ExtendedDocument}; use crate::data_contract::DriveContractExt; use crate::document::document_transition::INITIAL_REVISION; -use crate::document::{Document}; +use crate::document::Document; use crate::identity::TimestampMillis; use crate::{ data_contract::{errors::DataContractError, DataContract}, @@ -22,7 +21,7 @@ use crate::{ prelude::Identifier, state_repository::StateRepositoryLike, util::entropy_generator, - util::{json_value::JsonValueExt}, + util::json_value::JsonValueExt, ProtocolError, }; @@ -170,7 +169,7 @@ where let extended_document = ExtendedDocument { protocol_version: self.protocol_version, document_type_name, - data_contract_id: data_contract.id.clone(), + data_contract_id: data_contract.id, document, data_contract, metadata: None, diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index 8655848e555..28019ab8025 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -27,7 +27,7 @@ pub enum DocumentError { errors: Vec, raw_document: Value, }, - #[error("Invalid Document initial revision '{}'", document.revision().map(|r| *r).unwrap_or_default())] + #[error("Invalid Document initial revision '{}'", document.revision().copied().unwrap_or_default())] InvalidInitialRevisionError { document: Box }, #[error("Revision absent on mutable document")] diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 082b7eedb6c..118b0898b6e 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -2,12 +2,12 @@ use crate::data_contract::{DataContract, DriveContractExt}; use crate::identifier::Identifier; use crate::metadata::Metadata; use crate::prelude::{Revision, TimestampMillis}; -use crate::util::cbor_value::{CborCanonicalMap}; +use crate::util::cbor_value::CborCanonicalMap; +use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::util::hash::hash; use crate::util::json_value::JsonValueExt; use crate::util::json_value::ReplaceWith; -use crate::util::{deserializer}; use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 77592830e94..2e7f8cbe63b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -146,9 +146,8 @@ fn document_from_transition_replace( mod test { use serde_json::{json, Value}; - use crate::tests::fixtures::get_extended_documents_fixture; - + use crate::{ document::{ document_transition::{Action, DocumentTransitionObjectLike}, diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs index af8cf70e1da..243de48384a 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs @@ -198,7 +198,7 @@ mod test { let data_contract = get_data_contract_fixture(None); let data_contract_create_transition = DataContractCreateTransition { - entropy: data_contract.entropy.clone(), + entropy: data_contract.entropy, data_contract, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -231,7 +231,7 @@ mod test { let data_contract = get_data_contract_fixture(None); let data_contract_create_transition = DataContractCreateTransition { - entropy: data_contract.entropy.clone(), + entropy: data_contract.entropy, data_contract, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -260,7 +260,7 @@ mod test { get_documents_fixture_with_owner_id_from_contract(data_contract.clone()).unwrap(); let transitions = get_document_transitions_fixture([(Action::Create, documents)]); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id.clone(), + owner_id: data_contract.owner_id, transitions, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -296,7 +296,7 @@ mod test { get_documents_fixture_with_owner_id_from_contract(data_contract.clone()).unwrap(); let transitions = get_document_transitions_fixture([(Action::Create, documents)]); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id.clone(), + owner_id: data_contract.owner_id, transitions, execution_context: execution_context_with_cost(40, 5), ..Default::default() @@ -328,7 +328,7 @@ mod test { execution_context.enable_dry_run(); let documents_batch_transition = DocumentsBatchTransition { - owner_id: data_contract.owner_id.clone(), + owner_id: data_contract.owner_id, transitions, execution_context, ..Default::default() diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 37db46cbce1..6b2464ab0ab 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -146,7 +146,7 @@ async fn protocol_version_should_be_valid() { .expect("validation result should be returned"); assert!(matches!( - result.errors.iter().next(), + result.errors.first(), Some(ConsensusError::ProtocolVersionParsingError { .. }) )); } diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 35658900c49..37815b06e1a 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -1,4 +1,3 @@ - use std::time::Duration; use chrono::Utc; diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 0e011e8e4be..60dc1663f32 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -2,7 +2,6 @@ use futures::StreamExt; use mockall::predicate; use serde_json::json; - use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ document_transition::{Action, DocumentTransition}, state_transition::documents_batch_transition::validation::state::validate_documents_uniqueness_by_indices::*, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 57ac4c411a9..ca4cdb63fb2 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -1,5 +1,4 @@ -use serde_json::{Value as JsonValue}; - +use serde_json::Value as JsonValue; use crate::{ consensus::{basic::BasicError, ConsensusError}, diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 424d47b8193..b220ff95c98 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -33,7 +33,7 @@ pub fn get_documents_fixture_with_owner_id_from_contract( data_contract_fetcher_and_validator, None, ); - let owner_id = data_contract.owner_id.clone(); + let owner_id = data_contract.owner_id; get_extended_documents(factory, data_contract, owner_id) } diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index bfdbd352e53..09ead7ee8f4 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -690,7 +690,7 @@ mod tests { use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; use rand::Rng; use serde::{Deserialize, Serialize}; - use serde_json::{json}; + use serde_json::json; use tempfile::TempDir; use super::*; diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index f0268d60cb8..57b22567312 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -1,5 +1,4 @@ - -use crate::value_map::{ValueMapHelper}; +use crate::value_map::ValueMapHelper; use crate::{Error, Value}; use std::collections::{BTreeMap, HashMap}; @@ -44,7 +43,7 @@ impl BTreeValueMapInsertionPathHelper for BTreeMap { path: &str, replacement_type: ReplacementType, ) -> Result { - let mut split = path.split(".").peekable(); + let mut split = path.split('.').peekable(); let first = split.next(); let Some(first_path_component) = first else { return Err(Error::PathError("path was empty".to_string())); diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_path_extensions.rs index 91a2f796c86..fc65e47a990 100644 --- a/packages/rs-platform-value/src/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_extensions.rs @@ -1,11 +1,10 @@ -use serde_json::{Value as JsonValue}; +use serde_json::Value as JsonValue; use std::borrow::Borrow; use std::convert::TryFrom; use std::iter::FromIterator; use std::{collections::BTreeMap, convert::TryInto}; - use crate::value_map::ValueMapHelper; use crate::{Error, Value}; @@ -136,7 +135,7 @@ where V: Borrow, { fn get_at_path(&self, path: &str) -> Result<&Value, Error> { - let mut split = path.split("."); + let mut split = path.split('.'); let first = split.next(); let Some(first_path_component) = first else { return Err(Error::PathError("path was empty".to_string())); @@ -149,7 +148,7 @@ where )) })? .borrow(); - while let Some(path_component) = split.next() { + for path_component in split { let map = current_value.to_map_ref()?; current_value = map.get_key(path_component).ok_or_else(|| { Error::StructureError(format!("unable to get property {path_component} in {path}")) @@ -159,7 +158,7 @@ where } fn get_optional_at_path(&self, path: &str) -> Result, Error> { - let mut split = path.split("."); + let mut split = path.split('.'); let first = split.next(); let Some(first_path_component) = first else { return Err(Error::PathError("path was empty".to_string())); @@ -167,7 +166,7 @@ where let Some(mut current_value) = self.get(first_path_component).map(|v| v.borrow()) else { return Ok(None); }; - while let Some(path_component) = split.next() { + for path_component in split { let map = current_value.to_map_ref()?; let Some(new_value) = map.get_key(path_component) else { return Ok(None); diff --git a/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs b/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs index 5697119aac5..154398bed43 100644 --- a/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs @@ -8,7 +8,7 @@ pub trait BTreeValueMapInsertionPathHelper { impl BTreeValueMapInsertionPathHelper for BTreeMap { fn insert_at_path(&mut self, path: &str, value: Value) -> Result<(), Error> { - let mut split = path.split(".").peekable(); + let mut split = path.split('.').peekable(); let first = split.next(); let Some(first_path_component) = first else { return Err(Error::PathError("path was empty".to_string())); diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index e421d728818..405d43050d6 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -966,7 +966,7 @@ impl Value { path: &str, replacement_type: ReplacementType, ) -> Result { - let mut split = path.split(".").peekable(); + let mut split = path.split('.').peekable(); let mut current_value = self; while let Some(path_component) = split.next() { let map = current_value.as_map_mut_ref()?; diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 6a52884fd8d..cf448295ff9 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,5 +1,5 @@ use crate::{Error, Value}; -use std::collections::{BTreeMap}; +use std::collections::BTreeMap; pub type ValueMap = Vec<(Value, Value)>; @@ -42,11 +42,7 @@ impl ValueMapHelper for ValueMap { fn get_key_mut_or_insert(&mut self, search_key: &str, value: Value) -> &mut Value { let found = self.iter().position(|(key, _)| { if let Value::Text(text) = key { - if text == search_key { - true - } else { - false - } + text == search_key } else { false } @@ -68,11 +64,7 @@ impl ValueMapHelper for ValueMap { self.iter() .position(|(key, _)| { if let Value::Text(text) = key { - if text == search_key { - true - } else { - false - } + text == search_key } else { false } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 61e47acdcf7..976092f8742 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -6,7 +6,6 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; - use dpp::{ data_contract::state_transition::DataContractUpdateTransition, state_transition::{ diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index dfca7493305..47ae8280f99 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -6,8 +6,8 @@ use crate::{ fetch_and_validate_data_contract::DataContractFetcherAndValidatorWasm, utils::{get_class_name, IntoWasm}, validation::ValidationResultWasm, - DataContractWasm, DocumentFactoryWASM, DocumentValidatorWasm, - DocumentsBatchTransitionWASM, ExtendedDocumentWasm, + DataContractWasm, DocumentFactoryWASM, DocumentValidatorWasm, DocumentsBatchTransitionWASM, + ExtendedDocumentWasm, }; #[derive(Clone)] diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 698c6508351..e94f8ec65d8 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -1,4 +1,3 @@ - use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::document::{ extended_document_property_names, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index d7c296ab170..0f796d11ca9 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -1,8 +1,7 @@ use anyhow::anyhow; -use std::collections::{HashMap}; +use std::collections::HashMap; use std::sync::Arc; - use dpp::platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; use dpp::platform_value::ReplacementType; use dpp::{ diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index e3e1715357b..e43eb831383 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -6,13 +6,12 @@ use dpp::util::json_value::{JsonValueExt, ReplaceWith}; use anyhow::anyhow; use serde::{Deserialize, Serialize}; use serde_json::Value; -use std::convert::{TryInto}; +use std::convert::TryInto; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; - -use crate::identifier::{IdentifierWrapper}; +use crate::identifier::IdentifierWrapper; use crate::lodash::lodash_set; use crate::utils::{ replace_identifiers_with_bytes_without_failing, with_serde_to_json_value, ToSerdeJSONExt, @@ -32,14 +31,10 @@ mod validator; pub use document_batch_transition::DocumentsBatchTransitionWASM; use dpp::data_contract::DriveContractExt; -use dpp::document::{ - Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, - IDENTIFIER_FIELDS, -}; +use dpp::document::{Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, IDENTIFIER_FIELDS}; pub use extended_document::ExtendedDocumentWasm; - use dpp::document::extended_document::property_names; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; use dpp::platform_value::ReplacementType; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 6f000fce2de..b1483375b70 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,4 +1,3 @@ - use dpp::identity::KeyID; use dpp::{ document::{ @@ -11,7 +10,7 @@ use dpp::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::json_value::{JsonValueExt}, + util::json_value::JsonValueExt, }; use js_sys::{Array, Reflect}; use serde::{Deserialize, Serialize}; @@ -26,7 +25,8 @@ use crate::{ lodash::lodash_set, utils::{ replace_identifiers_with_bytes_without_failing, IntoWasm, ToSerdeJSONExt, WithJsError, - }, IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, + }, + IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, }; pub mod apply_document_batch_transition; pub mod document_transition; diff --git a/packages/wasm-dpp/src/document/validator.rs b/packages/wasm-dpp/src/document/validator.rs index 31b5ddcb6cc..528b84d4fa0 100644 --- a/packages/wasm-dpp/src/document/validator.rs +++ b/packages/wasm-dpp/src/document/validator.rs @@ -35,7 +35,7 @@ impl DocumentValidatorWasm { impl DocumentValidatorWasm { pub(crate) fn new_with_arc(protocol_validator: Arc) -> Self { - DocumentValidatorWasm(DocumentValidator::new(protocol_validator.clone())) + DocumentValidatorWasm(DocumentValidator::new(protocol_validator)) } } diff --git a/packages/wasm-dpp/src/utils.rs b/packages/wasm-dpp/src/utils.rs index 244bb44216e..f4830abf24f 100644 --- a/packages/wasm-dpp/src/utils.rs +++ b/packages/wasm-dpp/src/utils.rs @@ -13,9 +13,7 @@ use serde::de::DeserializeOwned; use serde_json::Value as JsonValue; use wasm_bindgen::{convert::RefFromWasmAbi, prelude::*}; -use crate::{ - errors::{from_dpp_err, RustConversionError}, -}; +use crate::errors::{from_dpp_err, RustConversionError}; pub trait ToSerdeJSONExt { fn with_serde_to_json_value(&self) -> Result; From a99b188a8b0e75ba13aea90acc0ef2e26c5b3feb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Mar 2023 19:53:08 +0700 Subject: [PATCH 036/228] added another convenience method --- packages/rs-dpp/src/document/document.rs | 19 ++++++++++++++++++ .../src/btreemap_extensions.rs | 20 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 9a2be750978..e9609fa7496 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -41,6 +41,7 @@ use ciborium::Value as CborValue; use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; +use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; @@ -462,6 +463,24 @@ impl Document { .map_err(ProtocolError::ValueError)?; Ok(document) } + + pub fn from_platform_value(document_value: Value) -> Result { + let mut properties = document_value + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + let mut document = Self { + ..Default::default() + }; + + document.id = properties.remove_system_hash256_bytes(property_names::ID)?; + document.owner_id = properties.remove_system_hash256_bytes(property_names::OWNER_ID)?; + document.revision = properties.remove_optional_integer(property_names::REVISION)?; + document.created_at = properties.remove_optional_integer(property_names::CREATED_AT)?; + document.updated_at = properties.remove_optional_integer(property_names::UPDATED_AT)?; + + document.properties = properties; + Ok(document) + } } impl fmt::Display for Document { diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 526bb99c0c8..7e5c378229b 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -116,6 +116,8 @@ pub trait BTreeValueMapHelper { fn get_optional_bytes(&self, key: &str) -> Result>, Error>; fn get_bytes(&self, key: &str) -> Result, Error>; fn to_json_value(&self) -> Result; + fn remove_optional_bool(&mut self, key: &str) -> Result, Error>; + fn remove_bool(&mut self, key: &str) -> Result; } impl BTreeValueMapHelper for BTreeMap @@ -485,6 +487,24 @@ where .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) } + fn remove_optional_bool(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + let borrowed = v.borrow(); + if borrowed.is_null() { + None + } else { + Some(v.borrow().to_bool()) + } + }) + .transpose() + } + + fn remove_bool(&mut self, key: &str) -> Result { + self.remove_optional_bool(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) + } + fn get_optional_float(&self, key: &str) -> Result, Error> { self.get(key) .and_then(|v| { From 47ed827a079b1e52e247526756bb036b2a58bb48 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Fri, 3 Mar 2023 20:16:48 +0700 Subject: [PATCH 037/228] attempt to fix appy_document_batch_transition --- .../test/mocks/createStateRepositoryMock.js | 2 ++ .../rs-dpp/src/data_contract/data_contract.rs | 1 - .../document_type/document_type.rs | 1 - .../reward_share_data_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/serialize.rs | 1 - ...pply_documents_batch_transition_factory.rs | 10 +++--- .../document_replace_transition.rs | 33 ++++++++++++++++++- .../validation/state/fetch_documents.rs | 10 +++--- ...lidate_documents_batch_transition_state.rs | 32 +++++++++--------- .../wasm-dpp/src/document/document_facade.rs | 2 +- .../src/document/extended_document.rs | 13 ++++++-- packages/wasm-dpp/src/document/mod.rs | 7 ++-- .../validation/state/fetch_documents.rs | 2 +- packages/wasm-dpp/src/document/validator.rs | 3 +- .../test/unit/document/Document.spec.js | 22 ++++++------- .../unit/document/DocumentFactory.spec.js | 14 ++++---- .../DocumentsBatchTransition.spec.js | 6 ++-- .../state/fetchDocumentsFactory.spec.js | 13 ++++++-- 18 files changed, 110 insertions(+), 64 deletions(-) diff --git a/packages/js-dpp/lib/test/mocks/createStateRepositoryMock.js b/packages/js-dpp/lib/test/mocks/createStateRepositoryMock.js index 908caba5079..b6dc56ee6c9 100644 --- a/packages/js-dpp/lib/test/mocks/createStateRepositoryMock.js +++ b/packages/js-dpp/lib/test/mocks/createStateRepositoryMock.js @@ -6,6 +6,7 @@ * createDataContract: *, * updateDataContract: *, * fetchDocuments: *, + * fetchExtendedDocuments: *, * createDocument: *, * updateDocument: *, * removeDocument: *, @@ -37,6 +38,7 @@ module.exports = function createStateRepositoryMock(sinonSandbox) { createDataContract: sinonSandbox.stub(), updateDataContract: sinonSandbox.stub(), fetchDocuments: sinonSandbox.stub(), + fetchExtendedDocuments: sinonSandbox.stub(), createDocument: sinonSandbox.stub(), updateDocument: sinonSandbox.stub(), removeDocument: sinonSandbox.stub(), diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 9647c98fbc1..972ad11f04a 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -17,7 +17,6 @@ use crate::data_contract::contract_config::{ }; use crate::data_contract::get_binary_properties_from_schema::get_binary_properties; -use crate::util::cbor_value::CborBTreeMapHelper; use crate::util::json_value::{JsonValueExt, ReplaceWith}; use crate::util::string_encoding::Encoding; diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index 92a7c94c99e..b58ffdcbc18 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -8,7 +8,6 @@ use super::{ use crate::data_contract::document_type::{property_names, ArrayFieldType}; use crate::data_contract::errors::{DataContractError, StructureError}; -use crate::util::cbor_value::CborBTreeMapHelper; use crate::ProtocolError; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 894a9dfb24a..48fca9e9927 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -13,7 +13,7 @@ use crate::{ mocks::SMLStore, prelude::Identifier, state_repository::StateRepositoryLike, - util::{json_value::JsonValueExt, string_encoding::Encoding}, + util::{string_encoding::Encoding}, ProtocolError, }; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 24d3ffe87aa..3441c691368 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -9,7 +9,6 @@ use crate::document::Document; use crate::identity::TimestampMillis; use crate::prelude::Revision; -use crate::util::cbor_value::CborBTreeMapHelper; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 2e7f8cbe63b..95fea893c6b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -10,7 +10,7 @@ use crate::{ use super::{ document_transition::{Action, DocumentReplaceTransition, DocumentTransition}, - validation::state::fetch_documents::fetch_documents, + validation::state::fetch_documents::fetch_extended_documents, DocumentsBatchTransition, }; @@ -49,16 +49,16 @@ pub async fn apply_documents_batch_transition( .iter() .filter(|dt| dt.base().action == Action::Replace); - let fetched_documents = fetch_documents( + let fetched_documents = fetch_extended_documents( state_repository, replace_transitions, &state_transition.execution_context, ) .await?; - let mut fetched_documents_by_id: HashMap = fetched_documents + let mut fetched_documents_by_id: HashMap = fetched_documents .into_iter() - .map(|dt| (dt.id.into(), dt)) + .map(|dt| (dt.id(), dt)) .collect(); // since groveDB doesn't support parallel inserts, we need to make them sequential @@ -85,7 +85,7 @@ pub async fn apply_documents_batch_transition( .ok_or(DocumentError::DocumentNotProvidedError { document_transition: document_transition.clone(), })?; - document_replace_transition.replace_document(document)?; + document_replace_transition.replace_extended_document(document)?; state_repository .update_document(document, state_transition.get_execution_context()) .await?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index a4d1bf39772..6d66ade5b0f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -4,7 +4,7 @@ use serde_json::Value as JsonValue; use crate::document::Document; use crate::identity::TimestampMillis; -use crate::prelude::Revision; +use crate::prelude::{ExtendedDocument, Revision}; use crate::{ data_contract::DataContract, errors::ProtocolError, @@ -69,6 +69,22 @@ impl DocumentReplaceTransition { Ok(()) } + pub(crate) fn replace_extended_document(&self, document: &mut ExtendedDocument) -> Result<(), ProtocolError> { + let properties = self + .data + .as_ref() + .map(|json_value| { + let value: Value = json_value.clone().into(); + value.into_btree_map().map_err(ProtocolError::ValueError) + }) + .transpose()? + .unwrap_or_default(); + document.document.revision = Some(self.revision); + document.document.updated_at = self.updated_at; + document.document.properties = properties; + Ok(()) + } + pub(crate) fn patch_document(self, document: &mut Document) -> Result<(), ProtocolError> { let properties = self .data @@ -83,6 +99,21 @@ impl DocumentReplaceTransition { document.properties.extend(properties); Ok(()) } + + pub(crate) fn patch_extended_document(self, document: &mut ExtendedDocument) -> Result<(), ProtocolError> { + let properties = self + .data + .map(|json_value| { + let value: Value = json_value.into(); + value.into_btree_map().map_err(ProtocolError::ValueError) + }) + .transpose()? + .unwrap_or_default(); + document.document.revision = Some(self.revision); + document.document.updated_at = self.updated_at; + document.document.properties.extend(properties); + Ok(()) + } } impl DocumentTransitionObjectLike for DocumentReplaceTransition { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs index 49fd31d61d0..79dbf1d6d06 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs @@ -7,7 +7,7 @@ use futures::future::join_all; use itertools::Itertools; use serde_json::json; -use crate::document::Document; +use crate::document::ExtendedDocument; use crate::{ document::document_transition::DocumentTransition, get_from_transition, state_repository::StateRepositoryLike, @@ -15,11 +15,11 @@ use crate::{ util::string_encoding::Encoding, ProtocolError, }; -pub async fn fetch_documents( +pub async fn fetch_extended_documents( state_repository: &impl StateRepositoryLike, document_transitions: impl IntoIterator>, execution_context: &StateTransitionExecutionContext, -) -> Result, anyhow::Error> { +) -> Result, anyhow::Error> { let mut transitions_by_contracts_and_types: HashMap> = HashMap::new(); let collected_transitions: Vec<_> = document_transitions.into_iter().collect(); @@ -50,7 +50,7 @@ pub async fn fetch_documents( "orderBy" : [[ "$id", "asc"]], }); - let future = state_repository.fetch_documents( + let future = state_repository.fetch_extended_documents( get_from_transition!(dts[0], data_contract_id), get_from_transition!(dts[0], document_type), options, @@ -64,7 +64,7 @@ pub async fn fetch_documents( let mut documents = vec![]; for result in results.into_iter() { let result = result?; - let documents_from_fetch: Vec = result + let documents_from_fetch: Vec = result .into_iter() .map(|d| d.try_into().map_err(Into::::into)) .try_collect()?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index ed55a948e0e..e833bddbfb2 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use futures::future::join_all; use itertools::Itertools; -use crate::document::Document; +use crate::document::{ExtendedDocument}; use crate::{ block_time_window::validate_time_in_block_time_window::validate_time_in_block_time_window, consensus::ConsensusError, @@ -23,7 +23,7 @@ use crate::{ }; use super::{ - execute_data_triggers::execute_data_triggers, fetch_documents::fetch_documents, + execute_data_triggers::execute_data_triggers, fetch_documents::fetch_extended_documents, validate_documents_uniqueness_by_indices::validate_documents_uniqueness_by_indices, }; @@ -85,7 +85,7 @@ pub async fn validate_document_transitions( execution_context.add_operations(tmp_execution_context.get_operations()); let fetched_documents = - fetch_documents(state_repository, &transitions, execution_context).await?; + fetch_extended_documents(state_repository, &transitions, execution_context).await?; // Calculate time window for timestamp let last_header_time_millis = state_repository.fetch_latest_platform_block_time().await?; @@ -146,7 +146,7 @@ pub async fn validate_document_transitions( fn validate_transition( transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[ExtendedDocument], last_header_block_time_millis: u64, owner_id: &Identifier, ) -> ValidationResult<()> { @@ -201,23 +201,23 @@ fn validate_transition( fn check_ownership( document_transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[ExtendedDocument], owner_id: &Identifier, ) -> ValidationResult<()> { let mut result = ValidationResult::default(); let fetched_document = match fetched_documents .iter() - .find(|d| d.id == document_transition.base().id) + .find(|d| d.id() == document_transition.base().id) { Some(d) => d, None => return result, }; - if &fetched_document.owner_id != owner_id { + if &fetched_document.owner_id() != owner_id { result.add_error(ConsensusError::StateError(Box::new( StateError::DocumentOwnerIdMismatchError { document_id: document_transition.base().id, document_owner_id: owner_id.to_owned(), - existing_document_owner_id: fetched_document.owner_id.into(), + existing_document_owner_id: fetched_document.owner_id().into(), }, ))); } @@ -226,12 +226,12 @@ fn check_ownership( fn check_revision( document_transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[ExtendedDocument], ) -> ValidationResult<()> { let mut result = ValidationResult::default(); let fetched_document = match fetched_documents .iter() - .find(|d| d.id == document_transition.base().id) + .find(|d| d.id() == document_transition.base().id) { Some(d) => d, None => return result, @@ -240,7 +240,7 @@ fn check_revision( Some(d) => d.revision, None => return result, }; - let Some(previous_revision) = fetched_document.revision else { + let Some(previous_revision) = fetched_document.revision() else { result.add_error(ConsensusError::StateError(Box::new( StateError::InvalidDocumentRevisionError { document_id: document_transition.base().id, @@ -254,7 +254,7 @@ fn check_revision( result.add_error(ConsensusError::StateError(Box::new( StateError::InvalidDocumentRevisionError { document_id: document_transition.base().id, - current_revision: Some(previous_revision), + current_revision: Some(*previous_revision), }, ))) } @@ -263,12 +263,12 @@ fn check_revision( fn check_if_document_is_already_present( document_transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[ExtendedDocument], ) -> ValidationResult<()> { let mut result = ValidationResult::default(); let maybe_fetched_document = fetched_documents .iter() - .find(|d| d.id == document_transition.base().id); + .find(|d| d.id() == document_transition.base().id); if maybe_fetched_document.is_some() { result.add_error(ConsensusError::StateError(Box::new( @@ -282,12 +282,12 @@ fn check_if_document_is_already_present( fn check_if_document_can_be_found( document_transition: &DocumentTransition, - fetched_documents: &[Document], + fetched_documents: &[ExtendedDocument], ) -> ValidationResult<()> { let mut result = ValidationResult::default(); let maybe_fetched_document = fetched_documents .iter() - .find(|d| d.id == document_transition.base().id); + .find(|d| d.id() == document_transition.base().id); if maybe_fetched_document.is_none() { result.add_error(ConsensusError::StateError(Box::new( diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index 47ae8280f99..123c483cfbd 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -121,6 +121,6 @@ impl DocumentFacadeWasm { .to_wasm::("DataContract")?; self.validator - .validate_extended(&js_raw_document, &data_contract) + .validate(&js_raw_document, &data_contract) } } diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index e94f8ec65d8..e88271bef40 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -16,18 +16,18 @@ use wasm_bindgen::prelude::*; use crate::buffer::Buffer; use crate::document::BinaryType; use crate::errors::RustConversionError; -use crate::identifier::IdentifierWrapper; +use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; use crate::lodash::lodash_set; use crate::utils::WithJsError; use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt}; use crate::{with_js_error, ConversionOptions}; use crate::{DataContractWasm, MetadataWasm}; -#[wasm_bindgen(js_name=DocumentInStateTransition)] +#[wasm_bindgen(js_name=ExtendedDocument)] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExtendedDocumentWasm(pub(crate) ExtendedDocument); -#[wasm_bindgen(js_class=DocumentInStateTransition)] +#[wasm_bindgen(js_class=ExtendedDocument)] impl ExtendedDocumentWasm { #[wasm_bindgen(constructor)] pub fn new( @@ -95,6 +95,13 @@ impl ExtendedDocumentWasm { self.0.data_contract.clone().into() } + #[wasm_bindgen(js_name=setDataContractId)] + pub fn set_data_contract_id(&mut self, js_data_contract_id: &JsValue) -> Result<(), JsValue> { + let identifier = identifier_from_js_value(js_data_contract_id)?; + self.0.data_contract_id = identifier; + Ok(()) + } + #[wasm_bindgen(js_name=setOwnerId)] pub fn set_owner_id(&mut self, owner_id: IdentifierWrapper) { self.0.document.owner_id = owner_id.inner().buffer; diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index e43eb831383..10b8186aabf 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -80,14 +80,15 @@ impl DocumentWasm { .get_identifiers_and_binary_paths(document_type_name.as_str()) .with_js_error()?; - raw_document + // TODO: figure out a better way to replace identifiers + let _ = raw_document .replace_identifier_paths( identifier_paths .into_iter() .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS), ReplaceWith::Bytes, - ) - .with_js_error()?; + ); + // .with_js_error()?; // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array let document = Document::from_raw_json_document(raw_document).with_js_error()?; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_documents.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_documents.rs index 7499a531a4b..769d10f2456 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_documents.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_documents.rs @@ -26,7 +26,7 @@ pub async fn fetch_documents_wasm( } let execution_context: StateTransitionExecutionContext = js_execution_context.into(); - let documents = fetch_documents::fetch_documents( + let documents = fetch_documents::fetch_extended_documents( &wrapped_state_repository, document_transitions, &execution_context, diff --git a/packages/wasm-dpp/src/document/validator.rs b/packages/wasm-dpp/src/document/validator.rs index 528b84d4fa0..7c50cc19d41 100644 --- a/packages/wasm-dpp/src/document/validator.rs +++ b/packages/wasm-dpp/src/document/validator.rs @@ -18,7 +18,8 @@ impl DocumentValidatorWasm { DocumentValidatorWasm(DocumentValidator::new(Arc::new(protocol_validator.into()))) } - pub fn validate_extended( + #[wasm_bindgen] + pub fn validate( &self, js_raw_document: &JsValue, js_data_contract: &DataContractWasm, diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index eff363bb4ed..3b4816f0b59 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -15,9 +15,9 @@ const { default: loadWasmDpp } = require('../../../dist'); let DataContractFactory; let DataContractValidator; let Identifier; -let DocumentInStateTransition; +let ExtendedDocument; -// TODO: should be renamed to DocumentInStateTransition? +// TODO: should be renamed to ExtendedDocument? describe('Document', () => { let rawDocument; let document; @@ -30,7 +30,7 @@ describe('Document', () => { // eslint-disable-next-line prefer-arrow-callback beforeEach(async function beforeEach() { ({ - Identifier, DataContractFactory, DataContractValidator, DocumentInStateTransition, + Identifier, DataContractFactory, DataContractValidator, ExtendedDocument, } = await loadWasmDpp()); const now = new Date().getTime(); @@ -101,7 +101,7 @@ describe('Document', () => { $updatedAt: now, }; - document = new DocumentInStateTransition(rawDocument, dataContract); + document = new ExtendedDocument(rawDocument, dataContract); rawDocumentJs = lodash.cloneDeepWith(rawDocument); rawDocumentJs.$id = jsId; rawDocumentJs.$ownerId = jsOwnerId; @@ -123,7 +123,7 @@ describe('Document', () => { ...data, }; - document = new DocumentInStateTransition(rawDocument, dataContract); + document = new ExtendedDocument(rawDocument, dataContract); expect(document.getId().toBuffer()).to.deep.equal(rawDocument.$id.toBuffer()); }); @@ -153,7 +153,7 @@ describe('Document', () => { ...data, }; - document = new DocumentInStateTransition(rawDocument, dataContract); + document = new ExtendedDocument(rawDocument, dataContract); expect(document.getDataContractId().toBuffer()) .to.deep.equal(rawDocument.$dataContractId.toBuffer()); @@ -170,7 +170,7 @@ describe('Document', () => { ...data, }; - document = new DocumentInStateTransition(rawDocument, dataContract); + document = new ExtendedDocument(rawDocument, dataContract); expect(document.getOwnerId().toBuffer()).to.deep.equal(rawDocument.$ownerId.toBuffer()); }); @@ -185,7 +185,7 @@ describe('Document', () => { ...data, }; - document = new DocumentInStateTransition(rawDocument, dataContract); + document = new ExtendedDocument(rawDocument, dataContract); expect(document.get('action')).to.equal(undefined); }); @@ -200,7 +200,7 @@ describe('Document', () => { ...data, }; - document = new DocumentInStateTransition(rawDocument, dataContract); + document = new ExtendedDocument(rawDocument, dataContract); expect(document.getRevision()).to.equal(rawDocument.$revision); }); @@ -218,7 +218,7 @@ describe('Document', () => { ...data, }; - document = new DocumentInStateTransition(rawDocument, dataContract); + document = new ExtendedDocument(rawDocument, dataContract); expect(document.getCreatedAt()).to.equal(rawDocument.$createdAt); }); @@ -236,7 +236,7 @@ describe('Document', () => { ...data, }; - document = new DocumentInStateTransition(rawDocument, dataContract); + document = new ExtendedDocument(rawDocument, dataContract); expect(document.getUpdatedAt()).to.equal(rawDocument.$updatedAt); }); diff --git a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js index ab27d78b443..b7be7f75198 100644 --- a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js @@ -27,7 +27,7 @@ const { default: loadWasmDpp } = require('../../../dist'); let Identifier; let DocumentFactory; let DataContract; -let DocumentInStateTransition; +let ExtendedDocument; let DocumentValidator; let ProtocolVersionValidator; @@ -64,7 +64,7 @@ describe('DocumentFactory', () => { beforeEach(async () => { ({ Identifier, ProtocolVersionValidator, DocumentValidator, DocumentFactory, - DataContract, DocumentInStateTransition, + DataContract, ExtendedDocument, // Errors: InvalidDocumentTypeInDataContractError, InvalidDocumentError, @@ -88,7 +88,7 @@ describe('DocumentFactory', () => { documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { - const doc = new DocumentInStateTransition(d.toObject(), dataContract); + const doc = new ExtendedDocument(d.toObject(), dataContract); doc.setEntropy(d.entropy); return doc; }); @@ -164,7 +164,7 @@ describe('DocumentFactory', () => { { name }, ); - expect(newDocument).to.be.an.instanceOf(DocumentInStateTransition); + expect(newDocument).to.be.an.instanceOf(ExtendedDocument); expect(newDocumentJs).to.be.an.instanceOf(DocumentJs); expect(newDocumentJs.getType()).to.equal(newRawDocument.$type); @@ -275,7 +275,7 @@ describe('DocumentFactory', () => { it('should return new Data Contract with data from passed object - Rust', async () => { const result = await factory.createFromObject(rawDocument); - expect(result).to.be.an.instanceOf(DocumentInStateTransition); + expect(result).to.be.an.instanceOf(ExtendedDocument); expect(result.toJSON()).to.deep.equal(document.toJSON()); expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnce(); @@ -303,7 +303,7 @@ describe('DocumentFactory', () => { it('should return new Document without validation if "skipValidation" option is passed - Rust', async () => { delete rawDocument.lastName; const result = await factory.createFromObject(rawDocument, { skipValidation: true }); - expect(result).to.be.an.instanceOf(DocumentInStateTransition); + expect(result).to.be.an.instanceOf(ExtendedDocument); expect(result.toObject()).to.deep.equal(rawDocument); expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnce(); @@ -587,7 +587,7 @@ describe('DocumentFactory', () => { it('should create DocumentsBatchTransition with passed documents - Rust', async () => { const [newDocumentJs] = getDocumentsFixture(dataContractJs); - const newDocument = new DocumentInStateTransition(newDocumentJs.toObject(), dataContract); + const newDocument = new ExtendedDocument(newDocumentJs.toObject(), dataContract); const stateTransition = factory.createStateTransition({ create: documents, diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js index ecebcf04307..d5ed97def59 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/DocumentsBatchTransition.spec.js @@ -8,7 +8,7 @@ const { default: loadWasmDpp } = require('../../../../../dist'); let DocumentFactory; let DataContract; -let DocumentInStateTransition; +let ExtendedDocument; let DocumentValidator; let ProtocolVersionValidator; @@ -24,7 +24,7 @@ describe('DocumentsBatchTransition', () => { beforeEach(async () => { ({ ProtocolVersionValidator, DocumentValidator, DocumentFactory, DataContract, - DocumentInStateTransition, + ExtendedDocument, } = await loadWasmDpp()); }); @@ -34,7 +34,7 @@ describe('DocumentsBatchTransition', () => { documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { - const doc = new DocumentInStateTransition(d.toObject(), dataContract); + const doc = new ExtendedDocument(d.toObject(), dataContract); doc.setEntropy(d.entropy); return doc; }); diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js index 5a360c91be6..202199fc80c 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js @@ -15,6 +15,7 @@ let fetchDocuments; let DocumentTransition; let DocumentCreateTransition; let StateTransitionExecutionContext; +let ExtendedDocument; describe('fetchDocumentsFactory', () => { let stateRepositoryMock; @@ -43,9 +44,15 @@ describe('fetchDocumentsFactory', () => { const dataContractBuffer = documentsJs[0].dataContract.toBuffer(); const dataContract = DataContract.fromBuffer(dataContractBuffer); - documents = documentsJs.map((document) => new Document( - document.toObject(), dataContract.clone(), - )); + documents = documentsJs.map((document) => { + console.log(1); + document.toObject(); + console.log(2); + + return new Document( + document.toObject(), dataContract.clone(), document.getType(), + ); + }); documentTransitionsJs = getDocumentTransitionsFixture({ create: documentsJs, }); From e5c225a3a5b90d4f0a1974593627822e23379aa8 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Fri, 3 Mar 2023 20:24:43 +0700 Subject: [PATCH 038/228] fix bytes replacement --- packages/wasm-dpp/src/document/mod.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 10b8186aabf..86ff0073fe0 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -5,7 +5,6 @@ use dpp::util::json_value::{JsonValueExt, ReplaceWith}; use anyhow::anyhow; use serde::{Deserialize, Serialize}; -use serde_json::Value; use std::convert::TryInto; use wasm_bindgen::prelude::*; @@ -38,6 +37,7 @@ pub use extended_document::ExtendedDocumentWasm; use dpp::document::extended_document::property_names; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; use dpp::platform_value::ReplacementType; +use dpp::platform_value::Value; use dpp::ProtocolError; pub use factory::DocumentFactoryWASM; use serde_json::Value as JsonValue; @@ -68,7 +68,7 @@ impl DocumentWasm { js_data_contract: &DataContractWasm, js_document_type_name: JsValue, ) -> Result { - let mut raw_document = with_serde_to_json_value(&js_raw_document)?; + let mut raw_document: Value = with_serde_to_json_value(&js_raw_document)?.into(); let document_type_name = js_document_type_name .as_string() @@ -81,17 +81,18 @@ impl DocumentWasm { .with_js_error()?; // TODO: figure out a better way to replace identifiers - let _ = raw_document - .replace_identifier_paths( + raw_document + .replace_at_paths( identifier_paths .into_iter() .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS), - ReplaceWith::Bytes, - ); - // .with_js_error()?; + ReplacementType::Bytes, + ) + .map_err(ProtocolError::ValueError) + .with_js_error()?; // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array - let document = Document::from_raw_json_document(raw_document).with_js_error()?; + let document = Document::from_platform_value(raw_document).with_js_error()?; Ok(document.into()) } @@ -347,7 +348,7 @@ pub(crate) fn document_data_to_bytes( pub(crate) fn raw_document_from_js_value( js_raw_document: &JsValue, data_contract: &DataContract, -) -> Result { +) -> Result { let mut raw_document = js_raw_document.with_serde_to_json_value()?; let document_type = raw_document From 497b47aa84e8934c8528ca3b264b6f31adeb294b Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Sat, 4 Mar 2023 19:04:51 +0700 Subject: [PATCH 039/228] fix fetch extended document test --- ...pply_documents_batch_transition_factory.rs | 4 ++-- ...cuments.rs => fetch_extended_documents.rs} | 1 + .../validation/state/mod.rs | 2 +- ...lidate_documents_batch_transition_state.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 2 +- ...cuments.rs => fetch_extended_documents.rs} | 17 ++++++--------- .../validation/state/mod.rs | 2 +- packages/wasm-dpp/src/state_repository.rs | 2 +- .../state/fetchDocumentsFactory.spec.js | 21 +++++++++---------- 9 files changed, 24 insertions(+), 29 deletions(-) rename packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/{fetch_documents.rs => fetch_extended_documents.rs} (99%) rename packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/{fetch_documents.rs => fetch_extended_documents.rs} (63%) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 95fea893c6b..d811994035a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -10,7 +10,7 @@ use crate::{ use super::{ document_transition::{Action, DocumentReplaceTransition, DocumentTransition}, - validation::state::fetch_documents::fetch_extended_documents, + validation::state::fetch_extended_documents::fetch_extended_documents, DocumentsBatchTransition, }; @@ -87,7 +87,7 @@ pub async fn apply_documents_batch_transition( })?; document_replace_transition.replace_extended_document(document)?; state_repository - .update_document(document, state_transition.get_execution_context()) + .update_document(&document.document, state_transition.get_execution_context()) .await?; }; } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs similarity index 99% rename from packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs rename to packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs index 79dbf1d6d06..dc9b3507523 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs @@ -2,6 +2,7 @@ use std::{ collections::hash_map::{Entry, HashMap}, convert::TryInto, }; +use anyhow::anyhow; use futures::future::join_all; use itertools::Itertools; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/mod.rs index 6e2a50de31d..cc9fc53d891 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/mod.rs @@ -1,4 +1,4 @@ pub mod execute_data_triggers; -pub mod fetch_documents; +pub mod fetch_extended_documents; pub mod validate_documents_batch_transition_state; pub mod validate_documents_uniqueness_by_indices; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index e833bddbfb2..d7df8e80ac0 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -23,7 +23,7 @@ use crate::{ }; use super::{ - execute_data_triggers::execute_data_triggers, fetch_documents::fetch_extended_documents, + execute_data_triggers::execute_data_triggers, fetch_extended_documents::fetch_extended_documents, validate_documents_uniqueness_by_indices::validate_documents_uniqueness_by_indices, }; diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 86ff0073fe0..d879caf27d6 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -1,7 +1,7 @@ use dpp::dashcore::anyhow::Context; use dpp::prelude::{DataContract, Identifier}; use dpp::util::json_schema::JsonSchemaExt; -use dpp::util::json_value::{JsonValueExt, ReplaceWith}; +use dpp::util::json_value::JsonValueExt; use anyhow::anyhow; use serde::{Deserialize, Serialize}; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_documents.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs similarity index 63% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_documents.rs rename to packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs index 769d10f2456..d3ffbdb770e 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_documents.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs @@ -1,19 +1,14 @@ use dpp::{ - document::validation::state::fetch_documents, prelude::DocumentTransition, + document::validation::state::fetch_extended_documents, prelude::DocumentTransition, state_transition::state_transition_execution_context::StateTransitionExecutionContext, }; use js_sys::Array; use wasm_bindgen::prelude::*; -use crate::{ - document_batch_transition::document_transition::DocumentTransitionWasm, - state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - utils::{IntoWasm, WithJsError}, - DocumentWasm, StateTransitionExecutionContextWasm, -}; +use crate::{document_batch_transition::document_transition::DocumentTransitionWasm, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, utils::{IntoWasm, WithJsError}, DocumentWasm, StateTransitionExecutionContextWasm, ExtendedDocumentWasm}; -#[wasm_bindgen(js_name = fetchDocuments)] -pub async fn fetch_documents_wasm( +#[wasm_bindgen(js_name = fetchExtendedDocuments)] +pub async fn fetch_extended_documents_wasm( state_repository: ExternalStateRepositoryLike, js_document_transitions: Array, js_execution_context: &StateTransitionExecutionContextWasm, @@ -26,7 +21,7 @@ pub async fn fetch_documents_wasm( } let execution_context: StateTransitionExecutionContext = js_execution_context.into(); - let documents = fetch_documents::fetch_extended_documents( + let documents = fetch_extended_documents::fetch_extended_documents( &wrapped_state_repository, document_transitions, &execution_context, @@ -35,7 +30,7 @@ pub async fn fetch_documents_wasm( .with_js_error()?; let array = js_sys::Array::new(); - for document in documents.into_iter().map(DocumentWasm::from) { + for document in documents.into_iter().map(ExtendedDocumentWasm::from) { array.push(&document.into()); } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/mod.rs index b6625506445..a619bff0b1d 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/mod.rs @@ -1,3 +1,3 @@ -pub mod fetch_documents; +pub mod fetch_extended_documents; pub mod validate_documents_batch_transitions_state; pub mod validate_documents_uniqueness_by_indices; diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 6c421d98e77..58fd56577d8 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -370,7 +370,7 @@ impl StateRepositoryLike for ExternalStateRepositoryLikeWrapper { let mut documents: Vec = vec![]; for js_document in js_documents_array.iter() { let document = js_document - .to_wasm::("Document") + .to_wasm::("ExtendedDocument") .map_err(|e| anyhow!("{e:#?}"))?; documents.push(document.to_owned()); } diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js index 202199fc80c..dcb2f988462 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js @@ -11,7 +11,7 @@ const { default: loadWasmDpp } = require('../../../../../../../dist'); let Identifier; let DataContract; let Document; -let fetchDocuments; +let fetchExtendedDocuments; let DocumentTransition; let DocumentCreateTransition; let StateTransitionExecutionContext; @@ -33,7 +33,8 @@ describe('fetchDocumentsFactory', () => { DocumentTransition, DocumentCreateTransition, StateTransitionExecutionContext, - fetchDocuments, + fetchExtendedDocuments, + ExtendedDocument, } = await loadWasmDpp()); stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); @@ -45,12 +46,10 @@ describe('fetchDocumentsFactory', () => { const dataContract = DataContract.fromBuffer(dataContractBuffer); documents = documentsJs.map((document) => { - console.log(1); document.toObject(); - console.log(2); - return new Document( - document.toObject(), dataContract.clone(), document.getType(), + return new ExtendedDocument( + document.toObject(), dataContract.clone(), // document.getType(), ); }); documentTransitionsJs = getDocumentTransitionsFixture({ @@ -71,27 +70,27 @@ describe('fetchDocumentsFactory', () => { documentTransitions[0].setDataContractId(firstDocumentDataContractId); documents[0].setDataContractId(firstDocumentDataContractId); - stateRepositoryMock.fetchDocuments.withArgs( + stateRepositoryMock.fetchExtendedDocuments.withArgs( sinon.match.instanceOf(Identifier), documentTransitions[0].getType(), ).resolves([documents[0]]); - stateRepositoryMock.fetchDocuments.withArgs( + stateRepositoryMock.fetchExtendedDocuments.withArgs( sinon.match.instanceOf(Identifier), documentTransitions[1].getType(), ).resolves([documents[1], documents[2]]); - stateRepositoryMock.fetchDocuments.withArgs( + stateRepositoryMock.fetchExtendedDocuments.withArgs( sinon.match.instanceOf(Identifier), documentTransitionsJs[3].getType(), ).resolves([documents[3], documents[4]]); - await fetchDocuments( + await fetchExtendedDocuments( stateRepositoryMock, documentTransitions, executionContext, ); - expect(stateRepositoryMock.fetchDocuments).to.have.been.calledThrice(); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.calledThrice(); }); }); From 6d268330d4360c6916afd73f06a69d914c4433ca Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 5 Mar 2023 10:10:52 +0700 Subject: [PATCH 040/228] fmt --- .../data_trigger/reward_share_data_triggers/mod.rs | 11 +++-------- .../apply_documents_batch_transition_factory.rs | 5 ++++- .../document_replace_transition.rs | 10 ++++++++-- .../validation/state/fetch_extended_documents.rs | 2 +- .../validate_documents_batch_transition_state.rs | 5 +++-- packages/wasm-dpp/src/document/document_facade.rs | 3 +-- .../validation/state/fetch_extended_documents.rs | 7 ++++++- 7 files changed, 26 insertions(+), 17 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 48fca9e9927..36a6a91d79e 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -7,14 +7,9 @@ use serde_json::json; use crate::document::Document; use crate::{ - data_trigger::create_error, - document::document_transition::DocumentTransition, - get_from_transition, - mocks::SMLStore, - prelude::Identifier, - state_repository::StateRepositoryLike, - util::{string_encoding::Encoding}, - ProtocolError, + data_trigger::create_error, document::document_transition::DocumentTransition, + get_from_transition, mocks::SMLStore, prelude::Identifier, + state_repository::StateRepositoryLike, util::string_encoding::Encoding, ProtocolError, }; use super::{DataTriggerExecutionContext, DataTriggerExecutionResult}; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index d811994035a..fbd00fd94d4 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -87,7 +87,10 @@ pub async fn apply_documents_batch_transition( })?; document_replace_transition.replace_extended_document(document)?; state_repository - .update_document(&document.document, state_transition.get_execution_context()) + .update_document( + &document.document, + state_transition.get_execution_context(), + ) .await?; }; } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 6d66ade5b0f..43e75b9e3f5 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -69,7 +69,10 @@ impl DocumentReplaceTransition { Ok(()) } - pub(crate) fn replace_extended_document(&self, document: &mut ExtendedDocument) -> Result<(), ProtocolError> { + pub(crate) fn replace_extended_document( + &self, + document: &mut ExtendedDocument, + ) -> Result<(), ProtocolError> { let properties = self .data .as_ref() @@ -100,7 +103,10 @@ impl DocumentReplaceTransition { Ok(()) } - pub(crate) fn patch_extended_document(self, document: &mut ExtendedDocument) -> Result<(), ProtocolError> { + pub(crate) fn patch_extended_document( + self, + document: &mut ExtendedDocument, + ) -> Result<(), ProtocolError> { let properties = self .data .map(|json_value| { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs index dc9b3507523..1194acd4dfb 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs @@ -1,8 +1,8 @@ +use anyhow::anyhow; use std::{ collections::hash_map::{Entry, HashMap}, convert::TryInto, }; -use anyhow::anyhow; use futures::future::join_all; use itertools::Itertools; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index d7df8e80ac0..8735a1db545 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use futures::future::join_all; use itertools::Itertools; -use crate::document::{ExtendedDocument}; +use crate::document::ExtendedDocument; use crate::{ block_time_window::validate_time_in_block_time_window::validate_time_in_block_time_window, consensus::ConsensusError, @@ -23,7 +23,8 @@ use crate::{ }; use super::{ - execute_data_triggers::execute_data_triggers, fetch_extended_documents::fetch_extended_documents, + execute_data_triggers::execute_data_triggers, + fetch_extended_documents::fetch_extended_documents, validate_documents_uniqueness_by_indices::validate_documents_uniqueness_by_indices, }; diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index 123c483cfbd..5a1c1b7f12d 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -120,7 +120,6 @@ impl DocumentFacadeWasm { .get_data() .to_wasm::("DataContract")?; - self.validator - .validate(&js_raw_document, &data_contract) + self.validator.validate(&js_raw_document, &data_contract) } } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs index d3ffbdb770e..59b2eaf7221 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs @@ -5,7 +5,12 @@ use dpp::{ use js_sys::Array; use wasm_bindgen::prelude::*; -use crate::{document_batch_transition::document_transition::DocumentTransitionWasm, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, utils::{IntoWasm, WithJsError}, DocumentWasm, StateTransitionExecutionContextWasm, ExtendedDocumentWasm}; +use crate::{ + document_batch_transition::document_transition::DocumentTransitionWasm, + state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, + utils::{IntoWasm, WithJsError}, + DocumentWasm, ExtendedDocumentWasm, StateTransitionExecutionContextWasm, +}; #[wasm_bindgen(js_name = fetchExtendedDocuments)] pub async fn fetch_extended_documents_wasm( From f3cbc310bd58b9ac8f9dacca324215f21500388d Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 02:09:46 +0700 Subject: [PATCH 041/228] much more work --- .../data_trigger/dashpay_data_triggers/mod.rs | 16 +- .../src/data_trigger/dpns_triggers/mod.rs | 51 +++++-- .../feature_flags_data_triggers/mod.rs | 12 +- .../reward_share_data_triggers/mod.rs | 36 ++--- packages/rs-dpp/src/document/document.rs | 41 +++-- .../rs-dpp/src/document/document_factory.rs | 2 +- packages/rs-dpp/src/document/errors.rs | 2 + .../rs-dpp/src/document/extended_document.rs | 7 +- packages/rs-dpp/src/document/serialize.rs | 4 +- ...pply_documents_batch_transition_factory.rs | 20 +-- .../document_base_transition.rs | 140 ++++++++++++++---- .../document_create_transition.rs | 132 ++++++++++------- .../document_delete_transition.rs | 26 +++- .../document_replace_transition.rs | 73 ++++++--- .../document_transition/mod.rs | 77 +++++----- .../documents_batch_transition/mod.rs | 38 +++-- .../basic/find_duplicates_by_indices.rs | 15 +- .../src/btreemap_extensions.rs | 54 +++---- .../src/btreemap_field_replacement.rs | 18 ++- .../src/btreemap_path_extensions.rs | 6 +- .../src/converter/serde_json.rs | 30 +++- packages/rs-platform-value/src/error.rs | 3 + packages/rs-platform-value/src/lib.rs | 15 +- .../rs-platform-value/src/system_bytes.rs | 16 +- .../document_create_transition.rs | 59 +++----- 25 files changed, 557 insertions(+), 336 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs index 10a82fdf2bf..012947fba1e 100644 --- a/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dashpay_data_triggers/mod.rs @@ -1,14 +1,14 @@ use anyhow::{anyhow, bail}; +use platform_value::btreemap_extensions::BTreeValueMapHelper; use crate::{ document::document_transition::DocumentTransition, errors::DataTriggerError, - get_from_transition, prelude::Identifier, state_repository::StateRepositoryLike, - util::json_value::JsonValueExt, + get_from_transition, prelude::Identifier, state_repository::StateRepositoryLike, ProtocolError, }; use super::{DataTriggerExecutionContext, DataTriggerExecutionResult}; -const BLOCKS_SIZE_WINDOW: i64 = 8; +const BLOCKS_SIZE_WINDOW: u64 = 8; const PROPERTY_CORE_HEIGHT_CREATED_AT: &str = "coreHeightCreatedAt"; const PROPERTY_CORE_CHAIN_LOCKED_HEIGHT: &str = "coreChainLockedHeight"; @@ -38,16 +38,18 @@ where ) })?; - let core_height_created_at = data.get_i64(PROPERTY_CORE_HEIGHT_CREATED_AT)?; + let core_height_created_at: u64 = data + .get_integer(PROPERTY_CORE_HEIGHT_CREATED_AT) + .map_err(ProtocolError::ValueError)?; let core_chain_locked_height = context .state_repository .fetch_latest_platform_core_chain_locked_height() .await? - .unwrap_or_default() as i64; + .unwrap_or_default() as u64; - let height_window_start = core_chain_locked_height - BLOCKS_SIZE_WINDOW; - let height_window_end = core_chain_locked_height + BLOCKS_SIZE_WINDOW; + let height_window_start = core_chain_locked_height.saturating_sub(BLOCKS_SIZE_WINDOW); + let height_window_end = core_chain_locked_height.saturating_add(BLOCKS_SIZE_WINDOW); let mut result = DataTriggerExecutionResult::default(); diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 8101d4747cf..f462e10f997 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -51,20 +51,29 @@ where })?; let top_level_identity = top_level_identity.context("top level identity isn't provided")?; - let owner_id = context.owner_id.to_string(Encoding::Base58); - let label = data.get_string(PROPERTY_LABEL)?; - let normalized_label = data.get_string(PROPERTY_NORMALIZED_LABEL)?; - let normalized_parent_domain_name = data.get_string(PROPERTY_NORMALIZED_PARENT_DOMAIN_NAME)?; - - let preorder_salt = data.get_bytes(PROPERTY_PREORDER_SALT)?; + let owner_id = context.owner_id; + let label = data + .get_string(PROPERTY_LABEL) + .map_err(ProtocolError::ValueError)?; + let normalized_label = data + .get_str(PROPERTY_NORMALIZED_LABEL) + .map_err(ProtocolError::ValueError)?; + let normalized_parent_domain_name = data + .get_string(PROPERTY_NORMALIZED_PARENT_DOMAIN_NAME) + .map_err(ProtocolError::ValueError)?; + + let preorder_salt = data + .get_hash256_bytes(PROPERTY_PREORDER_SALT) + .map_err(ProtocolError::ValueError)?; let records = data .get(PROPERTY_RECORDS) - .ok_or_else(|| anyhow!("property '{}' doesn't exist", PROPERTY_RECORDS))?; + .ok_or_else(|| anyhow!("property '{}' doesn't exist", PROPERTY_RECORDS))? + .to_btree_ref_map() + .map_err(ProtocolError::ValueError)?; let rule_allow_subdomains = data - .get_value(PROPERTY_ALLOW_SUBDOMAINS)? - .as_bool() - .ok_or_else(|| anyhow!("property '{}' isn't a bool", PROPERTY_ALLOW_SUBDOMAINS))?; + .get_bool(PROPERTY_ALLOW_SUBDOMAINS) + .map_err(ProtocolError::ValueError)?; let mut result = DataTriggerExecutionResult::default(); let full_domain_name = normalized_label; @@ -92,28 +101,38 @@ where result.add_error(err.into()); } - if let Some(JsonValue::String(ref id)) = records.get(PROPERTY_DASH_UNIQUE_IDENTITY_ID) { - if id != &owner_id { + if let Some(id) = records + .get_optional_identifier(PROPERTY_DASH_UNIQUE_IDENTITY_ID) + .map_err(ProtocolError::ValueError)? + { + if id != owner_id.buffer { let err = create_error( context, dt_create, format!( "ownerId {} doesn't match {} {}", - owner_id, PROPERTY_DASH_UNIQUE_IDENTITY_ID, id + owner_id, + PROPERTY_DASH_UNIQUE_IDENTITY_ID, + Identifier::new(id) ), ); result.add_error(err.into()) } } - if let Some(JsonValue::String(ref id)) = records.get(PROPERTY_DASH_ALIAS_IDENTITY_ID) { - if id != &owner_id { + if let Some(id) = records + .get_optional_identifier(PROPERTY_DASH_ALIAS_IDENTITY_ID) + .map_err(ProtocolError::ValueError)? + { + if id != owner_id.buffer { let err = create_error( context, dt_create, format!( "ownerId {} doesn't match {} {}", - owner_id, PROPERTY_DASH_ALIAS_IDENTITY_ID, id + owner_id, + PROPERTY_DASH_ALIAS_IDENTITY_ID, + Identifier::new(id) ), ); result.add_error(err.into()); diff --git a/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs index 18f07029c6a..172d13e3c54 100644 --- a/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs @@ -1,9 +1,10 @@ use anyhow::{anyhow, bail, Context}; +use platform_value::btreemap_extensions::BTreeValueMapHelper; use crate::{ data_trigger::create_error, document::document_transition::DocumentTransition, get_from_transition, prelude::Identifier, state_repository::StateRepositoryLike, - util::json_value::JsonValueExt, + util::json_value::JsonValueExt, ProtocolError, }; use super::{DataTriggerExecutionContext, DataTriggerExecutionResult}; @@ -43,9 +44,14 @@ where let block_height = context .state_repository .fetch_latest_platform_block_height() - .await? as i64; + .await? as u64; - let enable_at_height = data.get_i64(PROPERTY_ENABLE_AT_HEIGHT)?; + let enable_at_height: u64 = data.get_integer(PROPERTY_ENABLE_AT_HEIGHT).map_err(|_| { + anyhow!( + "property missing for create_feature_flag_data_trigger '{}'", + PROPERTY_ENABLE_AT_HEIGHT + ) + })?; if enable_at_height < block_height { let err = create_error( diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 36a6a91d79e..0eec149a456 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -38,20 +38,14 @@ where get_from_transition!(document_transition, id) ), }; - let data: Value = document_create_transition - .data - .as_ref() - .ok_or_else(|| { - anyhow!( - "data isn't defined in Data Transition '{}'", - document_create_transition.base.id - ) - })? - .clone() - .into(); - - let properties = data.into_btree_map()?; - let pay_to_id = properties.get_system_hash256_bytes(PROPERTY_PAY_TO_ID)?; + let properties = document_create_transition.data.as_ref().ok_or_else(|| { + anyhow!( + "data isn't defined in Data Transition '{}'", + document_create_transition.base.id + ) + })?; + + let pay_to_id = properties.get_hash256_bytes(PROPERTY_PAY_TO_ID)?; let percentage = properties.get_integer(PROPERTY_PERCENTAGE)?; if !is_dry_run { @@ -215,7 +209,6 @@ mod test { }; let document_transitions = get_document_transitions_fixture([(Action::Create, vec![documents[0].clone()])]); - dbg!(&document_transitions); TestData { extended_documents: documents, data_contract, @@ -272,7 +265,7 @@ mod test { .returning(move |_, _, _, _| Ok(documents.clone())); // documentsFixture contains percentage = 500 - document_transition.insert_dynamic_property(String::from("percentage"), json!(9501)); + document_transition.insert_dynamic_property(String::from("percentage"), Value::U64(9501)); let execution_context = StateTransitionExecutionContext::default(); let context = DataTriggerExecutionContext { @@ -326,15 +319,12 @@ mod test { .await; let error = get_data_trigger_error(&result, 0); - let pay_to_id_bytes: Vec = document_transition + let pay_to_id_bytes = document_transition .get_dynamic_property(PROPERTY_PAY_TO_ID) .expect("payToId should exist") - .as_array() - .unwrap() - .iter() - .map(|v| v.as_u64().unwrap() as u8) - .collect_vec(); - let pay_to_id = Identifier::from_bytes(&pay_to_id_bytes).unwrap(); + .to_hash256() + .expect("expected to be able to get a hash"); + let pay_to_id = Identifier::from(pay_to_id_bytes); assert_eq!( format!("Identity '{}' doesn't exist", pay_to_id), diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index e9609fa7496..2533c218467 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -38,7 +38,7 @@ use std::convert::TryInto; use std::fmt; use ciborium::Value as CborValue; -use serde_json::{json, Value as JsonValue}; +use serde_json::{json, Map, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; use platform_value::btreemap_extensions::BTreeValueMapHelper; @@ -255,7 +255,7 @@ impl Document { Ok((identifiers_paths, binary_paths)) } - pub fn to_json(&self) -> Result { + pub fn to_json_with_identifiers_using_bytes(&self) -> Result { let mut value = json!({ property_names::ID: self.id, property_names::OWNER_ID: self.owner_id, @@ -283,10 +283,27 @@ impl Document { self.properties .iter() .try_for_each(|(key, property_value)| { - let serde_value: JsonValue = property_value - .clone() - .try_into() - .map_err(ProtocolError::ValueError)?; + let serde_value: JsonValue = match property_value { + Value::Identifier(bytes) => { + // In order to be able to validate using JSON schema it needs to be in byte form + JsonValue::Array( + bytes + .into_iter() + .map(|a| JsonValue::Number((*a).into())) + .collect(), + ) + } + Value::Bytes(bytes) => JsonValue::Array( + bytes + .into_iter() + .map(|byte| JsonValue::Number((*byte).into())) + .collect(), + ), + _ => property_value + .clone() + .try_into() + .map_err(ProtocolError::ValueError)?, + }; value_mut.insert(key.to_string(), serde_value); Ok::<(), ProtocolError>(()) })?; @@ -338,11 +355,7 @@ impl Document { Ok(value) } - pub fn to_pretty_json( - &self, - data_contract: &DataContract, - document_type_name: &str, - ) -> Result { + pub fn to_json(&self) -> Result { let mut value = json!({ property_names::ID: bs58::encode(self.id).into_string(), property_names::OWNER_ID: bs58::encode(self.owner_id).into_string(), @@ -378,8 +391,6 @@ impl Document { Ok::<(), ProtocolError>(()) })?; - Self::replace_property_fields(&mut value, data_contract, document_type_name)?; - Ok(value) } @@ -472,8 +483,8 @@ impl Document { ..Default::default() }; - document.id = properties.remove_system_hash256_bytes(property_names::ID)?; - document.owner_id = properties.remove_system_hash256_bytes(property_names::OWNER_ID)?; + document.id = properties.remove_hash256_bytes(property_names::ID)?; + document.owner_id = properties.remove_hash256_bytes(property_names::OWNER_ID)?; document.revision = properties.remove_optional_integer(property_names::REVISION)?; document.created_at = properties.remove_optional_integer(property_names::CREATED_AT)?; document.updated_at = properties.remove_optional_integer(property_names::UPDATED_AT)?; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 7ab4135442f..7fc7d165492 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -159,7 +159,7 @@ where updated_at, }; - let mut json_value = document.to_json()?; + let mut json_value = document.to_json_with_identifiers_using_bytes()?; let validation_result = self.document_validator .validate(&json_value, &data_contract, document_type)?; diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index 28019ab8025..ba97a618423 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -16,6 +16,8 @@ pub enum DocumentError { DocumentNotProvidedError { document_transition: DocumentTransition, }, + #[error("Invalid Document action number {0}")] + InvalidActionError(u8), #[error("Invalid Document action submitted")] InvalidActionNameError { actions: Vec }, #[error("Invalid Document action '{}'", document_transition.base().action)] diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 118b0898b6e..f77c15949dc 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -17,6 +17,7 @@ use crate::document::Document; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper; +use platform_value::converter::serde_json::BTreeValueJsonConverter; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; @@ -191,9 +192,7 @@ impl ExtendedDocument { } pub fn to_pretty_json(&self) -> Result { - let mut value = self - .document - .to_pretty_json(&self.data_contract, &self.document_type_name)?; + let mut value = self.document.to_json()?; let value_mut = value.as_object_mut().unwrap(); value_mut.insert( property_names::PROTOCOL_VERSION.to_string(), @@ -226,7 +225,7 @@ impl ExtendedDocument { let data_contract_id = Identifier::new( document_map - .remove_system_hash256_bytes(property_names::DATA_CONTRACT_ID) + .remove_hash256_bytes(property_names::DATA_CONTRACT_ID) .map_err(ProtocolError::ValueError)?, ); diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 3441c691368..e53a2a27f01 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -357,14 +357,14 @@ impl Document { ) -> Result { let owner_id = match owner_id { None => document_map - .remove_system_hash256_bytes(property_names::OWNER_ID) + .remove_hash256_bytes(property_names::OWNER_ID) .map_err(ProtocolError::ValueError)?, Some(owner_id) => owner_id, }; let id = match document_id { None => document_map - .remove_system_hash256_bytes(property_names::ID) + .remove_hash256_bytes(property_names::ID) .map_err(ProtocolError::ValueError)?, Some(document_id) => document_id, }; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index fbd00fd94d4..23884aee8dc 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -1,5 +1,5 @@ use platform_value::Value; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use crate::document::{Document, ExtendedDocument}; use crate::prelude::TimestampMillis; @@ -115,12 +115,6 @@ fn document_from_transition_replace( created_at: TimestampMillis, ) -> Result { // TODO cloning is costly. Probably the [`Document`] should have properties of type `Cow<'a, K>` - let property_value: Value = document_replace_transition - .data - .as_ref() - .unwrap_or(&serde_json::Value::Null) - .clone() - .into(); Ok(ExtendedDocument { protocol_version: state_transition.protocol_version, document_type_name: document_replace_transition.base.document_type.clone(), @@ -135,9 +129,7 @@ fn document_from_transition_replace( document: Document { id: document_replace_transition.base.id.buffer, owner_id: state_transition.owner_id.buffer, - properties: property_value - .into_btree_map() - .map_err(ProtocolError::ValueError)?, + properties: document_replace_transition.data.clone().unwrap_or_default(), revision: Some(document_replace_transition.revision), created_at: Some(created_at), updated_at: document_replace_transition.updated_at, @@ -147,7 +139,9 @@ fn document_from_transition_replace( #[cfg(test)] mod test { - use serde_json::{json, Value}; + use platform_value::Value; + use serde_json::{json, Value as JsonValue}; + use std::convert::TryInto; use crate::tests::fixtures::get_extended_documents_fixture; @@ -177,9 +171,9 @@ mod test { (Action::Replace, documents), (Action::Create, vec![]), ]); - let raw_document_transitions: Vec = documents_transitions + let raw_document_transitions: Vec = documents_transitions .iter() - .map(|dt| dt.to_object().unwrap()) + .map(|dt| dt.to_object().unwrap().try_into().unwrap()) .collect(); let owner_id_bytes = owner_id.to_buffer(); let state_transition = DocumentsBatchTransition::from_raw_object( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index f50a9192104..059d3a43a1a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -1,11 +1,17 @@ -use std::convert::TryFrom; +use std::collections::BTreeMap; +use std::convert::{TryFrom, TryInto}; use anyhow::bail; use num_enum::{IntoPrimitive, TryFromPrimitive}; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; use serde::{Deserialize, Serialize}; pub use serde_json::Value as JsonValue; use serde_repr::*; +use crate::document::document_transition::Action::{Create, Delete, Replace}; +use crate::document::document_transition::DocumentCreateTransition; +use crate::document::errors::DocumentError; use crate::{ data_contract::DataContract, errors::ProtocolError, @@ -13,19 +19,17 @@ use crate::{ util::json_value::{JsonValueExt, ReplaceWith}, }; -pub const IDENTIFIER_FIELDS: [&str; 2] = ["$id", "$dataContractId"]; +pub(self) mod property_names { + pub const ID: &str = "$id"; + pub const DATA_CONTRACT_ID: &str = "$dataContractId"; + pub const DOCUMENT_TYPE: &str = "$type"; + pub const ACTION: &str = "$action"; +} + +pub const IDENTIFIER_FIELDS: [&str; 2] = [property_names::ID, property_names::DATA_CONTRACT_ID]; #[derive( - Debug, - Serialize_repr, - Deserialize_repr, - Clone, - Copy, - PartialEq, - Eq, - Hash, - TryFromPrimitive, - IntoPrimitive, + Debug, Serialize_repr, Deserialize_repr, Clone, Copy, PartialEq, Eq, Hash, IntoPrimitive, )] #[repr(u8)] pub enum Action { @@ -47,6 +51,21 @@ impl std::fmt::Display for Action { } } +impl TryFrom for Action { + type Error = ProtocolError; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Create), + 1 => Ok(Replace), + 2 => Ok(Delete), + other => Err(ProtocolError::Document(Box::new( + DocumentError::InvalidActionError(other), + ))), + } + } +} + impl TryFrom<&str> for Action { type Error = anyhow::Error; @@ -89,6 +108,29 @@ pub struct DocumentBaseTransition { pub data_contract: DataContract, } +impl DocumentBaseTransition { + pub fn from_value_map_consume( + map: &mut BTreeMap, + data_contract: DataContract, + ) -> Result { + Ok(DocumentBaseTransition { + id: Identifier::from( + map.remove_hash256_bytes(property_names::ID) + .map_err(ProtocolError::ValueError)?, + ), + document_type: map + .remove_string(property_names::DOCUMENT_TYPE) + .map_err(ProtocolError::ValueError)?, + action: map + .remove_integer::(property_names::ACTION) + .map_err(ProtocolError::ValueError)? + .try_into()?, + data_contract_id: data_contract.id, + data_contract, + }) + } +} + impl DocumentTransitionObjectLike for DocumentBaseTransition { fn from_json_object( json_value: JsonValue, @@ -102,23 +144,59 @@ impl DocumentTransitionObjectLike for DocumentBaseTransition { } fn from_raw_object( - mut raw_transition: JsonValue, + mut raw_transition: Value, data_contract: DataContract, ) -> Result { - raw_transition.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Base58)?; - let mut document: DocumentBaseTransition = serde_json::from_value(raw_transition)?; - - document.data_contract_id = data_contract.id; - document.data_contract = data_contract; + let map = raw_transition + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + Self::from_value_map(map, data_contract) + } - Ok(document) + fn from_value_map( + map: BTreeMap, + data_contract: DataContract, + ) -> Result { + Ok(DocumentBaseTransition { + id: Identifier::from( + map.get_hash256_bytes(property_names::ID) + .map_err(ProtocolError::ValueError)?, + ), + document_type: map + .get_string(property_names::DOCUMENT_TYPE) + .map_err(ProtocolError::ValueError)?, + action: map + .get_integer::(property_names::ACTION) + .map_err(ProtocolError::ValueError)? + .try_into()?, + data_contract_id: data_contract.id, + data_contract, + }) } - fn to_object(&self) -> Result { - let mut object = serde_json::to_value(self)?; + fn to_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } - object.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Bytes)?; - Ok(object) + fn to_value_map(&self) -> Result, ProtocolError> { + let mut btree_map = BTreeMap::new(); + btree_map.insert( + property_names::ID.to_string(), + Value::Identifier(self.id.buffer), + ); + btree_map.insert( + property_names::DATA_CONTRACT_ID.to_string(), + Value::Identifier(self.data_contract_id.buffer), + ); + btree_map.insert( + property_names::ACTION.to_string(), + Value::U8(self.action as u8), + ); + btree_map.insert( + property_names::DOCUMENT_TYPE.to_string(), + Value::Text(self.document_type.clone()), + ); + Ok(btree_map) } fn to_json(&self) -> Result { @@ -138,14 +216,24 @@ pub trait DocumentTransitionObjectLike { Self: std::marker::Sized; /// Creates the document transition from Raw Object fn from_raw_object( - raw_transition: JsonValue, + raw_transition: Value, data_contract: DataContract, ) -> Result where Self: std::marker::Sized; - /// Object is an [`serde_json::Value`] instance that preserves the `Vec` representation + fn from_value_map( + map: BTreeMap, + data_contract: DataContract, + ) -> Result + where + Self: std::marker::Sized; + /// Object is an [`platform::Value`] instance that preserves the `Vec` representation /// for Identifiers and binary data - fn to_object(&self) -> Result; + fn to_object(&self) -> Result; + + /// Value Map is a Map of string to [`platform::Value`] that represents the state transition + fn to_value_map(&self) -> Result, ProtocolError>; + /// Object is an [`serde_json::Value`] instance that replaces the binary data with /// - base58 string for Identifiers /// - base64 string for other binary data diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 75390a2815a..abcf36386f5 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,7 +1,11 @@ use itertools::Itertools; -use platform_value::Value; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; +use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use std::collections::BTreeMap; +use std::string::ToString; use crate::document::Document; use crate::identity::TimestampMillis; @@ -15,11 +19,18 @@ use crate::{ use super::INITIAL_REVISION; use super::{ document_base_transition, document_base_transition::DocumentBaseTransition, - merge_serde_json_values, DocumentTransitionObjectLike, + DocumentTransitionObjectLike, }; +pub(self) mod property_names { + pub const ENTROPY: &str = "$entropy"; + pub const CREATED_AT: &str = "$createdAt"; + pub const UPDATED_AT: &str = "$updatedAt"; +} + /// The Binary fields in [`DocumentCreateTransition`] pub const BINARY_FIELDS: [&str; 1] = ["$entropy"]; +pub const BINARY_FIELDS_OWNED: [String; 1] = ["$entropy".to_string()]; /// The Identifier fields in [`DocumentCreateTransition`] pub use super::document_base_transition::IDENTIFIER_FIELDS; @@ -40,7 +51,7 @@ pub struct DocumentCreateTransition { pub updated_at: Option, #[serde(flatten, skip_serializing_if = "Option::is_none")] - pub data: Option, + pub data: Option>, } impl DocumentCreateTransition { @@ -57,15 +68,7 @@ impl DocumentCreateTransition { } pub(crate) fn to_document(&self, owner_id: [u8; 32]) -> Result { - let properties = self - .data - .as_ref() - .map(|json_value| { - let value: Value = json_value.clone().into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }) - .transpose()? - .unwrap_or_default(); + let properties = self.data.clone().unwrap_or_default(); Ok(Document { id: self.base.id.to_buffer(), owner_id, @@ -81,14 +84,7 @@ impl DocumentCreateTransition { let revision = self.get_revision(); let created_at = self.created_at; let updated_at = self.updated_at; - let properties = self - .data - .map(|json_value| { - let value: Value = json_value.into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }) - .transpose()? - .unwrap_or_default(); + let properties = self.data.unwrap_or_default(); Ok(Document { id, owner_id, @@ -102,51 +98,83 @@ impl DocumentCreateTransition { impl DocumentTransitionObjectLike for DocumentCreateTransition { fn from_json_object( - mut json_value: JsonValue, + json_value: JsonValue, data_contract: DataContract, ) -> Result { - let document_type = json_value.get_string("$type")?; + let value: Value = json_value.into(); + let mut map = value.into_btree_map().map_err(ProtocolError::ValueError)?; + + let document_type = map.get_str("$type")?; let (identifiers_paths, binary_paths) = - data_contract.get_identifiers_and_binary_paths(document_type)?; + data_contract.get_identifiers_and_binary_paths_owned(document_type)?; - json_value.replace_binary_paths( - binary_paths.into_iter().chain(BINARY_FIELDS), - ReplaceWith::Bytes, + map.replace_at_paths( + binary_paths.into_iter().chain(BINARY_FIELDS_OWNED), + ReplacementType::Bytes, )?; - // Only dynamic identifiers are being replaced with bytes. Static are Strings - json_value.replace_identifier_paths(identifiers_paths, ReplaceWith::Bytes)?; - let mut document: DocumentCreateTransition = serde_json::from_value(json_value)?; - document.base.action = Action::Create; - document.base.data_contract = data_contract; + map.replace_at_paths(identifiers_paths.into_iter(), ReplacementType::Identifier)?; + let document = Self::from_value_map(map, data_contract)?; Ok(document) } fn from_raw_object( - mut raw_transition: JsonValue, + mut raw_transition: Value, data_contract: DataContract, ) -> Result { - // Only static identifiers are replaced, as the dynamic ones are stored as Arrays - raw_transition.replace_identifier_paths( - document_base_transition::IDENTIFIER_FIELDS, - ReplaceWith::Base58, - )?; - - let mut document: DocumentCreateTransition = serde_json::from_value(raw_transition)?; - document.base.action = Action::Create; - document.base.data_contract = data_contract; + let map = raw_transition + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + Self::from_value_map(map, data_contract) + } - Ok(document) + fn from_value_map( + mut map: BTreeMap, + data_contract: DataContract, + ) -> Result { + Ok(DocumentCreateTransition { + base: DocumentBaseTransition::from_value_map_consume(&mut map, data_contract)?, + entropy: map + .remove_hash256_bytes(property_names::ENTROPY) + .map_err(ProtocolError::ValueError)?, + created_at: map + .remove_optional_integer(property_names::CREATED_AT) + .map_err(ProtocolError::ValueError)?, + updated_at: map + .remove_optional_integer(property_names::UPDATED_AT) + .map_err(ProtocolError::ValueError)?, + data: Some(map), + }) } - fn to_object(&self) -> Result { - let transition_base_value = self.base.to_object()?; - let mut transition_create_value = serde_json::to_value(self)?; + fn to_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } - merge_serde_json_values(&mut transition_create_value, transition_base_value)?; - Ok(transition_create_value) + fn to_value_map(&self) -> Result, ProtocolError> { + let mut transition_base_map = self.base.to_value_map()?; + transition_base_map.insert( + property_names::ENTROPY.to_string(), + Value::Bytes(self.entropy.to_vec()), + ); + if let Some(created_at) = self.created_at { + transition_base_map.insert( + property_names::CREATED_AT.to_string(), + Value::U64(created_at), + ); + } + if let Some(updated_at) = self.updated_at { + transition_base_map.insert( + property_names::UPDATED_AT.to_string(), + Value::U64(updated_at), + ); + } + if let Some(properties) = self.data.clone() { + transition_base_map.extend(properties) + } + Ok(transition_base_map) } fn to_json(&self) -> Result { @@ -225,7 +253,7 @@ mod test { }); let transition: DocumentCreateTransition = - DocumentCreateTransition::from_raw_object(raw_document, data_contract).unwrap(); + DocumentCreateTransition::from_json_object(raw_document, data_contract).unwrap(); let json_transition = transition.to_json().expect("no errors"); assert_eq!( @@ -271,9 +299,13 @@ mod test { }); let document: DocumentCreateTransition = - DocumentCreateTransition::from_raw_object(raw_document, data_contract).unwrap(); + DocumentCreateTransition::from_json_object(raw_document, data_contract).unwrap(); - let object_transition = document.to_object().expect("no errors"); + let object_transition = document + .to_object() + .expect("no errors") + .into_btree_map() + .unwrap(); assert_eq!(object_transition.get_bytes("$id").unwrap(), id); assert_eq!( object_transition.get_bytes("$dataContractId").unwrap(), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs index 3cb959fa90c..d04eb5ff7ee 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs @@ -1,6 +1,8 @@ use crate::{data_contract::DataContract, errors::ProtocolError}; +use platform_value::Value; use serde::{Deserialize, Serialize}; -use serde_json::Value; +use serde_json::Value as JsonValue; +use std::collections::BTreeMap; use super::{document_base_transition::DocumentBaseTransition, DocumentTransitionObjectLike}; @@ -15,7 +17,7 @@ pub struct DocumentDeleteTransition { impl DocumentTransitionObjectLike for DocumentDeleteTransition { fn from_json_object( - json_value: Value, + json_value: JsonValue, data_contract: DataContract, ) -> Result { let mut document: DocumentDeleteTransition = serde_json::from_value(json_value)?; @@ -28,7 +30,19 @@ impl DocumentTransitionObjectLike for DocumentDeleteTransition { raw_transition: Value, data_contract: DataContract, ) -> Result { - let base = DocumentBaseTransition::from_raw_object(raw_transition, data_contract)?; + let base = DocumentBaseTransition::from_raw_object(raw_transition.into(), data_contract)?; + + Ok(DocumentDeleteTransition { base }) + } + + fn from_value_map( + mut map: BTreeMap, + data_contract: DataContract, + ) -> Result + where + Self: Sized, + { + let base = DocumentBaseTransition::from_value_map_consume(&mut map, data_contract)?; Ok(DocumentDeleteTransition { base }) } @@ -37,7 +51,11 @@ impl DocumentTransitionObjectLike for DocumentDeleteTransition { self.base.to_object() } - fn to_json(&self) -> Result { + fn to_value_map(&self) -> Result, ProtocolError> { + self.base.to_value_map() + } + + fn to_json(&self) -> Result { self.base.to_json() } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 43e75b9e3f5..c415dabf8dd 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -1,6 +1,8 @@ +use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use std::collections::BTreeMap; use crate::document::Document; use crate::identity::TimestampMillis; @@ -12,10 +14,15 @@ use crate::{ }; use super::{ - document_base_transition, document_base_transition::DocumentBaseTransition, - merge_serde_json_values, Action, DocumentTransitionObjectLike, + document_base_transition, document_base_transition::DocumentBaseTransition, Action, + DocumentTransitionObjectLike, }; +pub(self) mod property_names { + pub const REVISION: &str = "$revision"; + pub const UPDATED_AT: &str = "$updatedAt"; +} + /// Identifier fields in [`DocumentReplaceTransition`] pub use super::document_base_transition::IDENTIFIER_FIELDS; @@ -29,7 +36,7 @@ pub struct DocumentReplaceTransition { #[serde(skip_serializing_if = "Option::is_none", rename = "$updatedAt")] pub updated_at: Option, #[serde(flatten, skip_serializing_if = "Option::is_none")] - pub data: Option, + pub data: Option>, } impl DocumentReplaceTransition { @@ -145,28 +152,54 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { } fn from_raw_object( - mut raw_transition: JsonValue, + mut raw_transition: Value, data_contract: DataContract, ) -> Result { - // Only static identifiers are replaced, as the dynamic ones are stored as Arrays - raw_transition.replace_identifier_paths( - document_base_transition::IDENTIFIER_FIELDS, - ReplaceWith::Base58, - )?; - - let mut document: DocumentReplaceTransition = serde_json::from_value(raw_transition)?; - document.base.action = Action::Replace; - document.base.data_contract = data_contract; + let map = raw_transition + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + Self::from_value_map(map, data_contract) + } - Ok(document) + fn from_value_map( + mut map: BTreeMap, + data_contract: DataContract, + ) -> Result + where + Self: Sized, + { + Ok(DocumentReplaceTransition { + base: DocumentBaseTransition::from_value_map_consume(&mut map, data_contract)?, + revision: map + .remove_integer(property_names::REVISION) + .map_err(ProtocolError::ValueError)?, + updated_at: map + .remove_optional_integer(property_names::UPDATED_AT) + .map_err(ProtocolError::ValueError)?, + data: Some(map), + }) } - fn to_object(&self) -> Result { - let transition_base_value = self.base.to_object()?; - let mut transition_create_value = serde_json::to_value(self)?; + fn to_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } - merge_serde_json_values(&mut transition_create_value, transition_base_value)?; - Ok(transition_create_value) + fn to_value_map(&self) -> Result, ProtocolError> { + let mut transition_base_map = self.base.to_value_map()?; + transition_base_map.insert( + property_names::REVISION.to_string(), + Value::U64(self.revision), + ); + if let Some(updated_at) = self.updated_at { + transition_base_map.insert( + property_names::UPDATED_AT.to_string(), + Value::U64(updated_at), + ); + } + if let Some(properties) = self.data.clone() { + transition_base_map.extend(properties) + } + Ok(transition_base_map) } fn to_json(&self) -> Result { @@ -212,7 +245,7 @@ mod test { assert_eq!(cdt.base.document_type, "note"); assert_eq!(cdt.revision, 1); assert_eq!( - cdt.data.as_ref().unwrap()["message"], + cdt.data.as_ref().unwrap().get_str("message").unwrap(), "example_message_replace" ); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index 4786c35d3f0..aa05d0e5777 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -1,8 +1,9 @@ -use std::convert::TryFrom; +use std::collections::BTreeMap; +use std::convert::{TryFrom, TryInto}; use anyhow::{bail, Context}; use serde::{Deserialize, Serialize}; -use serde_json::Value; +use serde_json::Value as JsonValue; use crate::{ data_contract::DataContract, prelude::Identifier, util::json_value::JsonValueExt, ProtocolError, @@ -20,6 +21,8 @@ pub use document_base_transition::{Action, DocumentTransitionObjectLike}; pub use document_create_transition::DocumentCreateTransition; pub use document_delete_transition::DocumentDeleteTransition; pub use document_replace_transition::DocumentReplaceTransition; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; /// the initial revision of newly created document pub const INITIAL_REVISION: u64 = 1; @@ -48,7 +51,7 @@ pub trait DocumentTransitionExt { /// get the data contract id fn get_data_contract_id(&self) -> &Identifier; /// get the data of the transition if exits - fn get_data(&self) -> Option<&Value>; + fn get_data(&self) -> Option<&BTreeMap>; /// get the revision of transition if exits fn get_revision(&self) -> Option; #[cfg(test)] @@ -95,7 +98,7 @@ struct TransitionWithAction { impl DocumentTransitionObjectLike for DocumentTransition { fn from_json_object( - json_value: Value, + json_value: JsonValue, data_contract: DataContract, ) -> Result where @@ -124,28 +127,46 @@ impl DocumentTransitionObjectLike for DocumentTransition { where Self: Sized, { - let action: Action = TryFrom::try_from(raw_transition.get_u64(PROPERTY_ACTION)? as u8) - .context("invalid document transition action")?; - Ok(match action { - Action::Create => DocumentTransition::Create( - DocumentCreateTransition::from_raw_object(raw_transition, data_contract)?, - ), - Action::Replace => DocumentTransition::Replace( - DocumentReplaceTransition::from_raw_object(raw_transition, data_contract)?, - ), - Action::Delete => DocumentTransition::Delete( - DocumentDeleteTransition::from_raw_object(raw_transition, data_contract)?, - ), - }) + let map = raw_transition + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + Self::from_value_map(map, data_contract) } - fn to_json(&self) -> Result { + fn to_json(&self) -> Result { call_method!(self, to_json) } + fn to_value_map(&self) -> Result, ProtocolError> { + call_method!(self, to_value_map) + } + fn to_object(&self) -> Result { call_method!(self, to_object) } + + fn from_value_map( + map: BTreeMap, + data_contract: DataContract, + ) -> Result + where + Self: Sized, + { + let action: Action = map.get_integer::(PROPERTY_ACTION)?.try_into()?; + Ok(match action { + Action::Create => DocumentTransition::Create(DocumentCreateTransition::from_value_map( + map, + data_contract, + )?), + Action::Replace => DocumentTransition::Replace( + DocumentReplaceTransition::from_value_map(map, data_contract)?, + ), + Action::Delete => DocumentTransition::Delete(DocumentDeleteTransition::from_value_map( + map, + data_contract, + )?), + }) + } } impl DocumentTransition { @@ -242,14 +263,14 @@ impl DocumentTransitionExt for DocumentTransition { match self { DocumentTransition::Create(t) => { if let Some(ref data) = t.data { - data.get_value(path).ok() + data.get(path) } else { None } } DocumentTransition::Replace(t) => { if let Some(ref data) = t.data { - data.get_value(path).ok() + data.get(path) } else { None } @@ -258,7 +279,7 @@ impl DocumentTransitionExt for DocumentTransition { } } - fn get_data(&self) -> Option<&Value> { + fn get_data(&self) -> Option<&BTreeMap> { match self { DocumentTransition::Create(t) => t.data.as_ref(), DocumentTransition::Replace(t) => t.data.as_ref(), @@ -305,17 +326,3 @@ impl DocumentTransitionExt for DocumentTransition { } } } - -/// Assumes both values are maps and merges them together. In case of overlap, b is used. -fn merge_serde_json_values(a: &mut Value, b: Value) -> Result<(), anyhow::Error> { - if let Value::Object(ref mut map_a) = a { - if let Value::Object(map_b) = b { - map_a.extend(map_b); - } else { - bail!("{} isn't a map", b) - } - } else { - bail!("{} isn't a map", a) - } - Ok(()) -} diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index be611ddacc1..44f626dbc13 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -4,6 +4,8 @@ use std::convert::TryInto; use anyhow::{anyhow, Context}; use ciborium::value::Value as CborValue; use integer_encoding::VarInt; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -145,33 +147,43 @@ impl DocumentsBatchTransition { /// creates the instance of [`DocumentsBatchTransition`] from raw object pub fn from_raw_object( - mut raw_object: JsonValue, + raw_object: Value, data_contracts: Vec, ) -> Result { + let mut map = raw_object + .into_btree_map() + .map_err(ProtocolError::ValueError)?; let mut batch_transitions = DocumentsBatchTransition { - protocol_version: raw_object - .get_u64(property_names::PROTOCOL_VERSION) + protocol_version: map + .get_integer(property_names::PROTOCOL_VERSION) // js-dpp allows `protocolVersion` to be undefined .unwrap_or(LATEST_VERSION as u64) as u32, - signature: raw_object.get_bytes(property_names::SIGNATURE).ok(), - signature_public_key_id: raw_object - .get_u64(property_names::SIGNATURE_PUBLIC_KEY_ID) - .ok() - .map(|v| v as KeyID), - owner_id: Identifier::from_bytes(&raw_object.get_bytes(property_names::OWNER_ID)?)?, + signature: map + .get_optional_bytes(property_names::SIGNATURE) + .map_err(ProtocolError::ValueError)?, + signature_public_key_id: map + .get_optional_integer(property_names::SIGNATURE_PUBLIC_KEY_ID) + .map_err(ProtocolError::ValueError)?, + owner_id: Identifier::from( + map.get_hash256_bytes(property_names::OWNER_ID) + .map_err(ProtocolError::ValueError)?, + ), ..Default::default() }; let mut document_transitions: Vec = vec![]; - let maybe_transitions = raw_object.remove(property_names::TRANSITIONS); - if let Ok(JsonValue::Array(raw_transitions)) = maybe_transitions { + let maybe_transitions = map.remove(property_names::TRANSITIONS); + if let Some(Value::Array(raw_transitions)) = maybe_transitions { let data_contracts_map: HashMap, DataContract> = data_contracts .into_iter() .map(|dc| (dc.id.as_bytes().to_vec(), dc)) .collect(); for raw_transition in raw_transitions { - let id = raw_transition.get_bytes(property_names::DATA_CONTRACT_ID)?; + let mut raw_transition_map = raw_object + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + let id = raw_transition_map.get_bytes(property_names::DATA_CONTRACT_ID)?; let data_contract = data_contracts_map.get(&id).ok_or_else(|| { anyhow!( "Data Contract doesn't exists for Transition: {:?}", @@ -179,7 +191,7 @@ impl DocumentsBatchTransition { ) })?; let document_transition = - DocumentTransition::from_raw_object(raw_transition, data_contract.clone())?; + DocumentTransition::from_value_map(raw_transition_map, data_contract.clone())?; document_transitions.push(document_transition); } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index 692b0f4d7ac..8558494a58b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -1,3 +1,4 @@ +use platform_value::btreemap_extensions::BTreeValueMapHelper; use serde_json::Value; use std::collections::{hash_map::Entry, HashMap}; @@ -98,16 +99,18 @@ fn get_data_property(document_transition: &DocumentTransition, property_name: &s DocumentTransition::Create(dt_create) => match &dt_create.data { None => String::from(""), Some(data) => data - .get(property_name) - .unwrap_or(&Value::String(String::from(""))) - .to_string(), + .get_optional_string(property_name) + .ok() + .flatten() + .unwrap_or(String::from("")), }, DocumentTransition::Replace(dt_replace) => match &dt_replace.data { None => String::from(""), Some(data) => data - .get(property_name) - .unwrap_or(&Value::String(String::from(""))) - .to_string(), + .get_optional_string(property_name) + .ok() + .flatten() + .unwrap_or(String::from("")), }, } } diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 7e5c378229b..124cdb0ee54 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -75,7 +75,7 @@ pub trait BTreeValueMapHelper { key: &str, ) -> Result; fn get_optional_system_hash256_bytes(&self, key: &str) -> Result, Error>; - fn get_system_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error>; + fn get_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error>; fn get_optional_system_bytes(&self, key: &str) -> Result>, Error>; fn get_system_bytes(&self, key: &str) -> Result, Error>; fn remove_optional_string(&mut self, key: &str) -> Result, Error>; @@ -106,16 +106,12 @@ pub trait BTreeValueMapHelper { + TryFrom + TryFrom + TryFrom; - fn remove_optional_system_hash256_bytes( - &mut self, - key: &str, - ) -> Result, Error>; - fn remove_system_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error>; - fn remove_optional_system_bytes(&mut self, key: &str) -> Result>, Error>; - fn remove_system_bytes(&mut self, key: &str) -> Result, Error>; + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error>; + fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error>; + fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error>; + fn remove_bytes(&mut self, key: &str) -> Result, Error>; fn get_optional_bytes(&self, key: &str) -> Result>, Error>; fn get_bytes(&self, key: &str) -> Result, Error>; - fn to_json_value(&self) -> Result; fn remove_optional_bool(&mut self, key: &str) -> Result, Error>; fn remove_bool(&mut self, key: &str) -> Result; } @@ -125,9 +121,7 @@ where V: Borrow, { fn get_optional_identifier(&self, key: &str) -> Result, Error> { - self.get(key) - .map(|v| v.borrow().to_system_hash256()) - .transpose() + self.get(key).map(|v| v.borrow().to_hash256()).transpose() } fn get_identifier(&self, key: &str) -> Result<[u8; 32], Error> { @@ -399,12 +393,10 @@ where } fn get_optional_system_hash256_bytes(&self, key: &str) -> Result, Error> { - self.get(key) - .map(|v| v.borrow().to_system_hash256()) - .transpose() + self.get(key).map(|v| v.borrow().to_hash256()).transpose() } - fn get_system_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error> { + fn get_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error> { self.get_optional_system_hash256_bytes(key)?.ok_or_else(|| { Error::StructureError(format!("unable to get system hash256 property {key}")) }) @@ -432,30 +424,26 @@ where }) } - fn remove_optional_system_hash256_bytes( - &mut self, - key: &str, - ) -> Result, Error> { + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { self.remove(key) - .map(|v| v.borrow().to_system_hash256()) + .map(|v| v.borrow().to_hash256()) .transpose() } - fn remove_system_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error> { - self.remove_optional_system_hash256_bytes(key)? - .ok_or_else(|| { - Error::StructureError(format!("unable to remove system hash256 property {key}")) - }) + fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error> { + self.remove_optional_hash256_bytes(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove system hash256 property {key}")) + }) } - fn remove_optional_system_bytes(&mut self, key: &str) -> Result>, Error> { + fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { self.remove(key) .map(|v| v.borrow().to_system_bytes()) .transpose() } - fn remove_system_bytes(&mut self, key: &str) -> Result, Error> { - self.remove_optional_system_bytes(key)?.ok_or_else(|| { + fn remove_bytes(&mut self, key: &str) -> Result, Error> { + self.remove_optional_bytes(key)?.ok_or_else(|| { Error::StructureError(format!("unable to remove system bytes property {key}")) }) } @@ -522,12 +510,4 @@ where self.get_optional_float(key)? .ok_or_else(|| Error::StructureError(format!("unable to get float property {key}"))) } - - fn to_json_value(&self) -> Result { - Ok(JsonValue::Object( - self.iter() - .map(|(key, value)| Ok((key.to_string(), value.borrow().clone().try_into()?))) - .collect::, Error>>()?, - )) - } } diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index 57b22567312..8af39b5ff61 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -4,23 +4,29 @@ use std::collections::{BTreeMap, HashMap}; #[derive(Debug, Clone, Copy)] pub enum ReplacementType { + Identifier, Bytes, TextBase58, TextBase64, } impl ReplacementType { - pub fn replace_for_bytes(&self, bytes: Vec) -> Value { + pub fn replace_for_bytes(&self, bytes: Vec) -> Result { match self { - ReplacementType::Bytes => Value::Bytes(bytes), - ReplacementType::TextBase58 => Value::Text(bs58::encode(bytes).into_string()), - ReplacementType::TextBase64 => Value::Text(base64::encode(bytes)), + ReplacementType::Identifier => Ok(Value::Identifier( + bytes + .try_into() + .map_err(|_| Error::ByteLengthNot32BytesError)?, + )), + ReplacementType::Bytes => Ok(Value::Bytes(bytes)), + ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), + ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), } } pub fn replace_consume_value(&self, value: Value) -> Result { let bytes = value.into_system_bytes()?; - Ok(self.replace_for_bytes(bytes)) + self.replace_for_bytes(bytes) } } @@ -59,7 +65,7 @@ impl BTreeValueMapInsertionPathHelper for BTreeMap { current_value = new_value; if split.peek().is_none() { let bytes = current_value.to_system_bytes()?; - new_value = &mut replacement_type.replace_for_bytes(bytes); + new_value = &mut replacement_type.replace_for_bytes(bytes)?; return Ok(true); } } diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_path_extensions.rs index fc65e47a990..eb0820841bf 100644 --- a/packages/rs-platform-value/src/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_extensions.rs @@ -178,7 +178,7 @@ where fn get_optional_identifier_at_path(&self, path: &str) -> Result, Error> { self.get_optional_at_path(path)? - .map(|v| v.borrow().to_system_hash256()) + .map(|v| v.borrow().to_hash256()) .transpose() } @@ -466,7 +466,7 @@ where path: &str, ) -> Result, Error> { self.get_optional_at_path(path)? - .map(|v| v.borrow().to_system_hash256()) + .map(|v| v.borrow().to_hash256()) .transpose() } @@ -507,7 +507,7 @@ where path: &str, ) -> Result, Error> { self.remove(path) - .map(|v| v.borrow().to_system_hash256()) + .map(|v| v.borrow().to_hash256()) .transpose() } diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 1a629211ba8..054f4d690f7 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -79,12 +79,7 @@ impl TryInto for Value { Value::I16(i) => JsonValue::Number(i.into()), Value::U8(i) => JsonValue::Number(i.into()), Value::I8(i) => JsonValue::Number(i.into()), - Value::Bytes(bytes) => JsonValue::Array( - bytes - .into_iter() - .map(|byte| JsonValue::Number(byte.into())) - .collect(), - ), + Value::Bytes(bytes) => JsonValue::String(base64::encode(bytes.as_slice())), Value::Float(float) => JsonValue::Number(Number::from_f64(float).unwrap_or(0.into())), Value::Text(string) => JsonValue::String(string), Value::Bool(value) => JsonValue::Bool(value), @@ -116,6 +111,7 @@ impl TryInto for Value { pub trait BTreeValueJsonConverter { fn into_json_value(self) -> Result; + fn to_json_value(&self) -> Result; fn from_json_value(value: JsonValue) -> Result where Self: Sized; @@ -130,8 +126,30 @@ impl BTreeValueJsonConverter for BTreeMap { )) } + fn to_json_value(&self) -> Result { + Ok(JsonValue::Object( + self.into_iter() + .map(|(key, value)| Ok((key.clone(), value.clone().try_into()?))) + .collect::, Error>>()?, + )) + } + fn from_json_value(value: JsonValue) -> Result { let platform_value: Value = value.into(); platform_value.into_btree_map() } } + +pub trait BTreeValueRefJsonConverter { + fn to_json_value(self) -> Result; +} + +impl BTreeValueRefJsonConverter for BTreeMap { + fn to_json_value(self) -> Result { + Ok(JsonValue::Object( + self.into_iter() + .map(|(key, value)| Ok((key, value.clone().try_into()?))) + .collect::, Error>>()?, + )) + } +} diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index fafc6f6b22e..7ef71fa9bf6 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -13,4 +13,7 @@ pub enum Error { #[error("integer out of bounds")] IntegerSizeError, + + #[error("byte length not 32 bytes error")] + ByteLengthNot32BytesError, } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 405d43050d6..3b20c1c42ce 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -21,7 +21,7 @@ use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; pub use integer::Integer; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; pub type Hash256 = [u8; 32]; pub use btreemap_field_replacement::ReplacementType; @@ -976,7 +976,7 @@ impl Value { current_value = new_value; if split.peek().is_none() { let bytes = current_value.to_system_bytes()?; - new_value = &mut replacement_type.replace_for_bytes(bytes); + new_value = &mut replacement_type.replace_for_bytes(bytes)?; return Ok(true); } } @@ -1043,6 +1043,17 @@ implfrom! { Map(Vec<(Value, Value)>), } +impl From> for Value { + fn from(value: BTreeMap) -> Self { + Value::Map( + value + .into_iter() + .map(|(key, value)| (Value::Text(key), value)) + .collect(), + ) + } +} + impl From for Value { #[inline] fn from(value: char) -> Self { diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index 140b39b4c60..b8fa4ef679f 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -157,27 +157,27 @@ impl Value { /// # use platform_value::{Error, Value}; /// # /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]); - /// assert_eq!(value.to_system_hash256(), Ok([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50])); /// + /// assert_eq!(value.to_hash256(), Ok([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50])); /// /// /// let value = Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string()); - /// assert_eq!(value.to_system_hash256(), Ok([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117])); + /// assert_eq!(value.to_hash256(), Ok([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117])); /// /// let value = Value::Text("a811".to_string()); - /// assert_eq!(value.to_system_hash256(), Err(Error::StructureError("value was a string, could be decoded from base 58, but was not 32 bytes long".to_string()))); + /// assert_eq!(value.to_hash256(), Err(Error::StructureError("value was a string, could be decoded from base 58, but was not 32 bytes long".to_string()))); /// /// let value = Value::Text("a811Ii".to_string()); - /// assert_eq!(value.to_system_hash256(), Err(Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))); + /// assert_eq!(value.to_hash256(), Err(Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))); /// /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); - /// assert_eq!(value.to_system_hash256(), Ok([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101])); + /// assert_eq!(value.to_hash256(), Ok([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101])); /// /// let value = Value::Identifier([5u8;32]); - /// assert_eq!(value.to_system_hash256(), Ok([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// assert_eq!(value.to_hash256(), Ok([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.to_system_hash256(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// assert_eq!(value.to_hash256(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); /// ``` - pub fn to_system_hash256(&self) -> Result<[u8; 32], Error> { + pub fn to_hash256(&self) -> Result<[u8; 32], Error> { match self { Value::Text(text) => { bs58::decode(text).into_vec() diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index d59612292bf..c53c8c357e1 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -1,6 +1,10 @@ use std::convert; +use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::identity::TimestampMillis; +use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; +use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; use dpp::prelude::Revision; use dpp::{ document::document_transition::{ @@ -8,6 +12,7 @@ use dpp::{ }, prelude::{DataContract, Identifier}, util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, + ProtocolError, }; use serde::Serialize; use wasm_bindgen::prelude::*; @@ -122,22 +127,27 @@ impl DocumentCreateTransitionWasm { return Ok(JsValue::undefined()); }; - let mut value = if let Ok(value) = document_data.get_value(&path) { - value.to_owned() + let mut value = if let Ok(value) = document_data.get_at_path(&path) { + value.clone() } else { return Ok(JsValue::undefined()); }; match self.get_binary_type_of_path(&path) { BinaryType::Buffer => { - let bytes: Vec = serde_json::from_value(value).unwrap(); - let buffer = Buffer::from_bytes(&bytes); + let buffer = value + .to_bytes() + .map_err(ProtocolError::ValueError) + .with_js_error()?; return Ok(buffer.into()); } BinaryType::Identifier => { - let bytes: Vec = serde_json::from_value(value).unwrap(); + let buffer = value + .to_hash256() + .map_err(ProtocolError::ValueError) + .with_js_error()?; let id = >::from( - Identifier::from_bytes(&bytes).with_js_error()?, + Identifier::from(buffer).with_js_error()?, ); return Ok(id.into()); } @@ -146,8 +156,8 @@ impl DocumentCreateTransitionWasm { // or may not captain it at all } } - - let js_value = value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; + let json_value: JsonValue = value.into(); + let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; let (identifier_paths, binary_paths) = self .inner .base @@ -182,7 +192,6 @@ impl DocumentCreateTransitionWasm { } } } - Ok(js_value) } @@ -219,37 +228,15 @@ impl DocumentCreateTransitionWasm { // AbstractDataDocumentTransition #[wasm_bindgen(js_name=getData)] pub fn get_data(&self) -> Result { - let data = if let Some(ref data) = self.inner.data { - data + let json_data = if let Some(ref data) = self.inner.data { + data.to_json_value() + .map_err(ProtocolError::ValueError) + .with_js_error()? } else { return Ok(JsValue::undefined()); }; - let js_value = data.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; - let (identifier_paths, binary_paths) = self - .inner - .base - .data_contract - .get_identifiers_and_binary_paths(&self.inner.base.document_type) - .with_js_error()?; - - for path in identifier_paths { - if let Ok(value) = data.get_value(path) { - let bytes: Vec = serde_json::from_value(value.to_owned()).with_js_error()?; - let id = >::from( - Identifier::from_bytes(&bytes).unwrap(), - ); - lodash_set(&js_value, path, id.into()); - } - } - for path in binary_paths { - if let Ok(value) = data.get_value(path) { - let bytes: Vec = serde_json::from_value(value.to_owned()).with_js_error()?; - let buffer = Buffer::from_bytes(&bytes); - lodash_set(&js_value, path, buffer.into()); - } - } - + let js_value = json_data.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; Ok(js_value) } } From 43fe274b373ce977a073c719e33f094e32fc33eb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 02:52:55 +0700 Subject: [PATCH 042/228] more work --- packages/rs-dpp/src/document/document.rs | 96 +++++---------- .../rs-dpp/src/document/document_factory.rs | 116 ++++++++++-------- .../rs-dpp/src/document/extended_document.rs | 21 ++++ ...pply_documents_batch_transition_factory.rs | 24 ++-- .../documents_batch_transition/mod.rs | 14 ++- .../state_transition_factory.rs | 7 +- 6 files changed, 145 insertions(+), 133 deletions(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 2533c218467..8fb86932a91 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -311,87 +311,47 @@ impl Document { Ok(value) } - pub fn to_cbor_value(&self) -> Result { - let mut value = CborValue::Map(vec![]); - let value_mut = value.as_map_mut().unwrap(); - value_mut.push(( - CborValue::Text(property_names::ID.to_string()), - CborValue::Bytes(self.id.to_vec()), - )); - value_mut.push(( - CborValue::Text(property_names::OWNER_ID.to_string()), - CborValue::Bytes(self.owner_id.to_vec()), - )); - if let Some(created_at) = self.created_at { - value_mut.push(( - CborValue::Text(property_names::CREATED_AT.to_string()), - CborValue::Integer(created_at.into()), - )); - } - if let Some(updated_at) = self.updated_at { - value_mut.push(( - CborValue::Text(property_names::UPDATED_AT.to_string()), - CborValue::Integer(updated_at.into()), - )); - } - if let Some(revision) = self.revision { - value_mut.push(( - CborValue::Text(property_names::REVISION.to_string()), - CborValue::Integer(revision.into()), - )); - } - - self.properties - .iter() - .try_for_each(|(key, property_value)| { - let cbor_value: CborValue = property_value - .clone() - .try_into() - .map_err(ProtocolError::ValueError)?; - value_mut.push((CborValue::Text(key.clone()), cbor_value)); - Ok::<(), ProtocolError>(()) - })?; - - Ok(value) - } + pub fn to_map_value(&self) -> Result, ProtocolError> { + let mut map: BTreeMap = BTreeMap::new(); + map.insert(property_names::ID.to_string(), Value::Identifier(self.id)); + map.insert( + property_names::OWNER_ID.to_string(), + Value::Identifier(self.owner_id), + ); - pub fn to_json(&self) -> Result { - let mut value = json!({ - property_names::ID: bs58::encode(self.id).into_string(), - property_names::OWNER_ID: bs58::encode(self.owner_id).into_string(), - }); - let value_mut = value.as_object_mut().unwrap(); if let Some(created_at) = self.created_at { - value_mut.insert( + map.insert( property_names::CREATED_AT.to_string(), - JsonValue::Number(created_at.into()), + Value::U64(created_at), ); } if let Some(updated_at) = self.updated_at { - value_mut.insert( + map.insert( property_names::UPDATED_AT.to_string(), - JsonValue::Number(updated_at.into()), + Value::U64(updated_at), ); } if let Some(revision) = self.revision { - value_mut.insert( - property_names::REVISION.to_string(), - JsonValue::Number(revision.into()), - ); + map.insert(property_names::REVISION.to_string(), Value::U64(revision)); } - self.properties - .iter() - .try_for_each(|(key, property_value)| { - let serde_value: JsonValue = property_value - .clone() - .try_into() - .map_err(ProtocolError::ValueError)?; - value_mut.insert(key.to_string(), serde_value); - Ok::<(), ProtocolError>(()) - })?; + map.extend(self.properties.clone()); - Ok(value) + Ok(map) + } + + pub fn to_value(&self) -> Result { + Ok(self.to_map_value()?.into()) + } + + pub fn to_cbor_value(&self) -> Result { + self.to_value() + .map(|v| v.try_into().map_err(ProtocolError::ValueError))? + } + + pub fn to_json(&self) -> Result { + self.to_value() + .map(|v| v.try_into().map_err(ProtocolError::ValueError))? } pub fn replace_all_fields( diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 7fc7d165492..90b0dc59395 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -1,5 +1,6 @@ use anyhow::Context; use chrono::Utc; +use std::collections::BTreeMap; use itertools::Itertools; @@ -192,7 +193,7 @@ where &self, documents_iter: impl IntoIterator)>, ) -> Result { - let mut raw_documents_transitions: Vec = vec![]; + let mut raw_documents_transitions: Vec = vec![]; let mut data_contracts: Vec = vec![]; let documents: Vec<(Action, Vec)> = documents_iter.into_iter().collect(); let flattened_documents_iter = documents.iter().flat_map(|(_, v)| v); @@ -235,13 +236,22 @@ where return Err(DocumentError::NoDocumentsSuppliedError.into()); } - let raw_batch_transition = json!({ - PROPERTY_PROTOCOL_VERSION: self.protocol_version, - PROPERTY_OWNER_ID : owner_id.to_buffer(), - PROPERTY_TRANSITIONS: raw_documents_transitions, - }); - - DocumentsBatchTransition::from_raw_object(raw_batch_transition, data_contracts) + let raw_batch_transition = BTreeMap::from([ + ( + PROPERTY_PROTOCOL_VERSION.to_string(), + Value::U32(self.protocol_version), + ), + ( + PROPERTY_OWNER_ID.to_string(), + Value::Identifier(owner_id.buffer), + ), + ( + PROPERTY_TRANSITIONS.to_string(), + Value::Array(raw_documents_transitions), + ), + ]); + + DocumentsBatchTransition::from_value_map(raw_batch_transition, data_contracts) } pub async fn create_from_buffer( @@ -321,7 +331,7 @@ where fn raw_document_create_transitions( documents: Vec, - ) -> Result, ProtocolError> { + ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { if document.needs_revision() { @@ -337,22 +347,17 @@ where .into()); } } - let mut raw_document = document.to_object()?; - - if let Some(map) = raw_document.as_object_mut() { - map.retain(|key, _| { - !key.starts_with('$') || DOCUMENT_CREATE_KEYS_TO_STAY.contains(&key.as_str()) - }); - map.insert( - PROPERTY_ACTION.to_string(), - serde_json::to_value(Action::Create)?, - ); - map.insert( - PROPERTY_ENTROPY.to_string(), - serde_json::to_value(document.entropy)?, - ); - } - raw_transitions.push(raw_document); + let mut map = document.to_map_value()?; + + map.retain(|key, _| { + !key.starts_with('$') || DOCUMENT_CREATE_KEYS_TO_STAY.contains(&key.as_str()) + }); + map.insert(PROPERTY_ACTION.to_string(), Value::U8(Action::Create as u8)); + map.insert( + PROPERTY_ENTROPY.to_string(), + Value::Bytes(document.entropy.to_vec()), + ); + raw_transitions.push(map.into()); } Ok(raw_transitions) @@ -360,7 +365,7 @@ where fn raw_document_replace_transitions( documents: Vec, - ) -> Result, ProtocolError> { + ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { if !document.can_be_modified() { @@ -374,42 +379,55 @@ where document: Box::new(document), }.into()); }; - let mut raw_document = document.to_object()?; - - if let Some(map) = raw_document.as_object_mut() { - map.retain(|key, _| { - !key.starts_with('$') || DOCUMENT_REPLACE_KEYS_TO_STAY.contains(&key.as_str()) - }); + let mut map = document.to_map_value()?; + + map.retain(|key, _| { + !key.starts_with('$') || DOCUMENT_REPLACE_KEYS_TO_STAY.contains(&key.as_str()) + }); + map.insert( + PROPERTY_ACTION.to_string(), + Value::U8(Action::Replace as u8), + ); + let new_revision = document_revision + 1; + map.insert(PROPERTY_REVISION.to_string(), Value::U64(new_revision)); + + // If document have an originally set `updatedAt` + // we should update it then + if let Some(updated_at) = map.get_mut(PROPERTY_UPDATED_AT) { + *updated_at = Value::U64(Utc::now().timestamp_millis() as TimestampMillis); + } else { map.insert( - PROPERTY_ACTION.to_string(), - serde_json::to_value(Action::Replace)?, + PROPERTY_UPDATED_AT.to_string(), + Value::U64(Utc::now().timestamp_millis() as TimestampMillis), ); - let new_revision = document_revision + 1; - map.insert(PROPERTY_REVISION.to_string(), json!(new_revision)); - - // If document have an originally set `updatedAt` - // we should update it then - if let Some(update_at) = map.get_mut(PROPERTY_UPDATED_AT) { - *update_at = json!(Utc::now().timestamp_millis()) - } } - raw_transitions.push(raw_document); + raw_transitions.push(map.into()); } Ok(raw_transitions) } fn raw_document_delete_transitions( documents: Vec, - ) -> Result, ProtocolError> { + ) -> Result, ProtocolError> { Ok(documents .into_iter() .map(|document| { - json!({ - PROPERTY_ACTION: Action::Delete, - PROPERTY_ID: document.id().buffer, - PROPERTY_TYPE: document.document_type_name, - PROPERTY_DATA_CONTRACT_ID: document.data_contract_id.buffer}) + let mut map: BTreeMap = BTreeMap::new(); + map.insert(PROPERTY_ACTION.to_string(), Value::U8(Action::Delete as u8)); + map.insert( + PROPERTY_ID.to_string(), + Value::Identifier(document.document.id), + ); + map.insert( + PROPERTY_TYPE.to_string(), + Value::Text(document.document_type_name), + ); + map.insert( + PROPERTY_DATA_CONTRACT_ID.to_string(), + Value::Identifier(document.data_contract_id.buffer), + ); + map.into() }) .collect()) } diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index f77c15949dc..ff708ed9bb2 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -241,6 +241,27 @@ impl ExtendedDocument { }) } + pub fn to_map_value(&self) -> Result, ProtocolError> { + let mut object = self.document.to_map_value()?; + object.insert( + property_names::PROTOCOL_VERSION.to_string(), + Value::U32(self.protocol_version), + ); + object.insert( + property_names::DOCUMENT_TYPE.to_string(), + Value::Text(self.document_type_name.clone()), + ); + object.insert( + property_names::DATA_CONTRACT_ID.to_string(), + Value::Identifier(self.data_contract_id.to_buffer()), + ); + Ok(object) + } + + pub fn to_value(&self) -> Result { + Ok(self.to_map_value()?.into()) + } + // The skipIdentifierConversion option is removed as it doesn't make sense in the case of // of Rust. Rust doesn't distinguish between `Buffer` and `Identifier` pub fn to_object(&self) -> Result { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 23884aee8dc..f7a426958db 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -141,6 +141,7 @@ fn document_from_transition_replace( mod test { use platform_value::Value; use serde_json::{json, Value as JsonValue}; + use std::collections::BTreeMap; use std::convert::TryInto; use crate::tests::fixtures::get_extended_documents_fixture; @@ -171,19 +172,20 @@ mod test { (Action::Replace, documents), (Action::Create, vec![]), ]); - let raw_document_transitions: Vec = documents_transitions + let raw_document_transitions: Vec = documents_transitions .iter() - .map(|dt| dt.to_object().unwrap().try_into().unwrap()) - .collect(); + .map(|dt| dt.to_value_map().unwrap().into()) + .collect::>(); let owner_id_bytes = owner_id.to_buffer(); - let state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id_bytes, - "transitions" : raw_document_transitions, - }), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert("ownerId".to_string(), Value::Identifier(owner_id_bytes)); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); state_transition.get_execution_context().enable_dry_run(); state_repository diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 44f626dbc13..970ae481144 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{BTreeMap, HashMap}; use std::convert::TryInto; use anyhow::{anyhow, Context}; @@ -150,9 +150,17 @@ impl DocumentsBatchTransition { raw_object: Value, data_contracts: Vec, ) -> Result { - let mut map = raw_object + let map = raw_object .into_btree_map() .map_err(ProtocolError::ValueError)?; + Self::from_value_map(map, data_contracts) + } + + /// creates the instance of [`DocumentsBatchTransition`] from a value map + pub fn from_value_map( + mut map: BTreeMap, + data_contracts: Vec, + ) -> Result { let mut batch_transitions = DocumentsBatchTransition { protocol_version: map .get_integer(property_names::PROTOCOL_VERSION) @@ -180,7 +188,7 @@ impl DocumentsBatchTransition { .collect(); for raw_transition in raw_transitions { - let mut raw_transition_map = raw_object + let mut raw_transition_map = raw_transition .into_btree_map() .map_err(ProtocolError::ValueError)?; let id = raw_transition_map.get_bytes(property_names::DATA_CONTRACT_ID)?; diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 236b420d4e8..3462ca1ad50 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -25,6 +25,7 @@ use super::{ StateTransitionType, }; +//todo: change from JsonValue to Platform Value pub async fn create_state_transition( state_repository: &impl StateRepositoryLike, raw_state_transition: JsonValue, @@ -67,8 +68,10 @@ pub async fn create_state_transition( &execution_context, ) .await?; - let documents_batch_transition = - DocumentsBatchTransition::from_raw_object(raw_state_transition, data_contracts)?; + let documents_batch_transition = DocumentsBatchTransition::from_raw_object( + raw_state_transition.into(), + data_contracts, + )?; Ok(StateTransition::DocumentsBatch(documents_batch_transition)) } // TODO!! add basic validation From f954d6ae9959c94df71a39f3a5fbcedd5d230489 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 03:04:44 +0700 Subject: [PATCH 043/228] more work --- .../documents_batch_transition/mod.rs | 20 +- ...e_documents_batch_transition_state_spec.rs | 221 +++++++++++------- .../validate_partial_compound_indices_spec.rs | 6 +- 3 files changed, 158 insertions(+), 89 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 970ae481144..7f2eef36e1a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -558,14 +558,18 @@ mod test { t.base.id = transition_id; } - let state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id.as_bytes(), - "transitions" : [transition.to_object().unwrap()], - }), - vec![data_contract], - ) - .expect("transition should be created"); + let mut map = BTreeMap::new(); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); + map.insert( + "transitions".to_string(), + Value::Array(vec![transition.to_object().unwrap()]), + ); + + let state_transition = DocumentsBatchTransition::from_value_map(map, vec![data_contract]) + .expect("transition should be created"); let bytes = state_transition.to_buffer(false).unwrap(); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 37815b06e1a..0f46cbf8565 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -1,6 +1,8 @@ +use std::collections::BTreeMap; use std::time::Duration; use chrono::Utc; +use platform_value::Value; use serde_json::{json, Value as JsonValue}; use crate::{ @@ -50,19 +52,20 @@ fn setup_test() -> TestData { let document_transitions = get_document_transitions_fixture([(Action::Create, documents.clone())]); - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .iter() .map(|dt| dt.to_object().unwrap()) .collect(); let owner_id_bytes = owner_id.to_buffer(); - let state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id_bytes, - "transitions" : raw_document_transitions, - }), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert("ownerId".to_string(), Value::Identifier(owner_id_bytes)); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); let mut state_repository_mock = MockStateRepositoryLike::default(); let data_contract_to_return = data_contract.clone(); @@ -159,18 +162,20 @@ async fn should_return_invalid_result_if_document_transition_with_action_delete_ let transition_id = document_transitions[0].base().id; let owner_id_bytes = owner_id.to_buffer(); - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .into_iter() .map(|dt| dt.to_object().unwrap()) .collect(); - let state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id_bytes, - "transitions": raw_document_transitions}), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert("ownerId".to_string(), Value::Identifier(owner_id_bytes)); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); state_repository_mock .expect_fetch_documents() @@ -221,19 +226,27 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace ]); let transition_id = document_transitions[0].base().id; - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .into_iter() .map(|dt| dt.to_object().unwrap()) .collect(); - let state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id.to_buffer(), - "contractId" : data_contract.id.to_buffer(), - "transitions": raw_document_transitions}), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); + map.insert( + "contractId".to_string(), + Value::Identifier(data_contract.id.to_buffer()), + ); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); state_repository_mock .expect_fetch_documents() @@ -283,19 +296,27 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace ]); let transition_id = document_transitions[0].base().id; - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .into_iter() .map(|dt| dt.to_object().unwrap()) .collect(); - let state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id.to_buffer(), - "contractId" : data_contract.id.to_buffer(), - "transitions": raw_document_transitions}), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); + map.insert( + "contractId".to_string(), + Value::Identifier(data_contract.id.to_buffer()), + ); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); state_repository_mock .expect_fetch_documents() @@ -344,18 +365,26 @@ async fn should_return_invalid_result_if_timestamps_mismatch() { let document_transitions = get_document_transitions_fixture([(Action::Create, vec![documents[0].clone()])]); let transition_id = document_transitions[0].base().id; - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .into_iter() .map(|dt| dt.to_object().unwrap()) .collect(); - let mut state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id.to_buffer(), - "contractId" : data_contract.id.to_buffer(), - "transitions": raw_document_transitions}), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); + map.insert( + "contractId".to_string(), + Value::Identifier(data_contract.id.to_buffer()), + ); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let mut state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); let now_ts = Utc::now().timestamp_millis() as u64; state_transition @@ -395,18 +424,26 @@ async fn should_return_invalid_result_if_crated_at_has_violated_time_window() { let document_transitions = get_document_transitions_fixture([(Action::Create, vec![documents[0].clone()])]); let transition_id = document_transitions[0].base().id; - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .into_iter() .map(|dt| dt.to_object().unwrap()) .collect(); - let mut state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id.to_buffer(), - "contractId" : data_contract.id.to_buffer(), - "transitions": raw_document_transitions}), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); + map.insert( + "contractId".to_string(), + Value::Identifier(data_contract.id.to_buffer()), + ); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let mut state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); let now_ts_minus_6_mins = Utc::now().timestamp_millis() as u64 - Duration::from_secs(60 * 6).as_millis() as u64; @@ -447,18 +484,26 @@ async fn should_not_validate_time_in_block_window_on_dry_run() { let document_transitions = get_document_transitions_fixture([(Action::Create, vec![documents[0].clone()])]); - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .into_iter() .map(|dt| dt.to_object().unwrap()) .collect(); - let mut state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id.to_buffer(), - "contractId" : data_contract.id.to_buffer(), - "transitions": raw_document_transitions}), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); + map.insert( + "contractId".to_string(), + Value::Identifier(data_contract.id.to_buffer()), + ); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let mut state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); state_transition.get_execution_context().enable_dry_run(); let now_ts_minus_6_mins = @@ -493,18 +538,26 @@ async fn should_return_invalid_result_if_updated_at_has_violated_time_window() { let document_transitions = get_document_transitions_fixture([(Action::Create, vec![documents[1].clone()])]); let transition_id = document_transitions[0].base().id; - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .into_iter() .map(|dt| dt.to_object().unwrap()) .collect(); - let mut state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id.to_buffer(), - "contractId" : data_contract.id.to_buffer(), - "transitions": raw_document_transitions}), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); + map.insert( + "contractId".to_string(), + Value::Identifier(data_contract.id.to_buffer()), + ); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let mut state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); let now_ts_minus_6_mins = Utc::now().timestamp_millis() as u64 - Duration::from_secs(60 * 6).as_millis() as u64; @@ -561,18 +614,26 @@ async fn should_return_valid_result_if_document_transitions_are_valid() { (Action::Replace, vec![documents[1].clone()]), (Action::Delete, vec![documents[2].clone()]), ]); - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .into_iter() .map(|dt| dt.to_object().unwrap()) .collect(); - let state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "ownerId" : owner_id.to_buffer(), - "contractId" : data_contract.id.to_buffer(), - "transitions": raw_document_transitions}), - vec![data_contract.clone()], - ) - .expect("documents batch state transition should be created"); + let mut map = BTreeMap::new(); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); + map.insert( + "contractId".to_string(), + Value::Identifier(data_contract.id.to_buffer()), + ); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions), + ); + let state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("documents batch state transition should be created"); let validation_result = validate_document_batch_transition_state(&state_repository_mock, &state_transition) diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index ca4cdb63fb2..66322c5df6d 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -1,4 +1,6 @@ +use platform_value::Value; use serde_json::Value as JsonValue; +use std::convert::TryInto; use crate::{ consensus::{basic::BasicError, ConsensusError}, @@ -45,7 +47,7 @@ fn should_return_invalid_result_if_compound_index_contains_not_all_fields() { .expect("lastName property should exist and be removed"); let documents_for_transition = vec![document]; - let raw_document_transitions: Vec = + let raw_document_transitions: Vec = get_document_transitions_fixture([(Action::Create, documents_for_transition)]) .into_iter() .map(|dt| { @@ -84,6 +86,8 @@ fn should_return_valid_result_if_compound_index_contains_nof_fields() { .map(|dt| { dt.to_object() .expect("the transition should be converted to object") + .try_into() + .expect("expected to get json values") }) .collect(); let result = validate_partial_compound_indices(raw_document_transitions.iter(), &data_contract) From 8b30f8514ead1c334a54270bd7ce85b2a0114c96 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 03:34:41 +0700 Subject: [PATCH 044/228] compiles again --- .../document_create_transition.rs | 5 +- .../documents_batch_transition/mod.rs | 52 ++++++++++++++++++- .../abstract_state_transition.rs | 4 ++ .../state_transition_factory.rs | 24 +++++---- ..._documents_batch_transitions_basic_spec.rs | 32 +++++++----- .../validate_partial_compound_indices_spec.rs | 6 ++- 6 files changed, 95 insertions(+), 28 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index abcf36386f5..5aaf868ee5b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -30,7 +30,6 @@ pub(self) mod property_names { /// The Binary fields in [`DocumentCreateTransition`] pub const BINARY_FIELDS: [&str; 1] = ["$entropy"]; -pub const BINARY_FIELDS_OWNED: [String; 1] = ["$entropy".to_string()]; /// The Identifier fields in [`DocumentCreateTransition`] pub use super::document_base_transition::IDENTIFIER_FIELDS; @@ -110,7 +109,9 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { data_contract.get_identifiers_and_binary_paths_owned(document_type)?; map.replace_at_paths( - binary_paths.into_iter().chain(BINARY_FIELDS_OWNED), + binary_paths + .into_iter() + .chain(BINARY_FIELDS.iter().map(|a| a.to_string())), ReplacementType::Bytes, )?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 7f2eef36e1a..1cad1d54b51 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -35,6 +35,7 @@ pub mod document_transition; pub mod validation; pub mod property_names { + pub const TRANSITION_TYPE: &str = "type"; pub const DATA_CONTRACT_ID: &str = "$dataContractId"; pub const TRANSITIONS: &str = "transitions"; pub const OWNER_ID: &str = "ownerId"; @@ -195,7 +196,7 @@ impl DocumentsBatchTransition { let data_contract = data_contracts_map.get(&id).ok_or_else(|| { anyhow!( "Data Contract doesn't exists for Transition: {:?}", - raw_transition + raw_transition_map ) })?; let document_transition = @@ -258,6 +259,53 @@ impl StateTransitionIdentitySigned for DocumentsBatchTransition { } } +impl DocumentsBatchTransition { + fn to_value(&self, skip_signature: bool) -> Result { + Ok(self.to_value_map(skip_signature)?.into()) + } + + fn to_value_map(&self, skip_signature: bool) -> Result, ProtocolError> { + let mut map = BTreeMap::new(); + map.insert( + property_names::PROTOCOL_VERSION.to_string(), + Value::U32(self.protocol_version), + ); + map.insert( + property_names::TRANSITION_TYPE.to_string(), + Value::U8(self.transition_type as u8), + ); + map.insert( + property_names::OWNER_ID.to_string(), + Value::Identifier(self.owner_id.buffer), + ); + + if !skip_signature { + if let Some(signature) = self.signature.as_ref() { + map.insert( + property_names::SIGNATURE.to_string(), + Value::Bytes(signature.clone()), + ); + } + if let Some(signature_key_id) = self.signature_public_key_id { + map.insert( + property_names::SIGNATURE.to_string(), + Value::U32(signature_key_id), + ); + } + } + let mut transitions = vec![]; + for transition in self.transitions.iter() { + transitions.push(transition.to_object()?) + } + map.insert( + property_names::TRANSITIONS.to_string(), + Value::Array(transitions), + ); + + Ok(map) + } +} + impl StateTransitionConvert for DocumentsBatchTransition { fn binary_property_paths() -> Vec<&'static str> { vec![property_names::SIGNATURE] @@ -308,7 +356,7 @@ impl StateTransitionConvert for DocumentsBatchTransition { } let mut transitions = vec![]; for transition in self.transitions.iter() { - transitions.push(transition.to_object()?) + transitions.push(transition.to_object()?.try_into().unwrap()) } json_object.insert( String::from(property_names::TRANSITIONS), diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index fe87d540745..ace711ecc9d 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -1,9 +1,13 @@ +use std::collections::BTreeMap; use std::fmt::Debug; +use std::vec; use dashcore::signer; +use platform_value::Value; use serde::Serialize; use serde_json::Value as JsonValue; +use crate::document::state_transition::documents_batch_transition::property_names; use crate::{ identity::KeyType, prelude::ProtocolError, diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 3462ca1ad50..4f8c9fadfb0 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -126,7 +126,9 @@ fn missing_state_transition_error() -> ProtocolError { #[cfg(test)] mod test { use dashcore::network::constants::PROTOCOL_VERSION; + use platform_value::Value; use serde_json::{json, Value as JsonValue}; + use std::collections::BTreeMap; use crate::{ data_contract::state_transition::DataContractCreateTransition, @@ -185,7 +187,7 @@ mod test { let document_transitions = get_document_transitions_fixture(vec![(Action::Create, documents)]); - let raw_document_transitions: Vec = document_transitions + let raw_document_transitions: Vec = document_transitions .iter() .map(|t| t.to_object().unwrap()) .collect(); @@ -196,15 +198,19 @@ mod test { .expect_fetch_data_contract() .returning(move |_, _| Ok(Some(data_contract_to_return.clone()))); - let state_transition_data = json!( { - "protocolVersion" : PROTOCOL_VERSION, - "ownerId": data_contract.owner_id.as_bytes(), - "transitions": raw_document_transitions, - } + let mut map = BTreeMap::new(); + map.insert("protocolVersion".to_string(), Value::U32(PROTOCOL_VERSION)); + map.insert( + "ownerId".to_string(), + Value::Identifier(data_contract.owner_id.buffer), ); + map.insert( + "transitions".to_string(), + Value::Array(raw_document_transitions.clone()), + ); + let documents_batch_state_transition = - DocumentsBatchTransition::from_raw_object(state_transition_data, vec![data_contract]) - .unwrap(); + DocumentsBatchTransition::from_value_map(map, vec![data_contract]).unwrap(); let result = create_state_transition( &state_repostiory_mock, @@ -215,7 +221,7 @@ mod test { assert!( matches!(result, StateTransition::DocumentsBatch(transition) if { - transition.get_transitions().iter().map(|t| t.to_object().unwrap()).collect::>() == raw_document_transitions + transition.get_transitions().iter().map(|t| t.to_object().unwrap()).collect::>() == raw_document_transitions }) ) } diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index a4e866636e9..c38df6dbc3d 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeMap; use crate::{ data_contract::{DataContract}, document::{ @@ -23,6 +24,7 @@ use crate::{ }; use jsonschema::error::ValidationErrorKind; +use platform_value::Value; use serde_json::{json, Value as JsonValue}; use test_case::test_case; @@ -52,21 +54,23 @@ fn setup_test(action: Action) -> TestData { }; let owner_id = data_contract.owner_id; - let raw_transitions: Vec = - transitions.iter().map(|d| d.to_object().unwrap()).collect(); + let raw_transitions: Vec = transitions.iter().map(|d| d.to_object().unwrap()).collect(); let signature = [0_u8; 65].to_vec(); - let state_transition = DocumentsBatchTransition::from_raw_object( - json!({ - "protocolVersion": LATEST_VERSION, - "ownerId" : owner_id.as_bytes(), - "contractId" : data_contract.id.as_bytes(), - "transitions" : raw_transitions, - "signature": signature, - "signaturePublicKeyId": 0, - }), - vec![data_contract.clone()], - ) - .expect("crating state transition shouldn't fail"); + let mut map = BTreeMap::new(); + map.insert("protocolVersion".to_string(), Value::U32(LATEST_VERSION)); + map.insert("ownerId".to_string(), Value::Identifier(owner_id.buffer)); + map.insert( + "contractId".to_string(), + Value::Identifier(data_contract.id.buffer), + ); + map.insert("signature".to_string(), Value::Bytes(signature)); + map.insert("signaturePublicKeyId".to_string(), Value::U32(0)); + + map.insert("transitions".to_string(), Value::Array(raw_transitions)); + + let state_transition = + DocumentsBatchTransition::from_value_map(map, vec![data_contract.clone()]) + .expect("crating state transition shouldn't fail"); let raw_state_transition = state_transition .to_object(false) diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 66322c5df6d..38c9ef6c54f 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -47,12 +47,14 @@ fn should_return_invalid_result_if_compound_index_contains_not_all_fields() { .expect("lastName property should exist and be removed"); let documents_for_transition = vec![document]; - let raw_document_transitions: Vec = + let raw_document_transitions: Vec = get_document_transitions_fixture([(Action::Create, documents_for_transition)]) .into_iter() .map(|dt| { dt.to_object() .expect("the transition should be converted to object") + .try_into() + .expect("expected json values") }) .collect(); let result = validate_partial_compound_indices(raw_document_transitions.iter(), &data_contract) @@ -109,6 +111,8 @@ fn should_return_valid_result_if_compound_index_contains_all_fields() { .map(|dt| { dt.to_object() .expect("the transition should be converted to object") + .try_into() + .expect("expected json values") }) .collect(); let result = validate_partial_compound_indices(raw_document_transitions.iter(), &data_contract) From 9ac0ff83996d47ff71f53686595b644d2d5f6782 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 04:19:20 +0700 Subject: [PATCH 045/228] more fixes --- .../src/data_trigger/dpns_triggers/mod.rs | 3 +- packages/rs-dpp/src/document/document.rs | 22 +--- .../rs-dpp/src/document/document_factory.rs | 2 - .../documents_batch_transition/mod.rs | 18 +-- .../fixtures/get_dpns_document_fixture.rs | 41 ++++-- .../src/btreemap_path_extensions.rs | 4 +- .../src/converter/ciborium.rs | 1 + .../src/converter/serde_json.rs | 117 ++++++++++++++++++ packages/rs-platform-value/src/display.rs | 4 + packages/rs-platform-value/src/lib.rs | 9 +- .../rs-platform-value/src/system_bytes.rs | 4 + 11 files changed, 177 insertions(+), 48 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index f462e10f997..25c7791ca99 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -3,6 +3,7 @@ use std::convert::TryInto; use anyhow::Context; use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use serde_json::{json, Value as JsonValue}; use crate::document::Document; @@ -72,7 +73,7 @@ where .map_err(ProtocolError::ValueError)?; let rule_allow_subdomains = data - .get_bool(PROPERTY_ALLOW_SUBDOMAINS) + .get_bool_at_path(PROPERTY_ALLOW_SUBDOMAINS) .map_err(ProtocolError::ValueError)?; let mut result = DataTriggerExecutionResult::default(); diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 8fb86932a91..d0c2df9a065 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -283,27 +283,7 @@ impl Document { self.properties .iter() .try_for_each(|(key, property_value)| { - let serde_value: JsonValue = match property_value { - Value::Identifier(bytes) => { - // In order to be able to validate using JSON schema it needs to be in byte form - JsonValue::Array( - bytes - .into_iter() - .map(|a| JsonValue::Number((*a).into())) - .collect(), - ) - } - Value::Bytes(bytes) => JsonValue::Array( - bytes - .into_iter() - .map(|byte| JsonValue::Number((*byte).into())) - .collect(), - ), - _ => property_value - .clone() - .try_into() - .map_err(ProtocolError::ValueError)?, - }; + let serde_value: JsonValue = property_value.try_to_validating_json()?; value_mut.insert(key.to_string(), serde_value); Ok::<(), ProtocolError>(()) })?; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 90b0dc59395..1907e4ad9f9 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -165,8 +165,6 @@ where self.document_validator .validate(&json_value, &data_contract, document_type)?; - Document::replace_all_fields(&mut json_value, &data_contract, document_type.name.as_str())?; - let extended_document = ExtendedDocument { protocol_version: self.protocol_version, document_type_name, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 1cad1d54b51..fd0afe2a9cd 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -5,6 +5,7 @@ use anyhow::{anyhow, Context}; use ciborium::value::Value as CborValue; use integer_encoding::VarInt; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -192,13 +193,16 @@ impl DocumentsBatchTransition { let mut raw_transition_map = raw_transition .into_btree_map() .map_err(ProtocolError::ValueError)?; - let id = raw_transition_map.get_bytes(property_names::DATA_CONTRACT_ID)?; - let data_contract = data_contracts_map.get(&id).ok_or_else(|| { - anyhow!( - "Data Contract doesn't exists for Transition: {:?}", - raw_transition_map - ) - })?; + let data_contract_id = + raw_transition_map.get_hash256_bytes(property_names::DATA_CONTRACT_ID)?; + let data_contract = data_contracts_map + .get(data_contract_id.as_slice()) + .ok_or_else(|| { + anyhow!( + "Data Contract doesn't exists for Transition: {:?}", + raw_transition_map + ) + })?; let document_transition = DocumentTransition::from_value_map(raw_transition_map, data_contract.clone())?; document_transitions.push(document_transition); diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs index 72716d9e55d..0a7994e64aa 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs @@ -1,6 +1,8 @@ +use std::collections::BTreeMap; use std::sync::Arc; use getrandom::getrandom; +use platform_value::Value; use serde_json::json; use crate::document::ExtendedDocument; @@ -44,25 +46,38 @@ pub fn get_dpns_parent_document_fixture(options: ParentDocumentOptions) -> Exten let mut pre_order_salt = [0u8; 32]; let _ = getrandom(&mut pre_order_salt); - let data = json!({ - "label" : options.label, - "normalizedLabel" : options.normalized_label, - "normalizedParentDomainName" : "", - "preorderSalt" : pre_order_salt, - "records" : { - "dashUniqueIdentityId" : options.owner_id.as_bytes(), - }, - "subdomainRules" : { - "allowSubdomains" : true - } - }); + let mut map = BTreeMap::new(); + map.insert("label".to_string(), Value::Text(options.label)); + map.insert( + "normalizedLabel".to_string(), + Value::Text(options.normalized_label), + ); + map.insert( + "normalizedParentDomainName".to_string(), + Value::Text(String::new()), + ); + map.insert("preorderSalt".to_string(), Value::Bytes32(pre_order_salt)); + map.insert( + "records".to_string(), + Value::Map(vec![( + Value::Text("dashUniqueIdentityId".to_string()), + Value::Identifier(options.owner_id.buffer), + )]), + ); + map.insert( + "subdomainRules".to_string(), + Value::Map(vec![( + Value::Text("allowSubdomains".to_string()), + Value::Bool(true), + )]), + ); document_factory .create_document_for_state_transition( data_contract, options.owner_id, String::from("domain"), - data.into(), + map.into(), ) .expect("DPNS document should be created") } diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_path_extensions.rs index eb0820841bf..755a6fef5c1 100644 --- a/packages/rs-platform-value/src/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_extensions.rs @@ -85,7 +85,7 @@ pub trait BTreeValueMapPathHelper { &self, path: &str, ) -> Result, Error>; - fn get_system_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error>; + fn get_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error>; fn get_optional_system_bytes_at_path(&self, path: &str) -> Result>, Error>; fn get_system_bytes_at_path(&self, path: &str) -> Result, Error>; fn remove_optional_string_at_path(&mut self, path: &str) -> Result, Error>; @@ -470,7 +470,7 @@ where .transpose() } - fn get_system_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error> { + fn get_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error> { self.get_optional_system_hash256_bytes_at_path(path)? .ok_or_else(|| { Error::StructureError(format!("unable to get system hash256 property {path}")) diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 8a2d2f48044..35525f627f2 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -84,6 +84,7 @@ impl TryInto for Value { Value::U8(i) => CborValue::Integer(i.into()), Value::I8(i) => CborValue::Integer(i.into()), Value::Bytes(bytes) => CborValue::Bytes(bytes), + Value::Bytes32(bytes) => CborValue::Bytes(bytes.to_vec()), Value::Float(float) => CborValue::Float(float), Value::Text(string) => CborValue::Text(string), Value::Bool(value) => CborValue::Bool(value), diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 054f4d690f7..8375eb3864d 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -12,6 +12,122 @@ impl Value { .map(|(key, serde_json_value)| (key, serde_json_value.into())) .collect() } + + pub fn try_into_validating_json(self) -> Result { + Ok(match self { + Value::U128(i) => JsonValue::Number((i as u64).into()), + Value::I128(i) => JsonValue::Number((i as i64).into()), + Value::U64(i) => JsonValue::Number(i.into()), + Value::I64(i) => JsonValue::Number(i.into()), + Value::U32(i) => JsonValue::Number(i.into()), + Value::I32(i) => JsonValue::Number(i.into()), + Value::U16(i) => JsonValue::Number(i.into()), + Value::I16(i) => JsonValue::Number(i.into()), + Value::U8(i) => JsonValue::Number(i.into()), + Value::I8(i) => JsonValue::Number(i.into()), + Value::Float(float) => JsonValue::Number(Number::from_f64(float).unwrap_or(0.into())), + Value::Text(string) => JsonValue::String(string), + Value::Bool(value) => JsonValue::Bool(value), + Value::Null => JsonValue::Null, + //todo support tags + Value::Tag(_, _) => { + return Err(Error::Unsupported("tags not yet supported".to_string())); + } + Value::Array(array) => JsonValue::Array( + array + .into_iter() + .map(|value| value.try_into_validating_json()) + .collect::, Error>>()?, + ), + Value::Map(map) => JsonValue::Object( + map.into_iter() + .map(|(k, v)| { + let string = k.into_text()?; + Ok((string, v.try_into_validating_json()?)) + }) + .collect::, Error>>()?, + ), + Value::Identifier(bytes) => { + // In order to be able to validate using JSON schema it needs to be in byte form + JsonValue::Array( + bytes + .into_iter() + .map(|a| JsonValue::Number(a.into())) + .collect(), + ) + } + Value::Bytes(bytes) => JsonValue::Array( + bytes + .into_iter() + .map(|byte| JsonValue::Number(byte.into())) + .collect(), + ), + Value::Bytes32(bytes) => JsonValue::Array( + bytes + .into_iter() + .map(|byte| JsonValue::Number(byte.into())) + .collect(), + ), + }) + } + + pub fn try_to_validating_json(&self) -> Result { + Ok(match self { + Value::U128(i) => JsonValue::Number(((*i) as u64).into()), + Value::I128(i) => JsonValue::Number(((*i) as i64).into()), + Value::U64(i) => JsonValue::Number((*i).into()), + Value::I64(i) => JsonValue::Number((*i).into()), + Value::U32(i) => JsonValue::Number((*i).into()), + Value::I32(i) => JsonValue::Number((*i).into()), + Value::U16(i) => JsonValue::Number((*i).into()), + Value::I16(i) => JsonValue::Number((*i).into()), + Value::U8(i) => JsonValue::Number((*i).into()), + Value::I8(i) => JsonValue::Number((*i).into()), + Value::Float(float) => JsonValue::Number(Number::from_f64(*float).unwrap_or(0.into())), + Value::Text(string) => JsonValue::String(string.clone()), + Value::Bool(value) => JsonValue::Bool(*value), + Value::Null => JsonValue::Null, + //todo support tags + Value::Tag(_, _) => { + return Err(Error::Unsupported("tags not yet supported".to_string())); + } + Value::Array(array) => JsonValue::Array( + array + .into_iter() + .map(|value| value.try_to_validating_json()) + .collect::, Error>>()?, + ), + Value::Map(map) => JsonValue::Object( + map.into_iter() + .map(|(k, v)| { + let string = k.to_text()?; + Ok((string, v.try_to_validating_json()?)) + }) + .collect::, Error>>()?, + ), + Value::Identifier(bytes) => { + // In order to be able to validate using JSON schema it needs to be in byte form + JsonValue::Array( + bytes + .into_iter() + .map(|a| JsonValue::Number((*a).into())) + .collect(), + ) + } + Value::Bytes(bytes) => JsonValue::Array( + bytes + .into_iter() + .map(|byte| JsonValue::Number((*byte).into())) + .collect(), + ), + Value::Bytes32(bytes) => JsonValue::Array( + bytes + .into_iter() + .map(|byte| JsonValue::Number((*byte).into())) + .collect(), + ), + }) + } } impl From for Value { @@ -80,6 +196,7 @@ impl TryInto for Value { Value::U8(i) => JsonValue::Number(i.into()), Value::I8(i) => JsonValue::Number(i.into()), Value::Bytes(bytes) => JsonValue::String(base64::encode(bytes.as_slice())), + Value::Bytes32(bytes) => JsonValue::String(base64::encode(bytes.as_slice())), Value::Float(float) => JsonValue::Number(Number::from_f64(float).unwrap_or(0.into())), Value::Text(string) => JsonValue::String(string), Value::Bool(value) => JsonValue::Bool(value), diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index c0d44049dbf..720e8611aff 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -47,6 +47,10 @@ impl Value { Value::I16(i) => format!("(i16){}", i), Value::U8(i) => format!("(u8){}", i), Value::I8(i) => format!("(i8){}", i), + Value::Bytes32(bytes32) => format!( + "bytes32 {}", + base64::encode(bytes32.as_slice()) + ), Value::Identifier(identifier) => format!( "identifier {}", bs58::encode(identifier.as_slice()).into_string() diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 3b20c1c42ce..f71808dfede 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -64,6 +64,9 @@ pub enum Value { /// Bytes Bytes(Vec), + /// Bytes 32 + Bytes32([u8;32]), + /// Identifier /// The identifier is very similar to bytes, however it is serialized to Base58 when converted /// to a JSON Value @@ -304,6 +307,7 @@ impl Value { pub fn into_bytes(self) -> Result, Error> { match self { Value::Bytes(vec) => Ok(vec), + Value::Bytes32(vec) => Ok(vec.to_vec()), _other => Err(Error::StructureError("value are not bytes".to_string())), } } @@ -323,6 +327,7 @@ impl Value { pub fn to_bytes(&self) -> Result, Error> { match self { Value::Bytes(vec) => Ok(vec.clone()), + Value::Bytes32(vec) => Ok(vec.to_vec()), other => Err(Error::StructureError(format!( "ref value are not bytes found {} instead", other @@ -345,6 +350,7 @@ impl Value { pub fn as_bytes_slice(&self) -> Result<&[u8], Error> { match self { Value::Bytes(vec) => Ok(vec), + Value::Bytes32(vec) => Ok(vec.as_slice()), _other => Err(Error::StructureError( "ref value are not bytes slice".to_string(), )), @@ -1025,8 +1031,7 @@ implfrom! { Bytes(Vec), Bytes(&[u8]), - - Identifier(Hash256), + Bytes32([u8;32]), Float(f64), Float(f32), diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index b8fa4ef679f..ad936bbf5ed 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -38,6 +38,7 @@ impl Value { }) .collect::, Error>>(), Value::Bytes(vec) => Ok(vec), + Value::Bytes32(bytes) => Ok(bytes.into()), Value::Identifier(identifier) => Ok(Vec::from(identifier)), _other => Err(Error::StructureError( "value are not bytes, a string, or an array of values representing bytes" @@ -83,6 +84,7 @@ impl Value { }) .collect::, Error>>(), Value::Bytes(vec) => Ok(vec.clone()), + Value::Bytes32(vec) => Ok(vec.to_vec()), Value::Identifier(identifier) => Ok(Vec::from(identifier.as_slice())), _other => Err(Error::StructureError( "value are not bytes, a string, or an array of values representing bytes" @@ -144,6 +146,7 @@ impl Value { vec.try_into() .map_err(|_| Error::StructureError("value was bytes, but was not 32 bytes long".to_string())) }, + Value::Bytes32(bytes) => Ok(bytes), Value::Identifier(identifier) => Ok(identifier), _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), } @@ -193,6 +196,7 @@ impl Value { .try_into() .map_err(|_| Error::StructureError("value was an array of bytes, but was not 32 bytes long".to_string()))?) }, + Value::Bytes32(bytes) => Ok(*bytes), Value::Bytes(vec) => { vec.clone().try_into() .map_err(|_| Error::StructureError("value was bytes, but was not 32 bytes long".to_string())) From 169d0ea5bb2512dfecfd002669f28cbf9700a7a8 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 04:24:47 +0700 Subject: [PATCH 046/228] more fixes --- .../validate_documents_batch_transition_state_spec.rs | 10 +++++----- .../tests/fixtures/get_document_transitions_fixture.rs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 0f46cbf8565..e0095f1a7bc 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -178,7 +178,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_delete_ .expect("documents batch state transition should be created"); state_repository_mock - .expect_fetch_documents() + .expect_fetch_extended_documents() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -393,7 +393,7 @@ async fn should_return_invalid_result_if_timestamps_mismatch() { .for_each(|t| set_updated_at(t, Some(now_ts))); state_repository_mock - .expect_fetch_documents() + .expect_fetch_extended_documents() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -453,7 +453,7 @@ async fn should_return_invalid_result_if_crated_at_has_violated_time_window() { .for_each(|t| set_created_at(t, Some(now_ts_minus_6_mins))); state_repository_mock - .expect_fetch_documents() + .expect_fetch_extended_documents() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = @@ -514,7 +514,7 @@ async fn should_not_validate_time_in_block_window_on_dry_run() { .for_each(|t| set_created_at(t, Some(now_ts_minus_6_mins))); state_repository_mock - .expect_fetch_documents() + .expect_fetch_extended_documents() .returning(move |_, _, _, _| Ok(vec![])); let result = @@ -567,7 +567,7 @@ async fn should_return_invalid_result_if_updated_at_has_violated_time_window() { }); state_repository_mock - .expect_fetch_documents() + .expect_fetch_extended_documents() .returning(move |_, _, _, _| Ok(vec![])); let validation_result = diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index c6ccfa85343..cc899541053 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -43,7 +43,7 @@ pub fn get_document_transitions_fixture( (Action::Replace, replace_documents), (Action::Delete, delete_documents), ]) - .expect("the transitions should be crated") + .expect("the transitions should be created") .get_transitions() .to_owned() } From 92a52a2941f7caea75a4c12422009ebea635bf38 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 04:52:43 +0700 Subject: [PATCH 047/228] more fixes --- .../document/state_transition/documents_batch_transition/mod.rs | 2 +- .../basic/validate_documents_batch_transition_basic.rs | 1 + .../validate_documents_batch_transitions_basic_spec.rs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index fd0afe2a9cd..a96eedf843b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -360,7 +360,7 @@ impl StateTransitionConvert for DocumentsBatchTransition { } let mut transitions = vec![]; for transition in self.transitions.iter() { - transitions.push(transition.to_object()?.try_into().unwrap()) + transitions.push(transition.to_object()?.try_into_validating_json().unwrap()) } json_object.insert( String::from(property_names::TRANSITIONS), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 81cc92ae236..68a405eea29 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -90,6 +90,7 @@ pub async fn validate_documents_batch_transition_basic( HashMap::new(); for raw_document_transition in raw_document_transitions { + dbg!(raw_document_transition); let data_contract_id_bytes = match raw_document_transition.get_bytes("$dataContractId") { Err(_) => { result.add_error(BasicError::MissingDataContractIdError); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index c38df6dbc3d..0b3c6ffb8a9 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -932,7 +932,7 @@ async fn validation_should_be_successful() { .await .expect("validation result should be returned"); - assert!(result.is_valid()); + assert!(result.is_valid(), "{:?}", result.errors); } #[tokio::test] From 1fa33ee24cdc79ffb4273aeace03c3d999dc8805 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 05:40:48 +0700 Subject: [PATCH 048/228] more fixes --- .../rs-dpp/src/document/extended_document.rs | 29 ++++++++-- ...pply_documents_batch_transition_factory.rs | 2 +- .../document_base_transition.rs | 2 +- .../document_create_transition.rs | 36 ++++++------ ...e_documents_batch_transition_state_spec.rs | 50 ++++++++++------- .../src/btreemap_field_replacement.rs | 56 +++++++++++++++---- 6 files changed, 119 insertions(+), 56 deletions(-) diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index ff708ed9bb2..852a06f75c4 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -15,10 +15,11 @@ use integer_encoding::VarInt; use crate::data_contract::document_type::DocumentType; use crate::document::Document; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper; use platform_value::converter::serde_json::BTreeValueJsonConverter; -use platform_value::Value; +use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; use std::collections::{BTreeMap, HashSet}; @@ -153,8 +154,22 @@ impl ExtendedDocument { where for<'de> S: Deserialize<'de> + TryInto, { + let document_type_name: String = + if let Ok(document_type_name) = document_value.remove(property_names::DOCUMENT_TYPE) { + serde_json::from_value(document_type_name)? + } else { + return Err(ProtocolError::DecodingError( + "no document type in json value".to_string(), + )); + }; + + //Because we don't know how the json came in we need to sanitize it + let (identifiers, binary_paths) = + data_contract.get_identifiers_and_binary_paths_owned(document_type_name.as_str())?; + let mut extended_document = Self { data_contract, + document_type_name, ..Default::default() }; @@ -162,14 +177,20 @@ impl ExtendedDocument { extended_document.protocol_version = serde_json::from_value(value)? } - if let Ok(value) = document_value.remove(property_names::DOCUMENT_TYPE) { - extended_document.document_type_name = serde_json::from_value(value)? - } if let Ok(value) = document_value.remove(property_names::DATA_CONTRACT_ID) { let data: S = serde_json::from_value(value)?; extended_document.data_contract_id = data.try_into()? } extended_document.document = Document::from_json_value::(document_value)?; + + extended_document + .document + .properties + .replace_at_paths(identifiers, ReplacementType::Identifier)?; + extended_document + .document + .properties + .replace_at_paths(binary_paths, ReplacementType::Bytes)?; Ok(extended_document) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index f7a426958db..59642deef78 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -189,7 +189,7 @@ mod test { state_transition.get_execution_context().enable_dry_run(); state_repository - .expect_fetch_documents() + .expect_fetch_extended_documents() .returning(|_, _, _, _| Ok(vec![])); state_repository .expect_update_document() diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index 059d3a43a1a..7db413ad0eb 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -58,7 +58,7 @@ impl TryFrom for Action { match value { 0 => Ok(Create), 1 => Ok(Replace), - 2 => Ok(Delete), + 3 => Ok(Delete), other => Err(ProtocolError::Document(Box::new( DocumentError::InvalidActionError(other), ))), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 5aaf868ee5b..544e1edabbc 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,10 +1,11 @@ use itertools::Itertools; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; +use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; +use std::convert::TryInto; use std::string::ToString; use crate::document::Document; @@ -115,7 +116,12 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { ReplacementType::Bytes, )?; - map.replace_at_paths(identifiers_paths.into_iter(), ReplacementType::Identifier)?; + map.replace_at_paths( + identifiers_paths + .into_iter() + .chain(IDENTIFIER_FIELDS.iter().map(|a| a.to_string())), + ReplacementType::Identifier, + )?; let document = Self::from_value_map(map, data_contract)?; Ok(document) @@ -179,19 +185,9 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { } fn to_json(&self) -> Result { - let mut value = serde_json::to_value(self)?; - let (identifier_paths, binary_paths) = self - .base - .data_contract - .get_identifiers_and_binary_paths(&self.base.document_type)?; - - value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; - value.replace_binary_paths( - binary_paths.into_iter().chain(BINARY_FIELDS).unique(), - ReplaceWith::Base64, - )?; - - Ok(value) + self.to_object()? + .try_into() + .map_err(ProtocolError::ValueError) } } @@ -307,9 +303,11 @@ mod test { .expect("no errors") .into_btree_map() .unwrap(); - assert_eq!(object_transition.get_bytes("$id").unwrap(), id); + assert_eq!(object_transition.get_system_bytes("$id").unwrap(), id); assert_eq!( - object_transition.get_bytes("$dataContractId").unwrap(), + object_transition + .get_system_bytes("$dataContractId") + .unwrap(), data_contract_id ); assert_eq!( @@ -317,7 +315,9 @@ mod test { alpha_value ); assert_eq!( - object_transition.get_bytes("alphaIdentifier").unwrap(), + object_transition + .get_system_bytes("alphaIdentifier") + .unwrap(), alpha_value ); } diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index e0095f1a7bc..01529d4378e 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -1,4 +1,5 @@ use std::collections::BTreeMap; +use std::convert::TryInto; use std::time::Duration; use chrono::Utc; @@ -249,8 +250,8 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace .expect("documents batch state transition should be created"); state_repository_mock - .expect_fetch_documents() - .returning(move |_, _, _, _| Ok(vec![documents[0].clone()])); + .expect_fetch_extended_documents() + .returning(move |_, _, _, _| Ok(vec![extended_documents[0].clone()])); let validation_result = validate_document_batch_transition_state(&state_repository_mock, &state_transition) @@ -274,21 +275,32 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let TestData { data_contract, owner_id, - extended_documents: documents, + extended_documents, mut state_repository_mock, .. } = setup_test(); let mut replace_document = ExtendedDocument::from_raw_document( - documents[0].to_object().unwrap(), + extended_documents[0] + .to_object() + .unwrap() + .try_into() + .unwrap(), data_contract.clone(), ) .expect("document should be created"); replace_document.document.revision = Some(1); - let mut fetched_document = Document::from_raw_json_document(documents[0].to_object().unwrap()) - .expect("document should be created"); + let mut fetched_document = ExtendedDocument::from_raw_document( + extended_documents[0] + .to_object() + .unwrap() + .try_into() + .unwrap(), + data_contract.clone(), + ) + .expect("document should be created"); let another_owner_id = generate_random_identifier_struct(); - fetched_document.owner_id = another_owner_id.buffer; + fetched_document.document.owner_id = another_owner_id.buffer; let document_transitions = get_document_transitions_fixture([ (Action::Create, vec![]), @@ -319,7 +331,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace .expect("documents batch state transition should be created"); state_repository_mock - .expect_fetch_documents() + .expect_fetch_extended_documents() .returning(move |_, _, _, _| Ok(vec![fetched_document.clone()])); let validation_result = @@ -591,28 +603,26 @@ async fn should_return_valid_result_if_document_transitions_are_valid() { let TestData { data_contract, owner_id, - extended_documents: documents, + extended_documents, mut state_repository_mock, .. } = setup_test(); - let mut fetched_document_1 = - Document::from_raw_json_document(documents[1].to_object().unwrap()).unwrap(); - let mut fetched_document_2 = - Document::from_raw_json_document(documents[2].to_object().unwrap()).unwrap(); - fetched_document_1.revision = Some(1); - fetched_document_2.revision = Some(1); - fetched_document_1.owner_id = owner_id.to_buffer(); - fetched_document_2.owner_id = owner_id.to_buffer(); + let mut fetched_document_1 = extended_documents[1].clone(); + let mut fetched_document_2 = extended_documents[2].clone(); + fetched_document_1.document.revision = Some(1); + fetched_document_2.document.revision = Some(1); + fetched_document_1.document.owner_id = owner_id.to_buffer(); + fetched_document_2.document.owner_id = owner_id.to_buffer(); state_repository_mock - .expect_fetch_documents() + .expect_fetch_extended_documents() .returning(move |_, _, _, _| { Ok(vec![fetched_document_1.clone(), fetched_document_2.clone()]) }); let document_transitions = get_document_transitions_fixture([ (Action::Create, vec![]), - (Action::Replace, vec![documents[1].clone()]), - (Action::Delete, vec![documents[2].clone()]), + (Action::Replace, vec![extended_documents[1].clone()]), + (Action::Delete, vec![extended_documents[2].clone()]), ]); let raw_document_transitions: Vec = document_transitions .into_iter() diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index 8af39b5ff61..068661205a4 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -24,13 +24,26 @@ impl ReplacementType { } } + pub fn replace_for_bytes_32(&self, bytes: [u8;32]) -> Result { + match self { + ReplacementType::Identifier => Ok(Value::Identifier( + bytes + .try_into() + .map_err(|_| Error::ByteLengthNot32BytesError)?, + )), + ReplacementType::Bytes => Ok(Value::Bytes32(bytes)), + ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), + ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), + } + } + pub fn replace_consume_value(&self, value: Value) -> Result { let bytes = value.into_system_bytes()?; self.replace_for_bytes(bytes) } } -pub trait BTreeValueMapInsertionPathHelper { +pub trait BTreeValueMapReplacementPathHelper { fn replace_at_path( &mut self, path: &str, @@ -43,7 +56,7 @@ pub trait BTreeValueMapInsertionPathHelper { ) -> Result, Error>; } -impl BTreeValueMapInsertionPathHelper for BTreeMap { +impl BTreeValueMapReplacementPathHelper for BTreeMap { fn replace_at_path( &mut self, path: &str, @@ -57,16 +70,35 @@ impl BTreeValueMapInsertionPathHelper for BTreeMap { let Some(mut current_value) = self.get_mut(first_path_component) else { return Ok(false); }; - while let Some(path_component) = split.next() { - let map = current_value.as_map_mut_ref()?; - let Some(mut new_value) = map.get_key_mut(path_component) else { - return Ok(false); - }; - current_value = new_value; - if split.peek().is_none() { - let bytes = current_value.to_system_bytes()?; - new_value = &mut replacement_type.replace_for_bytes(bytes)?; - return Ok(true); + if split.peek().is_none() { + match current_value { + Value::Bytes32(bytes) => { + *current_value = replacement_type.replace_for_bytes_32(*bytes)?; + } + _ => { + let bytes = current_value.to_system_bytes()?; + *current_value = replacement_type.replace_for_bytes(bytes)?; + } + } + } else { + while let Some(path_component) = split.next() { + let map = current_value.as_map_mut_ref()?; + let Some(mut new_value) = map.get_key_mut(path_component) else { + return Ok(false); + }; + current_value = new_value; + if split.peek().is_none() { + match current_value { + Value::Bytes32(bytes) => { + *current_value = replacement_type.replace_for_bytes_32(*bytes)?; + } + _ => { + let bytes = current_value.to_system_bytes()?; + *current_value = replacement_type.replace_for_bytes(bytes)?; + } + } + return Ok(true); + } } } Ok(false) From 2b58cd4e3841fd135cce6a528ffec7b684869b19 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 05:54:00 +0700 Subject: [PATCH 049/228] more work --- .../state_transition/state_transition_factory.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 4f8c9fadfb0..91ef60b053c 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -219,11 +219,16 @@ mod test { .await .expect("the state transition should be created"); - assert!( - matches!(result, StateTransition::DocumentsBatch(transition) if { - transition.get_transitions().iter().map(|t| t.to_object().unwrap()).collect::>() == raw_document_transitions - }) - ) + assert!(matches!(result, StateTransition::DocumentsBatch(_))); + + let StateTransition::DocumentsBatch(transition) = result else { + panic!("must be a DocumentsBatch transition") + }; + let values = transition.get_transitions().iter().map(|t| t.to_object().unwrap()).collect::>(); + + assert_eq!( + values,raw_document_transitions + ); } #[tokio::test] From d90d9498398f73e719b64ca75a489f11b5ec63d8 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 05:54:11 +0700 Subject: [PATCH 050/228] fmt --- .../src/state_transition/state_transition_factory.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 91ef60b053c..78a882f414f 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -224,11 +224,13 @@ mod test { let StateTransition::DocumentsBatch(transition) = result else { panic!("must be a DocumentsBatch transition") }; - let values = transition.get_transitions().iter().map(|t| t.to_object().unwrap()).collect::>(); + let values = transition + .get_transitions() + .iter() + .map(|t| t.to_object().unwrap()) + .collect::>(); - assert_eq!( - values,raw_document_transitions - ); + assert_eq!(values, raw_document_transitions); } #[tokio::test] From 9470006515fa25929a622ae338180219627bc621 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 06:06:19 +0700 Subject: [PATCH 051/228] fixes --- .../documents_batch_transition/mod.rs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index a96eedf843b..a0fd591b788 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -5,12 +5,15 @@ use anyhow::{anyhow, Context}; use ciborium::value::Value as CborValue; use integer_encoding::VarInt; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; -use platform_value::Value; +use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::data_contract::DataContract; +use crate::document::document_transition::document_base_transition::IDENTIFIER_FIELDS; +use crate::document::document_transition::document_create_transition::BINARY_FIELDS; use crate::document::document_transition::DocumentTransitionObjectLike; use crate::prelude::{DocumentTransition, Identifier}; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; @@ -38,6 +41,7 @@ pub mod validation; pub mod property_names { pub const TRANSITION_TYPE: &str = "type"; pub const DATA_CONTRACT_ID: &str = "$dataContractId"; + pub const DOCUMENT_TYPE: &str = "$type"; pub const TRANSITIONS: &str = "transitions"; pub const OWNER_ID: &str = "ownerId"; pub const SIGNATURE_PUBLIC_KEY_ID: &str = "signaturePublicKeyId"; @@ -193,8 +197,10 @@ impl DocumentsBatchTransition { let mut raw_transition_map = raw_transition .into_btree_map() .map_err(ProtocolError::ValueError)?; + dbg!(&raw_transition_map); let data_contract_id = raw_transition_map.get_hash256_bytes(property_names::DATA_CONTRACT_ID)?; + let document_type = raw_transition_map.get_str(property_names::DOCUMENT_TYPE)?; let data_contract = data_contracts_map .get(data_contract_id.as_slice()) .ok_or_else(|| { @@ -203,6 +209,28 @@ impl DocumentsBatchTransition { raw_transition_map ) })?; + + //Because we don't know how the json came in we need to sanitize it + let (identifiers, binary_paths) = + data_contract.get_identifiers_and_binary_paths_owned(document_type)?; + + raw_transition_map + .replace_at_paths( + identifiers + .into_iter() + .chain(IDENTIFIER_FIELDS.iter().map(|a| a.to_string())), + ReplacementType::Identifier, + ) + .map_err(ProtocolError::ValueError)?; + raw_transition_map + .replace_at_paths( + binary_paths + .into_iter() + .chain(BINARY_FIELDS.iter().map(|a| a.to_string())), + ReplacementType::Bytes, + ) + .map_err(ProtocolError::ValueError)?; + let document_transition = DocumentTransition::from_value_map(raw_transition_map, data_contract.clone())?; document_transitions.push(document_transition); From 51dff8a24e2ab7a3e381eb604f5ce610dea7d519 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 06:40:42 +0700 Subject: [PATCH 052/228] wasm fixes --- .../document_type/document_type.rs | 2 +- .../document_create_transition.rs | 6 +- packages/rs-drive/src/query/mod.rs | 2 +- .../src/btreemap_extensions.rs | 28 +++-- .../src/btreemap_field_replacement.rs | 6 +- .../src/btreemap_path_extensions.rs | 49 +++++--- packages/rs-platform-value/src/lib.rs | 2 +- .../rs-platform-value/src/system_bytes.rs | 116 ++++++++++++++++-- .../src/document/extended_document.rs | 4 +- packages/wasm-dpp/src/document/factory.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 2 +- .../document_replace_transition.rs | 38 +++--- .../document_transition/mod.rs | 11 +- .../basic/find_duplicates_by_indices.rs | 2 +- 14 files changed, 193 insertions(+), 77 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index b58ffdcbc18..c96b728e8d2 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -141,7 +141,7 @@ impl DocumentType { ) -> Result, ProtocolError> { match key { "$ownerId" | "$id" => { - let bytes = value.to_system_bytes().map_err(ProtocolError::ValueError)?; + let bytes = value.to_identifier_bytes().map_err(ProtocolError::ValueError)?; if bytes.len() != DEFAULT_HASH_SIZE { Err(ProtocolError::DataContractError( DataContractError::FieldRequirementUnmet( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 544e1edabbc..7521f75b724 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -303,10 +303,10 @@ mod test { .expect("no errors") .into_btree_map() .unwrap(); - assert_eq!(object_transition.get_system_bytes("$id").unwrap(), id); + assert_eq!(object_transition.get_identifier_bytes("$id").unwrap(), id); assert_eq!( object_transition - .get_system_bytes("$dataContractId") + .get_identifier_bytes("$dataContractId") .unwrap(), data_contract_id ); @@ -316,7 +316,7 @@ mod test { ); assert_eq!( object_transition - .get_system_bytes("alphaIdentifier") + .get_identifier_bytes("alphaIdentifier") .unwrap(), alpha_value ); diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 52f69eb6127..047c8f6711c 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -387,7 +387,7 @@ impl<'a> DriveQuery<'a> { let start_at: Option> = start_option .map(|v| { - v.into_system_bytes() + v.into_identifier_bytes() .map_err(|e| Error::Protocol(ProtocolError::ValueError(e))) }) .transpose()?; diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 124cdb0ee54..80d63c6a799 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -76,8 +76,8 @@ pub trait BTreeValueMapHelper { ) -> Result; fn get_optional_system_hash256_bytes(&self, key: &str) -> Result, Error>; fn get_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error>; - fn get_optional_system_bytes(&self, key: &str) -> Result>, Error>; - fn get_system_bytes(&self, key: &str) -> Result, Error>; + fn get_optional_identifier_bytes(&self, key: &str) -> Result>, Error>; + fn get_identifier_bytes(&self, key: &str) -> Result, Error>; fn remove_optional_string(&mut self, key: &str) -> Result, Error>; fn remove_string(&mut self, key: &str) -> Result; fn remove_optional_float(&mut self, key: &str) -> Result, Error>; @@ -114,6 +114,8 @@ pub trait BTreeValueMapHelper { fn get_bytes(&self, key: &str) -> Result, Error>; fn remove_optional_bool(&mut self, key: &str) -> Result, Error>; fn remove_bool(&mut self, key: &str) -> Result; + fn get_optional_binary_bytes(&self, key: &str) -> Result>, Error>; + fn get_binary_bytes(&self, key: &str) -> Result, Error>; } impl BTreeValueMapHelper for BTreeMap @@ -412,14 +414,26 @@ where }) } - fn get_optional_system_bytes(&self, key: &str) -> Result>, Error> { + fn get_optional_identifier_bytes(&self, key: &str) -> Result>, Error> { self.get(key) - .map(|v| v.borrow().to_system_bytes()) + .map(|v| v.borrow().to_identifier_bytes()) .transpose() } - fn get_system_bytes(&self, key: &str) -> Result, Error> { - self.get_optional_system_bytes(key)?.ok_or_else(|| { + fn get_identifier_bytes(&self, key: &str) -> Result, Error> { + self.get_optional_identifier_bytes(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to get system bytes property {key}")) + }) + } + + fn get_optional_binary_bytes(&self, key: &str) -> Result>, Error> { + self.get(key) + .map(|v| v.borrow().to_binary_bytes()) + .transpose() + } + + fn get_binary_bytes(&self, key: &str) -> Result, Error> { + self.get_optional_binary_bytes(key)?.ok_or_else(|| { Error::StructureError(format!("unable to get system bytes property {key}")) }) } @@ -438,7 +452,7 @@ where fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { self.remove(key) - .map(|v| v.borrow().to_system_bytes()) + .map(|v| v.borrow().to_identifier_bytes()) .transpose() } diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index 068661205a4..5189aaffe71 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -38,7 +38,7 @@ impl ReplacementType { } pub fn replace_consume_value(&self, value: Value) -> Result { - let bytes = value.into_system_bytes()?; + let bytes = value.into_identifier_bytes()?; self.replace_for_bytes(bytes) } } @@ -76,7 +76,7 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { *current_value = replacement_type.replace_for_bytes_32(*bytes)?; } _ => { - let bytes = current_value.to_system_bytes()?; + let bytes = current_value.to_identifier_bytes()?; *current_value = replacement_type.replace_for_bytes(bytes)?; } } @@ -93,7 +93,7 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { *current_value = replacement_type.replace_for_bytes_32(*bytes)?; } _ => { - let bytes = current_value.to_system_bytes()?; + let bytes = current_value.to_identifier_bytes()?; *current_value = replacement_type.replace_for_bytes(bytes)?; } } diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_path_extensions.rs index 755a6fef5c1..0b99414eaeb 100644 --- a/packages/rs-platform-value/src/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_extensions.rs @@ -86,8 +86,8 @@ pub trait BTreeValueMapPathHelper { path: &str, ) -> Result, Error>; fn get_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error>; - fn get_optional_system_bytes_at_path(&self, path: &str) -> Result>, Error>; - fn get_system_bytes_at_path(&self, path: &str) -> Result, Error>; + fn get_optional_identifier_bytes_at_path(&self, path: &str) -> Result>, Error>; + fn get_identifier_bytes_at_path(&self, path: &str) -> Result, Error>; fn remove_optional_string_at_path(&mut self, path: &str) -> Result, Error>; fn remove_string_at_path(&mut self, path: &str) -> Result; fn remove_optional_float_at_path(&mut self, path: &str) -> Result, Error>; @@ -116,18 +116,20 @@ pub trait BTreeValueMapPathHelper { + TryFrom + TryFrom + TryFrom; - fn remove_optional_system_hash256_bytes_at_path( + fn remove_optional_hash256_bytes_at_path( &mut self, path: &str, ) -> Result, Error>; - fn remove_system_hash256_bytes_at_path(&mut self, path: &str) -> Result<[u8; 32], Error>; - fn remove_optional_system_bytes_at_path( + fn remove_hash256_bytes_at_path(&mut self, path: &str) -> Result<[u8; 32], Error>; + fn remove_optional_identifier_bytes_at_path( &mut self, path: &str, ) -> Result>, Error>; - fn remove_system_bytes_at_path(&mut self, path: &str) -> Result, Error>; + fn remove_identifier_bytes_at_path(&mut self, path: &str) -> Result, Error>; fn get_optional_bytes_at_path(&self, path: &str) -> Result>, Error>; fn get_bytes_at_path(&self, path: &str) -> Result, Error>; + fn get_optional_binary_bytes_at_path(&self, path: &str) -> Result>, Error>; + fn get_binary_bytes_at_path(&self, path: &str) -> Result, Error>; } impl BTreeValueMapPathHelper for BTreeMap @@ -489,20 +491,33 @@ where }) } - fn get_optional_system_bytes_at_path(&self, path: &str) -> Result>, Error> { + fn get_optional_identifier_bytes_at_path(&self, path: &str) -> Result>, Error> { self.get_optional_at_path(path)? - .map(|v| v.borrow().to_system_bytes()) + .map(|v| v.borrow().to_identifier_bytes()) .transpose() } - fn get_system_bytes_at_path(&self, path: &str) -> Result, Error> { - self.get_optional_system_bytes_at_path(path)? + fn get_identifier_bytes_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_identifier_bytes_at_path(path)? .ok_or_else(|| { Error::StructureError(format!("unable to get system bytes property {path}")) }) } - fn remove_optional_system_hash256_bytes_at_path( + fn get_optional_binary_bytes_at_path(&self, path: &str) -> Result>, Error> { + self.get_optional_at_path(path)? + .map(|v| v.borrow().to_binary_bytes()) + .transpose() + } + + fn get_binary_bytes_at_path(&self, path: &str) -> Result, Error> { + self.get_optional_binary_bytes_at_path(path)? + .ok_or_else(|| { + Error::StructureError(format!("unable to get system bytes property {path}")) + }) + } + + fn remove_optional_hash256_bytes_at_path( &mut self, path: &str, ) -> Result, Error> { @@ -511,24 +526,24 @@ where .transpose() } - fn remove_system_hash256_bytes_at_path(&mut self, path: &str) -> Result<[u8; 32], Error> { - self.remove_optional_system_hash256_bytes_at_path(path)? + fn remove_hash256_bytes_at_path(&mut self, path: &str) -> Result<[u8; 32], Error> { + self.remove_optional_hash256_bytes_at_path(path)? .ok_or_else(|| { Error::StructureError(format!("unable to remove system hash256 property {path}")) }) } - fn remove_optional_system_bytes_at_path( + fn remove_optional_identifier_bytes_at_path( &mut self, path: &str, ) -> Result>, Error> { self.remove(path) - .map(|v| v.borrow().to_system_bytes()) + .map(|v| v.borrow().to_identifier_bytes()) .transpose() } - fn remove_system_bytes_at_path(&mut self, path: &str) -> Result, Error> { - self.remove_optional_system_bytes_at_path(path)? + fn remove_identifier_bytes_at_path(&mut self, path: &str) -> Result, Error> { + self.remove_optional_identifier_bytes_at_path(path)? .ok_or_else(|| { Error::StructureError(format!("unable to remove system bytes property {path}")) }) diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index f71808dfede..bd1a682089f 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -981,7 +981,7 @@ impl Value { }; current_value = new_value; if split.peek().is_none() { - let bytes = current_value.to_system_bytes()?; + let bytes = current_value.to_identifier_bytes()?; new_value = &mut replacement_type.replace_for_bytes(bytes)?; return Ok(true); } diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index ad936bbf5ed..5e89e3c4395 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -9,21 +9,21 @@ impl Value { /// # use platform_value::{Error, Value}; /// # /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]); - /// assert_eq!(value.into_system_bytes(), Ok(vec![104, 101, 108, 108, 111])); /// + /// assert_eq!(value.into_identifier_bytes(), Ok(vec![104, 101, 108, 108, 111])); /// /// /// let value = Value::Text("a811".to_string()); - /// assert_eq!(value.into_system_bytes(), Ok(vec![98, 155, 36])); + /// assert_eq!(value.into_identifier_bytes(), Ok(vec![98, 155, 36])); /// /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108)]); - /// assert_eq!(value.into_system_bytes(), Ok(vec![104, 101, 108])); + /// assert_eq!(value.into_identifier_bytes(), Ok(vec![104, 101, 108])); /// /// let value = Value::Identifier([5u8;32]); - /// assert_eq!(value.into_system_bytes(), Ok(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// assert_eq!(value.into_identifier_bytes(), Ok(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.into_system_bytes(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// assert_eq!(value.into_identifier_bytes(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); /// ``` - pub fn into_system_bytes(self) -> Result, Error> { + pub fn into_identifier_bytes(self) -> Result, Error> { match self { Value::Text(text) => bs58::decode(text).into_vec().map_err(|_| { Error::StructureError( @@ -55,21 +55,21 @@ impl Value { /// # use platform_value::{Error, Value}; /// # /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]); - /// assert_eq!(value.to_system_bytes(), Ok(vec![104, 101, 108, 108, 111])); /// + /// assert_eq!(value.to_identifier_bytes(), Ok(vec![104, 101, 108, 108, 111])); /// /// /// let value = Value::Text("a811".to_string()); - /// assert_eq!(value.to_system_bytes(), Ok(vec![98, 155, 36])); + /// assert_eq!(value.to_identifier_bytes(), Ok(vec![98, 155, 36])); /// /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108)]); - /// assert_eq!(value.to_system_bytes(), Ok(vec![104, 101, 108])); + /// assert_eq!(value.to_identifier_bytes(), Ok(vec![104, 101, 108])); /// /// let value = Value::Identifier([5u8;32]); - /// assert_eq!(value.to_system_bytes(), Ok(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// assert_eq!(value.to_identifier_bytes(), Ok(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.to_system_bytes(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// assert_eq!(value.to_identifier_bytes(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); /// ``` - pub fn to_system_bytes(&self) -> Result, Error> { + pub fn to_identifier_bytes(&self) -> Result, Error> { match self { Value::Text(text) => bs58::decode(text).into_vec().map_err(|_| { Error::StructureError( @@ -93,6 +93,98 @@ impl Value { } } + /// If the `Value` is a `Bytes`, a `Text` using base 64 or Vector of `U8`, returns the + /// associated `Vec` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Value}; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]); + /// assert_eq!(value.into_binary_bytes(), Ok(vec![104, 101, 108, 108, 111])); /// + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.into_binary_bytes(), Ok(vec![107, 205, 117])); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108)]); + /// assert_eq!(value.into_binary_bytes(), Ok(vec![104, 101, 108])); + /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.into_binary_bytes(), Ok(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.into_binary_bytes(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn into_binary_bytes(self) -> Result, Error> { + match self { + Value::Text(text) => base64::decode(text).map_err(|_| { + Error::StructureError( + "value was a string, but could not be decoded from base 64".to_string(), + ) + }), + Value::Array(array) => array + .into_iter() + .map(|byte| match byte { + Value::U8(value_as_u8) => Ok(value_as_u8), + _ => Err(Error::StructureError("not an array of bytes".to_string())), + }) + .collect::, Error>>(), + Value::Bytes(vec) => Ok(vec), + Value::Bytes32(bytes) => Ok(bytes.into()), + Value::Identifier(identifier) => Ok(Vec::from(identifier)), + _other => Err(Error::StructureError( + "value are not bytes, a string, or an array of values representing bytes" + .to_string(), + )), + } + } + + /// If the `Value` is a ref to a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the + /// associated `Vec` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Value}; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]); + /// assert_eq!(value.to_binary_bytes(), Ok(vec![104, 101, 108, 108, 111])); /// + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.to_binary_bytes(), Ok(vec![107, 205, 117])); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108)]); + /// assert_eq!(value.to_binary_bytes(), Ok(vec![104, 101, 108])); + /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.to_binary_bytes(), Ok(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_binary_bytes(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn to_binary_bytes(&self) -> Result, Error> { + match self { + Value::Text(text) => base64::decode(text).map_err(|_| { + Error::StructureError( + "value was a string, but could not be decoded from base 64".to_string(), + ) + }), + Value::Array(array) => array + .iter() + .map(|byte| match byte { + Value::U8(value_as_u8) => Ok(*value_as_u8), + _ => Err(Error::StructureError("not an array of bytes".to_string())), + }) + .collect::, Error>>(), + Value::Bytes(vec) => Ok(vec.clone()), + Value::Bytes32(vec) => Ok(vec.to_vec()), + Value::Identifier(identifier) => Ok(Vec::from(identifier.as_slice())), + _other => Err(Error::StructureError( + "value are not bytes, a string, or an array of values representing bytes" + .to_string(), + )), + } + } + /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the /// associated `Vec` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index e88271bef40..7e9b9d503cc 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -194,14 +194,14 @@ impl ExtendedDocumentWasm { if let Some(value) = self.0.get(&path) { match binary_type { BinaryType::Identifier => { - if let Ok(bytes) = value.to_system_bytes() { + if let Ok(bytes) = value.to_identifier_bytes() { let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); return id.into(); } } BinaryType::Buffer => { - if let Ok(bytes) = value.to_system_bytes() { + if let Ok(bytes) = value.to_identifier_bytes() { return Buffer::from_bytes(&bytes).into(); } } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 0f796d11ca9..6169f4a432b 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use std::collections::HashMap; use std::sync::Arc; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; +use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::ReplacementType; use dpp::{ document::{ diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index d879caf27d6..38ce8cf7981 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -35,7 +35,7 @@ use dpp::document::{Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, IDENTIFIER_FI pub use extended_document::ExtendedDocumentWasm; use dpp::document::extended_document::property_names; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapInsertionPathHelper; +use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::ReplacementType; use dpp::platform_value::Value; use dpp::ProtocolError; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 78bd60ad7f3..ab2719a16e7 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -2,19 +2,17 @@ use std::convert; use dpp::identity::TimestampMillis; use dpp::prelude::Revision; -use dpp::{ - document::{ - self, - document_transition::{ - document_create_transition, document_replace_transition, DocumentReplaceTransition, - DocumentTransitionObjectLike, - }, +use dpp::{document::{ + self, + document_transition::{ + document_create_transition, document_replace_transition, DocumentReplaceTransition, + DocumentTransitionObjectLike, }, - prelude::{DataContract, Identifier}, - util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, -}; +}, prelude::{DataContract, Identifier}, ProtocolError, util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}}; use serde::Serialize; use wasm_bindgen::prelude::*; +use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; +use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use crate::{ buffer::Buffer, @@ -131,20 +129,16 @@ impl DocumentReplaceTransitionWasm { .with_js_error()?; for path in identifier_paths { - if let Ok(value) = data.get_value(path) { - let bytes: Vec = serde_json::from_value(value.to_owned()).with_js_error()?; - let id = >::from( - Identifier::from_bytes(&bytes).unwrap(), - ); - lodash_set(&js_value, path, id.into()); - } + let bytes = data.get_identifier_bytes_at_path(path).map_err(ProtocolError::ValueError).with_js_error()?; + let id = >::from( + Identifier::from_bytes(&bytes).unwrap(), + ); + lodash_set(&js_value, path, id.into()); } for path in binary_paths { - if let Ok(value) = data.get_value(path) { - let bytes: Vec = serde_json::from_value(value.to_owned()).with_js_error()?; - let buffer = Buffer::from_bytes(&bytes); - lodash_set(&js_value, path, buffer.into()); - } + let bytes = data.get_binary_bytes_at_path(path).map_err(ProtocolError::ValueError).with_js_error()?; + let buffer = Buffer::from_bytes(&bytes); + lodash_set(&js_value, path, buffer.into()); } Ok(js_value) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index 6fcf3f8e8d1..992114d49b4 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -16,8 +16,9 @@ use dpp::{ util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, }; use serde::Serialize; -use serde_json::Value; +use serde_json::Value as JsonValue; use wasm_bindgen::prelude::*; +use dpp::platform_value::Value; use crate::{ buffer::Buffer, @@ -129,7 +130,7 @@ impl DocumentTransitionWasm { .with_js_error()?; let js_value = to_object( - data.to_owned(), + data.clone().into(), &JsValue::NULL, identifier_paths, binary_paths, @@ -147,14 +148,14 @@ impl DocumentTransitionWasm { if let Some(value) = self.0.get_dynamic_property(path) { match binary_type { BinaryType::Identifier => { - if let Ok(bytes) = serde_json::from_value::>(value.to_owned()) { + if let Ok(bytes) = serde_json::from_value::>(value.to_owned().into()) { let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); return id.into(); } } BinaryType::Buffer => { - if let Ok(bytes) = serde_json::from_value::>(value.to_owned()) { + if let Ok(bytes) = serde_json::from_value::>(value.to_owned().into()) { return Buffer::from_bytes(&bytes).into(); } } @@ -273,7 +274,7 @@ pub(crate) fn to_object<'a>( identifiers_paths: impl IntoIterator, binary_paths: impl IntoIterator, ) -> Result { - let mut value = value; + let mut value : JsonValue = value.into(); let options: ConversionOptions = if options.is_object() { let raw_options = options.with_serde_to_json_value()?; serde_json::from_value(raw_options).with_js_error()? diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index cfafc03ab20..6acd950b135 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -38,7 +38,7 @@ pub fn find_duplicates_by_indices_wasm( .into_iter() .map(|v| { to_object( - v.to_owned(), + v.to_owned().into(), &JsValue::NULL, document_base_transition::IDENTIFIER_FIELDS, document_create_transition::BINARY_FIELDS, From 779e2643c7d24adc67f91888f0a408d4faa31bc0 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 15:19:53 +0700 Subject: [PATCH 053/228] fixes --- packages/rs-drive-abci/src/state/genesis.rs | 3 +- .../src/btreemap_extensions.rs | 36 +++++++- .../src/btreemap_field_replacement.rs | 88 ++++++++++++------- .../src/btreemap_mut_value_extensions.rs | 42 +++++++++ packages/rs-platform-value/src/lib.rs | 23 +++++ packages/rs-platform-value/src/value_map.rs | 74 ++++++++++++++++ .../document/errors/invalid_action_error.rs | 21 +++++ packages/wasm-dpp/src/document/errors/mod.rs | 5 ++ .../document_create_transition.rs | 35 ++++---- .../document_replace_transition.rs | 40 ++++----- .../document_transition/mod.rs | 20 ++--- .../document_batch_transition/mod.rs | 47 ++++------ .../validation/basic/find_duplicates_by_id.rs | 2 +- packages/wasm-dpp/src/utils.rs | 10 +++ 14 files changed, 329 insertions(+), 117 deletions(-) create mode 100644 packages/rs-platform-value/src/btreemap_mut_value_extensions.rs create mode 100644 packages/wasm-dpp/src/document/errors/invalid_action_error.rs diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 0a0f7789241..3c878574937 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -315,8 +315,7 @@ mod tests { assert_eq!( root_hash, [ - 111, 88, 10, 143, 94, 71, 51, 8, 40, 196, 201, 45, 155, 81, 130, 150, 9, 253, - 0, 184, 61, 2, 173, 157, 131, 24, 71, 199, 114, 11, 16, 44 + 52, 133, 20, 245, 44, 13, 159, 73, 228, 237, 23, 190, 110, 242, 54, 217, 16, 231, 15, 161, 56, 19, 25, 224, 45, 42, 68, 252, 21, 187, 113, 210 ] ) } diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 80d63c6a799..7b87c4bdbb5 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -1,5 +1,5 @@ use serde_json::{Map, Value as JsonValue}; -use std::borrow::Borrow; +use std::borrow::{Borrow, BorrowMut}; use std::convert::TryFrom; use std::iter::FromIterator; use std::{collections::BTreeMap, convert::TryInto}; @@ -49,6 +49,14 @@ pub trait BTreeValueMapHelper { &'a self, key: &str, ) -> Result; + fn get_optional_inner_map_in_array<'a, M: FromIterator<(String, &'a Value)>, I: FromIterator>( + &'a self, + key: &str, + ) -> Result, Error>; + fn get_inner_map_in_array<'a, M: FromIterator<(String, &'a Value)>, I: FromIterator>( + &'a self, + key: &str, + ) -> Result; fn get_optional_inner_string_array>( &self, key: &str, @@ -289,6 +297,32 @@ where }) } + fn get_optional_inner_map_in_array<'a, M: FromIterator<(String, &'a Value)>, I: FromIterator>( + &'a self, + key: &str, + ) -> Result, Error> { + self.get(key) + .map(|v| { + v.borrow() + .as_array() + .map(|vec| vec.iter().map(|v| v.to_ref_map::()).collect::>()) + .ok_or_else(|| Error::StructureError(format!("{key} must be a an array"))) + }) + .transpose()? + .transpose() + } + + fn get_inner_map_in_array<'a, M: FromIterator<(String, &'a Value)>, I: FromIterator>( + &'a self, + key: &str, + ) -> Result { + self.get_optional_inner_map_in_array(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to get inner value array property {key}")) + }) + } + + + fn get_optional_inner_string_array>( &self, key: &str, diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index 5189aaffe71..ecfdf7c92b6 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -1,6 +1,9 @@ use crate::value_map::ValueMapHelper; use crate::{Error, Value}; use std::collections::{BTreeMap, HashMap}; +use std::io::Split; +use std::iter::Peekable; +use std::vec::IntoIter; #[derive(Debug, Clone, Copy)] pub enum ReplacementType { @@ -48,12 +51,48 @@ pub trait BTreeValueMapReplacementPathHelper { &mut self, path: &str, replacement_type: ReplacementType, - ) -> Result; + ) -> Result<(), Error>; fn replace_at_paths>( &mut self, paths: I, replacement_type: ReplacementType, - ) -> Result, Error>; + ) -> Result<(), Error>; +} + +fn replace_down(mut current_values: Vec<&mut Value>, mut split: Peekable>, replacement_type: ReplacementType) -> Result<(), Error> { + if let Some(path_component) = split.next() { + let next_values = current_values.iter_mut().map(|current_value| { + if current_value.is_map() { + let map = current_value.as_map_mut_ref()?; + let Some(mut new_value) = map.get_key_mut(path_component) else { + return Ok(None); + }; + if split.peek().is_none() { + match new_value { + Value::Bytes32(bytes) => { + *new_value = replacement_type.replace_for_bytes_32(*bytes)?; + } + _ => { + let bytes = new_value.to_identifier_bytes()?; + *new_value = replacement_type.replace_for_bytes(bytes)?; + } + } + Ok(None) + } else { + Ok(Some(vec![new_value])) + } + } else if current_value.is_array() { + // if it's an array we apply to all members + let array = current_value.to_array_mut()?.iter_mut().collect(); + Ok(Some(array)) + } else { + Err(Error::PathError("path was not an array or map".to_string())) + } + }).collect::, Error>>()?.into_iter().filter_map(|v| v).flatten().collect(); + replace_down(next_values, split, replacement_type) + } else { + Ok(()) + } } impl BTreeValueMapReplacementPathHelper for BTreeMap { @@ -61,16 +100,16 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { &mut self, path: &str, replacement_type: ReplacementType, - ) -> Result { - let mut split = path.split('.').peekable(); - let first = split.next(); + ) -> Result<(), Error> { + let mut split: Vec<_> = path.split('.').collect(); + let first = split.first(); let Some(first_path_component) = first else { return Err(Error::PathError("path was empty".to_string())); }; - let Some(mut current_value) = self.get_mut(first_path_component) else { - return Ok(false); + let Some(mut current_value) = self.get_mut(first_path_component.clone()) else { + return Ok(()); }; - if split.peek().is_none() { + if split.len() == 1 { match current_value { Value::Bytes32(bytes) => { *current_value = replacement_type.replace_for_bytes_32(*bytes)?; @@ -80,41 +119,24 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { *current_value = replacement_type.replace_for_bytes(bytes)?; } } + Ok(()) } else { - while let Some(path_component) = split.next() { - let map = current_value.as_map_mut_ref()?; - let Some(mut new_value) = map.get_key_mut(path_component) else { - return Ok(false); - }; - current_value = new_value; - if split.peek().is_none() { - match current_value { - Value::Bytes32(bytes) => { - *current_value = replacement_type.replace_for_bytes_32(*bytes)?; - } - _ => { - let bytes = current_value.to_identifier_bytes()?; - *current_value = replacement_type.replace_for_bytes(bytes)?; - } - } - return Ok(true); - } - } + split.remove(0); + let mut current_values = vec![current_value]; + //todo: make this non recursive + replace_down(current_values, split.into_iter().peekable(), replacement_type) } - Ok(false) } fn replace_at_paths>( &mut self, paths: I, replacement_type: ReplacementType, - ) -> Result, Error> { + ) -> Result<(), Error> { paths .into_iter() - .map(|path| { - let success = self.replace_at_path(path.as_str(), replacement_type)?; - Ok((path, success)) + .try_for_each(|path| { + self.replace_at_path(path.as_str(), replacement_type) }) - .collect() } } diff --git a/packages/rs-platform-value/src/btreemap_mut_value_extensions.rs b/packages/rs-platform-value/src/btreemap_mut_value_extensions.rs new file mode 100644 index 00000000000..67e3a434ee2 --- /dev/null +++ b/packages/rs-platform-value/src/btreemap_mut_value_extensions.rs @@ -0,0 +1,42 @@ +use std::borrow::BorrowMut; +use std::collections::BTreeMap; +use crate::{Error, Value}; + +pub trait BTreeMutValueMapHelper { + fn get_optional_inner_map_in_array_mut<'a, M: FromIterator<(String, &'a mut Value)>, I: FromIterator>( + &'a mut self, + key: &str, + ) -> Result, Error>; + fn get_inner_map_in_array_mut<'a, M: FromIterator<(String, &'a mut Value)>, I: FromIterator>( + &'a mut self, + key: &str, + ) -> Result; +} + +impl BTreeMutValueMapHelper for BTreeMap + where + V: BorrowMut, +{ + fn get_optional_inner_map_in_array_mut<'a, M: FromIterator<(String, &'a mut Value)>, I: FromIterator>( + &'a mut self, + key: &str, + ) -> Result, Error> { + self.get_mut(key) + .map(|v| { + v.borrow_mut().as_array_mut() + .map(|vec| vec.iter_mut().map(|v| v.to_ref_map_mut::()).collect::>()) + .ok_or_else(|| Error::StructureError(format!("{key} must be a an array"))) + }) + .transpose()? + .transpose() + } + + fn get_inner_map_in_array_mut<'a, M: FromIterator<(String, &'a mut Value)>, I: FromIterator>( + &'a mut self, + key: &str, + ) -> Result { + self.get_optional_inner_map_in_array_mut(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to get inner value array property {key}")) + }) + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index bd1a682089f..3a622a4da4a 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -16,6 +16,7 @@ pub mod inner_value; mod integer; pub mod system_bytes; pub mod value_map; +mod btreemap_mut_value_extensions; use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; @@ -308,6 +309,7 @@ impl Value { match self { Value::Bytes(vec) => Ok(vec), Value::Bytes32(vec) => Ok(vec.to_vec()), + Value::Identifier(vec) => Ok(vec.to_vec()), _other => Err(Error::StructureError("value are not bytes".to_string())), } } @@ -328,6 +330,7 @@ impl Value { match self { Value::Bytes(vec) => Ok(vec.clone()), Value::Bytes32(vec) => Ok(vec.to_vec()), + Value::Identifier(vec) => Ok(vec.to_vec()), other => Err(Error::StructureError(format!( "ref value are not bytes found {} instead", other @@ -779,6 +782,26 @@ impl Value { } } + /// If the `Value` is an Array, returns a mutable reference to the associated vector. + /// Returns None otherwise. + /// + /// ``` + /// # use platform_value::Value; + /// # + /// let mut value = Value::Array( + /// vec![ + /// Value::Text(String::from("foo")), + /// Value::Text(String::from("bar")) + /// ] + /// ); + /// + /// value.to_array_mut().unwrap().clear(); + /// assert_eq!(value, Value::Array(vec![])); + /// ``` + pub fn to_array_mut(&mut self) -> Result<&mut Vec, Error> { + self.as_array_mut().ok_or(Error::StructureError("value is not an array".to_string())) + } + /// If the `Value` is a `Array`, returns a the associated `Vec` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. /// diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index cf448295ff9..4201960e785 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -116,6 +116,52 @@ impl Value { Self::map_ref_into_btree_map(self.to_map_ref()?) } + /// If the `Value` is a `Map`, returns a the associated `BTreeMap` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use std::collections::BTreeMap; + /// # use platform_value::{Error, Value}; + /// # + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("key")), Value::Float(18.)), + /// ] + /// ); + /// assert_eq!(value.to_ref_map::>(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))]))); + /// + /// assert_eq!(value.to_ref_map::>(), Ok(vec![(String::from("key"), &Value::Float(18.))])); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_ref_map::>(), Err(Error::StructureError("value is not a map".to_string()))) + /// ``` + pub fn to_ref_map<'a, I: FromIterator<(String, &'a Value)>>(&'a self) -> Result { + Self::map_ref_into_map(self.to_map_ref()?) + } + + /// If the `Value` is a `Map`, returns a the associated `BTreeMap` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use std::collections::BTreeMap; + /// # use platform_value::{Error, Value}; + /// # + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("key")), Value::Float(18.)), + /// ] + /// ); + /// assert_eq!(value.to_ref_map_mut::>(), Ok(BTreeMap::from([(String::from("key"), &mut Value::Float(18.))]))); + /// + /// assert_eq!(value.to_ref_map_mut::>(), Ok(vec![(String::from("key"), &mut Value::Float(18.))])); + /// + /// let mut value = Value::Bool(true); + /// assert_eq!(value.to_ref_map_mut::>(), Err(Error::StructureError("value is not a map".to_string()))) + /// ``` + pub fn to_ref_map_mut<'a, I: FromIterator<(String, &'a mut Value)>>(&'a mut self) -> Result { + Self::map_mut_ref_into_map(self.as_map_mut_ref()?) + } + /// Takes a ValueMap which is a `Vec<(Value, Value)>` /// Returns a BTreeMap as long as each Key is a String /// Returns `Err(Error::Structure("reason"))` otherwise. @@ -143,4 +189,32 @@ impl Value { }) .collect::, Error>>() } + + /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>` + /// Returns a BTreeMap as long as each Key is a String + /// Returns `Err(Error::Structure("reason"))` otherwise. + pub fn map_ref_into_map<'a, I: FromIterator<(String, &'a Value)>>(map: &'a ValueMap) -> Result { + map.iter() + .map(|(key, value)| { + let key = key + .to_text() + .map_err(|_| Error::StructureError("expected key to be string".to_string()))?; + Ok((key, value)) + }) + .collect::>() + } + + /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>` + /// Returns a BTreeMap as long as each Key is a String + /// Returns `Err(Error::Structure("reason"))` otherwise. + pub fn map_mut_ref_into_map<'a, I: FromIterator<(String, &'a mut Value)>>(map: &'a mut ValueMap) -> Result { + map.iter_mut() + .map(|(key, value)| { + let key = key + .to_text() + .map_err(|_| Error::StructureError("expected key to be string".to_string()))?; + Ok((key, value)) + }) + .collect::>() + } } diff --git a/packages/wasm-dpp/src/document/errors/invalid_action_error.rs b/packages/wasm-dpp/src/document/errors/invalid_action_error.rs new file mode 100644 index 00000000000..00682b36598 --- /dev/null +++ b/packages/wasm-dpp/src/document/errors/invalid_action_error.rs @@ -0,0 +1,21 @@ +use thiserror::Error; + +use super::*; + +#[wasm_bindgen] +#[derive(Error, Debug)] +#[error("Invalid action: {:?}", action)] +pub struct InvalidActionError { + // the point is how we hold all there different types in the Vector + action: JsValue, +} + +#[wasm_bindgen(js_class=InvalidDocumentError)] +impl InvalidActionError { + #[wasm_bindgen(constructor)] + pub fn new(action: JsValue) -> InvalidActionError { + Self { + action, + } + } +} diff --git a/packages/wasm-dpp/src/document/errors/mod.rs b/packages/wasm-dpp/src/document/errors/mod.rs index 32fc15a73cb..0fdef9e8bc3 100644 --- a/packages/wasm-dpp/src/document/errors/mod.rs +++ b/packages/wasm-dpp/src/document/errors/mod.rs @@ -13,6 +13,7 @@ pub use invalid_document_error::*; pub use invalid_initial_revision_error::*; pub use mismatch_owners_ids_error::*; pub use no_documents_supplied_error::*; +use crate::document::errors::invalid_action_error::InvalidActionError; use crate::errors::consensus_error::from_consensus_error; use crate::utils::*; @@ -28,6 +29,7 @@ mod mismatch_owners_ids_error; mod no_documents_supplied_error; mod revision_absent_error; mod trying_to_replace_immutable_document_error; +mod invalid_action_error; pub fn from_document_to_js_error(e: DocumentError) -> JsValue { match e { @@ -70,5 +72,8 @@ pub fn from_document_to_js_error(e: DocumentError) -> JsValue { DocumentError::TryingToReplaceImmutableDocument { document } => { TryingToReplaceImmutableDocumentError::new((*document).into()).into() } + DocumentError::InvalidActionError(action) => { + InvalidActionError::new(action.into()).into() + } } } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index c53c8c357e1..16d1ab91739 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -1,4 +1,5 @@ use std::convert; +use std::convert::TryInto; use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::identity::TimestampMillis; @@ -16,6 +17,8 @@ use dpp::{ }; use serde::Serialize; use wasm_bindgen::prelude::*; +use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use dpp::platform_value::ReplacementType; use crate::{ buffer::Buffer, @@ -52,22 +55,19 @@ impl DocumentCreateTransitionWasm { data_contract: &DataContractWasm, ) -> Result { let data_contract: DataContract = data_contract.clone().into(); - let mut value = raw_object.with_serde_to_json_value()?; + let mut value = raw_object.with_serde_to_platform_value_map()?; let document_type = value .get_string(dpp::document::extended_document::property_names::DOCUMENT_TYPE) + .map_err(ProtocolError::ValueError) .with_js_error()?; let (identifier_paths, _) = data_contract - .get_identifiers_and_binary_paths(document_type) + .get_identifiers_and_binary_paths_owned(document_type.as_str()) + .with_js_error()?; + value.replace_at_paths(identifier_paths, ReplacementType::Identifier).map_err(ProtocolError::ValueError) .with_js_error()?; - replace_identifiers_with_bytes_without_failing( - &mut value, - identifier_paths - .into_iter() - .chain(document_create_transition::IDENTIFIER_FIELDS), - ); let transition = - DocumentCreateTransition::from_raw_object(value, data_contract).with_js_error()?; + DocumentCreateTransition::from_value_map(value, data_contract).with_js_error()?; Ok(transition.into()) } @@ -135,10 +135,11 @@ impl DocumentCreateTransitionWasm { match self.get_binary_type_of_path(&path) { BinaryType::Buffer => { - let buffer = value + let bytes = value .to_bytes() .map_err(ProtocolError::ValueError) .with_js_error()?; + let buffer = Buffer::from_bytes(&bytes); return Ok(buffer.into()); } BinaryType::Identifier => { @@ -147,7 +148,7 @@ impl DocumentCreateTransitionWasm { .map_err(ProtocolError::ValueError) .with_js_error()?; let id = >::from( - Identifier::from(buffer).with_js_error()?, + Identifier::from(buffer) ); return Ok(id.into()); } @@ -156,7 +157,9 @@ impl DocumentCreateTransitionWasm { // or may not captain it at all } } - let json_value: JsonValue = value.into(); + + let json_value: JsonValue = value.clone().try_into().map_err(ProtocolError::ValueError).with_js_error()?; + let map = value.to_btree_ref_map().map_err(ProtocolError::ValueError).with_js_error()?; let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; let (identifier_paths, binary_paths) = self .inner @@ -169,9 +172,7 @@ impl DocumentCreateTransitionWasm { if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - if value.get_value(suffix).is_ok() { - // unwrap allowed because the line above - let bytes = value.remove_path_into::>(suffix).unwrap(); + if let Some(bytes) = map.get_optional_bytes_at_path(suffix).map_err(ProtocolError::ValueError).with_js_error()? { let id = >::from( Identifier::from_bytes(&bytes).unwrap(), ); @@ -184,9 +185,7 @@ impl DocumentCreateTransitionWasm { if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - if value.get_value(suffix).is_ok() { - // unwrap allowed because the line above - let bytes = value.remove_path_into::>(suffix).unwrap(); + if let Some(bytes) = map.get_optional_bytes_at_path(suffix).map_err(ProtocolError::ValueError).with_js_error()? { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, suffix, buffer.into()); } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index ab2719a16e7..b7d5b3db588 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -1,4 +1,5 @@ use std::convert; +use std::convert::TryInto; use dpp::identity::TimestampMillis; use dpp::prelude::Revision; @@ -11,8 +12,11 @@ use dpp::{document::{ }, prelude::{DataContract, Identifier}, ProtocolError, util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}}; use serde::Serialize; use wasm_bindgen::prelude::*; +use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; +use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use dpp::platform_value::ReplacementType; use crate::{ buffer::Buffer, @@ -49,22 +53,19 @@ impl DocumentReplaceTransitionWasm { data_contract: &DataContractWasm, ) -> Result { let data_contract: DataContract = data_contract.clone().into(); - let mut value = raw_object.with_serde_to_json_value()?; + let mut value = raw_object.with_serde_to_platform_value_map()?; let document_type = value - .get_string(document::extended_document::property_names::DOCUMENT_TYPE) + .get_string(dpp::document::extended_document::property_names::DOCUMENT_TYPE) + .map_err(ProtocolError::ValueError) .with_js_error()?; let (identifier_paths, _) = data_contract - .get_identifiers_and_binary_paths(document_type) + .get_identifiers_and_binary_paths_owned(document_type.as_str()) + .with_js_error()?; + value.replace_at_paths(identifier_paths, ReplacementType::Identifier).map_err(ProtocolError::ValueError) .with_js_error()?; - replace_identifiers_with_bytes_without_failing( - &mut value, - identifier_paths - .into_iter() - .chain(document_create_transition::BINARY_FIELDS), - ); let transition = - DocumentReplaceTransition::from_raw_object(value, data_contract).with_js_error()?; + DocumentReplaceTransition::from_value_map(value, data_contract).with_js_error()?; Ok(transition.into()) } @@ -173,7 +174,7 @@ impl DocumentReplaceTransitionWasm { return Ok(JsValue::undefined()); }; - let mut value = if let Ok(value) = document_data.get_value(&path) { + let mut value = if let Ok(value) = document_data.get_at_path(&path) { value.to_owned() } else { return Ok(JsValue::undefined()); @@ -181,12 +182,12 @@ impl DocumentReplaceTransitionWasm { match self.get_binary_type_of_path(&path) { BinaryType::Buffer => { - let bytes: Vec = serde_json::from_value(value).unwrap(); + let bytes: Vec = serde_json::from_value(value.try_into().map_err(ProtocolError::ValueError).with_js_error()?).unwrap(); let buffer = Buffer::from_bytes(&bytes); return Ok(buffer.into()); } BinaryType::Identifier => { - let bytes: Vec = serde_json::from_value(value).unwrap(); + let bytes: Vec = serde_json::from_value(value.try_into().map_err(ProtocolError::ValueError).with_js_error()?).unwrap(); let id = >::from( Identifier::from_bytes(&bytes).unwrap(), ); @@ -198,7 +199,10 @@ impl DocumentReplaceTransitionWasm { } } - let js_value = value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; + + let json_value: JsonValue = value.clone().try_into().map_err(ProtocolError::ValueError).with_js_error()?; + let map = value.to_btree_ref_map().map_err(ProtocolError::ValueError).with_js_error()?; + let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; let (identifier_paths, binary_paths) = self .inner .base @@ -210,9 +214,7 @@ impl DocumentReplaceTransitionWasm { if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - if value.get_value(suffix).is_ok() { - // unwrap allowed because the line above - let bytes = value.remove_path_into::>(suffix).unwrap(); + if let Some(bytes) = map.get_optional_bytes_at_path(suffix).map_err(ProtocolError::ValueError).with_js_error()? { let id = >::from( Identifier::from_bytes(&bytes).unwrap(), ); @@ -225,9 +227,7 @@ impl DocumentReplaceTransitionWasm { if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - if value.get_value(suffix).is_ok() { - // unwrap allowed because the line above - let bytes = value.remove_path_into::>(suffix).unwrap(); + if let Some(bytes) = map.get_optional_bytes_at_path(suffix).map_err(ProtocolError::ValueError).with_js_error()? { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, suffix, buffer.into()); } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index 992114d49b4..8043ddb9645 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -2,19 +2,16 @@ mod document_create_transition; mod document_delete_transition; mod document_replace_transition; +use std::convert::TryInto; use anyhow::Context; pub use document_create_transition::*; pub use document_delete_transition::*; pub use document_replace_transition::*; -use dpp::{ - document::document_transition::{ - DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, - DocumentTransitionExt, DocumentTransitionObjectLike, - }, - prelude::{DocumentTransition, Identifier}, - util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, -}; +use dpp::{document::document_transition::{ + DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, + DocumentTransitionExt, DocumentTransitionObjectLike, +}, prelude::{DocumentTransition, Identifier}, ProtocolError, util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}}; use serde::Serialize; use serde_json::Value as JsonValue; use wasm_bindgen::prelude::*; @@ -148,14 +145,13 @@ impl DocumentTransitionWasm { if let Some(value) = self.0.get_dynamic_property(path) { match binary_type { BinaryType::Identifier => { - if let Ok(bytes) = serde_json::from_value::>(value.to_owned().into()) { + if let Ok( bytes) = value.to_identifier_bytes() { let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); - return id.into(); } } BinaryType::Buffer => { - if let Ok(bytes) = serde_json::from_value::>(value.to_owned().into()) { + if let Ok( bytes) = value.to_binary_bytes() { return Buffer::from_bytes(&bytes).into(); } } @@ -274,7 +270,7 @@ pub(crate) fn to_object<'a>( identifiers_paths: impl IntoIterator, binary_paths: impl IntoIterator, ) -> Result { - let mut value : JsonValue = value.into(); + let mut value : JsonValue = value.try_into().map_err(ProtocolError::ValueError).with_js_error()?; let options: ConversionOptions = if options.is_object() { let raw_options = options.with_serde_to_json_value()?; serde_json::from_value(raw_options).with_js_error()? diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index b1483375b70..ced8b893bca 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,21 +1,20 @@ +use std::collections::BTreeMap; use dpp::identity::KeyID; -use dpp::{ - document::{ - document_transition::document_base_transition, - state_transition::documents_batch_transition::{self, property_names}, - DocumentsBatchTransition, - }, - prelude::{DataContract, DocumentTransition, Identifier}, - state_transition::{ - StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, - StateTransitionType, - }, - util::json_value::JsonValueExt, -}; +use dpp::{document::{ + document_transition::document_base_transition, + state_transition::documents_batch_transition::{self, property_names}, + DocumentsBatchTransition, +}, prelude::{DataContract, DocumentTransition, Identifier}, ProtocolError, state_transition::{ + StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, + StateTransitionType, +}, util::json_value::JsonValueExt}; use js_sys::{Array, Reflect}; use serde::{Deserialize, Serialize}; use serde_json::Value; use wasm_bindgen::prelude::*; +use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; +use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use dpp::platform_value::ReplacementType; use crate::{ bls_adapter::{BlsAdapter, JsBlsAdapter}, @@ -61,25 +60,13 @@ impl DocumentsBatchTransitionWASM { data_contracts.push(data_contract); } - let mut batch_transition_value = js_raw_transition.with_serde_to_json_value()?; - replace_identifiers_with_bytes_without_failing( - &mut batch_transition_value, - DocumentsBatchTransition::identifiers_property_paths(), - ); - - if let Some(Value::Array(ref mut transitions)) = - batch_transition_value.get_mut(documents_batch_transition::property_names::TRANSITIONS) - { - for t in transitions { - replace_identifiers_with_bytes_without_failing( - t, - document_base_transition::IDENTIFIER_FIELDS, - ); - } - } + let mut batch_transition_value = js_raw_transition.with_serde_to_platform_value_map()?; + let base_identifier_fields = document_base_transition::IDENTIFIER_FIELDS.iter().map(|field| format!("{}.{}", property_names::TRANSITIONS, field)); + batch_transition_value.replace_at_paths(DocumentsBatchTransition::identifiers_property_paths().into_iter().map(|field| field.to_string()).chain(base_identifier_fields), + ReplacementType::Identifier).map_err(ProtocolError::ValueError).with_js_error()?; let documents_batch_transition = - DocumentsBatchTransition::from_raw_object(batch_transition_value, data_contracts) + DocumentsBatchTransition::from_value_map(batch_transition_value, data_contracts) .with_js_error()?; Ok(documents_batch_transition.into()) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs index 7d2bc8417f0..c35725f0a90 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -28,7 +28,7 @@ pub fn find_duplicates_by_id_wasm(js_raw_transitions: Array) -> Result Result; fn with_serde_to_platform_value(&self) -> Result; + /// Converts the `JsValue` into `platform::Value`. It's an expensive conversion, + /// as `JsValue` must be stringified first + fn with_serde_to_platform_value_map(&self) -> Result, JsValue>; fn with_serde_into(&self) -> Result where D: for<'de> serde::de::Deserialize<'de> + 'static; @@ -36,6 +40,12 @@ impl ToSerdeJSONExt for JsValue { with_serde_to_platform_value(self) } + /// Converts the `JsValue` into `platform::Value`. It's an expensive conversion, + /// as `JsValue` must be stringified first + fn with_serde_to_platform_value_map(&self) -> Result, JsValue> { + self.with_serde_to_platform_value()?.into_btree_map().map_err(ProtocolError::ValueError).with_js_error() + } + /// converts the `JsValue` into any type that is supported by serde. It's an expensive conversion /// as the `jsValue` must be stringified first fn with_serde_into(&self) -> Result From c92318fabfe118d347a3d6531fc01b948c9a0c16 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 15:32:29 +0700 Subject: [PATCH 054/228] fixes --- packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs | 4 ++-- .../data_trigger/feature_flags_data_triggers/mod.rs | 1 - .../src/data_trigger/reward_share_data_triggers/mod.rs | 3 ++- packages/rs-dpp/src/document/document.rs | 2 +- packages/rs-dpp/src/document/document_factory.rs | 2 +- .../apply_documents_batch_transition_factory.rs | 4 ++-- .../document_transition/document_base_transition.rs | 8 ++++---- .../document_transition/document_create_transition.rs | 8 ++++---- .../document_transition/document_replace_transition.rs | 4 ++-- .../document_transition/mod.rs | 2 +- .../state_transition/documents_batch_transition/mod.rs | 2 +- .../validation/state/fetch_extended_documents.rs | 2 +- .../src/state_transition/abstract_state_transition.rs | 8 ++++---- .../src/tests/fixtures/get_dpns_document_fixture.rs | 2 +- packages/rs-platform-value/src/btreemap_extensions.rs | 4 ++-- .../src/btreemap_field_replacement.rs | 10 +++++----- packages/rs-platform-value/src/lib.rs | 9 +++++---- 17 files changed, 38 insertions(+), 37 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 25c7791ca99..762037ae6d4 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -4,11 +4,11 @@ use anyhow::Context; use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; -use serde_json::{json, Value as JsonValue}; +use serde_json::{json}; use crate::document::Document; use crate::util::hash::hash; -use crate::util::string_encoding::Encoding; + use crate::ProtocolError; use crate::{ document::document_transition::DocumentTransition, get_from_transition, prelude::Identifier, diff --git a/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs index 172d13e3c54..53ef3fee4e1 100644 --- a/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs @@ -4,7 +4,6 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use crate::{ data_trigger::create_error, document::document_transition::DocumentTransition, get_from_transition, prelude::Identifier, state_repository::StateRepositoryLike, - util::json_value::JsonValueExt, ProtocolError, }; use super::{DataTriggerExecutionContext, DataTriggerExecutionResult}; diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 0eec149a456..b5b2d3762a2 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::Value; + use serde_json::json; use crate::document::Document; @@ -143,6 +143,7 @@ mod test { use super::*; use itertools::Itertools; use serde_json::json; + use platform_value::Value; use crate::document::{Document, ExtendedDocument}; use crate::identity::Identity; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index d0c2df9a065..df2677685ed 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -38,7 +38,7 @@ use std::convert::TryInto; use std::fmt; use ciborium::Value as CborValue; -use serde_json::{json, Map, Value as JsonValue}; +use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; use platform_value::btreemap_extensions::BTreeValueMapHelper; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 1907e4ad9f9..9e6c0b22eab 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -160,7 +160,7 @@ where updated_at, }; - let mut json_value = document.to_json_with_identifiers_using_bytes()?; + let json_value = document.to_json_with_identifiers_using_bytes()?; let validation_result = self.document_validator .validate(&json_value, &data_contract, document_type)?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 59642deef78..53f5af2aa08 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -1,5 +1,5 @@ -use platform_value::Value; -use std::collections::{BTreeMap, HashMap}; + +use std::collections::{HashMap}; use crate::document::{Document, ExtendedDocument}; use crate::prelude::TimestampMillis; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index 7db413ad0eb..10622584e92 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; use anyhow::bail; -use num_enum::{IntoPrimitive, TryFromPrimitive}; +use num_enum::{IntoPrimitive}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; @@ -10,13 +10,13 @@ pub use serde_json::Value as JsonValue; use serde_repr::*; use crate::document::document_transition::Action::{Create, Delete, Replace}; -use crate::document::document_transition::DocumentCreateTransition; + use crate::document::errors::DocumentError; use crate::{ data_contract::DataContract, errors::ProtocolError, identifier::Identifier, - util::json_value::{JsonValueExt, ReplaceWith}, + util::json_value::{JsonValueExt}, }; pub(self) mod property_names { @@ -144,7 +144,7 @@ impl DocumentTransitionObjectLike for DocumentBaseTransition { } fn from_raw_object( - mut raw_transition: Value, + raw_transition: Value, data_contract: DataContract, ) -> Result { let map = raw_transition diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 7521f75b724..beeba6b195d 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,4 +1,4 @@ -use itertools::Itertools; + use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use platform_value::{ReplacementType, Value}; @@ -13,13 +13,13 @@ use crate::identity::TimestampMillis; use crate::prelude::Revision; use crate::{ - data_contract::DataContract, document::document_transition::Action, errors::ProtocolError, + data_contract::DataContract, errors::ProtocolError, util::json_value::JsonValueExt, util::json_value::ReplaceWith, }; use super::INITIAL_REVISION; use super::{ - document_base_transition, document_base_transition::DocumentBaseTransition, + document_base_transition::DocumentBaseTransition, DocumentTransitionObjectLike, }; @@ -128,7 +128,7 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { } fn from_raw_object( - mut raw_transition: Value, + raw_transition: Value, data_contract: DataContract, ) -> Result { let map = raw_transition diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index c415dabf8dd..865687ed0f9 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -14,7 +14,7 @@ use crate::{ }; use super::{ - document_base_transition, document_base_transition::DocumentBaseTransition, Action, + document_base_transition::DocumentBaseTransition, Action, DocumentTransitionObjectLike, }; @@ -152,7 +152,7 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { } fn from_raw_object( - mut raw_transition: Value, + raw_transition: Value, data_contract: DataContract, ) -> Result { let map = raw_transition diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index aa05d0e5777..f5802c46d0e 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; -use anyhow::{bail, Context}; +use anyhow::{Context}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index a0fd591b788..b457c8125cc 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -6,7 +6,7 @@ use ciborium::value::Value as CborValue; use integer_encoding::VarInt; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; -use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; + use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs index 1194acd4dfb..2eaf1e7f1a3 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs @@ -1,4 +1,4 @@ -use anyhow::anyhow; + use std::{ collections::hash_map::{Entry, HashMap}, convert::TryInto, diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index ace711ecc9d..a5ebd3c8060 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -1,13 +1,13 @@ -use std::collections::BTreeMap; + use std::fmt::Debug; -use std::vec; + use dashcore::signer; -use platform_value::Value; + use serde::Serialize; use serde_json::Value as JsonValue; -use crate::document::state_transition::documents_batch_transition::property_names; + use crate::{ identity::KeyType, prelude::ProtocolError, diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs index 0a7994e64aa..7d5d0c8f92e 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use getrandom::getrandom; use platform_value::Value; -use serde_json::json; + use crate::document::ExtendedDocument; use crate::{ diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 7b87c4bdbb5..7141a1c48a6 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -1,5 +1,5 @@ -use serde_json::{Map, Value as JsonValue}; -use std::borrow::{Borrow, BorrowMut}; +use serde_json::{Value as JsonValue}; +use std::borrow::{Borrow}; use std::convert::TryFrom; use std::iter::FromIterator; use std::{collections::BTreeMap, convert::TryInto}; diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index ecfdf7c92b6..561637b6e00 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -1,7 +1,7 @@ use crate::value_map::ValueMapHelper; use crate::{Error, Value}; -use std::collections::{BTreeMap, HashMap}; -use std::io::Split; +use std::collections::{BTreeMap}; + use std::iter::Peekable; use std::vec::IntoIter; @@ -64,7 +64,7 @@ fn replace_down(mut current_values: Vec<&mut Value>, mut split: Peekable { let Some(first_path_component) = first else { return Err(Error::PathError("path was empty".to_string())); }; - let Some(mut current_value) = self.get_mut(first_path_component.clone()) else { + let Some(current_value) = self.get_mut(first_path_component.clone()) else { return Ok(()); }; if split.len() == 1 { @@ -122,7 +122,7 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { Ok(()) } else { split.remove(0); - let mut current_values = vec![current_value]; + let current_values = vec![current_value]; //todo: make this non recursive replace_down(current_values, split.into_iter().peekable(), replacement_type) } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 3a622a4da4a..79cd00d763e 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -999,15 +999,16 @@ impl Value { let mut current_value = self; while let Some(path_component) = split.next() { let map = current_value.as_map_mut_ref()?; - let Some(mut new_value) = map.get_key_mut(path_component) else { + let Some(new_value) = map.get_key_mut(path_component) else { return Ok(false); }; - current_value = new_value; + if split.peek().is_none() { - let bytes = current_value.to_identifier_bytes()?; - new_value = &mut replacement_type.replace_for_bytes(bytes)?; + let bytes = new_value.to_identifier_bytes()?; + *new_value = replacement_type.replace_for_bytes(bytes)?; return Ok(true); } + current_value = new_value; } Ok(false) } From 7fd2ea9df5b9de4264cce753ef7f62ed0055a23a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 15:50:36 +0700 Subject: [PATCH 055/228] fixes --- .../src/data_trigger/reward_share_data_triggers/mod.rs | 4 ++-- .../apply_documents_batch_transition_factory.rs | 4 ++-- .../src/state_transition/state_transition_factory.rs | 2 +- .../validate_documents_batch_transition_state_spec.rs | 2 +- .../validation/validate_partial_compound_indices_spec.rs | 2 +- .../document_transition/document_create_transition.rs | 4 ++-- .../document_transition/document_replace_transition.rs | 7 +++---- .../state_transition/document_batch_transition/mod.rs | 8 ++++---- .../validation/state/fetch_extended_documents.rs | 3 +-- 9 files changed, 17 insertions(+), 19 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index b5b2d3762a2..fe608b2c95e 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -141,8 +141,8 @@ where #[cfg(test)] mod test { use super::*; - use itertools::Itertools; - use serde_json::json; + + use platform_value::Value; use crate::document::{Document, ExtendedDocument}; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 53f5af2aa08..070361813cb 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -140,9 +140,9 @@ fn document_from_transition_replace( #[cfg(test)] mod test { use platform_value::Value; - use serde_json::{json, Value as JsonValue}; + use std::collections::BTreeMap; - use std::convert::TryInto; + use crate::tests::fixtures::get_extended_documents_fixture; diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 78a882f414f..d4e79ce0f8c 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -127,7 +127,7 @@ fn missing_state_transition_error() -> ProtocolError { mod test { use dashcore::network::constants::PROTOCOL_VERSION; use platform_value::Value; - use serde_json::{json, Value as JsonValue}; + use serde_json::{json}; use std::collections::BTreeMap; use crate::{ diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 01529d4378e..31bc187b69e 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -4,7 +4,7 @@ use std::time::Duration; use chrono::Utc; use platform_value::Value; -use serde_json::{json, Value as JsonValue}; + use crate::{ codes::ErrorWithCode, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 38c9ef6c54f..c5fa56e0cfd 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -1,4 +1,4 @@ -use platform_value::Value; + use serde_json::Value as JsonValue; use std::convert::TryInto; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 16d1ab91739..3bedf7baca0 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -25,7 +25,7 @@ use crate::{ document_batch_transition::document_transition::to_object, identifier::IdentifierWrapper, lodash::lodash_set, - utils::{replace_identifiers_with_bytes_without_failing, ToSerdeJSONExt, WithJsError}, + utils::{ToSerdeJSONExt, WithJsError}, BinaryType, DataContractWasm, }; @@ -127,7 +127,7 @@ impl DocumentCreateTransitionWasm { return Ok(JsValue::undefined()); }; - let mut value = if let Ok(value) = document_data.get_at_path(&path) { + let value = if let Ok(value) = document_data.get_at_path(&path) { value.clone() } else { return Ok(JsValue::undefined()); diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index b7d5b3db588..2887c05b416 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -4,9 +4,8 @@ use std::convert::TryInto; use dpp::identity::TimestampMillis; use dpp::prelude::Revision; use dpp::{document::{ - self, document_transition::{ - document_create_transition, document_replace_transition, DocumentReplaceTransition, + document_replace_transition, DocumentReplaceTransition, DocumentTransitionObjectLike, }, }, prelude::{DataContract, Identifier}, ProtocolError, util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}}; @@ -23,7 +22,7 @@ use crate::{ document_batch_transition::document_transition::to_object, identifier::IdentifierWrapper, lodash::lodash_set, - utils::{replace_identifiers_with_bytes_without_failing, ToSerdeJSONExt, WithJsError}, + utils::{ToSerdeJSONExt, WithJsError}, BinaryType, DataContractWasm, }; @@ -174,7 +173,7 @@ impl DocumentReplaceTransitionWasm { return Ok(JsValue::undefined()); }; - let mut value = if let Ok(value) = document_data.get_at_path(&path) { + let value = if let Ok(value) = document_data.get_at_path(&path) { value.to_owned() } else { return Ok(JsValue::undefined()); diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index ced8b893bca..9aab8b445df 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,8 +1,8 @@ -use std::collections::BTreeMap; + use dpp::identity::KeyID; use dpp::{document::{ document_transition::document_base_transition, - state_transition::documents_batch_transition::{self, property_names}, + state_transition::documents_batch_transition::{property_names}, DocumentsBatchTransition, }, prelude::{DataContract, DocumentTransition, Identifier}, ProtocolError, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, @@ -10,7 +10,7 @@ use dpp::{document::{ }, util::json_value::JsonValueExt}; use js_sys::{Array, Reflect}; use serde::{Deserialize, Serialize}; -use serde_json::Value; + use wasm_bindgen::prelude::*; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; @@ -23,7 +23,7 @@ use crate::{ identifier::IdentifierWrapper, lodash::lodash_set, utils::{ - replace_identifiers_with_bytes_without_failing, IntoWasm, ToSerdeJSONExt, WithJsError, + IntoWasm, ToSerdeJSONExt, WithJsError, }, IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, }; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs index 59b2eaf7221..67f9afac251 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs @@ -8,8 +8,7 @@ use wasm_bindgen::prelude::*; use crate::{ document_batch_transition::document_transition::DocumentTransitionWasm, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - utils::{IntoWasm, WithJsError}, - DocumentWasm, ExtendedDocumentWasm, StateTransitionExecutionContextWasm, + utils::{IntoWasm, WithJsError}, ExtendedDocumentWasm, StateTransitionExecutionContextWasm, }; #[wasm_bindgen(js_name = fetchExtendedDocuments)] From 6d382c2c8499f558d21f658ddfe3d8bb821505d4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 16:03:56 +0700 Subject: [PATCH 056/228] fmt --- .../document_type/document_type.rs | 4 +- .../src/data_trigger/dpns_triggers/mod.rs | 2 +- .../feature_flags_data_triggers/mod.rs | 2 +- .../reward_share_data_triggers/mod.rs | 3 +- ...pply_documents_batch_transition_factory.rs | 6 +- .../document_base_transition.rs | 8 +- .../document_create_transition.rs | 10 +-- .../document_delete_transition.rs | 2 +- .../document_replace_transition.rs | 3 +- .../document_transition/mod.rs | 2 +- .../state/fetch_extended_documents.rs | 1 - ...lidate_documents_batch_transition_state.rs | 2 +- .../abstract_state_transition.rs | 3 - .../state_transition_factory.rs | 2 +- ...e_documents_batch_transition_state_spec.rs | 1 - .../validate_partial_compound_indices_spec.rs | 1 - .../fixtures/get_dpns_document_fixture.rs | 1 - packages/rs-drive-abci/src/state/genesis.rs | 3 +- .../src/btreemap_extensions.rs | 24 ++++-- .../src/btreemap_field_replacement.rs | 71 ++++++++++------- .../src/btreemap_mut_value_extensions.rs | 48 ++++++++---- .../src/converter/serde_json.rs | 12 +-- packages/rs-platform-value/src/display.rs | 5 +- packages/rs-platform-value/src/lib.rs | 7 +- packages/rs-platform-value/src/value_map.rs | 12 ++- .../document/errors/invalid_action_error.rs | 4 +- packages/wasm-dpp/src/document/errors/mod.rs | 8 +- .../document_create_transition.rs | 37 ++++++--- .../document_replace_transition.rs | 76 ++++++++++++++----- .../document_transition/mod.rs | 26 ++++--- .../document_batch_transition/mod.rs | 44 +++++++---- .../state/fetch_extended_documents.rs | 3 +- packages/wasm-dpp/src/utils.rs | 5 +- 33 files changed, 273 insertions(+), 165 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index c96b728e8d2..d9e0e00bb05 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -141,7 +141,9 @@ impl DocumentType { ) -> Result, ProtocolError> { match key { "$ownerId" | "$id" => { - let bytes = value.to_identifier_bytes().map_err(ProtocolError::ValueError)?; + let bytes = value + .to_identifier_bytes() + .map_err(ProtocolError::ValueError)?; if bytes.len() != DEFAULT_HASH_SIZE { Err(ProtocolError::DataContractError( DataContractError::FieldRequirementUnmet( diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 762037ae6d4..042519c5285 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -4,7 +4,7 @@ use anyhow::Context; use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; -use serde_json::{json}; +use serde_json::json; use crate::document::Document; use crate::util::hash::hash; diff --git a/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs index 53ef3fee4e1..eed45ccf499 100644 --- a/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/feature_flags_data_triggers/mod.rs @@ -43,7 +43,7 @@ where let block_height = context .state_repository .fetch_latest_platform_block_height() - .await? as u64; + .await?; let enable_at_height: u64 = data.get_integer(PROPERTY_ENABLE_AT_HEIGHT).map_err(|_| { anyhow!( diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index fe608b2c95e..c822b0bcc07 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -141,8 +141,7 @@ where #[cfg(test)] mod test { use super::*; - - + use platform_value::Value; use crate::document::{Document, ExtendedDocument}; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 070361813cb..d942487630f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -1,5 +1,4 @@ - -use std::collections::{HashMap}; +use std::collections::HashMap; use crate::document::{Document, ExtendedDocument}; use crate::prelude::TimestampMillis; @@ -140,9 +139,8 @@ fn document_from_transition_replace( #[cfg(test)] mod test { use platform_value::Value; - + use std::collections::BTreeMap; - use crate::tests::fixtures::get_extended_documents_fixture; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index 10622584e92..de3c35f1618 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; use anyhow::bail; -use num_enum::{IntoPrimitive}; +use num_enum::IntoPrimitive; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; @@ -13,10 +13,8 @@ use crate::document::document_transition::Action::{Create, Delete, Replace}; use crate::document::errors::DocumentError; use crate::{ - data_contract::DataContract, - errors::ProtocolError, - identifier::Identifier, - util::json_value::{JsonValueExt}, + data_contract::DataContract, errors::ProtocolError, identifier::Identifier, + util::json_value::JsonValueExt, }; pub(self) mod property_names { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index beeba6b195d..c12f98ad9ea 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,4 +1,3 @@ - use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use platform_value::{ReplacementType, Value}; @@ -13,15 +12,12 @@ use crate::identity::TimestampMillis; use crate::prelude::Revision; use crate::{ - data_contract::DataContract, errors::ProtocolError, - util::json_value::JsonValueExt, util::json_value::ReplaceWith, + data_contract::DataContract, errors::ProtocolError, util::json_value::JsonValueExt, + util::json_value::ReplaceWith, }; use super::INITIAL_REVISION; -use super::{ - document_base_transition::DocumentBaseTransition, - DocumentTransitionObjectLike, -}; +use super::{document_base_transition::DocumentBaseTransition, DocumentTransitionObjectLike}; pub(self) mod property_names { pub const ENTROPY: &str = "$entropy"; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs index d04eb5ff7ee..5d41c4bb06e 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs @@ -30,7 +30,7 @@ impl DocumentTransitionObjectLike for DocumentDeleteTransition { raw_transition: Value, data_contract: DataContract, ) -> Result { - let base = DocumentBaseTransition::from_raw_object(raw_transition.into(), data_contract)?; + let base = DocumentBaseTransition::from_raw_object(raw_transition, data_contract)?; Ok(DocumentDeleteTransition { base }) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 865687ed0f9..91d9637053a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -14,8 +14,7 @@ use crate::{ }; use super::{ - document_base_transition::DocumentBaseTransition, Action, - DocumentTransitionObjectLike, + document_base_transition::DocumentBaseTransition, Action, DocumentTransitionObjectLike, }; pub(self) mod property_names { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index f5802c46d0e..28e40e43a3e 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; -use anyhow::{Context}; +use anyhow::Context; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs index 2eaf1e7f1a3..79dbf1d6d06 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs @@ -1,4 +1,3 @@ - use std::{ collections::hash_map::{Entry, HashMap}, convert::TryInto, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index 8735a1db545..8e06187d798 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -218,7 +218,7 @@ fn check_ownership( StateError::DocumentOwnerIdMismatchError { document_id: document_transition.base().id, document_owner_id: owner_id.to_owned(), - existing_document_owner_id: fetched_document.owner_id().into(), + existing_document_owner_id: fetched_document.owner_id(), }, ))); } diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index a5ebd3c8060..075a2a011fa 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -1,13 +1,10 @@ - use std::fmt::Debug; - use dashcore::signer; use serde::Serialize; use serde_json::Value as JsonValue; - use crate::{ identity::KeyType, prelude::ProtocolError, diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index d4e79ce0f8c..e0ef58ccdbd 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -127,7 +127,7 @@ fn missing_state_transition_error() -> ProtocolError { mod test { use dashcore::network::constants::PROTOCOL_VERSION; use platform_value::Value; - use serde_json::{json}; + use serde_json::json; use std::collections::BTreeMap; use crate::{ diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 31bc187b69e..f409fcbaf9a 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -5,7 +5,6 @@ use std::time::Duration; use chrono::Utc; use platform_value::Value; - use crate::{ codes::ErrorWithCode, consensus::ConsensusError, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index c5fa56e0cfd..e13dd4e4feb 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -1,4 +1,3 @@ - use serde_json::Value as JsonValue; use std::convert::TryInto; diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs index 7d5d0c8f92e..2fdcdfdd403 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs @@ -4,7 +4,6 @@ use std::sync::Arc; use getrandom::getrandom; use platform_value::Value; - use crate::document::ExtendedDocument; use crate::{ document::{ diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 3c878574937..d3f33ee6f06 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -315,7 +315,8 @@ mod tests { assert_eq!( root_hash, [ - 52, 133, 20, 245, 44, 13, 159, 73, 228, 237, 23, 190, 110, 242, 54, 217, 16, 231, 15, 161, 56, 19, 25, 224, 45, 42, 68, 252, 21, 187, 113, 210 + 52, 133, 20, 245, 44, 13, 159, 73, 228, 237, 23, 190, 110, 242, 54, 217, 16, + 231, 15, 161, 56, 19, 25, 224, 45, 42, 68, 252, 21, 187, 113, 210 ] ) } diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 7141a1c48a6..7317a49f377 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -1,5 +1,5 @@ -use serde_json::{Value as JsonValue}; -use std::borrow::{Borrow}; +use serde_json::Value as JsonValue; +use std::borrow::Borrow; use std::convert::TryFrom; use std::iter::FromIterator; use std::{collections::BTreeMap, convert::TryInto}; @@ -49,7 +49,11 @@ pub trait BTreeValueMapHelper { &'a self, key: &str, ) -> Result; - fn get_optional_inner_map_in_array<'a, M: FromIterator<(String, &'a Value)>, I: FromIterator>( + fn get_optional_inner_map_in_array< + 'a, + M: FromIterator<(String, &'a Value)>, + I: FromIterator, + >( &'a self, key: &str, ) -> Result, Error>; @@ -297,7 +301,11 @@ where }) } - fn get_optional_inner_map_in_array<'a, M: FromIterator<(String, &'a Value)>, I: FromIterator>( + fn get_optional_inner_map_in_array< + 'a, + M: FromIterator<(String, &'a Value)>, + I: FromIterator, + >( &'a self, key: &str, ) -> Result, Error> { @@ -305,7 +313,11 @@ where .map(|v| { v.borrow() .as_array() - .map(|vec| vec.iter().map(|v| v.to_ref_map::()).collect::>()) + .map(|vec| { + vec.iter() + .map(|v| v.to_ref_map::()) + .collect::>() + }) .ok_or_else(|| Error::StructureError(format!("{key} must be a an array"))) }) .transpose()? @@ -321,8 +333,6 @@ where }) } - - fn get_optional_inner_string_array>( &self, key: &str, diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index 561637b6e00..13b7d7e4359 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -1,6 +1,6 @@ use crate::value_map::ValueMapHelper; use crate::{Error, Value}; -use std::collections::{BTreeMap}; +use std::collections::BTreeMap; use std::iter::Peekable; use std::vec::IntoIter; @@ -27,7 +27,7 @@ impl ReplacementType { } } - pub fn replace_for_bytes_32(&self, bytes: [u8;32]) -> Result { + pub fn replace_for_bytes_32(&self, bytes: [u8; 32]) -> Result { match self { ReplacementType::Identifier => Ok(Value::Identifier( bytes @@ -59,36 +59,47 @@ pub trait BTreeValueMapReplacementPathHelper { ) -> Result<(), Error>; } -fn replace_down(mut current_values: Vec<&mut Value>, mut split: Peekable>, replacement_type: ReplacementType) -> Result<(), Error> { +fn replace_down( + mut current_values: Vec<&mut Value>, + mut split: Peekable>, + replacement_type: ReplacementType, +) -> Result<(), Error> { if let Some(path_component) = split.next() { - let next_values = current_values.iter_mut().map(|current_value| { - if current_value.is_map() { - let map = current_value.as_map_mut_ref()?; - let Some(new_value) = map.get_key_mut(path_component) else { + let next_values = current_values + .iter_mut() + .map(|current_value| { + if current_value.is_map() { + let map = current_value.as_map_mut_ref()?; + let Some(new_value) = map.get_key_mut(path_component) else { return Ok(None); }; - if split.peek().is_none() { - match new_value { - Value::Bytes32(bytes) => { - *new_value = replacement_type.replace_for_bytes_32(*bytes)?; - } - _ => { - let bytes = new_value.to_identifier_bytes()?; - *new_value = replacement_type.replace_for_bytes(bytes)?; + if split.peek().is_none() { + match new_value { + Value::Bytes32(bytes) => { + *new_value = replacement_type.replace_for_bytes_32(*bytes)?; + } + _ => { + let bytes = new_value.to_identifier_bytes()?; + *new_value = replacement_type.replace_for_bytes(bytes)?; + } } + Ok(None) + } else { + Ok(Some(vec![new_value])) } - Ok(None) + } else if current_value.is_array() { + // if it's an array we apply to all members + let array = current_value.to_array_mut()?.iter_mut().collect(); + Ok(Some(array)) } else { - Ok(Some(vec![new_value])) + Err(Error::PathError("path was not an array or map".to_string())) } - } else if current_value.is_array() { - // if it's an array we apply to all members - let array = current_value.to_array_mut()?.iter_mut().collect(); - Ok(Some(array)) - } else { - Err(Error::PathError("path was not an array or map".to_string())) - } - }).collect::, Error>>()?.into_iter().filter_map(|v| v).flatten().collect(); + }) + .collect::, Error>>()? + .into_iter() + .flatten() + .flatten() + .collect(); replace_down(next_values, split, replacement_type) } else { Ok(()) @@ -124,7 +135,11 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { split.remove(0); let current_values = vec![current_value]; //todo: make this non recursive - replace_down(current_values, split.into_iter().peekable(), replacement_type) + replace_down( + current_values, + split.into_iter().peekable(), + replacement_type, + ) } } @@ -135,8 +150,6 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { ) -> Result<(), Error> { paths .into_iter() - .try_for_each(|path| { - self.replace_at_path(path.as_str(), replacement_type) - }) + .try_for_each(|path| self.replace_at_path(path.as_str(), replacement_type)) } } diff --git a/packages/rs-platform-value/src/btreemap_mut_value_extensions.rs b/packages/rs-platform-value/src/btreemap_mut_value_extensions.rs index 67e3a434ee2..e4b5c1cd022 100644 --- a/packages/rs-platform-value/src/btreemap_mut_value_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_mut_value_extensions.rs @@ -1,42 +1,64 @@ +use crate::{Error, Value}; use std::borrow::BorrowMut; use std::collections::BTreeMap; -use crate::{Error, Value}; pub trait BTreeMutValueMapHelper { - fn get_optional_inner_map_in_array_mut<'a, M: FromIterator<(String, &'a mut Value)>, I: FromIterator>( + fn get_optional_inner_map_in_array_mut< + 'a, + M: FromIterator<(String, &'a mut Value)>, + I: FromIterator, + >( &'a mut self, key: &str, ) -> Result, Error>; - fn get_inner_map_in_array_mut<'a, M: FromIterator<(String, &'a mut Value)>, I: FromIterator>( + fn get_inner_map_in_array_mut< + 'a, + M: FromIterator<(String, &'a mut Value)>, + I: FromIterator, + >( &'a mut self, key: &str, ) -> Result; } impl BTreeMutValueMapHelper for BTreeMap - where - V: BorrowMut, +where + V: BorrowMut, { - fn get_optional_inner_map_in_array_mut<'a, M: FromIterator<(String, &'a mut Value)>, I: FromIterator>( + fn get_optional_inner_map_in_array_mut< + 'a, + M: FromIterator<(String, &'a mut Value)>, + I: FromIterator, + >( &'a mut self, key: &str, ) -> Result, Error> { self.get_mut(key) .map(|v| { - v.borrow_mut().as_array_mut() - .map(|vec| vec.iter_mut().map(|v| v.to_ref_map_mut::()).collect::>()) + v.borrow_mut() + .as_array_mut() + .map(|vec| { + vec.iter_mut() + .map(|v| v.to_ref_map_mut::()) + .collect::>() + }) .ok_or_else(|| Error::StructureError(format!("{key} must be a an array"))) }) .transpose()? .transpose() } - fn get_inner_map_in_array_mut<'a, M: FromIterator<(String, &'a mut Value)>, I: FromIterator>( + fn get_inner_map_in_array_mut< + 'a, + M: FromIterator<(String, &'a mut Value)>, + I: FromIterator, + >( &'a mut self, key: &str, ) -> Result { - self.get_optional_inner_map_in_array_mut(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get inner value array property {key}")) - }) + self.get_optional_inner_map_in_array_mut(key)? + .ok_or_else(|| { + Error::StructureError(format!("unable to get inner value array property {key}")) + }) } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 8375eb3864d..a669cf0c4f8 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -93,12 +93,12 @@ impl Value { } Value::Array(array) => JsonValue::Array( array - .into_iter() + .iter() .map(|value| value.try_to_validating_json()) .collect::, Error>>()?, ), Value::Map(map) => JsonValue::Object( - map.into_iter() + map.iter() .map(|(k, v)| { let string = k.to_text()?; Ok((string, v.try_to_validating_json()?)) @@ -109,20 +109,20 @@ impl Value { // In order to be able to validate using JSON schema it needs to be in byte form JsonValue::Array( bytes - .into_iter() + .iter() .map(|a| JsonValue::Number((*a).into())) .collect(), ) } Value::Bytes(bytes) => JsonValue::Array( bytes - .into_iter() + .iter() .map(|byte| JsonValue::Number((*byte).into())) .collect(), ), Value::Bytes32(bytes) => JsonValue::Array( bytes - .into_iter() + .iter() .map(|byte| JsonValue::Number((*byte).into())) .collect(), ), @@ -245,7 +245,7 @@ impl BTreeValueJsonConverter for BTreeMap { fn to_json_value(&self) -> Result { Ok(JsonValue::Object( - self.into_iter() + self.iter() .map(|(key, value)| Ok((key.clone(), value.clone().try_into()?))) .collect::, Error>>()?, )) diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index 720e8611aff..0469c264143 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -47,10 +47,7 @@ impl Value { Value::I16(i) => format!("(i16){}", i), Value::U8(i) => format!("(u8){}", i), Value::I8(i) => format!("(i8){}", i), - Value::Bytes32(bytes32) => format!( - "bytes32 {}", - base64::encode(bytes32.as_slice()) - ), + Value::Bytes32(bytes32) => format!("bytes32 {}", base64::encode(bytes32.as_slice())), Value::Identifier(identifier) => format!( "identifier {}", bs58::encode(identifier.as_slice()).into_string() diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 79cd00d763e..5e71dd8f9a1 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -7,6 +7,7 @@ //! pub mod btreemap_extensions; pub mod btreemap_field_replacement; +mod btreemap_mut_value_extensions; pub mod btreemap_path_extensions; pub mod btreemap_path_insertion_extensions; pub mod converter; @@ -16,7 +17,6 @@ pub mod inner_value; mod integer; pub mod system_bytes; pub mod value_map; -mod btreemap_mut_value_extensions; use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; @@ -66,7 +66,7 @@ pub enum Value { Bytes(Vec), /// Bytes 32 - Bytes32([u8;32]), + Bytes32([u8; 32]), /// Identifier /// The identifier is very similar to bytes, however it is serialized to Base58 when converted @@ -799,7 +799,8 @@ impl Value { /// assert_eq!(value, Value::Array(vec![])); /// ``` pub fn to_array_mut(&mut self) -> Result<&mut Vec, Error> { - self.as_array_mut().ok_or(Error::StructureError("value is not an array".to_string())) + self.as_array_mut() + .ok_or(Error::StructureError("value is not an array".to_string())) } /// If the `Value` is a `Array`, returns a the associated `Vec` data as `Ok`. diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 4201960e785..5dedf0b1d72 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -158,7 +158,9 @@ impl Value { /// let mut value = Value::Bool(true); /// assert_eq!(value.to_ref_map_mut::>(), Err(Error::StructureError("value is not a map".to_string()))) /// ``` - pub fn to_ref_map_mut<'a, I: FromIterator<(String, &'a mut Value)>>(&'a mut self) -> Result { + pub fn to_ref_map_mut<'a, I: FromIterator<(String, &'a mut Value)>>( + &'a mut self, + ) -> Result { Self::map_mut_ref_into_map(self.as_map_mut_ref()?) } @@ -193,7 +195,9 @@ impl Value { /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>` /// Returns a BTreeMap as long as each Key is a String /// Returns `Err(Error::Structure("reason"))` otherwise. - pub fn map_ref_into_map<'a, I: FromIterator<(String, &'a Value)>>(map: &'a ValueMap) -> Result { + pub fn map_ref_into_map<'a, I: FromIterator<(String, &'a Value)>>( + map: &'a ValueMap, + ) -> Result { map.iter() .map(|(key, value)| { let key = key @@ -207,7 +211,9 @@ impl Value { /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>` /// Returns a BTreeMap as long as each Key is a String /// Returns `Err(Error::Structure("reason"))` otherwise. - pub fn map_mut_ref_into_map<'a, I: FromIterator<(String, &'a mut Value)>>(map: &'a mut ValueMap) -> Result { + pub fn map_mut_ref_into_map<'a, I: FromIterator<(String, &'a mut Value)>>( + map: &'a mut ValueMap, + ) -> Result { map.iter_mut() .map(|(key, value)| { let key = key diff --git a/packages/wasm-dpp/src/document/errors/invalid_action_error.rs b/packages/wasm-dpp/src/document/errors/invalid_action_error.rs index 00682b36598..011b72b51d7 100644 --- a/packages/wasm-dpp/src/document/errors/invalid_action_error.rs +++ b/packages/wasm-dpp/src/document/errors/invalid_action_error.rs @@ -14,8 +14,6 @@ pub struct InvalidActionError { impl InvalidActionError { #[wasm_bindgen(constructor)] pub fn new(action: JsValue) -> InvalidActionError { - Self { - action, - } + Self { action } } } diff --git a/packages/wasm-dpp/src/document/errors/mod.rs b/packages/wasm-dpp/src/document/errors/mod.rs index 0fdef9e8bc3..407b9d05160 100644 --- a/packages/wasm-dpp/src/document/errors/mod.rs +++ b/packages/wasm-dpp/src/document/errors/mod.rs @@ -2,6 +2,7 @@ use serde::Serialize; use wasm_bindgen::prelude::*; use crate::document::errors::document_no_revision_error::DocumentNoRevisionError; +use crate::document::errors::invalid_action_error::InvalidActionError; use crate::document::errors::revision_absent_error::RevisionAbsentError; use crate::document::errors::trying_to_replace_immutable_document_error::TryingToReplaceImmutableDocumentError; pub use document_already_exists_error::*; @@ -13,7 +14,6 @@ pub use invalid_document_error::*; pub use invalid_initial_revision_error::*; pub use mismatch_owners_ids_error::*; pub use no_documents_supplied_error::*; -use crate::document::errors::invalid_action_error::InvalidActionError; use crate::errors::consensus_error::from_consensus_error; use crate::utils::*; @@ -21,6 +21,7 @@ use crate::utils::*; mod document_already_exists_error; mod document_no_revision_error; mod document_not_provided_error; +mod invalid_action_error; mod invalid_action_name_error; mod invalid_document_action_error; mod invalid_document_error; @@ -29,7 +30,6 @@ mod mismatch_owners_ids_error; mod no_documents_supplied_error; mod revision_absent_error; mod trying_to_replace_immutable_document_error; -mod invalid_action_error; pub fn from_document_to_js_error(e: DocumentError) -> JsValue { match e { @@ -72,8 +72,6 @@ pub fn from_document_to_js_error(e: DocumentError) -> JsValue { DocumentError::TryingToReplaceImmutableDocument { document } => { TryingToReplaceImmutableDocumentError::new((*document).into()).into() } - DocumentError::InvalidActionError(action) => { - InvalidActionError::new(action.into()).into() - } + DocumentError::InvalidActionError(action) => InvalidActionError::new(action.into()).into(), } } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 3bedf7baca0..d410371b8a4 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -4,8 +4,10 @@ use std::convert::TryInto; use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::identity::TimestampMillis; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; +use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; +use dpp::platform_value::ReplacementType; use dpp::prelude::Revision; use dpp::{ document::document_transition::{ @@ -17,8 +19,6 @@ use dpp::{ }; use serde::Serialize; use wasm_bindgen::prelude::*; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; -use dpp::platform_value::ReplacementType; use crate::{ buffer::Buffer, @@ -64,7 +64,9 @@ impl DocumentCreateTransitionWasm { let (identifier_paths, _) = data_contract .get_identifiers_and_binary_paths_owned(document_type.as_str()) .with_js_error()?; - value.replace_at_paths(identifier_paths, ReplacementType::Identifier).map_err(ProtocolError::ValueError) + value + .replace_at_paths(identifier_paths, ReplacementType::Identifier) + .map_err(ProtocolError::ValueError) .with_js_error()?; let transition = DocumentCreateTransition::from_value_map(value, data_contract).with_js_error()?; @@ -147,9 +149,9 @@ impl DocumentCreateTransitionWasm { .to_hash256() .map_err(ProtocolError::ValueError) .with_js_error()?; - let id = >::from( - Identifier::from(buffer) - ); + let id = >::from(Identifier::from( + buffer, + )); return Ok(id.into()); } BinaryType::None => { @@ -158,8 +160,15 @@ impl DocumentCreateTransitionWasm { } } - let json_value: JsonValue = value.clone().try_into().map_err(ProtocolError::ValueError).with_js_error()?; - let map = value.to_btree_ref_map().map_err(ProtocolError::ValueError).with_js_error()?; + let json_value: JsonValue = value + .clone() + .try_into() + .map_err(ProtocolError::ValueError) + .with_js_error()?; + let map = value + .to_btree_ref_map() + .map_err(ProtocolError::ValueError) + .with_js_error()?; let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; let (identifier_paths, binary_paths) = self .inner @@ -172,7 +181,11 @@ impl DocumentCreateTransitionWasm { if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - if let Some(bytes) = map.get_optional_bytes_at_path(suffix).map_err(ProtocolError::ValueError).with_js_error()? { + if let Some(bytes) = map + .get_optional_bytes_at_path(suffix) + .map_err(ProtocolError::ValueError) + .with_js_error()? + { let id = >::from( Identifier::from_bytes(&bytes).unwrap(), ); @@ -185,7 +198,11 @@ impl DocumentCreateTransitionWasm { if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - if let Some(bytes) = map.get_optional_bytes_at_path(suffix).map_err(ProtocolError::ValueError).with_js_error()? { + if let Some(bytes) = map + .get_optional_bytes_at_path(suffix) + .map_err(ProtocolError::ValueError) + .with_js_error()? + { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, suffix, buffer.into()); } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 2887c05b416..66de343cfda 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -1,21 +1,23 @@ use std::convert; use std::convert::TryInto; -use dpp::identity::TimestampMillis; -use dpp::prelude::Revision; -use dpp::{document::{ - document_transition::{ - document_replace_transition, DocumentReplaceTransition, - DocumentTransitionObjectLike, - }, -}, prelude::{DataContract, Identifier}, ProtocolError, util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}}; -use serde::Serialize; -use wasm_bindgen::prelude::*; use dpp::document::document_transition::document_base_transition::JsonValue; +use dpp::identity::TimestampMillis; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use dpp::platform_value::ReplacementType; +use dpp::prelude::Revision; +use dpp::{ + document::document_transition::{ + document_replace_transition, DocumentReplaceTransition, DocumentTransitionObjectLike, + }, + prelude::{DataContract, Identifier}, + util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, + ProtocolError, +}; +use serde::Serialize; +use wasm_bindgen::prelude::*; use crate::{ buffer::Buffer, @@ -61,7 +63,9 @@ impl DocumentReplaceTransitionWasm { let (identifier_paths, _) = data_contract .get_identifiers_and_binary_paths_owned(document_type.as_str()) .with_js_error()?; - value.replace_at_paths(identifier_paths, ReplacementType::Identifier).map_err(ProtocolError::ValueError) + value + .replace_at_paths(identifier_paths, ReplacementType::Identifier) + .map_err(ProtocolError::ValueError) .with_js_error()?; let transition = DocumentReplaceTransition::from_value_map(value, data_contract).with_js_error()?; @@ -129,14 +133,20 @@ impl DocumentReplaceTransitionWasm { .with_js_error()?; for path in identifier_paths { - let bytes = data.get_identifier_bytes_at_path(path).map_err(ProtocolError::ValueError).with_js_error()?; + let bytes = data + .get_identifier_bytes_at_path(path) + .map_err(ProtocolError::ValueError) + .with_js_error()?; let id = >::from( Identifier::from_bytes(&bytes).unwrap(), ); lodash_set(&js_value, path, id.into()); } for path in binary_paths { - let bytes = data.get_binary_bytes_at_path(path).map_err(ProtocolError::ValueError).with_js_error()?; + let bytes = data + .get_binary_bytes_at_path(path) + .map_err(ProtocolError::ValueError) + .with_js_error()?; let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, path, buffer.into()); } @@ -181,12 +191,24 @@ impl DocumentReplaceTransitionWasm { match self.get_binary_type_of_path(&path) { BinaryType::Buffer => { - let bytes: Vec = serde_json::from_value(value.try_into().map_err(ProtocolError::ValueError).with_js_error()?).unwrap(); + let bytes: Vec = serde_json::from_value( + value + .try_into() + .map_err(ProtocolError::ValueError) + .with_js_error()?, + ) + .unwrap(); let buffer = Buffer::from_bytes(&bytes); return Ok(buffer.into()); } BinaryType::Identifier => { - let bytes: Vec = serde_json::from_value(value.try_into().map_err(ProtocolError::ValueError).with_js_error()?).unwrap(); + let bytes: Vec = serde_json::from_value( + value + .try_into() + .map_err(ProtocolError::ValueError) + .with_js_error()?, + ) + .unwrap(); let id = >::from( Identifier::from_bytes(&bytes).unwrap(), ); @@ -198,9 +220,15 @@ impl DocumentReplaceTransitionWasm { } } - - let json_value: JsonValue = value.clone().try_into().map_err(ProtocolError::ValueError).with_js_error()?; - let map = value.to_btree_ref_map().map_err(ProtocolError::ValueError).with_js_error()?; + let json_value: JsonValue = value + .clone() + .try_into() + .map_err(ProtocolError::ValueError) + .with_js_error()?; + let map = value + .to_btree_ref_map() + .map_err(ProtocolError::ValueError) + .with_js_error()?; let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; let (identifier_paths, binary_paths) = self .inner @@ -213,7 +241,11 @@ impl DocumentReplaceTransitionWasm { if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - if let Some(bytes) = map.get_optional_bytes_at_path(suffix).map_err(ProtocolError::ValueError).with_js_error()? { + if let Some(bytes) = map + .get_optional_bytes_at_path(suffix) + .map_err(ProtocolError::ValueError) + .with_js_error()? + { let id = >::from( Identifier::from_bytes(&bytes).unwrap(), ); @@ -226,7 +258,11 @@ impl DocumentReplaceTransitionWasm { if property_path.starts_with(&path) { let (_, suffix) = property_path.split_at(path.len() + 1); - if let Some(bytes) = map.get_optional_bytes_at_path(suffix).map_err(ProtocolError::ValueError).with_js_error()? { + if let Some(bytes) = map + .get_optional_bytes_at_path(suffix) + .map_err(ProtocolError::ValueError) + .with_js_error()? + { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, suffix, buffer.into()); } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index 8043ddb9645..81839472393 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -2,20 +2,25 @@ mod document_create_transition; mod document_delete_transition; mod document_replace_transition; -use std::convert::TryInto; use anyhow::Context; pub use document_create_transition::*; pub use document_delete_transition::*; pub use document_replace_transition::*; +use std::convert::TryInto; -use dpp::{document::document_transition::{ - DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, - DocumentTransitionExt, DocumentTransitionObjectLike, -}, prelude::{DocumentTransition, Identifier}, ProtocolError, util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}}; +use dpp::platform_value::Value; +use dpp::{ + document::document_transition::{ + DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, + DocumentTransitionExt, DocumentTransitionObjectLike, + }, + prelude::{DocumentTransition, Identifier}, + util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, + ProtocolError, +}; use serde::Serialize; use serde_json::Value as JsonValue; use wasm_bindgen::prelude::*; -use dpp::platform_value::Value; use crate::{ buffer::Buffer, @@ -145,13 +150,13 @@ impl DocumentTransitionWasm { if let Some(value) = self.0.get_dynamic_property(path) { match binary_type { BinaryType::Identifier => { - if let Ok( bytes) = value.to_identifier_bytes() { + if let Ok(bytes) = value.to_identifier_bytes() { let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); return id.into(); } } BinaryType::Buffer => { - if let Ok( bytes) = value.to_binary_bytes() { + if let Ok(bytes) = value.to_binary_bytes() { return Buffer::from_bytes(&bytes).into(); } } @@ -270,7 +275,10 @@ pub(crate) fn to_object<'a>( identifiers_paths: impl IntoIterator, binary_paths: impl IntoIterator, ) -> Result { - let mut value : JsonValue = value.try_into().map_err(ProtocolError::ValueError).with_js_error()?; + let mut value: JsonValue = value + .try_into() + .map_err(ProtocolError::ValueError) + .with_js_error()?; let options: ConversionOptions = if options.is_object() { let raw_options = options.with_serde_to_json_value()?; serde_json::from_value(raw_options).with_js_error()? diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 9aab8b445df..d3de208d92b 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -1,20 +1,24 @@ - use dpp::identity::KeyID; -use dpp::{document::{ - document_transition::document_base_transition, - state_transition::documents_batch_transition::{property_names}, - DocumentsBatchTransition, -}, prelude::{DataContract, DocumentTransition, Identifier}, ProtocolError, state_transition::{ - StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, - StateTransitionType, -}, util::json_value::JsonValueExt}; +use dpp::{ + document::{ + document_transition::document_base_transition, + state_transition::documents_batch_transition::property_names, DocumentsBatchTransition, + }, + prelude::{DataContract, DocumentTransition, Identifier}, + state_transition::{ + StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, + StateTransitionType, + }, + util::json_value::JsonValueExt, + ProtocolError, +}; use js_sys::{Array, Reflect}; use serde::{Deserialize, Serialize}; -use wasm_bindgen::prelude::*; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::ReplacementType; +use wasm_bindgen::prelude::*; use crate::{ bls_adapter::{BlsAdapter, JsBlsAdapter}, @@ -22,9 +26,7 @@ use crate::{ document_batch_transition::document_transition::DocumentTransitionWasm, identifier::IdentifierWrapper, lodash::lodash_set, - utils::{ - IntoWasm, ToSerdeJSONExt, WithJsError, - }, + utils::{IntoWasm, ToSerdeJSONExt, WithJsError}, IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, }; pub mod apply_document_batch_transition; @@ -61,9 +63,19 @@ impl DocumentsBatchTransitionWASM { } let mut batch_transition_value = js_raw_transition.with_serde_to_platform_value_map()?; - let base_identifier_fields = document_base_transition::IDENTIFIER_FIELDS.iter().map(|field| format!("{}.{}", property_names::TRANSITIONS, field)); - batch_transition_value.replace_at_paths(DocumentsBatchTransition::identifiers_property_paths().into_iter().map(|field| field.to_string()).chain(base_identifier_fields), - ReplacementType::Identifier).map_err(ProtocolError::ValueError).with_js_error()?; + let base_identifier_fields = document_base_transition::IDENTIFIER_FIELDS + .iter() + .map(|field| format!("{}.{}", property_names::TRANSITIONS, field)); + batch_transition_value + .replace_at_paths( + DocumentsBatchTransition::identifiers_property_paths() + .into_iter() + .map(|field| field.to_string()) + .chain(base_identifier_fields), + ReplacementType::Identifier, + ) + .map_err(ProtocolError::ValueError) + .with_js_error()?; let documents_batch_transition = DocumentsBatchTransition::from_value_map(batch_transition_value, data_contracts) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs index 67f9afac251..63a101f4ba6 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs @@ -8,7 +8,8 @@ use wasm_bindgen::prelude::*; use crate::{ document_batch_transition::document_transition::DocumentTransitionWasm, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - utils::{IntoWasm, WithJsError}, ExtendedDocumentWasm, StateTransitionExecutionContextWasm, + utils::{IntoWasm, WithJsError}, + ExtendedDocumentWasm, StateTransitionExecutionContextWasm, }; #[wasm_bindgen(js_name = fetchExtendedDocuments)] diff --git a/packages/wasm-dpp/src/utils.rs b/packages/wasm-dpp/src/utils.rs index d58f2a0db59..32cf12893e6 100644 --- a/packages/wasm-dpp/src/utils.rs +++ b/packages/wasm-dpp/src/utils.rs @@ -43,7 +43,10 @@ impl ToSerdeJSONExt for JsValue { /// Converts the `JsValue` into `platform::Value`. It's an expensive conversion, /// as `JsValue` must be stringified first fn with_serde_to_platform_value_map(&self) -> Result, JsValue> { - self.with_serde_to_platform_value()?.into_btree_map().map_err(ProtocolError::ValueError).with_js_error() + self.with_serde_to_platform_value()? + .into_btree_map() + .map_err(ProtocolError::ValueError) + .with_js_error() } /// converts the `JsValue` into any type that is supported by serde. It's an expensive conversion From f2d3d329882746799bda5bcc06b7db2c630fa9bc Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Mon, 6 Mar 2023 17:33:13 +0800 Subject: [PATCH 057/228] fix wasm build error --- packages/wasm-dpp/src/document/errors/invalid_action_error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/src/document/errors/invalid_action_error.rs b/packages/wasm-dpp/src/document/errors/invalid_action_error.rs index 011b72b51d7..ba0f51da2b7 100644 --- a/packages/wasm-dpp/src/document/errors/invalid_action_error.rs +++ b/packages/wasm-dpp/src/document/errors/invalid_action_error.rs @@ -10,7 +10,7 @@ pub struct InvalidActionError { action: JsValue, } -#[wasm_bindgen(js_class=InvalidDocumentError)] +#[wasm_bindgen(js_class=InvalidActiontError)] impl InvalidActionError { #[wasm_bindgen(constructor)] pub fn new(action: JsValue) -> InvalidActionError { From f3b9cbdc486e007cda547c1769f8a210bc413da6 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Mon, 6 Mar 2023 18:23:38 +0800 Subject: [PATCH 058/228] fix create_document --- packages/rs-dpp/src/state_repository.rs | 2 +- ...plyDocumentsBatchTransitionFactory.spec.js | 28 +++++------ ...cumentsBatchTransitionStateFactory.spec.js | 48 +++++++++---------- ...ocumentsUniquenessByIndicesFactory.spec.js | 40 ++++++++-------- 4 files changed, 59 insertions(+), 59 deletions(-) diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index 43f0508ffd2..cf12a65e564 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -82,7 +82,7 @@ pub trait StateRepositoryLike: Sync { /// Create Document async fn create_document( &self, - document: &Document, + document: &ExtendedDocument, execution_context: &StateTransitionExecutionContext, ) -> AnyResult<()>; diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js index c2eb3febefc..648438e2874 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js @@ -20,7 +20,7 @@ const StateTransitionExecutionContextJs = require('@dashevo/dpp/lib/stateTransit const { default: loadWasmDpp } = require('../../../../../dist'); -let Document; +let ExtendedDocument; let DocumentsBatchTransition; let DataContract; let StateTransitionExecutionContext; @@ -42,7 +42,7 @@ describe('applyDocumentsBatchTransitionFactory', () => { let applyDocumentsBatchTransitionJs; let stateRepositoryMockJs; let stateRepositoryMock; - let fetchDocumentsMock; + let fetchExtendedDocumentsMock; let executionContextJs; let executionContext; let blockTimeMs; @@ -50,7 +50,7 @@ describe('applyDocumentsBatchTransitionFactory', () => { beforeEach(async function beforeEach() { ({ DataContract, - Document, + ExtendedDocument, DocumentsBatchTransition, StateTransitionExecutionContext, applyDocumentsBatchTransition, @@ -63,7 +63,7 @@ describe('applyDocumentsBatchTransitionFactory', () => { documentsFixtureJs = getDocumentsFixture(dataContractJs); documentsFixture = documentsFixtureJs.map((d) => { - const doc = new Document(d.toObject(), dataContract); + const doc = new ExtendedDocument(d.toObject(), dataContract); doc.setEntropy(d.entropy); return doc; }); @@ -75,7 +75,7 @@ describe('applyDocumentsBatchTransitionFactory', () => { lastName: 'NotSoShiny', }, dataContractJs); - replaceDocument = new Document({ + replaceDocument = new ExtendedDocument({ ...documentsFixture[1].toObject(), lastName: 'NotSoShiny', }, dataContract); @@ -110,8 +110,8 @@ describe('applyDocumentsBatchTransitionFactory', () => { stateRepositoryMockJs.fetchDataContract.resolves(dataContractJs); stateRepositoryMockJs.fetchLatestPlatformBlockTime.resolves(blockTimeMs); - fetchDocumentsMock = this.sinonSandbox.stub(); - fetchDocumentsMock.resolves([ + fetchExtendedDocumentsMock = this.sinonSandbox.stub(); + fetchExtendedDocumentsMock.resolves([ replaceDocumentJs, ]); @@ -121,11 +121,11 @@ describe('applyDocumentsBatchTransitionFactory', () => { stateRepositoryMock.updateDocument.resolves(null); stateRepositoryMock.removeDocument.resolves(null); stateRepositoryMock.createDocument.resolves(null); - stateRepositoryMock.fetchDocuments.resolves([replaceDocument]); + stateRepositoryMock.fetchExtendedDocuments.resolves([replaceDocument]); applyDocumentsBatchTransitionJs = applyDocumentsBatchTransitionFactory( stateRepositoryMockJs, - fetchDocumentsMock, + fetchExtendedDocumentsMock, ); }); @@ -134,7 +134,7 @@ describe('applyDocumentsBatchTransitionFactory', () => { const replaceDocumentTransition = documentTransitionsJs[1]; - expect(fetchDocumentsMock).to.have.been.calledOnceWithExactly( + expect(fetchExtendedDocumentsMock).to.have.been.calledOnceWithExactly( [replaceDocumentTransition], executionContextJs, ); @@ -166,12 +166,12 @@ describe('applyDocumentsBatchTransitionFactory', () => { await applyDocumentsBatchTransition(stateRepositoryMock, stateTransition); expect(stateRepositoryMock.createDocument).to.have.been.calledOnce(); - const [fetchContractId, fetchDocumentType] = stateRepositoryMock.fetchDocuments.getCall(0).args; + const [fetchContractId, fetchDocumentType] = stateRepositoryMock.fetchExtendedDocuments.getCall(0).args; expect(fetchContractId.toBuffer()).to.deep.equal(documentTransitionsJs[1].getDataContractId()); expect(fetchDocumentType).to.equal(documentTransitionsJs[1].getType()); expect(stateRepositoryMock.updateDocument).to.have.been.calledOnce(); - expect(stateRepositoryMock.fetchDocuments).to.have.been.calledOnce(); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.calledOnce(); const [createDocument] = stateRepositoryMock.createDocument.getCall(0).args; const [updateDocument] = stateRepositoryMock.updateDocument.getCall(0).args; @@ -197,7 +197,7 @@ describe('applyDocumentsBatchTransitionFactory', () => { }); it('should throw an error if document was not provided for a replacement - Rust', async () => { - stateRepositoryMock.fetchDocuments.resolves([]); + stateRepositoryMock.fetchExtendedDocuments.resolves([]); const replaceDocumentTransition = documentTransitionsJs[1]; @@ -236,7 +236,7 @@ describe('applyDocumentsBatchTransitionFactory', () => { const [documentTransition] = stateTransition.getTransitions(); - const newDocument = new Document({ + const newDocument = new ExtendedDocument({ $protocolVersion: stateTransitionJs.getProtocolVersion(), $id: documentTransition.getId(), $type: documentTransition.getType(), diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js index adda6ac6533..22e938de6b4 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js @@ -13,7 +13,7 @@ const StateTransitionExecutionContextJs = require('@dashevo/dpp/lib/stateTransit const { default: loadWasmDpp } = require('../../../../../../../dist'); let Identifier; -let Document; +let ExtendedDocument; let DataContract; let DocumentsBatchTransition; let StateTransitionExecutionContext; @@ -48,7 +48,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { beforeEach(async function beforeEach() { ({ Identifier, - Document, + ExtendedDocument, DataContract, DocumentsBatchTransition, StateTransitionExecutionContext, @@ -68,7 +68,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { - const doc = new Document(d.toObject(), dataContract); + const doc = new ExtendedDocument(d.toObject(), dataContract); doc.setEntropy(d.entropy); return doc; }); @@ -105,7 +105,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { stateRepositoryMockJs.fetchLatestPlatformBlockTime.resolves(blockTime); stateRepositoryMock.fetchLatestPlatformBlockTime.resolves(blockTime); - stateRepositoryMock.fetchDocuments.resolves([]); + stateRepositoryMock.fetchExtendedDocuments.resolves([]); executeDataTriggersMock = this.sinonSandbox.stub(); validateDocumentsUniquenessByIndicesMock = this.sinonSandbox.stub(); @@ -138,7 +138,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { }); it('should return invalid result if document transition with action "create" is already present - Rust', async () => { - stateRepositoryMock.fetchDocuments.resolves([documents[0]]); + stateRepositoryMock.fetchExtendedDocuments.resolves([documents[0]]); const result = await validateDocumentsBatchTransitionState( stateRepositoryMock, stateTransition, @@ -182,7 +182,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchDocuments).to.have.been.callCount(documentTransitionsJs.length); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.callCount(documentTransitionsJs.length); }); it('should return invalid result if document transition with action "delete" is not present - Rust', async () => { @@ -212,7 +212,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchDocuments).to.have.been.callCount(documentTransitionsJs.length); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.callCount(documentTransitionsJs.length); }); it('should return invalid result if document transition with action "replace" has wrong revision - Rust', async () => { @@ -231,7 +231,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { }, [dataContract]); documents[0].setCreatedAt(replaceDocument.getCreatedAt().getMilliseconds()); - stateRepositoryMock.fetchDocuments.resolves([documents[0]]); + stateRepositoryMock.fetchExtendedDocuments.resolves([documents[0]]); const result = await validateDocumentsBatchTransitionState( stateRepositoryMock, stateTransition, @@ -250,14 +250,14 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchDocuments).to.have.been.callCount(documentTransitionsJs.length); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.callCount(documentTransitionsJs.length); }); it('should return invalid result if document transition with action "replace" has mismatch of ownerId with previous revision - Rust', async () => { const replaceDocument = new DocumentJs(documentsJs[0].toObject(), dataContractJs); replaceDocument.setRevision(1); - const fetchedDocument = new Document(documentsJs[0].toObject(), dataContract); + const fetchedDocument = new ExtendedDocument(documentsJs[0].toObject(), dataContract); fetchedDocument.setOwnerId(Identifier.from(generateRandomIdentifier().toBuffer())); documentTransitionsJs = getDocumentTransitionsFixture({ @@ -271,7 +271,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { transitions: documentTransitionsJs.map((t) => t.toObject()), }, [dataContract]); - stateRepositoryMock.fetchDocuments.resolves([fetchedDocument]); + stateRepositoryMock.fetchExtendedDocuments.resolves([fetchedDocument]); const result = await validateDocumentsBatchTransitionState( stateRepositoryMock, @@ -292,7 +292,7 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchDocuments).to.have.been.callCount(documentTransitionsJs.length); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.callCount(documentTransitionsJs.length); }); it('should throw an error if document transition has invalid action - Rust', async () => { @@ -524,8 +524,8 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { documentsJs[1].updatedAt.getMinutes() - 6, ); - const documentToReturn = new Document(documentsJs[1].toObject(), dataContract); - stateRepositoryMock.fetchDocuments.resolves([documentToReturn]); + const documentToReturn = new ExtendedDocument(documentsJs[1].toObject(), dataContract); + stateRepositoryMock.fetchExtendedDocuments.resolves([documentToReturn]); const transitions = stateTransition.getTransitions(); transitions.forEach((t) => { @@ -572,8 +572,8 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { documentsJs[1].updatedAt.getMinutes() - 6, ); - const documentToReturn = new Document(documentsJs[1].toObject(), dataContract); - stateRepositoryMock.fetchDocuments.resolves([documentToReturn]); + const documentToReturn = new ExtendedDocument(documentsJs[1].toObject(), dataContract); + stateRepositoryMock.fetchExtendedDocuments.resolves([documentToReturn]); const transitions = stateTransition.getTransitions(); transitions.forEach((t) => { const createdAtMinus6Mins = t.getUpdatedAt() - (6 * 60 * 1000); @@ -594,11 +594,11 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { it('should return valid result if document transitions are valid - Rust', async () => { const fetchedDocuments = [ - new Document(documentsJs[1].toObject(), dataContract), - new Document(documentsJs[2].toObject(), dataContract), + new ExtendedDocument(documentsJs[1].toObject(), dataContract), + new ExtendedDocument(documentsJs[2].toObject(), dataContract), ]; - stateRepositoryMock.fetchDocuments.resolves(fetchedDocuments); + stateRepositoryMock.fetchExtendedDocuments.resolves(fetchedDocuments); documentsJs[1].setRevision(1); documentsJs[2].setRevision(1); @@ -626,16 +626,16 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchDocuments).to.have.been.calledOnce(); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.calledOnce(); }); it('should return valid result if document transitions are valid - Rust', async () => { const fetchedDocuments = [ - new Document(documentsJs[1].toObject(), dataContract), - new Document(documentsJs[2].toObject(), dataContract), + new ExtendedDocument(documentsJs[1].toObject(), dataContract), + new ExtendedDocument(documentsJs[2].toObject(), dataContract), ]; - stateRepositoryMock.fetchDocuments.resolves(fetchedDocuments); + stateRepositoryMock.fetchExtendedDocuments.resolves(fetchedDocuments); documentsJs[1].setRevision(1); documentsJs[2].setRevision(1); @@ -663,6 +663,6 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchDocuments).to.have.been.calledOnce(); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.calledOnce(); }); }); diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js index a3db9bb7d1e..9558f749f23 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js @@ -9,7 +9,7 @@ const { expectValidationError } = require('../../../../../../../lib/test/expect/ const { default: loadWasmDpp } = require('../../../../../../../dist'); let DataContract; -let Document; +let ExtendedDocument; let ValidationResult; let DuplicateUniqueIndexError; let validateDocumentsUniquenessByIndices; @@ -32,7 +32,7 @@ describe('validateDocumentsUniquenessByIndices', () => { beforeEach(async function beforeEach() { ({ - Document, + ExtendedDocument, DataContract, Identifier, DocumentCreateTransition, @@ -64,10 +64,10 @@ describe('validateDocumentsUniquenessByIndices', () => { ); stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); - stateRepositoryMock.fetchDocuments.resolves([]); + stateRepositoryMock.fetchExtendedDocuments.resolves([]); stateRepositoryMockJs = createStateRepositoryMock(this.sinonSandbox); - stateRepositoryMockJs.fetchDocuments.resolves([]); + stateRepositoryMockJs.fetchExtendedDocuments.resolves([]); executionContext = new StateTransitionExecutionContext(); }); @@ -94,14 +94,14 @@ describe('validateDocumentsUniquenessByIndices', () => { expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); - expect(stateRepositoryMock.fetchDocuments).to.have.not.been.called(); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.not.been.called(); }); it('should return valid result if Document has unique indices and there are no duplicates - Rust', async () => { const [, , , william] = documentsJs; - const williamDocument = new Document(william.toObject(), dataContract); + const williamDocument = new ExtendedDocument(william.toObject(), dataContract); - stateRepositoryMock.fetchDocuments + stateRepositoryMock.fetchExtendedDocuments .withArgs( dataContract.getId().toBuffer(), williamDocument.getType(), @@ -114,7 +114,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([williamDocument]); - stateRepositoryMock.fetchDocuments + stateRepositoryMock.fetchExtendedDocuments .withArgs( dataContractJs.getId().toBuffer(), william.getType(), @@ -142,12 +142,12 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return invalid result if Document has unique indices and there are duplicates - Rust', async () => { let [, , , william, leon] = documentsJs; - william = new Document(william.toObject(), dataContract.clone()); - leon = new Document(leon.toObject(), dataContract.clone()); + william = new ExtendedDocument(william.toObject(), dataContract.clone()); + leon = new ExtendedDocument(leon.toObject(), dataContract.clone()); const indicesDefinition = dataContractJs.getDocumentSchema(william.getType()).indices; - stateRepositoryMock.fetchDocuments + stateRepositoryMock.fetchExtendedDocuments .withArgs( sinon.match.instanceOf(Identifier), william.getType(), @@ -160,7 +160,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([leon]); - stateRepositoryMock.fetchDocuments + stateRepositoryMock.fetchExtendedDocuments .withArgs( sinon.match.instanceOf(Identifier), william.getType(), @@ -173,7 +173,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([leon]); - stateRepositoryMock.fetchDocuments + stateRepositoryMock.fetchExtendedDocuments .withArgs( sinon.match.instanceOf(Identifier), leon.getType(), @@ -186,7 +186,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([william]); - stateRepositoryMock.fetchDocuments + stateRepositoryMock.fetchExtendedDocuments .withArgs( sinon.match.instanceOf(Identifier), leon.getType(), @@ -229,7 +229,7 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return valid result if Document has undefined field from index - Rust', async () => { const indexedDocumentJs = documentsJs[7]; - const indexedDocument = new Document(indexedDocumentJs.toObject(), dataContract.clone()); + const indexedDocument = new ExtendedDocument(indexedDocumentJs.toObject(), dataContract.clone()); const indexedDocumentTransitions = getDocumentTransitionsFixture({ create: [indexedDocumentJs], }).map( @@ -238,7 +238,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ), ); - stateRepositoryMockJs.fetchDocuments + stateRepositoryMockJs.fetchExtendedDocuments .withArgs( sinon.match.instanceOf(Identifier), indexedDocument.getType(), @@ -251,7 +251,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([indexedDocument]); - stateRepositoryMockJs.fetchDocuments + stateRepositoryMockJs.fetchExtendedDocuments .withArgs( sinon.match.instanceOf(Identifier), indexedDocument.getType(), @@ -277,7 +277,7 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return valid result if Document being created and has createdAt and updatedAt indices - Rust', async () => { const [, , , , , , uniqueDatesDocumentJs] = documentsJs; - const uniqueDatesDocument = new Document( + const uniqueDatesDocument = new ExtendedDocument( uniqueDatesDocumentJs.toObject(), dataContract.clone(), ); const uniqueDatesDocumentTransitions = getDocumentTransitionsFixture({ @@ -288,7 +288,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ), ); - stateRepositoryMock.fetchDocuments + stateRepositoryMock.fetchExtendedDocuments .withArgs( sinon.match.instanceOf(Identifier), uniqueDatesDocumentJs.getType(), @@ -335,6 +335,6 @@ describe('validateDocumentsUniquenessByIndices', () => { expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); - expect(stateRepositoryMock.fetchDocuments).to.have.not.been.called(); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.not.been.called(); }); }); From f5b1f8ca1d2e8c6f82c98457e9e66512888b0016 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 17:40:42 +0700 Subject: [PATCH 059/228] fixes --- .../src/data_trigger/dpns_triggers/mod.rs | 2 +- .../reward_share_data_triggers/mod.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 1 + ...pply_documents_batch_transition_factory.rs | 14 ++++++-------- .../document_base_transition.rs | 8 ++++---- .../document_create_transition.rs | 18 +++++++++++++++++- .../document_delete_transition.rs | 2 +- .../document_replace_transition.rs | 19 +++++++++++++++++-- .../document_transition/mod.rs | 2 +- .../documents_batch_transition/mod.rs | 6 ++++-- .../validation/basic/find_duplicates_by_id.rs | 6 +++--- .../validation/state/execute_data_triggers.rs | 2 +- .../state/fetch_extended_documents.rs | 4 ++-- ...alidate_documents_uniqueness_by_indices.rs | 4 ++-- ...ty_credit_withdrawal_transition_factory.rs | 16 ++++++++++++++-- packages/rs-dpp/src/state_repository.rs | 2 +- ...edit_withdrawal_transition_factory_spec.rs | 12 ++++++++---- .../document_create_transition.rs | 8 ++++---- .../document_delete_transition.rs | 2 +- .../document_replace_transition.rs | 10 +++++----- packages/wasm-dpp/src/state_repository.rs | 18 +++++++++--------- 21 files changed, 103 insertions(+), 55 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 042519c5285..b0441d0d656 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -160,7 +160,7 @@ where .state_repository .fetch_documents( &context.data_contract.id, - &dt_create.base.document_type, + &dt_create.base.document_type_name, json!({ "where" : [ ["normalizedParentDomainName", "==", grand_parent_domain_name], diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index c822b0bcc07..256585cb969 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -92,7 +92,7 @@ where .state_repository .fetch_documents( &context.data_contract.id, - &document_create_transition.base.document_type, + &document_create_transition.base.document_type_name, json!({ "where" : [ [ "$owner_id", "==", owner_id ]] }), diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 852a06f75c4..da6c95701c2 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -58,6 +58,7 @@ pub struct ExtendedDocument { #[serde(skip)] pub metadata: Option, #[serde(skip)] + //todo: make entropy optional pub entropy: [u8; 32], } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index d942487630f..5d3ad42a8f9 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -66,7 +66,7 @@ pub async fn apply_documents_batch_transition( match document_transition { DocumentTransition::Create(document_create_transition) => { let document = document_create_transition - .to_document(state_transition.owner_id.to_buffer())?; + .to_extended_document(state_transition.owner_id.to_buffer())?; //todo: eventually we should use Cow instead state_repository .create_document(&document, state_transition.get_execution_context()) @@ -74,7 +74,8 @@ pub async fn apply_documents_batch_transition( } DocumentTransition::Replace(document_replace_transition) => { if state_transition.execution_context.is_dry_run() { - let document = document_replace_transition.to_document_for_dry_run()?; + let document = + document_replace_transition.to_extended_document_for_dry_run()?; state_repository .update_document(&document, state_transition.get_execution_context()) .await?; @@ -86,10 +87,7 @@ pub async fn apply_documents_batch_transition( })?; document_replace_transition.replace_extended_document(document)?; state_repository - .update_document( - &document.document, - state_transition.get_execution_context(), - ) + .update_document(&document, state_transition.get_execution_context()) .await?; }; } @@ -97,7 +95,7 @@ pub async fn apply_documents_batch_transition( state_repository .remove_document( &document_delete_transition.base.data_contract, - &document_delete_transition.base.document_type, + &document_delete_transition.base.document_type_name, &document_delete_transition.base.id, state_transition.get_execution_context(), ) @@ -116,7 +114,7 @@ fn document_from_transition_replace( // TODO cloning is costly. Probably the [`Document`] should have properties of type `Cow<'a, K>` Ok(ExtendedDocument { protocol_version: state_transition.protocol_version, - document_type_name: document_replace_transition.base.document_type.clone(), + document_type_name: document_replace_transition.base.document_type_name.clone(), data_contract_id: document_replace_transition.base.data_contract_id, metadata: None, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index de3c35f1618..5c8f1ea7696 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -94,7 +94,7 @@ pub struct DocumentBaseTransition { pub id: Identifier, /// Name of document type found int the data contract associated with the `data_contract_id` #[serde(rename = "$type")] - pub document_type: String, + pub document_type_name: String, /// Action the platform should take for the associated document #[serde(rename = "$action")] pub action: Action, @@ -116,7 +116,7 @@ impl DocumentBaseTransition { map.remove_hash256_bytes(property_names::ID) .map_err(ProtocolError::ValueError)?, ), - document_type: map + document_type_name: map .remove_string(property_names::DOCUMENT_TYPE) .map_err(ProtocolError::ValueError)?, action: map @@ -160,7 +160,7 @@ impl DocumentTransitionObjectLike for DocumentBaseTransition { map.get_hash256_bytes(property_names::ID) .map_err(ProtocolError::ValueError)?, ), - document_type: map + document_type_name: map .get_string(property_names::DOCUMENT_TYPE) .map_err(ProtocolError::ValueError)?, action: map @@ -192,7 +192,7 @@ impl DocumentTransitionObjectLike for DocumentBaseTransition { ); btree_map.insert( property_names::DOCUMENT_TYPE.to_string(), - Value::Text(self.document_type.clone()), + Value::Text(self.document_type_name.clone()), ); Ok(btree_map) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index c12f98ad9ea..13a5198a0e7 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -7,10 +7,11 @@ use std::collections::BTreeMap; use std::convert::TryInto; use std::string::ToString; -use crate::document::Document; +use crate::document::{Document, ExtendedDocument}; use crate::identity::TimestampMillis; use crate::prelude::Revision; +use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::{ data_contract::DataContract, errors::ProtocolError, util::json_value::JsonValueExt, util::json_value::ReplaceWith, @@ -75,6 +76,21 @@ impl DocumentCreateTransition { }) } + pub(crate) fn to_extended_document( + &self, + owner_id: [u8; 32], + ) -> Result { + Ok(ExtendedDocument { + protocol_version: PROTOCOL_VERSION, + document_type_name: self.base.document_type_name.clone(), + data_contract_id: self.base.data_contract_id, + document: self.to_document(owner_id)?, + data_contract: self.base.data_contract.clone(), + metadata: None, + entropy: self.entropy, + }) + } + pub(crate) fn into_document(self, owner_id: [u8; 32]) -> Result { let id = self.base.id.to_buffer(); let revision = self.get_revision(); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs index 5d41c4bb06e..ff9ef6274cc 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs @@ -86,7 +86,7 @@ mod test { serde_json::from_str(transition_json).expect("no error"); assert_eq!(cdt.base.action, Action::Delete); - assert_eq!(cdt.base.document_type, "note"); + assert_eq!(cdt.base.document_type_name, "note"); let mut json_no_whitespace = transition_json.to_string(); json_no_whitespace.retain(|v| !v.is_whitespace()); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 91d9637053a..c5156191cb3 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; +use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::document::Document; use crate::identity::TimestampMillis; use crate::prelude::{ExtendedDocument, Revision}; @@ -59,6 +60,20 @@ impl DocumentReplaceTransition { }) } + pub(crate) fn to_extended_document_for_dry_run( + &self, + ) -> Result { + Ok(ExtendedDocument { + protocol_version: PROTOCOL_VERSION, + document_type_name: self.base.document_type_name.clone(), + data_contract_id: self.base.data_contract_id, + document: self.to_document_for_dry_run()?, + data_contract: self.base.data_contract.clone(), + metadata: None, + entropy: [0; 32], + }) + } + pub(crate) fn replace_document(&self, document: &mut Document) -> Result<(), ProtocolError> { let properties = self .data @@ -206,7 +221,7 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { let (identifier_paths, binary_paths) = self .base .data_contract - .get_identifiers_and_binary_paths(&self.base.document_type)?; + .get_identifiers_and_binary_paths(&self.base.document_type_name)?; value.replace_binary_paths(identifier_paths, ReplaceWith::Base58)?; value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; @@ -241,7 +256,7 @@ mod test { serde_json::from_str(transition_json).expect("no error"); assert_eq!(cdt.base.action, Action::Replace); - assert_eq!(cdt.base.document_type, "note"); + assert_eq!(cdt.base.document_type_name, "note"); assert_eq!(cdt.revision, 1); assert_eq!( cdt.data.as_ref().unwrap().get_str("message").unwrap(), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index 28e40e43a3e..2d40d68566f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -212,7 +212,7 @@ impl DocumentTransitionExt for DocumentTransition { } fn get_document_type(&self) -> &String { - &self.base().document_type + &self.base().document_type_name } fn get_action(&self) -> Action { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index b457c8125cc..7871e083eb7 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -265,7 +265,7 @@ impl StateTransitionIdentitySigned for DocumentsBatchTransition { let mut highest_security_level = SecurityLevel::lowest_level(); for transition in self.transitions.iter() { - let document_type = &transition.base().document_type; + let document_type = &transition.base().document_type_name; let data_contract = &transition.base().data_contract; let maybe_document_schema = data_contract.get_document_schema(document_type); @@ -421,7 +421,9 @@ impl StateTransitionConvert for DocumentsBatchTransition { let (identifier_properties, binary_properties) = transition .base() .data_contract - .get_identifiers_and_binary_paths(&self.transitions[i].base().document_type)?; + .get_identifiers_and_binary_paths( + &self.transitions[i].base().document_type_name, + )?; if transition.get_updated_at().is_none() { cbor_transition.remove("$updatedAt"); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs index a81007958ce..2ba1be6efd0 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -50,17 +50,17 @@ mod test { fn test_duplicates() { let mut dt_create = DocumentCreateTransition::default(); dt_create.base.id = generate_random_identifier_struct(); - dt_create.base.document_type = String::from("a"); + dt_create.base.document_type_name = String::from("a"); let dt_create_duplicate = dt_create.clone(); let mut dt_replace = DocumentReplaceTransition::default(); dt_replace.base.id = generate_random_identifier_struct(); - dt_replace.base.document_type = String::from("b"); + dt_replace.base.document_type_name = String::from("b"); let mut dt_delete = DocumentDeleteTransition::default(); dt_delete.base.id = generate_random_identifier_struct(); - dt_delete.base.document_type = String::from("c"); + dt_delete.base.document_type_name = String::from("c"); let create_json = dt_create.to_json().unwrap(); let dt_create_duplicate_json = dt_create_duplicate.to_json().unwrap(); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/execute_data_triggers.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/execute_data_triggers.rs index 61933307e0f..c1a6107dc74 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/execute_data_triggers.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/execute_data_triggers.rs @@ -20,7 +20,7 @@ where for dt in document_transitions { let document_transition = dt.as_ref(); - let document_type = &document_transition.base().document_type; + let document_type = &document_transition.base().document_type_name; let transition_action = document_transition.base().action; let data_triggers_for_transition = diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs index 79dbf1d6d06..b9905f4a106 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs @@ -26,7 +26,7 @@ pub async fn fetch_extended_documents( for dt in collected_transitions.iter() { let document_transition = dt.as_ref(); - let document_type = get_from_transition!(document_transition, document_type); + let document_type = get_from_transition!(document_transition, document_type_name); let data_contract_id = get_from_transition!(document_transition, data_contract_id); let unique_key = format!("{}{}", data_contract_id, document_type); @@ -52,7 +52,7 @@ pub async fn fetch_extended_documents( let future = state_repository.fetch_extended_documents( get_from_transition!(dts[0], data_contract_id), - get_from_transition!(dts[0], document_type), + get_from_transition!(dts[0], document_type_name), options, execution_context, ); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs index 86aa4bc0a2b..dc1f835903e 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs @@ -41,7 +41,7 @@ where for t in document_transitions { let transition = t.as_ref(); let document_schema = - data_contract.get_document_schema(&transition.base().document_type)?; + data_contract.get_document_schema(&transition.base().document_type_name)?; let document_indices = document_schema.get_indices::>()?; if document_indices.is_empty() { continue; @@ -89,7 +89,7 @@ fn generate_document_index_queries<'a>( .map(move |index| { let where_query = build_query_for_index_definition(index, transition, owner_id); QueryDefinition { - document_type: &transition.base().document_type, + document_type: &transition.base().document_type_name, index_definition: index, document_transition: transition, where_query, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs index 284f5e9a6d8..9e4ed613390 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs @@ -8,6 +8,8 @@ use platform_value::Value; use serde_json::json; use crate::contracts::withdrawals_contract::property_names; +use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; +use crate::document::ExtendedDocument; use crate::{ contracts::withdrawals_contract, data_contract::DataContract, document::generate_document_id, document::Document, identity::state_transition::identity_credit_withdrawal_transition::Pooling, @@ -49,7 +51,7 @@ where .transpose() .map_err(Into::into)?; - let _withdrawals_data_contract = maybe_withdrawals_data_contract + let withdrawals_data_contract = maybe_withdrawals_data_contract .ok_or_else(|| anyhow!("Withdrawals data contract not found"))?; let latest_platform_block_header_bytes: Vec = self @@ -126,9 +128,19 @@ where properties: document_properties, }; + let extended_withdrawal_document = ExtendedDocument { + protocol_version: PROTOCOL_VERSION, + document_type_name: document_type, + data_contract_id: withdrawals_data_contract.id, + document: withdrawal_document, + data_contract: withdrawals_data_contract, + metadata: None, + entropy: [0; 32], + }; + self.state_repository .create_document( - &withdrawal_document, + &extended_withdrawal_document, state_transition.get_execution_context(), ) .await?; diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index cf12a65e564..f69dd8c2f95 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -89,7 +89,7 @@ pub trait StateRepositoryLike: Sync { /// Update Document async fn update_document( &self, - document: &Document, + document: &ExtendedDocument, execution_context: &StateTransitionExecutionContext, ) -> AnyResult<()>; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs index ea78f642c56..752fd4a9cc1 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs @@ -7,6 +7,7 @@ mod apply_identity_credit_withdrawal_transition_factory { use crate::contracts::withdrawals_contract::property_names::{ AMOUNT, CORE_FEE_PER_BYTE, OUTPUT_SCRIPT, POOLING, STATUS, }; + use crate::document::ExtendedDocument; use crate::{ contracts::withdrawals_contract, document::Document, @@ -87,9 +88,12 @@ mod apply_identity_credit_withdrawal_transition_factory { state_repository .expect_create_document() .times(1) - .withf(move |doc: &Document, _| { - let created_at_match = doc.created_at == Some(block_time_seconds as u64 * 1000); - let updated_at_match = doc.updated_at == Some(block_time_seconds as u64 * 1000); + .withf(move |extended_document: &ExtendedDocument, _| { + let document = &extended_document.document; + let created_at_match = + document.created_at == Some(block_time_seconds as u64 * 1000); + let updated_at_match = + document.updated_at == Some(block_time_seconds as u64 * 1000); let document_expected_properties = BTreeMap::from([ (AMOUNT.to_string(), Value::U64(10)), @@ -102,7 +106,7 @@ mod apply_identity_credit_withdrawal_transition_factory { ), ]); - let document_data_match = doc.properties == document_expected_properties; + let document_data_match = document.properties == document_expected_properties; created_at_match && updated_at_match && document_data_match }) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index d410371b8a4..1362775bd6d 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -103,7 +103,7 @@ impl DocumentCreateTransitionWasm { #[wasm_bindgen(js_name=getType)] pub fn document_type(&self) -> String { - self.inner.base.document_type.clone() + self.inner.base.document_type_name.clone() } #[wasm_bindgen(js_name=getAction)] @@ -174,7 +174,7 @@ impl DocumentCreateTransitionWasm { .inner .base .data_contract - .get_identifiers_and_binary_paths(&self.inner.base.document_type) + .get_identifiers_and_binary_paths(&self.inner.base.document_type_name) .with_js_error()?; for property_path in identifier_paths { @@ -218,7 +218,7 @@ impl DocumentCreateTransitionWasm { .inner .base .data_contract - .get_identifiers_and_binary_paths(&self.inner.base.document_type) + .get_identifiers_and_binary_paths(&self.inner.base.document_type_name) .with_js_error()?; to_object( @@ -263,7 +263,7 @@ impl DocumentCreateTransitionWasm { .inner .base .data_contract - .get_binary_properties(&self.inner.base.document_type); + .get_binary_properties(&self.inner.base.document_type_name); if let Ok(binary_properties) = maybe_binary_properties { if let Some(data) = binary_properties.get(path) { diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs index 4e29770e0af..f442bf1723b 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs @@ -60,7 +60,7 @@ impl DocumentDeleteTransitionWasm { #[wasm_bindgen(js_name=getType)] pub fn document_type(&self) -> String { - self.inner.base.document_type.clone() + self.inner.base.document_type_name.clone() } #[wasm_bindgen(js_name=getDataContract)] diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 66de343cfda..8ecf6b38453 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -94,7 +94,7 @@ impl DocumentReplaceTransitionWasm { .inner .base .data_contract - .get_identifiers_and_binary_paths(&self.inner.base.document_type) + .get_identifiers_and_binary_paths(&self.inner.base.document_type_name) .with_js_error()?; to_object( @@ -129,7 +129,7 @@ impl DocumentReplaceTransitionWasm { .inner .base .data_contract - .get_identifiers_and_binary_paths(&self.inner.base.document_type) + .get_identifiers_and_binary_paths(&self.inner.base.document_type_name) .with_js_error()?; for path in identifier_paths { @@ -162,7 +162,7 @@ impl DocumentReplaceTransitionWasm { #[wasm_bindgen(js_name=getType)] pub fn document_type(&self) -> String { - self.inner.base.document_type.clone() + self.inner.base.document_type_name.clone() } #[wasm_bindgen(js_name=getDataContract)] @@ -234,7 +234,7 @@ impl DocumentReplaceTransitionWasm { .inner .base .data_contract - .get_identifiers_and_binary_paths(&self.inner.base.document_type) + .get_identifiers_and_binary_paths(&self.inner.base.document_type_name) .with_js_error()?; for property_path in identifier_paths { @@ -279,7 +279,7 @@ impl DocumentReplaceTransitionWasm { .inner .base .data_contract - .get_binary_properties(&self.inner.base.document_type); + .get_binary_properties(&self.inner.base.document_type_name); if let Ok(binary_properties) = maybe_binary_properties { if let Some(data) = binary_properties.get(path) { diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 58fd56577d8..155653c18ec 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -23,7 +23,7 @@ use js_sys::{Array, Number}; use wasm_bindgen::__rt::Ref; -use dpp::document::Document; +use dpp::document::{Document, ExtendedDocument}; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; @@ -56,14 +56,14 @@ extern "C" { #[wasm_bindgen(catch, structural, method, js_name=createDocument)] pub async fn create_document( this: &ExternalStateRepositoryLike, - document: DocumentWasm, + document: ExtendedDocumentWasm, execution_context: StateTransitionExecutionContextWasm, ) -> Result<(), JsValue>; #[wasm_bindgen(catch, structural, method, js_name=updateDocument)] pub async fn update_document( this: &ExternalStateRepositoryLike, - document: DocumentWasm, + document: ExtendedDocumentWasm, execution_context: StateTransitionExecutionContextWasm, ) -> Result<(), JsValue>; @@ -379,24 +379,24 @@ impl StateRepositoryLike for ExternalStateRepositoryLikeWrapper { async fn create_document( &self, - document: &Document, + extended_document: &ExtendedDocument, execution_context: &StateTransitionExecutionContext, ) -> anyhow::Result<()> { - let document_wasm: DocumentWasm = document.to_owned().into(); + let extended_document_wasm: ExtendedDocumentWasm = extended_document.to_owned().into(); self.0 - .create_document(document_wasm, execution_context.clone().into()) + .create_document(extended_document_wasm, execution_context.clone().into()) .await .map_err(from_js_error) } async fn update_document( &self, - document: &Document, + extended_document: &ExtendedDocument, execution_context: &StateTransitionExecutionContext, ) -> anyhow::Result<()> { - let document_wasm: DocumentWasm = document.to_owned().into(); + let extended_document_wasm: ExtendedDocumentWasm = extended_document.to_owned().into(); self.0 - .update_document(document_wasm, execution_context.clone().into()) + .update_document(extended_document_wasm, execution_context.clone().into()) .await .map_err(from_js_error) } From cb9bf5b7bafc4e5afebcedc0cbe2c268d1eda6d6 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Mon, 6 Mar 2023 19:20:31 +0800 Subject: [PATCH 060/228] fix Document test --- packages/wasm-dpp/src/document/extended_document.rs | 5 ++--- .../wasm-dpp/test/integration/document/Document.spec.js | 9 +++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 7e9b9d503cc..87ca049489f 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -246,9 +246,8 @@ impl ExtendedDocumentWasm { } #[wasm_bindgen(js_name=setMetadata)] - pub fn set_metadata(mut self, metadata: MetadataWasm) -> Self { - self.0.metadata = Some(metadata.into()); - self + pub fn set_metadata(&mut self, metadata: &MetadataWasm) { + self.0.metadata = Some(metadata.clone().into()); } #[wasm_bindgen(js_name=toObject)] diff --git a/packages/wasm-dpp/test/integration/document/Document.spec.js b/packages/wasm-dpp/test/integration/document/Document.spec.js index fa9e767120e..415c36772d3 100644 --- a/packages/wasm-dpp/test/integration/document/Document.spec.js +++ b/packages/wasm-dpp/test/integration/document/Document.spec.js @@ -5,19 +5,19 @@ const getDocumentsFixture = require('@dashevo/dpp/lib/test/fixtures/getDocuments const { default: loadWasmDpp } = require('../../../dist'); -let Document; +let ExtendedDocument; let DataContract; let Metadata; let Identifier; -describe('Document', () => { +describe('ExtendedDocument', () => { let document; let dataContract; let metadataFixture; beforeEach(async () => { ({ - Document, + ExtendedDocument, DataContract, Metadata, Identifier, @@ -27,7 +27,7 @@ describe('Document', () => { dataContract = new DataContract(dataContractJs.toObject()); const [documentJs] = getDocumentsFixture(dataContractJs).slice(8); - document = new Document(documentJs.toObject(), dataContract); + document = new ExtendedDocument(documentJs.toObject(), dataContract); const metadataFixtureJs = new MetadataJs({ blockHeight: 42, @@ -49,6 +49,7 @@ describe('Document', () => { describe('#toJSON', () => { it('should return json document - Rust', () => { + console.log(document); const result = document.toJSON(); expect(result).to.deep.equal({ From d228b981619928d5489da3e7fd9460101e840541 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 18:21:05 +0700 Subject: [PATCH 061/228] another small fix --- .../document_replace_transition.rs | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index c5156191cb3..d0843524d44 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -1,8 +1,9 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::Value; +use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; +use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::document::Document; @@ -148,19 +149,27 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { mut json_value: JsonValue, data_contract: DataContract, ) -> Result { - let document_type = json_value.get_string("$type")?; + let value: Value = json_value.into(); + let mut map = value.into_btree_map().map_err(ProtocolError::ValueError)?; + + let document_type = map.get_str("$type")?; let (identifiers_paths, binary_paths) = - data_contract.get_identifiers_and_binary_paths(document_type)?; + data_contract.get_identifiers_and_binary_paths_owned(document_type)?; - // Only dynamic binary paths are replaced with Bytes (no static ones) - json_value.replace_binary_paths(binary_paths.into_iter(), ReplaceWith::Bytes)?; - // Only dynamic identifiers are replaced with Bytes - json_value.replace_identifier_paths(identifiers_paths, ReplaceWith::Bytes)?; - let mut document: DocumentReplaceTransition = serde_json::from_value(json_value)?; + map.replace_at_paths( + binary_paths + .into_iter(), + ReplacementType::Bytes, + )?; - document.base.action = Action::Replace; - document.base.data_contract = data_contract; + map.replace_at_paths( + identifiers_paths + .into_iter() + .chain(IDENTIFIER_FIELDS.iter().map(|a| a.to_string())), + ReplacementType::Identifier, + )?; + let document = Self::from_value_map(map, data_contract)?; Ok(document) } From 9a84d32dd3b210c71d18c08cda7a67bd38f1cb57 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 18:54:05 +0700 Subject: [PATCH 062/228] more fixes --- .../document_replace_transition.rs | 76 ++++--------------- .../validate_partial_compound_indices_spec.rs | 1 - .../document_batch_transition/mod.rs | 1 - 3 files changed, 14 insertions(+), 64 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index d0843524d44..c6711add88f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -1,9 +1,10 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; -use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use std::convert::TryInto; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::document::Document; @@ -42,15 +43,7 @@ pub struct DocumentReplaceTransition { impl DocumentReplaceTransition { pub(crate) fn to_document_for_dry_run(&self) -> Result { - let properties = self - .data - .as_ref() - .map(|json_value| { - let value: Value = json_value.clone().into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }) - .transpose()? - .unwrap_or_default(); + let properties = self.data.clone().unwrap_or_default(); Ok(Document { id: self.base.id.to_buffer(), owner_id: [0; 32], //0s are fine here @@ -76,15 +69,7 @@ impl DocumentReplaceTransition { } pub(crate) fn replace_document(&self, document: &mut Document) -> Result<(), ProtocolError> { - let properties = self - .data - .as_ref() - .map(|json_value| { - let value: Value = json_value.clone().into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }) - .transpose()? - .unwrap_or_default(); + let properties = self.data.clone().unwrap_or_default(); document.revision = Some(self.revision); document.updated_at = self.updated_at; document.properties = properties; @@ -95,15 +80,7 @@ impl DocumentReplaceTransition { &self, document: &mut ExtendedDocument, ) -> Result<(), ProtocolError> { - let properties = self - .data - .as_ref() - .map(|json_value| { - let value: Value = json_value.clone().into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }) - .transpose()? - .unwrap_or_default(); + let properties = self.data.clone().unwrap_or_default(); document.document.revision = Some(self.revision); document.document.updated_at = self.updated_at; document.document.properties = properties; @@ -111,14 +88,7 @@ impl DocumentReplaceTransition { } pub(crate) fn patch_document(self, document: &mut Document) -> Result<(), ProtocolError> { - let properties = self - .data - .map(|json_value| { - let value: Value = json_value.into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }) - .transpose()? - .unwrap_or_default(); + let properties = self.data.clone().unwrap_or_default(); document.revision = Some(self.revision); document.updated_at = self.updated_at; document.properties.extend(properties); @@ -129,14 +99,7 @@ impl DocumentReplaceTransition { self, document: &mut ExtendedDocument, ) -> Result<(), ProtocolError> { - let properties = self - .data - .map(|json_value| { - let value: Value = json_value.into(); - value.into_btree_map().map_err(ProtocolError::ValueError) - }) - .transpose()? - .unwrap_or_default(); + let properties = self.data.clone().unwrap_or_default(); document.document.revision = Some(self.revision); document.document.updated_at = self.updated_at; document.document.properties.extend(properties); @@ -157,11 +120,7 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { let (identifiers_paths, binary_paths) = data_contract.get_identifiers_and_binary_paths_owned(document_type)?; - map.replace_at_paths( - binary_paths - .into_iter(), - ReplacementType::Bytes, - )?; + map.replace_at_paths(binary_paths.into_iter(), ReplacementType::Bytes)?; map.replace_at_paths( identifiers_paths @@ -226,16 +185,9 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { } fn to_json(&self) -> Result { - let mut value = serde_json::to_value(self)?; - let (identifier_paths, binary_paths) = self - .base - .data_contract - .get_identifiers_and_binary_paths(&self.base.document_type_name)?; - - value.replace_binary_paths(identifier_paths, ReplaceWith::Base58)?; - value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - - Ok(value) + self.to_object()? + .try_into() + .map_err(ProtocolError::ValueError) } } @@ -253,11 +205,11 @@ mod test { fn test_deserialize_serialize_to_json() { init(); let transition_json = r#"{ + "$action": 1, + "$dataContractId": "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8", "$id": "6oCKUeLVgjr7VZCyn1LdGbrepqKLmoabaff5WQqyTKYP", - "$type": "note", - "$action": 1, - "$dataContractId": "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8", "$revision" : 1, + "$type": "note", "message": "example_message_replace" }"#; diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index e13dd4e4feb..99bb6b29d28 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -11,7 +11,6 @@ use crate::{ tests::fixtures::{ get_data_contract_fixture, get_document_transitions_fixture, }, - util::json_value::JsonValueExt, validation::ValidationResult, }; use crate::document::ExtendedDocument; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index d3de208d92b..41464719475 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -15,7 +15,6 @@ use dpp::{ use js_sys::{Array, Reflect}; use serde::{Deserialize, Serialize}; -use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::ReplacementType; use wasm_bindgen::prelude::*; From e529670630b1f4b7ef28fbdafba760929b9783b5 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 19:30:59 +0700 Subject: [PATCH 063/228] more fixes --- packages/rs-dpp/src/document/document.rs | 30 +++++++++++++++++++ .../rs-dpp/src/document/document_factory.rs | 11 ------- .../documents_batch_transition/mod.rs | 1 - .../src/identity_credit_withdrawal/mod.rs | 8 ++--- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index df2677685ed..c5860089891 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -205,6 +205,36 @@ impl Document { .insert(property_name.to_string(), Value::U8(value)); } + pub fn set_i8(&mut self, property_name: &str, value: i8) { + self.properties + .insert(property_name.to_string(), Value::I8(value)); + } + + pub fn set_u16(&mut self, property_name: &str, value: u16) { + self.properties + .insert(property_name.to_string(), Value::U16(value)); + } + + pub fn set_i16(&mut self, property_name: &str, value: i16) { + self.properties + .insert(property_name.to_string(), Value::I16(value)); + } + + pub fn set_u32(&mut self, property_name: &str, value: u32) { + self.properties + .insert(property_name.to_string(), Value::U32(value)); + } + + pub fn set_i32(&mut self, property_name: &str, value: i32) { + self.properties + .insert(property_name.to_string(), Value::I32(value)); + } + + pub fn set_u64(&mut self, property_name: &str, value: u64) { + self.properties + .insert(property_name.to_string(), Value::U64(value)); + } + pub fn set_i64(&mut self, property_name: &str, value: i64) { self.properties .insert(property_name.to_string(), Value::I64(value)); diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 9e6c0b22eab..e4bb53f127d 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -389,17 +389,6 @@ where let new_revision = document_revision + 1; map.insert(PROPERTY_REVISION.to_string(), Value::U64(new_revision)); - // If document have an originally set `updatedAt` - // we should update it then - if let Some(updated_at) = map.get_mut(PROPERTY_UPDATED_AT) { - *updated_at = Value::U64(Utc::now().timestamp_millis() as TimestampMillis); - } else { - map.insert( - PROPERTY_UPDATED_AT.to_string(), - Value::U64(Utc::now().timestamp_millis() as TimestampMillis), - ); - } - raw_transitions.push(map.into()); } Ok(raw_transitions) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 7871e083eb7..85d4be63d53 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -197,7 +197,6 @@ impl DocumentsBatchTransition { let mut raw_transition_map = raw_transition .into_btree_map() .map_err(ProtocolError::ValueError)?; - dbg!(&raw_transition_map); let data_contract_id = raw_transition_map.get_hash256_bytes(property_names::DATA_CONTRACT_ID)?; let document_type = raw_transition_map.get_str(property_names::DOCUMENT_TYPE)?; diff --git a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs index 62fa9fd7e18..3ae4293d544 100644 --- a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs @@ -126,13 +126,9 @@ impl Platform { document.set_u8(withdrawals_contract::property_names::STATUS, status.into()); - document.set_i64( + document.set_u64( withdrawals_contract::property_names::UPDATED_AT, - block_info.time_ms.try_into().map_err(|_| { - Error::Execution(ExecutionError::CorruptedCodeExecution( - "Can't convert u64 block time to i64 updated_at", - )) - })?, + block_info.time_ms, ); document.increment_revision().map_err(Error::Protocol)?; From f2ec4840a1ac4451a33ed07b514b9ef9a32d8c40 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 19:43:39 +0700 Subject: [PATCH 064/228] remove some debugs --- .../basic/validate_documents_batch_transition_basic.rs | 1 - .../validate_documents_batch_transitions_basic_spec.rs | 1 - packages/rs-drive-abci/src/platform.rs | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 68a405eea29..81cc92ae236 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -90,7 +90,6 @@ pub async fn validate_documents_batch_transition_basic( HashMap::new(); for raw_document_transition in raw_document_transitions { - dbg!(raw_document_transition); let data_contract_id_bytes = match raw_document_transition.get_bytes("$dataContractId") { Err(_) => { result.add_error(BasicError::MissingDataContractIdError); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 0b3c6ffb8a9..7bebc36f25d 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -959,6 +959,5 @@ async fn should_not_validate_document_transitions_on_dry_run() { ) .await .expect("validation result should be returned"); - dbg!(&result); assert!(result.is_valid()); } diff --git a/packages/rs-drive-abci/src/platform.rs b/packages/rs-drive-abci/src/platform.rs index da4a29fea67..b0bbac3e4ef 100644 --- a/packages/rs-drive-abci/src/platform.rs +++ b/packages/rs-drive-abci/src/platform.rs @@ -84,7 +84,6 @@ impl Platform { config.core.rpc.password.clone(), ) .map_err(|e| { - dbg!(e); Error::Execution(ExecutionError::CorruptedCodeExecution( "Could not setup Dash Core RPC client", )) From 2035b24ebdc0e1dc2b288ac3456796f8d5966508 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Mon, 6 Mar 2023 20:46:01 +0800 Subject: [PATCH 065/228] fix Document test --- ...alidate_documents_uniqueness_by_indices.rs | 1 + ...ocumentsUniquenessByIndicesFactory.spec.js | 42 +++++++++---------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs index dc1f835903e..ae055f4ac2d 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs @@ -63,6 +63,7 @@ where (query.index_definition, query.document_transition), ) }); + let (futures, futures_meta) = unzip_iter_and_collect(queries); let results = join_all(futures).await; diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js index 9558f749f23..86b0e40585f 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js @@ -9,7 +9,7 @@ const { expectValidationError } = require('../../../../../../../lib/test/expect/ const { default: loadWasmDpp } = require('../../../../../../../dist'); let DataContract; -let ExtendedDocument; +let Document; let ValidationResult; let DuplicateUniqueIndexError; let validateDocumentsUniquenessByIndices; @@ -32,7 +32,7 @@ describe('validateDocumentsUniquenessByIndices', () => { beforeEach(async function beforeEach() { ({ - ExtendedDocument, + Document, DataContract, Identifier, DocumentCreateTransition, @@ -64,10 +64,10 @@ describe('validateDocumentsUniquenessByIndices', () => { ); stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); - stateRepositoryMock.fetchExtendedDocuments.resolves([]); + stateRepositoryMock.fetchDocuments.resolves([]); stateRepositoryMockJs = createStateRepositoryMock(this.sinonSandbox); - stateRepositoryMockJs.fetchExtendedDocuments.resolves([]); + stateRepositoryMockJs.fetchDocuments.resolves([]); executionContext = new StateTransitionExecutionContext(); }); @@ -94,17 +94,17 @@ describe('validateDocumentsUniquenessByIndices', () => { expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); - expect(stateRepositoryMock.fetchExtendedDocuments).to.have.not.been.called(); + expect(stateRepositoryMock.fetchDocuments).to.have.not.been.called(); }); it('should return valid result if Document has unique indices and there are no duplicates - Rust', async () => { const [, , , william] = documentsJs; - const williamDocument = new ExtendedDocument(william.toObject(), dataContract); + const williamDocument = new Document(william.toObject(), dataContract, william.getType()); - stateRepositoryMock.fetchExtendedDocuments + stateRepositoryMock.fetchDocuments .withArgs( dataContract.getId().toBuffer(), - williamDocument.getType(), + william.getType(), { where: [ ['$ownerId', '==', ownerIdJs], @@ -114,7 +114,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([williamDocument]); - stateRepositoryMock.fetchExtendedDocuments + stateRepositoryMock.fetchDocuments .withArgs( dataContractJs.getId().toBuffer(), william.getType(), @@ -142,12 +142,12 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return invalid result if Document has unique indices and there are duplicates - Rust', async () => { let [, , , william, leon] = documentsJs; - william = new ExtendedDocument(william.toObject(), dataContract.clone()); - leon = new ExtendedDocument(leon.toObject(), dataContract.clone()); + william = new Document(william.toObject(), dataContract.clone()); + leon = new Document(leon.toObject(), dataContract.clone()); const indicesDefinition = dataContractJs.getDocumentSchema(william.getType()).indices; - stateRepositoryMock.fetchExtendedDocuments + stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), william.getType(), @@ -160,7 +160,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([leon]); - stateRepositoryMock.fetchExtendedDocuments + stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), william.getType(), @@ -173,7 +173,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([leon]); - stateRepositoryMock.fetchExtendedDocuments + stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), leon.getType(), @@ -186,7 +186,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([william]); - stateRepositoryMock.fetchExtendedDocuments + stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), leon.getType(), @@ -229,7 +229,7 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return valid result if Document has undefined field from index - Rust', async () => { const indexedDocumentJs = documentsJs[7]; - const indexedDocument = new ExtendedDocument(indexedDocumentJs.toObject(), dataContract.clone()); + const indexedDocument = new Document(indexedDocumentJs.toObject(), dataContract.clone()); const indexedDocumentTransitions = getDocumentTransitionsFixture({ create: [indexedDocumentJs], }).map( @@ -238,7 +238,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ), ); - stateRepositoryMockJs.fetchExtendedDocuments + stateRepositoryMockJs.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), indexedDocument.getType(), @@ -251,7 +251,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ) .resolves([indexedDocument]); - stateRepositoryMockJs.fetchExtendedDocuments + stateRepositoryMockJs.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), indexedDocument.getType(), @@ -277,7 +277,7 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return valid result if Document being created and has createdAt and updatedAt indices - Rust', async () => { const [, , , , , , uniqueDatesDocumentJs] = documentsJs; - const uniqueDatesDocument = new ExtendedDocument( + const uniqueDatesDocument = new Document( uniqueDatesDocumentJs.toObject(), dataContract.clone(), ); const uniqueDatesDocumentTransitions = getDocumentTransitionsFixture({ @@ -288,7 +288,7 @@ describe('validateDocumentsUniquenessByIndices', () => { ), ); - stateRepositoryMock.fetchExtendedDocuments + stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), uniqueDatesDocumentJs.getType(), @@ -335,6 +335,6 @@ describe('validateDocumentsUniquenessByIndices', () => { expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); - expect(stateRepositoryMock.fetchExtendedDocuments).to.have.not.been.called(); + expect(stateRepositoryMock.fetchDocuments).to.have.not.been.called(); }); }); From b206bb3d6873f30855c7e877ea7667821aa71b7f Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Mon, 6 Mar 2023 20:46:38 +0800 Subject: [PATCH 066/228] fix linting issue --- .../state/validateDocumentsUniquenessByIndicesFactory.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js index 86b0e40585f..018089410b0 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js @@ -104,7 +104,7 @@ describe('validateDocumentsUniquenessByIndices', () => { stateRepositoryMock.fetchDocuments .withArgs( dataContract.getId().toBuffer(), - william.getType(), + william.getType(), { where: [ ['$ownerId', '==', ownerIdJs], From b941aa6d19aee6838d8b3eb037878a8b53f90853 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Mon, 6 Mar 2023 20:55:39 +0800 Subject: [PATCH 067/228] fix some document uniqueness validation tests --- packages/wasm-dpp/src/document/mod.rs | 4 ++-- ...ocumentsUniquenessByIndicesFactory.spec.js | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 38ce8cf7981..7d62c0e20e7 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -152,7 +152,7 @@ impl DocumentWasm { pub fn get( &mut self, path: String, - data_contract: DataContractWasm, + data_contract: &DataContractWasm, document_type_name: String, ) -> Result { let binary_type = self.get_binary_type_of_path(&path, data_contract, document_type_name); @@ -303,7 +303,7 @@ impl DocumentWasm { fn get_binary_type_of_path( &self, path: &String, - data_contract: DataContractWasm, + data_contract: &DataContractWasm, document_type_name: String, ) -> BinaryType { let maybe_binary_properties = data_contract diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js index 018089410b0..b1682cd5e0b 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js @@ -142,15 +142,18 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return invalid result if Document has unique indices and there are duplicates - Rust', async () => { let [, , , william, leon] = documentsJs; - william = new Document(william.toObject(), dataContract.clone()); - leon = new Document(leon.toObject(), dataContract.clone()); + const williamType = william.getType(); + const leonType = leon.getType(); - const indicesDefinition = dataContractJs.getDocumentSchema(william.getType()).indices; + william = new Document(william.toObject(), dataContract.clone(), williamType); + leon = new Document(leon.toObject(), dataContract.clone(), leonType); + + const indicesDefinition = dataContractJs.getDocumentSchema(williamType).indices; stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), - william.getType(), + williamType, { where: [ ['$ownerId', '==', ownerId.toJSON()], @@ -163,7 +166,7 @@ describe('validateDocumentsUniquenessByIndices', () => { stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), - william.getType(), + williamType, { where: [ ['$ownerId', '==', ownerId.toJSON()], @@ -176,7 +179,7 @@ describe('validateDocumentsUniquenessByIndices', () => { stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), - leon.getType(), + leonType, { where: [ ['$ownerId', '==', ownerId.toJSON()], @@ -229,7 +232,7 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return valid result if Document has undefined field from index - Rust', async () => { const indexedDocumentJs = documentsJs[7]; - const indexedDocument = new Document(indexedDocumentJs.toObject(), dataContract.clone()); + const indexedDocument = new Document(indexedDocumentJs.toObject(), dataContract.clone(), indexedDocumentJs.getType()); const indexedDocumentTransitions = getDocumentTransitionsFixture({ create: [indexedDocumentJs], }).map( @@ -241,7 +244,7 @@ describe('validateDocumentsUniquenessByIndices', () => { stateRepositoryMockJs.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), - indexedDocument.getType(), + indexedDocumentJs.getType(), { where: [ ['$ownerId', '==', ownerId.toJSON()], @@ -254,7 +257,7 @@ describe('validateDocumentsUniquenessByIndices', () => { stateRepositoryMockJs.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), - indexedDocument.getType(), + indexedDocumentJs.getType(), { where: [ ['$ownerId', '==', ownerId.toJSON()], @@ -278,7 +281,7 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return valid result if Document being created and has createdAt and updatedAt indices - Rust', async () => { const [, , , , , , uniqueDatesDocumentJs] = documentsJs; const uniqueDatesDocument = new Document( - uniqueDatesDocumentJs.toObject(), dataContract.clone(), + uniqueDatesDocumentJs.toObject(), dataContract.clone(), uniqueDatesDocumentJs.getType(), ); const uniqueDatesDocumentTransitions = getDocumentTransitionsFixture({ create: [uniqueDatesDocumentJs], From e16e77a3e590daaeed4f44838ac4592b8bf0bd87 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 20:03:45 +0700 Subject: [PATCH 068/228] removed contract and document type from document getter --- packages/wasm-dpp/src/document/mod.rs | 37 ++++++++++----------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 38ce8cf7981..933c6241e0c 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -149,32 +149,23 @@ impl DocumentWasm { } #[wasm_bindgen(js_name=get)] - pub fn get( - &mut self, - path: String, - data_contract: DataContractWasm, - document_type_name: String, - ) -> Result { - let binary_type = self.get_binary_type_of_path(&path, data_contract, document_type_name); - + pub fn get(&mut self, path: String) -> Result { if let Some(value) = self.0.get(&path) { - let json_value_result: Result = - value.clone().try_into().map_err(ProtocolError::ValueError); - let json_value = json_value_result.with_js_error()?; - match binary_type { - BinaryType::Identifier => { - if let Ok(bytes) = serde_json::from_value::>(json_value) { - let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); - - return Ok(id.into()); - } + match value { + Value::Bytes(bytes) => { + return Ok(Buffer::from_bytes(bytes.as_slice()).into()); } - BinaryType::Buffer => { - if let Ok(bytes) = serde_json::from_value::>(json_value) { - return Ok(Buffer::from_bytes(&bytes).into()); - } + Value::Bytes32(bytes) => { + return Ok(Buffer::from_bytes(bytes.as_slice()).into()); + } + Value::Identifier(identifier) => { + let id: IdentifierWrapper = Identifier::from(*identifier).into(); + return Ok(id.into()); } - BinaryType::None => { + _ => { + let json_value_result: Result = + value.clone().try_into().map_err(ProtocolError::ValueError); + let json_value = json_value_result.with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); if let Ok(js_value) = json_value.serialize(&serializer) { return Ok(js_value); From ed6015cd937a4787ebf3dc103077fb6441373ff4 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Mon, 6 Mar 2023 21:08:15 +0800 Subject: [PATCH 069/228] fix the other test --- .../state/validateDocumentsUniquenessByIndicesFactory.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js index b1682cd5e0b..e4a29c68029 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js @@ -192,7 +192,7 @@ describe('validateDocumentsUniquenessByIndices', () => { stateRepositoryMock.fetchDocuments .withArgs( sinon.match.instanceOf(Identifier), - leon.getType(), + leonType, { where: [ ['$ownerId', '==', ownerId.toJSON()], From bd24f1e45e638f841190dedc121adfe1bcfbbc4d Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 20:10:18 +0700 Subject: [PATCH 070/228] more fixes --- packages/rs-dpp/src/document/document.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index c5860089891..2394e9a3e77 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -42,6 +42,7 @@ use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; @@ -197,7 +198,8 @@ impl Document { /// Retrieves field specified by path pub fn get(&self, path: &str) -> Option<&Value> { - self.properties.get(path) + // this can only error if path is empty, to which we just return None + self.properties.get_optional_at_path(path).ok().flatten() } pub fn set_u8(&mut self, property_name: &str, value: u8) { From 4dce677307684ebe3ebdb1d57d79598066500c67 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 20:34:17 +0700 Subject: [PATCH 071/228] fix --- .../validation/basic/find_duplicates_by_id.rs | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs index c35725f0a90..9be3a0ae3fc 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -1,8 +1,12 @@ use dpp::document::document_transition::{document_base_transition, document_create_transition}; use dpp::document::validation::basic::find_duplicates_by_id::find_duplicates_by_id; +use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use dpp::platform_value::{ReplacementType, Value}; +use dpp::ProtocolError; use itertools::Itertools; use js_sys::Array; -use serde_json::Value; +use serde_json::Value as JsonValue; +use std::convert::TryInto; use wasm_bindgen::prelude::*; use crate::document_batch_transition::document_transition::to_object; @@ -10,18 +14,21 @@ use crate::utils::{replace_identifiers_with_bytes_without_failing, ToSerdeJSONEx #[wasm_bindgen(js_name=findDuplicatesById)] pub fn find_duplicates_by_id_wasm(js_raw_transitions: Array) -> Result, JsValue> { - let raw_transitions: Vec = js_raw_transitions + let raw_transitions: Vec = js_raw_transitions .iter() - .map(|t| { - t.with_serde_to_json_value().map(|mut v| { - replace_identifiers_with_bytes_without_failing( - &mut v, - document_base_transition::IDENTIFIER_FIELDS, - ); - v - }) + .map(|transition| { + let mut map = transition.with_serde_to_platform_value_map()?; + map.replace_at_paths( + document_base_transition::IDENTIFIER_FIELDS.map(|a| a.to_string()), + ReplacementType::Identifier, + ); + let value: Value = map.into(); + value + .try_into() + .map_err(ProtocolError::ValueError) + .with_js_error() }) - .try_collect()?; + .collect::, JsValue>>()?; let result: Vec = find_duplicates_by_id(&raw_transitions) .with_js_error()? From ffbdc1c4b42d62d767e155ad9dac66e6ca31abc8 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Mar 2023 20:40:40 +0700 Subject: [PATCH 072/228] trial --- .../validation/basic/find_duplicates_by_id.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs index 9be3a0ae3fc..2a2d90578d5 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -24,7 +24,7 @@ pub fn find_duplicates_by_id_wasm(js_raw_transitions: Array) -> Result Date: Mon, 6 Mar 2023 22:46:26 +0700 Subject: [PATCH 073/228] more fixes --- .../document_type/document_type.rs | 33 ++++--- packages/rs-dpp/src/document/document.rs | 2 +- .../validation/basic/find_duplicates_by_id.rs | 52 ++++++---- .../basic/find_duplicates_by_indices.rs | 32 ++++--- ...lidate_documents_batch_transition_basic.rs | 51 ++++++---- .../validate_partial_compound_indices.rs | 47 +++++---- .../consensus/basic/abstract_basic_error.rs | 4 +- .../validate_partial_compound_indices_spec.rs | 13 +-- packages/rs-drive/tests/query_tests.rs | 2 +- packages/rs-platform-value/src/inner_value.rs | 95 ++++++++++++++++--- packages/rs-platform-value/src/lib.rs | 24 +++++ .../validation/basic/find_duplicates_by_id.rs | 19 ++-- .../basic/find_duplicates_by_indices.rs | 19 ++-- .../validate_partial_compound_indices.rs | 20 ++-- ...ate_document_transitions_with_ids_error.rs | 6 +- ...document_transitions_with_indices_error.rs | 6 +- 16 files changed, 276 insertions(+), 149 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index d9e0e00bb05..1640d77d38c 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -183,16 +183,18 @@ impl DocumentType { // Do documents of this type keep history? (Overrides contract value) let documents_keep_history: bool = - Value::inner_bool_value(document_type_value_map, "documentsKeepHistory") + Value::inner_optional_bool_value(document_type_value_map, "documentsKeepHistory") .unwrap_or(default_keeps_history); // Are documents of this type mutable? (Overrides contract value) let documents_mutable: bool = - Value::inner_bool_value(document_type_value_map, "documentsMutable") + Value::inner_optional_bool_value(document_type_value_map, "documentsMutable") .unwrap_or(default_mutability); - let index_values = - Value::inner_array_slice_value(document_type_value_map, property_names::INDICES)?; + let index_values = Value::inner_optional_array_slice_value( + document_type_value_map, + property_names::INDICES, + )?; let indices: Vec = index_values .map(|index_values| { index_values @@ -215,17 +217,18 @@ impl DocumentType { // Extract the properties let property_values = - Value::inner_btree_map(document_type_value_map, property_names::PROPERTIES)?.ok_or( - { - ProtocolError::DataContractError(DataContractError::InvalidContractStructure( - "unable to get document properties from the contract", - )) - }, - )?; - - let mut required_fields = - Value::inner_array_of_strings(document_type_value_map, property_names::REQUIRED) - .unwrap_or_default(); + Value::inner_optional_btree_map(document_type_value_map, property_names::PROPERTIES)? + .ok_or({ + ProtocolError::DataContractError(DataContractError::InvalidContractStructure( + "unable to get document properties from the contract", + )) + })?; + + let mut required_fields = Value::inner_optional_array_of_strings( + document_type_value_map, + property_names::REQUIRED, + ) + .unwrap_or_default(); // Based on the property name, determine the type for (property_key, property_value) in property_values { diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 2394e9a3e77..2ea37eae252 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -153,7 +153,7 @@ impl Document { )) })?; // given a map of values and a key, get the corresponding value - match Value::get_from_map(map_values, key) { + match Value::get_optional_from_map(map_values, key) { None => Ok(None), Some(value) => get_value_at_path(value, rest_key_paths), } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs index 2ba1be6efd0..fced82bd024 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -1,37 +1,47 @@ +use crate::ProtocolError; use anyhow::Context; -use serde_json::Value as JsonValue; -use std::collections::{hash_map::Entry, HashMap}; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; +use std::collections::btree_map::Entry; +use std::collections::BTreeMap; +use std::convert::TryInto; + +#[derive(Hash, Eq, PartialEq, Ord, PartialOrd)] +struct IdFingerprint<'a> { + document_type: &'a str, + id: [u8; 32], +} /// Find the duplicates in the collection of Document Transitions pub fn find_duplicates_by_id<'a>( - document_transitions: impl IntoIterator, -) -> Result, anyhow::Error> { - let mut fingerprints: HashMap = HashMap::new(); - let mut duplicates: Vec = vec![]; + document_transitions: impl IntoIterator, +) -> Result, anyhow::Error> { + let mut fingerprints: BTreeMap = BTreeMap::new(); + let mut duplicates: Vec<&'a Value> = vec![]; for transition in document_transitions { let fingerprint = create_fingerprint(transition) - .context("Can't create fingerprint from a document transition")?; + .context("can't create fingerprint from a document transition")?; - match fingerprints.entry(fingerprint.clone()) { + match fingerprints.entry(fingerprint) { Entry::Occupied(val) => { - duplicates.push(val.get().clone()); - duplicates.push(transition.clone()); + duplicates.push(val.get()); + duplicates.push(transition); } Entry::Vacant(v) => { - v.insert(transition.clone()); + v.insert(transition); } } } Ok(duplicates) } -fn create_fingerprint(document_transition: &JsonValue) -> Option { - Some(format!( - "{}:{}", - document_transition.as_object()?.get("$type")?, - document_transition.as_object()?.get("$id")?, - )) +fn create_fingerprint(document_transition: &Value) -> Result { + let map = document_transition.to_map().context("should be a map")?; + Ok(IdFingerprint { + document_type: Value::inner_text_value(map, "$type")?, + id: Value::inner_hash256_value(map, "$id")?, + }) } #[cfg(test)] @@ -62,10 +72,10 @@ mod test { dt_delete.base.id = generate_random_identifier_struct(); dt_delete.base.document_type_name = String::from("c"); - let create_json = dt_create.to_json().unwrap(); - let dt_create_duplicate_json = dt_create_duplicate.to_json().unwrap(); - let dt_replace_json = dt_replace.to_json().unwrap(); - let dt_delete_json = dt_delete.to_json().unwrap(); + let create_json = dt_create.to_object().unwrap(); + let dt_create_duplicate_json = dt_create_duplicate.to_object().unwrap(); + let dt_replace_json = dt_replace.to_object().unwrap(); + let dt_delete_json = dt_delete.to_object().unwrap(); let input = vec![ create_json, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index 8558494a58b..fb93d6c7366 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -1,6 +1,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; -use serde_json::Value; -use std::collections::{hash_map::Entry, HashMap}; +use platform_value::Value; +use std::collections::btree_map::Entry; +use std::collections::BTreeMap; use crate::{ document::document_transition::DocumentTransition, @@ -34,7 +35,7 @@ pub fn find_duplicates_by_indices<'a>( transitions: Vec<&'a Value>, indices: Vec, } - let mut groups: HashMap<&'a str, Group> = HashMap::new(); + let mut groups: BTreeMap<&'a str, Group> = BTreeMap::new(); for dt in document_raw_transitions.into_iter() { let document_type = dt.get_string("$type")?; @@ -60,14 +61,14 @@ pub fn find_duplicates_by_indices<'a>( .filter(|(_, group)| group.transitions.len() > 1) { for transition in group.transitions.iter() { - let transition_id = transition.get("$id").unwrap(); + let transition_id = transition.get_hash256("$id").unwrap(); let mut found_duplicates: Vec<&'a Value> = vec![]; for transition_to_check in group .transitions .iter() // Exclude current transition from search - .filter(|t| t.get("$id").unwrap() != transition_id) + .filter(|t| t.get_hash256("$id").unwrap() != transition_id) { if is_duplicate_by_indices(transition, transition_to_check, &group.indices) { found_duplicates.push(transition_to_check) @@ -129,15 +130,15 @@ fn is_duplicate_by_indices( "{}:{}", property.name, original_transition - .get(&property.name) - .unwrap_or(&Value::Null) + .get_hash256_as_bs58_string(&property.name) + .unwrap_or_default() )); hash_to_check.push_str(&format!( "{}:{}", property.name, transition_to_check - .get(&property.name) - .unwrap_or(&Value::Null) + .get_string(&property.name) + .unwrap_or_default() )); } accumulator = accumulator || (original_hash == hash_to_check); @@ -147,6 +148,7 @@ fn is_duplicate_by_indices( #[cfg(test)] mod test { + use platform_value::Value; use serde_json::json; use crate::{prelude::*, util::string_encoding::Encoding}; @@ -217,7 +219,7 @@ mod test { Encoding::Base58, ) .unwrap(); - let document_raw_transition_1 = json!( + let document_raw_transition_1: Value = json!( { "$id": id_1.as_bytes(), "$type": "indexedDocument", @@ -227,14 +229,15 @@ mod test { "lastName": "Birkin", "$entropy": "hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=", } - ); + ) + .into(); let id_2 = Identifier::from_string( "3GDfArJJdHMviaRd5ta4F2EB7LN9RgbMKLAfjAxZEaUG", Encoding::Base58, ) .unwrap(); - let document_create_transition_2 = json!( + let document_create_transition_2: Value = json!( { "$id": id_2.as_bytes(), "$type": "indexedDocument", @@ -244,12 +247,13 @@ mod test { "lastName": "Birkin", "$entropy": "hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=", } - ); + ) + .into(); let duplicates = find_duplicates_by_indices( [&document_raw_transition_1, &document_create_transition_2], &data_contract, ) .expect("the error shouldn't be returned"); - assert!(duplicates.len() == 2); + assert_eq!(duplicates.len(), 2); } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 81cc92ae236..9bfd298f8b1 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -1,3 +1,4 @@ +use std::borrow::Borrow; use std::{ collections::{hash_map::Entry, HashMap}, convert::{TryFrom, TryInto}, @@ -23,6 +24,7 @@ use crate::{ }; use anyhow::anyhow; use lazy_static::lazy_static; +use platform_value::Value; use serde_json::Value as JsonValue; use super::{ @@ -196,6 +198,7 @@ fn get_enriched_contracts_by_action( Ok(enriched_contracts_by_action) } +//todo: switch to platform Value fn validate_raw_transitions<'a>( data_contract: &DataContract, raw_document_transitions: impl IntoIterator, @@ -289,37 +292,49 @@ fn validate_raw_transitions<'a>( } } - let raw_document_transitions_iter = raw_document_transitions.into_iter(); - - let duplicate_transitions = find_duplicates_by_id(raw_document_transitions_iter.clone())?; + let raw_document_transitions_as_value: Vec = raw_document_transitions + .into_iter() + .map(|v| v.clone().into()) + .collect(); + let raw_document_transitions_as_value_iter = raw_document_transitions_as_value.iter(); + let duplicate_transitions = + find_duplicates_by_id(raw_document_transitions_as_value_iter.clone())?; if !duplicate_transitions.is_empty() { - let references: Vec<(String, Vec)> = duplicate_transitions + let references: Vec<(String, [u8; 32])> = duplicate_transitions .iter() - .map(|t| { - let doc_type = t.get_string("$type")?.to_string(); - let id = t.get_bytes("$id")?; - Ok((doc_type, id)) + .map(|transition_value| { + let map = transition_value + .to_map() + .map_err(ProtocolError::ValueError)?; + let doc_type = Value::inner_text_value(map, "$type")?; + let id = Value::inner_hash256_value(map, "$id")?; + Ok((doc_type.to_string(), id)) }) - .collect::)>, anyhow::Error>>()?; + .collect::, ProtocolError>>()?; result.add_error(BasicError::DuplicateDocumentTransitionsWithIdsError { references }); } - let duplicate_transitions_by_indices = - find_duplicates_by_indices(raw_document_transitions_iter.clone(), data_contract)?; + let duplicate_transitions_by_indices = find_duplicates_by_indices( + raw_document_transitions_as_value_iter.clone(), + data_contract, + )?; if !duplicate_transitions_by_indices.is_empty() { - let references: Vec<(String, Vec)> = duplicate_transitions_by_indices + let references: Vec<(String, [u8; 32])> = duplicate_transitions_by_indices .iter() - .map(|t| { - let doc_type = t.get_string("$type")?.to_string(); - let id = t.get_bytes("$id")?; - Ok((doc_type, id)) + .map(|transition_value| { + let map = transition_value + .to_map() + .map_err(ProtocolError::ValueError)?; + let doc_type = Value::inner_text_value(map, "$type")?; + let id = Value::inner_hash256_value(map, "$id")?; + Ok((doc_type.to_string(), id)) }) - .collect::)>, anyhow::Error>>()?; + .collect::, ProtocolError>>()?; result.add_error(BasicError::DuplicateDocumentTransitionsWithIndicesError { references }); } let validation_result = validate_partial_compound_indices( - raw_document_transitions_iter + raw_document_transitions_as_value_iter .clone() .filter(|t| action_is_not_delete(t.get_string("$action").unwrap_or_default())), data_contract, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index 36607a32895..ccb093b594f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -1,5 +1,8 @@ use std::borrow::Borrow; +use std::collections::BTreeMap; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; use serde_json::Value as JsonValue; use crate::{ @@ -14,31 +17,37 @@ use crate::{ }; pub fn validate_partial_compound_indices<'a>( - raw_document_transitions: impl IntoIterator, + raw_document_transitions: impl IntoIterator, data_contract: &DataContract, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); for transition in raw_document_transitions { - let raw_transition = transition.borrow(); - let document_type = raw_transition.get_string("$type")?; + let document_type = transition.get_string("$type")?; let document_schema = data_contract.get_document_schema(document_type)?; let indices = document_schema.get_indices::>().unwrap_or_default(); if indices.is_empty() { continue; } - result.merge(validate_indices(&indices, document_type, raw_transition)); + result.merge(validate_indices( + &indices, + document_type, + &transition.to_btree_ref_map()?, + )); } Ok(result) } -pub fn validate_indices( +pub fn validate_indices( indices: &[Index], document_type: &str, - raw_transition: &JsonValue, -) -> ValidationResult<()> { + raw_transition_map: &BTreeMap, +) -> ValidationResult<()> +where + V: Borrow, +{ let mut validation_result = ValidationResult::default(); for index in indices @@ -47,7 +56,7 @@ pub fn validate_indices( { let properties = index.properties.iter().map(|property| &property.name); - if !are_all_properties_defined_or_undefined(properties.clone(), raw_transition) { + if !are_all_properties_defined_or_undefined(properties.clone(), raw_transition_map) { validation_result.add_error(BasicError::InconsistentCompoundIndexDataError { index_properties: properties.map(ToOwned::to_owned).collect(), document_type: document_type.to_string(), @@ -58,10 +67,13 @@ pub fn validate_indices( validation_result } -fn are_all_properties_defined_or_undefined( +fn are_all_properties_defined_or_undefined( properties: impl IntoIterator>, - json_value: &JsonValue, -) -> bool { + map: &BTreeMap, +) -> bool +where + V: Borrow, +{ let mut defined_property_counter = 0; let mut properties_len = 0; @@ -73,11 +85,12 @@ fn are_all_properties_defined_or_undefined( defined_property_counter += 1; continue; } - if property.as_ref().starts_with('$') && json_value.get(property_name).is_some() { + //todo: this seems weird + if property.as_ref().starts_with('$') && map.get(property_name).is_some() { defined_property_counter += 1; continue; } - if json_value.get_value(property_name).is_ok() { + if map.get(property_name).is_some() { defined_property_counter += 1 } } @@ -87,7 +100,9 @@ fn are_all_properties_defined_or_undefined( #[cfg(test)] mod test { + use platform_value::converter::serde_json::BTreeValueJsonConverter; use serde_json::json; + use std::collections::BTreeMap; use super::are_all_properties_defined_or_undefined; @@ -105,7 +120,7 @@ mod test { assert!(are_all_properties_defined_or_undefined( property_names, - &input + &BTreeMap::from_json_value(input).unwrap() )); } @@ -122,7 +137,7 @@ mod test { assert!(!are_all_properties_defined_or_undefined( property_names, - &input + &BTreeMap::from_json_value(input).unwrap() )); } @@ -139,7 +154,7 @@ mod test { assert!(are_all_properties_defined_or_undefined( property_names, - &input + &BTreeMap::from_json_value(input).unwrap() )); } } diff --git a/packages/rs-dpp/src/errors/consensus/basic/abstract_basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/abstract_basic_error.rs index ca52aa8191a..ad7c6e25bdd 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/abstract_basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/abstract_basic_error.rs @@ -70,13 +70,13 @@ pub enum BasicError { }, #[error("Document transitions with duplicate IDs {:?}", references)] - DuplicateDocumentTransitionsWithIdsError { references: Vec<(String, Vec)> }, + DuplicateDocumentTransitionsWithIdsError { references: Vec<(String, [u8; 32])> }, #[error( "Document transitions with duplicate unique properties: {:?}", references )] - DuplicateDocumentTransitionsWithIndicesError { references: Vec<(String, Vec)> }, + DuplicateDocumentTransitionsWithIndicesError { references: Vec<(String, [u8; 32])> }, #[error("$dataContractId is not present")] MissingDataContractIdError, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 99bb6b29d28..70d862c4082 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -1,3 +1,4 @@ +use platform_value::Value; use serde_json::Value as JsonValue; use std::convert::TryInto; @@ -45,14 +46,12 @@ fn should_return_invalid_result_if_compound_index_contains_not_all_fields() { .expect("lastName property should exist and be removed"); let documents_for_transition = vec![document]; - let raw_document_transitions: Vec = + let raw_document_transitions: Vec = get_document_transitions_fixture([(Action::Create, documents_for_transition)]) .into_iter() .map(|dt| { dt.to_object() .expect("the transition should be converted to object") - .try_into() - .expect("expected json values") }) .collect(); let result = validate_partial_compound_indices(raw_document_transitions.iter(), &data_contract) @@ -80,14 +79,12 @@ fn should_return_valid_result_if_compound_index_contains_nof_fields() { document.properties_as_mut().clear(); let documents_for_transition = vec![document]; - let raw_document_transitions: Vec = + let raw_document_transitions: Vec = get_document_transitions_fixture([(Action::Create, documents_for_transition)]) .into_iter() .map(|dt| { dt.to_object() .expect("the transition should be converted to object") - .try_into() - .expect("expected to get json values") }) .collect(); let result = validate_partial_compound_indices(raw_document_transitions.iter(), &data_contract) @@ -103,14 +100,12 @@ fn should_return_valid_result_if_compound_index_contains_all_fields() { } = setup_test(); let document = documents.remove(8); let documents_for_transition = vec![document]; - let raw_document_transitions: Vec = + let raw_document_transitions: Vec = get_document_transitions_fixture([(Action::Create, documents_for_transition)]) .into_iter() .map(|dt| { dt.to_object() .expect("the transition should be converted to object") - .try_into() - .expect("expected json values") }) .collect(); let result = validate_partial_compound_indices(raw_document_transitions.iter(), &data_contract) diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 61ad3979671..1bfa70318cc 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -2888,7 +2888,7 @@ fn test_dpns_query() { .expect("we should be able to get the records"); let map_records_value = records_value.as_map().expect("this should be a map"); let record_dash_unique_identity_id = - Value::inner_bytes_value(map_records_value, "dashUniqueIdentityId") + Value::inner_optional_bytes_value(map_records_value, "dashUniqueIdentityId") .unwrap() .expect("there should be a dashUniqueIdentityId"); base64::encode(record_dash_unique_identity_id) diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index b0bd50b9c29..9a49531a5b0 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -2,12 +2,38 @@ use crate::{Error, Value}; use std::collections::BTreeMap; impl Value { + pub fn get_value<'a>(&'a self, key: &'a str) -> Result<&'a Value, Error> { + let map = self.to_map()?; + Self::get_from_map(map, key) + } + + pub fn get_string<'a>(&'a self, key: &'a str) -> Result<&'a str, Error> { + let map = self.to_map()?; + Self::inner_text_value(map, key) + } + + pub fn get_hash256<'a>(&'a self, key: &'a str) -> Result<[u8; 32], Error> { + let map = self.to_map()?; + Self::inner_hash256_value(map, key) + } + + pub fn get_hash256_as_bs58_string<'a>(&'a self, key: &'a str) -> Result { + let map = self.to_map()?; + let value = Self::inner_hash256_value(map, key)?; + Ok(bs58::encode(value).into_string()) + } + + pub fn get_optional_value<'a>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Ok(Self::get_optional_from_map(map, key)) + } + /// Retrieves the value of a key from a map if it's an array of strings. - pub fn inner_array_of_strings<'a, I: FromIterator>( + pub fn inner_optional_array_of_strings<'a, I: FromIterator>( document_type: &'a [(Value, Value)], key: &'a str, ) -> Option { - let key_value = Self::get_from_map(document_type, key)?; + let key_value = Self::get_optional_from_map(document_type, key)?; if let Value::Array(key_value) = key_value { Some( key_value @@ -27,11 +53,11 @@ impl Value { } /// Gets the inner btree map from a map - pub fn inner_btree_map<'a>( + pub fn inner_optional_btree_map<'a>( document_type: &'a [(Value, Value)], key: &'a str, ) -> Result>, Error> { - let Some(key_value) = Self::get_from_map(document_type, key) else { + let Some(key_value) = Self::get_optional_from_map(document_type, key) else { return Ok(None); }; if let Value::Map(map_value) = key_value { @@ -41,8 +67,8 @@ impl Value { } /// Gets the inner bool value from a map - pub fn inner_bool_value(document_type: &[(Value, Value)], key: &str) -> Option { - let key_value = Self::get_from_map(document_type, key)?; + pub fn inner_optional_bool_value(document_type: &[(Value, Value)], key: &str) -> Option { + let key_value = Self::get_optional_from_map(document_type, key)?; if let Value::Bool(bool_value) = key_value { return Some(*bool_value); } @@ -50,47 +76,86 @@ impl Value { } /// Retrieves the value of a key from a map if it's a string. - pub fn inner_text_value<'a>( + pub fn inner_optional_text_value<'a>( document_type: &'a [(Value, Value)], key: &'a str, ) -> Result, Error> { - Self::get_from_map(document_type, key) + Self::get_optional_from_map(document_type, key) .map(|v| v.as_str()) .transpose() } + /// Retrieves the value of a key from a map if it's a string. + pub fn inner_text_value<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result<&'a str, Error> { + Self::get_from_map(document_type, key).map(|v| v.as_str())? + } + + /// Retrieves the value of a key from a map if it's a hash256. + pub fn inner_optional_hash256_value<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result, Error> { + Self::get_optional_from_map(document_type, key) + .map(|v| v.to_hash256()) + .transpose() + } + + /// Retrieves the value of a key from a map if it's a string. + pub fn inner_hash256_value<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result<[u8; 32], Error> { + Self::get_from_map(document_type, key).map(|v| v.to_hash256())? + } + /// Retrieves the value of a key from a map if it's a byte array. - pub fn inner_bytes_value<'a>( + pub fn inner_optional_bytes_value<'a>( document_type: &'a [(Value, Value)], key: &'a str, ) -> Result>, Error> { - Self::get_from_map(document_type, key) + Self::get_optional_from_map(document_type, key) .map(|v| v.to_bytes()) .transpose() } /// Retrieves the value of a key from a map if it's a byte array. - pub fn inner_bytes_slice_value<'a>( + pub fn inner_optional_bytes_slice_value<'a>( document_type: &'a [(Value, Value)], key: &'a str, ) -> Result, Error> { - Self::get_from_map(document_type, key) + Self::get_optional_from_map(document_type, key) .map(|v| v.as_bytes_slice()) .transpose() } /// Gets the inner array value from a borrowed ValueMap - pub fn inner_array_slice_value<'a>( + pub fn inner_optional_array_slice_value<'a>( document_type: &'a [(Value, Value)], key: &'a str, ) -> Result, Error> { - Self::get_from_map(document_type, key) + Self::get_optional_from_map(document_type, key) .map(|v| v.as_slice()) .transpose() } + pub fn get_from_map<'a>( + map: &'a [(Value, Value)], + search_key: &'a str, + ) -> Result<&'a Value, Error> { + Self::get_optional_from_map(map, search_key).ok_or(Error::StructureError(format!( + "{} not found in map", + search_key + ))) + } + /// Gets a value from a map - pub fn get_from_map<'a>(map: &'a [(Value, Value)], search_key: &'a str) -> Option<&'a Value> { + pub fn get_optional_from_map<'a>( + map: &'a [(Value, Value)], + search_key: &'a str, + ) -> Option<&'a Value> { for (key, value) in map.iter() { if !key.is_text() { continue; diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 5e71dd8f9a1..db2b88f25ed 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -943,6 +943,30 @@ impl Value { } } + /// If the `Value` is a `Map`, returns a the associated ValueMap which is a `Vec<(Value, Value)>` + /// data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Value}; + /// # + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("key")), Value::Float(18.)), + /// ] + /// ); + /// assert_eq!(value.to_map(), Ok(&vec![(Value::Text(String::from("key")), Value::Float(18.))])); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_map(), Err(Error::StructureError("value is not a map".to_string()))) + /// ``` + pub fn to_map(&self) -> Result<&ValueMap, Error> { + match self { + Value::Map(map) => Ok(map), + _other => Err(Error::StructureError("value is not a map".to_string())), + } + } + /// If the `Value` is a `Map`, returns the associated ValueMap ref which is a `&Vec<(Value, Value)>` /// data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs index 2a2d90578d5..33cbd2c7732 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -6,6 +6,7 @@ use dpp::ProtocolError; use itertools::Itertools; use js_sys::Array; use serde_json::Value as JsonValue; +use std::collections::BTreeMap; use std::convert::TryInto; use wasm_bindgen::prelude::*; @@ -14,28 +15,24 @@ use crate::utils::{replace_identifiers_with_bytes_without_failing, ToSerdeJSONEx #[wasm_bindgen(js_name=findDuplicatesById)] pub fn find_duplicates_by_id_wasm(js_raw_transitions: Array) -> Result, JsValue> { - let raw_transitions: Vec = js_raw_transitions + let raw_transitions: Vec = js_raw_transitions .iter() .map(|transition| { - let mut map = transition.with_serde_to_platform_value_map()?; - map.replace_at_paths( - document_base_transition::IDENTIFIER_FIELDS.map(|a| a.to_string()), + let mut value = transition.with_serde_to_platform_value()?; + value.replace_at_paths( + document_base_transition::IDENTIFIER_FIELDS, ReplacementType::Identifier, ); - let value: Value = map.into(); - value - .try_into_validating_json() - .map_err(ProtocolError::ValueError) - .with_js_error() + Ok(value) }) - .collect::, JsValue>>()?; + .collect::, JsValue>>()?; let result: Vec = find_duplicates_by_id(&raw_transitions) .with_js_error()? .into_iter() .map(|raw| { to_object( - raw.into(), + raw.clone(), &JsValue::null(), document_base_transition::IDENTIFIER_FIELDS, document_create_transition::BINARY_FIELDS, diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index 6acd950b135..81c1876707c 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -2,9 +2,9 @@ use dpp::document::{ document_transition::{document_base_transition, document_create_transition}, validation::basic::find_duplicates_by_indices::find_duplicates_by_indices, }; +use dpp::platform_value::{ReplacementType, Value}; use itertools::Itertools; use js_sys::Array; -use serde_json::Value; use wasm_bindgen::prelude::*; use crate::{ @@ -20,16 +20,15 @@ pub fn find_duplicates_by_indices_wasm( ) -> Result, JsValue> { let raw_transitions: Vec = js_raw_transitions .iter() - .map(|t| { - t.with_serde_to_json_value().map(|mut v| { - replace_identifiers_with_bytes_without_failing( - &mut v, - document_base_transition::IDENTIFIER_FIELDS, - ); - v - }) + .map(|transition| { + let mut value = transition.with_serde_to_platform_value()?; + value.replace_at_paths( + document_base_transition::IDENTIFIER_FIELDS, + ReplacementType::Identifier, + ); + Ok(value) }) - .try_collect()?; + .collect::, JsValue>>()?; let result = find_duplicates_by_indices(&raw_transitions, data_contract.inner()).with_js_error()?; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs index 50a292bfbf1..3cdd9ba2488 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -2,9 +2,10 @@ use dpp::document::{ document_transition::document_base_transition, validation::basic::validate_partial_compound_indices::validate_partial_compound_indices, }; +use dpp::platform_value::{ReplacementType, Value}; use itertools::Itertools; use js_sys::Array; -use serde_json::Value; +use std::collections::BTreeMap; use wasm_bindgen::prelude::*; use crate::{ @@ -20,16 +21,15 @@ pub fn validate_partial_compound_indices_wasm( ) -> Result { let raw_transitions: Vec = js_raw_transitions .iter() - .map(|t| { - t.with_serde_to_json_value().map(|mut v| { - replace_identifiers_with_bytes_without_failing( - &mut v, - document_base_transition::IDENTIFIER_FIELDS, - ); - v - }) + .map(|transition| { + let mut value = transition.with_serde_to_platform_value()?; + value.replace_at_paths( + document_base_transition::IDENTIFIER_FIELDS, + ReplacementType::Identifier, + ); + Ok(value) }) - .try_collect()?; + .collect::, JsValue>>()?; let validation_result = validate_partial_compound_indices(&raw_transitions, data_contract.inner()) diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs index 159c6f58517..911f41100c1 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs @@ -4,12 +4,12 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen(js_name=DuplicateDocumentTransitionsWithIdsError)] pub struct DuplicateDocumentTransitionsWithIdsErrorWasm { - references: Vec<(String, Vec)>, + references: Vec<(String, [u8; 32])>, code: u32, } impl DuplicateDocumentTransitionsWithIdsErrorWasm { - pub fn new(references: Vec<(String, Vec)>, code: u32) -> Self { + pub fn new(references: Vec<(String, [u8; 32])>, code: u32) -> Self { DuplicateDocumentTransitionsWithIdsErrorWasm { references, code } } } @@ -23,7 +23,7 @@ impl DuplicateDocumentTransitionsWithIdsErrorWasm { .map(|v| { js_sys::Array::from_iter(vec![ JsValue::from(v.0.clone()), - JsValue::from(Buffer::from_bytes(&v.1)), + JsValue::from(Buffer::from_bytes(&v.1.to_vec())), ]) }) .collect() diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs index ea8aba9e100..efec17a91c0 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs @@ -4,12 +4,12 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen(js_name=DuplicateDocumentTransitionsWithIndicesError)] pub struct DuplicateDocumentTransitionsWithIndicesErrorWasm { - references: Vec<(String, Vec)>, + references: Vec<(String, [u8; 32])>, code: u32, } impl DuplicateDocumentTransitionsWithIndicesErrorWasm { - pub fn new(references: Vec<(String, Vec)>, code: u32) -> Self { + pub fn new(references: Vec<(String, [u8; 32])>, code: u32) -> Self { DuplicateDocumentTransitionsWithIndicesErrorWasm { references, code } } } @@ -23,7 +23,7 @@ impl DuplicateDocumentTransitionsWithIndicesErrorWasm { .map(|v| { js_sys::Array::from_iter(vec![ JsValue::from(v.0.clone()), - JsValue::from(Buffer::from_bytes(&v.1)), + JsValue::from(Buffer::from_bytes(&v.1.to_vec())), ]) }) .collect() From a176469e3b25a73ef0ff20fc65083a1d9dbb968d Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 01:57:20 +0700 Subject: [PATCH 074/228] more work --- .../src/data_contract/document_type/index.rs | 20 ++ .../basic/find_duplicates_by_indices.rs | 301 +++++++++++++----- 2 files changed, 245 insertions(+), 76 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/index.rs b/packages/rs-dpp/src/data_contract/document_type/index.rs index da9cb238c04..b3f5abe48af 100644 --- a/packages/rs-dpp/src/data_contract/document_type/index.rs +++ b/packages/rs-dpp/src/data_contract/document_type/index.rs @@ -2,6 +2,7 @@ use crate::data_contract::errors::{DataContractError, StructureError}; use crate::ProtocolError; use anyhow::bail; +use platform_value::value_map::ValueMap; use platform_value::Value; use rand::distributions::{Alphanumeric, DistString}; use serde::{Deserialize, Serialize}; @@ -15,6 +16,25 @@ pub struct Index { pub unique: bool, } +impl Index { + /// Check to see if two objects are conflicting + pub fn objects_are_conflicting(&self, object1: &ValueMap, object2: &ValueMap) -> bool { + if self.unique == false { + return false; + } + self.properties.iter().all(|property| { + //if either or both are null then there can not be an overlap + let Some(value1) = Value::get_optional_from_map(object1,property.name.as_str()) else { + return false; + }; + let Some(value2) = Value::get_optional_from_map(object2,property.name.as_str()) else { + return false; + }; + value1 == value2 + }) + } +} + #[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] pub struct IndexProperty { pub name: String, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index fb93d6c7366..78dff8e5a06 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -1,8 +1,10 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::value_map::ValueMap; use platform_value::Value; use std::collections::btree_map::Entry; use std::collections::BTreeMap; +use crate::data_contract::DriveContractExt; use crate::{ document::document_transition::DocumentTransition, prelude::DataContract, @@ -28,25 +30,26 @@ macro_rules! get_from_transition { /// Finds duplicates of indices in Document Transitions. pub fn find_duplicates_by_indices<'a>( document_raw_transitions: impl IntoIterator, - data_contract: &DataContract, + data_contract: &'a DataContract, ) -> Result, ProtocolError> { #[derive(Debug)] struct Group<'a> { transitions: Vec<&'a Value>, - indices: Vec, + indices: &'a [Index], } let mut groups: BTreeMap<&'a str, Group> = BTreeMap::new(); for dt in document_raw_transitions.into_iter() { - let document_type = dt.get_string("$type")?; - match groups.entry(document_type) { + let document_type_name = dt.get_string("$type")?; + let document_type = data_contract.document_type_for_name(document_type_name)?; + match groups.entry(document_type_name) { Entry::Occupied(mut o) => { o.get_mut().transitions.push(dt); } Entry::Vacant(v) => { v.insert(Group { transitions: vec![dt], - indices: get_unique_indices(document_type, data_contract), + indices: document_type.indices.as_slice(), }); } }; @@ -60,18 +63,19 @@ pub fn find_duplicates_by_indices<'a>( // Filter out group with only one object .filter(|(_, group)| group.transitions.len() > 1) { - for transition in group.transitions.iter() { - let transition_id = transition.get_hash256("$id").unwrap(); - + for (i, value1) in group.transitions.iter().enumerate() { + let object1 = value1.to_map().map_err(ProtocolError::ValueError)?; let mut found_duplicates: Vec<&'a Value> = vec![]; - for transition_to_check in group + for value2 in group .transitions + .split_at(i + 1) + .1 // we get the second part .iter() - // Exclude current transition from search - .filter(|t| t.get_hash256("$id").unwrap() != transition_id) { - if is_duplicate_by_indices(transition, transition_to_check, &group.indices) { - found_duplicates.push(transition_to_check) + let object2 = value2.to_map().map_err(ProtocolError::ValueError)?; + if is_duplicate_by_indices(object1, object2, group.indices) { + found_duplicates.push(value1); + found_duplicates.push(value2); } } found_group_duplicates.extend(found_duplicates); @@ -81,19 +85,6 @@ pub fn find_duplicates_by_indices<'a>( Ok(found_group_duplicates) } -fn get_unique_indices(document_type: &str, data_contract: &DataContract) -> Vec { - let indices = data_contract - .get_document_schema(document_type) - .unwrap() - .get_indices::>(); - indices - // TODO should we panic or we should return and error or empty vector - .expect("error while getting indices from json schema") - .into_iter() - .filter(|i| i.unique) - .collect() -} - fn get_data_property(document_transition: &DocumentTransition, property_name: &str) -> String { match document_transition { DocumentTransition::Delete(_) => String::from(""), @@ -116,41 +107,20 @@ fn get_data_property(document_transition: &DocumentTransition, property_name: &s } } -fn is_duplicate_by_indices( - original_transition: &Value, - transition_to_check: &Value, - type_indices: &Vec, -) -> bool { - let mut accumulator = false; - for definition in type_indices { - let mut original_hash = String::new(); - let mut hash_to_check = String::new(); - for property in &definition.properties { - original_hash.push_str(&format!( - "{}:{}", - property.name, - original_transition - .get_hash256_as_bs58_string(&property.name) - .unwrap_or_default() - )); - hash_to_check.push_str(&format!( - "{}:{}", - property.name, - transition_to_check - .get_string(&property.name) - .unwrap_or_default() - )); - } - accumulator = accumulator || (original_hash == hash_to_check); - } - accumulator +fn is_duplicate_by_indices(object1: &ValueMap, object2: &ValueMap, type_indices: &[Index]) -> bool { + type_indices + .iter() + .any(|index| index.objects_are_conflicting(object1, object2)) } #[cfg(test)] mod test { use platform_value::Value; use serde_json::json; + use std::collections::BTreeMap; + use std::convert::TryInto; + use crate::data_contract::document_type::DocumentType; use crate::{prelude::*, util::string_encoding::Encoding}; use super::find_duplicates_by_indices; @@ -185,7 +155,7 @@ mod test { } #[test] - fn test_find_duplicates_by_indices() { + fn test_non_required_field_not_being_present_doesnt_find_index_duplicate() { let document_def = json!( { "indices": [ { @@ -210,7 +180,21 @@ mod test { } ); + let document_def_value: Value = document_def.clone().into(); + + let document_type = DocumentType::from_platform_value( + "indexedDocument", + document_def_value.to_map().expect("expected a map"), + &BTreeMap::new(), + false, + false, + ) + .expect("expected a document type"); + let mut data_contract = DataContract::default(); + data_contract + .document_types + .insert("indexedDocument".to_string(), document_type); data_contract.set_document_schema("indexedDocument".to_string(), document_def.clone()); data_contract.set_document_schema("singleDocument".to_string(), document_def); @@ -219,17 +203,35 @@ mod test { Encoding::Base58, ) .unwrap(); - let document_raw_transition_1: Value = json!( - { - "$id": id_1.as_bytes(), - "$type": "indexedDocument", - "$action": 0, - "$dataContractId": "F719NPkos8a2VqxSPv4co4F8owh9qBbYEMJ1gzyLANtg", - "name": "Leon", - "lastName": "Birkin", - "$entropy": "hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=", - } - ) + let document_raw_transition_1: Value = BTreeMap::from([ + ("$id".to_string(), Value::Identifier(id_1.buffer)), + ( + "$type".to_string(), + Value::Text("indexedDocument".to_string()), + ), + ("$action".to_string(), Value::U8(0)), + ( + "$dataContractId".to_string(), + Value::Identifier( + bs58::decode("F719NPkos8a2VqxSPv4co4F8owh9qBbYEMJ1gzyLANtg") + .into_vec() + .unwrap() + .try_into() + .unwrap(), + ), + ), + ("name".to_string(), Value::Text("Leon".to_string())), + ("lastName".to_string(), Value::Text("Birkin".to_string())), + ( + "$entropy".to_string(), + Value::Bytes32( + base64::decode("hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=") + .unwrap() + .try_into() + .unwrap(), + ), + ), + ]) .into(); let id_2 = Identifier::from_string( @@ -237,18 +239,165 @@ mod test { Encoding::Base58, ) .unwrap(); - let document_create_transition_2: Value = json!( - { - "$id": id_2.as_bytes(), - "$type": "indexedDocument", - "$action": 0, - "$dataContractId": "F719NPkos8a2VqxSPv4co4F8owh9qBbYEMJ1gzyLANtg", - "name": "William", - "lastName": "Birkin", - "$entropy": "hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=", - } + + let document_create_transition_2: Value = BTreeMap::from([ + ("$id".to_string(), Value::Identifier(id_2.buffer)), + ( + "$type".to_string(), + Value::Text("indexedDocument".to_string()), + ), + ("$action".to_string(), Value::U8(0)), + ( + "$dataContractId".to_string(), + Value::Identifier( + bs58::decode("F719NPkos8a2VqxSPv4co4F8owh9qBbYEMJ1gzyLANtg") + .into_vec() + .unwrap() + .try_into() + .unwrap(), + ), + ), + ("name".to_string(), Value::Text("William".to_string())), + ("lastName".to_string(), Value::Text("Birkin".to_string())), + ( + "$entropy".to_string(), + Value::Bytes32( + base64::decode("hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=") + .unwrap() + .try_into() + .unwrap(), + ), + ), + ]) + .into(); + + let duplicates = find_duplicates_by_indices( + [&document_raw_transition_1, &document_create_transition_2], + &data_contract, ) + .expect("the error shouldn't be returned"); + assert_eq!(duplicates.len(), 0); + } + + #[test] + fn test_find_duplicates_by_indices() { + let document_def = json!( { + "indices": [ + { + "name": "ownerIdLastName", + "properties": [ + {"$ownerId": "asc"}, + {"lastName": "asc"}, + ], + "unique": true, + }, + ], + "properties": { + "firstName": { + "type": "string", + }, + "lastName": { + "type": "string", + }, + }, + "required": ["lastName"], + "additionalProperties": false, + } + ); + + let document_def_value: Value = document_def.clone().into(); + + let document_type = DocumentType::from_platform_value( + "indexedDocument", + document_def_value.to_map().expect("expected a map"), + &BTreeMap::new(), + false, + false, + ) + .expect("expected a document type"); + + let mut data_contract = DataContract::default(); + data_contract + .document_types + .insert("indexedDocument".to_string(), document_type); + data_contract.set_document_schema("indexedDocument".to_string(), document_def.clone()); + data_contract.set_document_schema("singleDocument".to_string(), document_def); + + let id_1 = Identifier::from_string( + "AoqSTh5Bg6Fo26NaCRVoPP1FiDQ1ycihLkjQ75MYJziV", + Encoding::Base58, + ) + .unwrap(); + let document_raw_transition_1: Value = BTreeMap::from([ + ("$ownerId".to_string(), Value::Identifier(id_1.buffer)), + ("$id".to_string(), Value::Identifier(id_1.buffer)), + ( + "$type".to_string(), + Value::Text("indexedDocument".to_string()), + ), + ("$action".to_string(), Value::U8(0)), + ( + "$dataContractId".to_string(), + Value::Identifier( + bs58::decode("F719NPkos8a2VqxSPv4co4F8owh9qBbYEMJ1gzyLANtg") + .into_vec() + .unwrap() + .try_into() + .unwrap(), + ), + ), + ("name".to_string(), Value::Text("Leon".to_string())), + ("lastName".to_string(), Value::Text("Birkin".to_string())), + ( + "$entropy".to_string(), + Value::Bytes32( + base64::decode("hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=") + .unwrap() + .try_into() + .unwrap(), + ), + ), + ]) .into(); + + let id_2 = Identifier::from_string( + "3GDfArJJdHMviaRd5ta4F2EB7LN9RgbMKLAfjAxZEaUG", + Encoding::Base58, + ) + .unwrap(); + + let document_create_transition_2: Value = BTreeMap::from([ + ("$ownerId".to_string(), Value::Identifier(id_1.buffer)), + ("$id".to_string(), Value::Identifier(id_2.buffer)), + ( + "$type".to_string(), + Value::Text("indexedDocument".to_string()), + ), + ("$action".to_string(), Value::U8(0)), + ( + "$dataContractId".to_string(), + Value::Identifier( + bs58::decode("F719NPkos8a2VqxSPv4co4F8owh9qBbYEMJ1gzyLANtg") + .into_vec() + .unwrap() + .try_into() + .unwrap(), + ), + ), + ("name".to_string(), Value::Text("William".to_string())), + ("lastName".to_string(), Value::Text("Birkin".to_string())), + ( + "$entropy".to_string(), + Value::Bytes32( + base64::decode("hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=") + .unwrap() + .try_into() + .unwrap(), + ), + ), + ]) + .into(); + let duplicates = find_duplicates_by_indices( [&document_raw_transition_1, &document_create_transition_2], &data_contract, From 7892054a0a62973483ea365d2b276ca1a6ec7ed2 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 02:02:43 +0700 Subject: [PATCH 075/228] fmt --- .../basic/validate_partial_compound_indices.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index ccb093b594f..94bb5bc6c7e 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -2,6 +2,7 @@ use std::borrow::Borrow; use std::collections::BTreeMap; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::Value; use serde_json::Value as JsonValue; @@ -86,11 +87,22 @@ where continue; } //todo: this seems weird - if property.as_ref().starts_with('$') && map.get(property_name).is_some() { + if property.as_ref().starts_with('$') + && map + .get_optional_at_path(property_name) + .ok() + .flatten() + .is_some() + { defined_property_counter += 1; continue; } - if map.get(property_name).is_some() { + if map + .get_optional_at_path(property_name) + .ok() + .flatten() + .is_some() + { defined_property_counter += 1 } } From 1464e934b2460ff240f6dc77f482edeecf25f778 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 02:06:18 +0700 Subject: [PATCH 076/228] more fixes --- .../document_replace_transition.rs | 13 ++++-------- .../validation/basic/find_duplicates_by_id.rs | 4 +--- .../basic/find_duplicates_by_indices.rs | 5 +---- ...lidate_documents_batch_transition_basic.rs | 1 - .../validate_partial_compound_indices.rs | 1 - .../validation/basic/find_duplicates_by_id.rs | 20 ++++++++++--------- .../basic/find_duplicates_by_indices.rs | 14 ++++++++----- .../validate_partial_compound_indices.rs | 18 ++++++++++------- packages/wasm-dpp/src/state_repository.rs | 2 +- 9 files changed, 38 insertions(+), 40 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index c6711add88f..da3b8f7d2b2 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -10,15 +10,9 @@ use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::document::Document; use crate::identity::TimestampMillis; use crate::prelude::{ExtendedDocument, Revision}; -use crate::{ - data_contract::DataContract, - errors::ProtocolError, - util::json_value::{JsonValueExt, ReplaceWith}, -}; +use crate::{data_contract::DataContract, errors::ProtocolError, util::json_value::JsonValueExt}; -use super::{ - document_base_transition::DocumentBaseTransition, Action, DocumentTransitionObjectLike, -}; +use super::{document_base_transition::DocumentBaseTransition, DocumentTransitionObjectLike}; pub(self) mod property_names { pub const REVISION: &str = "$revision"; @@ -109,7 +103,7 @@ impl DocumentReplaceTransition { impl DocumentTransitionObjectLike for DocumentReplaceTransition { fn from_json_object( - mut json_value: JsonValue, + json_value: JsonValue, data_contract: DataContract, ) -> Result { let value: Value = json_value.into(); @@ -194,6 +188,7 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { #[cfg(test)] mod test { use super::*; + use crate::document::document_transition::Action; fn init() { let _ = env_logger::builder() diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs index fced82bd024..a4d357ae379 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -1,10 +1,8 @@ -use crate::ProtocolError; use anyhow::Context; -use platform_value::btreemap_extensions::BTreeValueMapHelper; + use platform_value::Value; use std::collections::btree_map::Entry; use std::collections::BTreeMap; -use std::convert::TryInto; #[derive(Hash, Eq, PartialEq, Ord, PartialOrd)] struct IdFingerprint<'a> { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index 78dff8e5a06..729a9f57b7f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -8,10 +8,7 @@ use crate::data_contract::DriveContractExt; use crate::{ document::document_transition::DocumentTransition, prelude::DataContract, - util::{ - json_schema::{Index, JsonSchemaExt}, - json_value::JsonValueExt, - }, + util::{json_schema::Index, json_value::JsonValueExt}, ProtocolError, }; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 9bfd298f8b1..3c75c0cbd97 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -1,4 +1,3 @@ -use std::borrow::Borrow; use std::{ collections::{hash_map::Entry, HashMap}, convert::{TryFrom, TryInto}, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index 94bb5bc6c7e..797d286093c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -4,7 +4,6 @@ use std::collections::BTreeMap; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::Value; -use serde_json::Value as JsonValue; use crate::{ consensus::basic::BasicError, diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs index 33cbd2c7732..1ede68f7128 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -2,16 +2,15 @@ use dpp::document::document_transition::{document_base_transition, document_crea use dpp::document::validation::basic::find_duplicates_by_id::find_duplicates_by_id; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::{ReplacementType, Value}; -use dpp::ProtocolError; + use itertools::Itertools; use js_sys::Array; -use serde_json::Value as JsonValue; -use std::collections::BTreeMap; -use std::convert::TryInto; + +use dpp::ProtocolError; use wasm_bindgen::prelude::*; use crate::document_batch_transition::document_transition::to_object; -use crate::utils::{replace_identifiers_with_bytes_without_failing, ToSerdeJSONExt, WithJsError}; +use crate::utils::{ToSerdeJSONExt, WithJsError}; #[wasm_bindgen(js_name=findDuplicatesById)] pub fn find_duplicates_by_id_wasm(js_raw_transitions: Array) -> Result, JsValue> { @@ -19,10 +18,13 @@ pub fn find_duplicates_by_id_wasm(js_raw_transitions: Array) -> Result, JsValue>>()?; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index 81c1876707c..0f0011df616 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -3,13 +3,14 @@ use dpp::document::{ validation::basic::find_duplicates_by_indices::find_duplicates_by_indices, }; use dpp::platform_value::{ReplacementType, Value}; +use dpp::ProtocolError; use itertools::Itertools; use js_sys::Array; use wasm_bindgen::prelude::*; use crate::{ document_batch_transition::document_transition::to_object, - utils::{replace_identifiers_with_bytes_without_failing, ToSerdeJSONExt, WithJsError}, + utils::{ToSerdeJSONExt, WithJsError}, DataContractWasm, }; @@ -22,10 +23,13 @@ pub fn find_duplicates_by_indices_wasm( .iter() .map(|transition| { let mut value = transition.with_serde_to_platform_value()?; - value.replace_at_paths( - document_base_transition::IDENTIFIER_FIELDS, - ReplacementType::Identifier, - ); + value + .replace_at_paths( + document_base_transition::IDENTIFIER_FIELDS, + ReplacementType::Identifier, + ) + .map_err(ProtocolError::ValueError) + .with_js_error()?; Ok(value) }) .collect::, JsValue>>()?; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs index 3cdd9ba2488..e75424b9532 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -3,13 +3,14 @@ use dpp::document::{ validation::basic::validate_partial_compound_indices::validate_partial_compound_indices, }; use dpp::platform_value::{ReplacementType, Value}; -use itertools::Itertools; + use js_sys::Array; -use std::collections::BTreeMap; + +use dpp::ProtocolError; use wasm_bindgen::prelude::*; use crate::{ - utils::{replace_identifiers_with_bytes_without_failing, ToSerdeJSONExt, WithJsError}, + utils::{ToSerdeJSONExt, WithJsError}, validation::ValidationResultWasm, DataContractWasm, }; @@ -23,10 +24,13 @@ pub fn validate_partial_compound_indices_wasm( .iter() .map(|transition| { let mut value = transition.with_serde_to_platform_value()?; - value.replace_at_paths( - document_base_transition::IDENTIFIER_FIELDS, - ReplacementType::Identifier, - ); + value + .replace_at_paths( + document_base_transition::IDENTIFIER_FIELDS, + ReplacementType::Identifier, + ) + .map_err(ProtocolError::ValueError) + .with_js_error()?; Ok(value) }) .collect::, JsValue>>()?; diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 155653c18ec..96f7d466fe7 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -23,7 +23,7 @@ use js_sys::{Array, Number}; use wasm_bindgen::__rt::Ref; -use dpp::document::{Document, ExtendedDocument}; +use dpp::document::ExtendedDocument; use wasm_bindgen::prelude::*; use crate::buffer::Buffer; From 36170393529620645fc2e265cc81308fbe2c9a78 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 02:13:01 +0700 Subject: [PATCH 077/228] added another test --- .../basic/find_duplicates_by_indices.rs | 124 ++++++++++++++++++ .../basic/findDuplicatesByIndices.spec.js | 3 +- 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index 729a9f57b7f..9a3be338919 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -402,4 +402,128 @@ mod test { .expect("the error shouldn't be returned"); assert_eq!(duplicates.len(), 2); } + + #[test] + fn test_find_duplicates_by_single_value_indices() { + let document_def = json!( { + "indices": [ + { + "name": "lastName", + "properties": [ + {"lastName": "asc"}, + ], + "unique": true, + }, + ], + "properties": { + "firstName": { + "type": "string", + }, + "lastName": { + "type": "string", + }, + }, + "required": ["lastName"], + "additionalProperties": false, + } + ); + + let document_def_value: Value = document_def.clone().into(); + + let document_type = DocumentType::from_platform_value( + "indexedDocument", + document_def_value.to_map().expect("expected a map"), + &BTreeMap::new(), + false, + false, + ) + .expect("expected a document type"); + + let mut data_contract = DataContract::default(); + data_contract + .document_types + .insert("indexedDocument".to_string(), document_type); + data_contract.set_document_schema("indexedDocument".to_string(), document_def.clone()); + data_contract.set_document_schema("singleDocument".to_string(), document_def); + + let id_1 = Identifier::from_string( + "AoqSTh5Bg6Fo26NaCRVoPP1FiDQ1ycihLkjQ75MYJziV", + Encoding::Base58, + ) + .unwrap(); + let document_raw_transition_1: Value = BTreeMap::from([ + ("$id".to_string(), Value::Identifier(id_1.buffer)), + ( + "$type".to_string(), + Value::Text("indexedDocument".to_string()), + ), + ("$action".to_string(), Value::U8(0)), + ( + "$dataContractId".to_string(), + Value::Identifier( + bs58::decode("F719NPkos8a2VqxSPv4co4F8owh9qBbYEMJ1gzyLANtg") + .into_vec() + .unwrap() + .try_into() + .unwrap(), + ), + ), + ("name".to_string(), Value::Text("Leon".to_string())), + ("lastName".to_string(), Value::Text("Birkin".to_string())), + ( + "$entropy".to_string(), + Value::Bytes32( + base64::decode("hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=") + .unwrap() + .try_into() + .unwrap(), + ), + ), + ]) + .into(); + + let id_2 = Identifier::from_string( + "3GDfArJJdHMviaRd5ta4F2EB7LN9RgbMKLAfjAxZEaUG", + Encoding::Base58, + ) + .unwrap(); + + let document_create_transition_2: Value = BTreeMap::from([ + ("$id".to_string(), Value::Identifier(id_2.buffer)), + ( + "$type".to_string(), + Value::Text("indexedDocument".to_string()), + ), + ("$action".to_string(), Value::U8(0)), + ( + "$dataContractId".to_string(), + Value::Identifier( + bs58::decode("F719NPkos8a2VqxSPv4co4F8owh9qBbYEMJ1gzyLANtg") + .into_vec() + .unwrap() + .try_into() + .unwrap(), + ), + ), + ("name".to_string(), Value::Text("William".to_string())), + ("lastName".to_string(), Value::Text("Birkin".to_string())), + ( + "$entropy".to_string(), + Value::Bytes32( + base64::decode("hxlmtQ34oR/lkql7AUQ13P5kS8OaX2BheksnPBIpxLc=") + .unwrap() + .try_into() + .unwrap(), + ), + ), + ]) + .into(); + + let duplicates = find_duplicates_by_indices( + [&document_raw_transition_1, &document_create_transition_2], + &data_contract, + ) + .expect("the error shouldn't be returned"); + assert_eq!(duplicates.len(), 2); + } } diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js index ff8314f0481..53a3586902b 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js @@ -25,9 +25,8 @@ describe('findDuplicatesByIndices', () => { contractJs.setDocumentSchema('nonUniqueIndexDocument', { indices: [ { - name: 'ownerIdLastName', + name: 'lastName', properties: [ - { $ownerId: 'asc' }, { lastName: 'asc' }, ], unique: false, From e49ee14cdf87688c5800b92595375617510fe674 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 02:20:31 +0700 Subject: [PATCH 078/228] more fixes --- .../validation/basic/validate_partial_compound_indices.rs | 1 - .../document_transition/document_create_transition.rs | 2 +- .../document_transition/document_replace_transition.rs | 2 +- .../document_batch_transition/document_transition/mod.rs | 2 +- .../validation/basic/find_duplicates_by_id.rs | 1 - 5 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index 797d286093c..06792aa6db7 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -1,7 +1,6 @@ use std::borrow::Borrow; use std::collections::BTreeMap; -use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::Value; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 1362775bd6d..916232a277d 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -14,7 +14,7 @@ use dpp::{ self, document_create_transition, DocumentCreateTransition, DocumentTransitionObjectLike, }, prelude::{DataContract, Identifier}, - util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, + util::{json_schema::JsonSchemaExt}, ProtocolError, }; use serde::Serialize; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 8ecf6b38453..69a58b7c05a 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -13,7 +13,7 @@ use dpp::{ document_replace_transition, DocumentReplaceTransition, DocumentTransitionObjectLike, }, prelude::{DataContract, Identifier}, - util::{json_schema::JsonSchemaExt, json_value::JsonValueExt}, + util::{json_schema::JsonSchemaExt}, ProtocolError, }; use serde::Serialize; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index 81839472393..c631c8950ca 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -276,7 +276,7 @@ pub(crate) fn to_object<'a>( binary_paths: impl IntoIterator, ) -> Result { let mut value: JsonValue = value - .try_into() + .try_into_validating_json() .map_err(ProtocolError::ValueError) .with_js_error()?; let options: ConversionOptions = if options.is_object() { diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs index 1ede68f7128..1ea0d0b0a39 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs @@ -1,6 +1,5 @@ use dpp::document::document_transition::{document_base_transition, document_create_transition}; use dpp::document::validation::basic::find_duplicates_by_id::find_duplicates_by_id; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::{ReplacementType, Value}; use itertools::Itertools; From e4f5b263c5ecae0daea5d3377c05278795dec324 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 02:51:19 +0700 Subject: [PATCH 079/228] more fixes --- .../rs-dpp/src/document/extended_document.rs | 43 ++++++++++++++++ .../src/document/extended_document.rs | 50 +++++++++---------- .../document_create_transition.rs | 2 +- .../document_replace_transition.rs | 2 +- 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index da6c95701c2..feea7e3bdad 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -12,6 +12,7 @@ use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; +use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::document::Document; use platform_value::btreemap_extensions::BTreeValueMapHelper; @@ -148,6 +149,48 @@ impl ExtendedDocument { Self::from_json_value::>(raw_document, data_contract) } + pub fn from_platform_value( + mut document_value: Value, + data_contract: DataContract, + ) -> Result { + let mut properties = document_value + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + let document_type_name = properties + .remove_string(property_names::DOCUMENT_TYPE) + .map_err(ProtocolError::ValueError)?; + + //Because we don't know how the json came in we need to sanitize it + let (identifiers, binary_paths) = + data_contract.get_identifiers_and_binary_paths_owned(document_type_name.as_str())?; + + let mut extended_document = Self { + data_contract, + document_type_name, + ..Default::default() + }; + + extended_document.protocol_version = properties + .remove_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)?; + extended_document.data_contract_id = Identifier::new( + properties + .remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? + .unwrap_or(extended_document.data_contract.id.buffer), + ); + extended_document.document = Document::from_map(properties, None, None)?; + + extended_document + .document + .properties + .replace_at_paths(identifiers, ReplacementType::Identifier)?; + extended_document + .document + .properties + .replace_at_paths(binary_paths, ReplacementType::Bytes)?; + Ok(extended_document) + } + fn from_json_value( mut document_value: JsonValue, data_contract: DataContract, diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 87ca049489f..78d6e10b457 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -18,8 +18,8 @@ use crate::document::BinaryType; use crate::errors::RustConversionError; use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; use crate::lodash::lodash_set; -use crate::utils::WithJsError; use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt}; +use crate::utils::{with_serde_to_platform_value, WithJsError}; use crate::{with_js_error, ConversionOptions}; use crate::{DataContractWasm, MetadataWasm}; @@ -34,32 +34,32 @@ impl ExtendedDocumentWasm { js_raw_document: JsValue, js_data_contract: &DataContractWasm, ) -> Result { - let mut raw_document = with_serde_to_json_value(&js_raw_document)?; - - let document_type = raw_document - .get_string(extended_document_property_names::DOCUMENT_TYPE) - .with_js_error()?; - - let (identifier_paths, _) = js_data_contract - .inner() - .get_identifiers_and_binary_paths(document_type) - .with_js_error()?; - - // Errors are ignored. When `Buffer` crosses the WASM boundary it becomes an Array. - // When `Identifier` crosses the WASM boundary it becomes a String. From perspective of JS - // `Identifier` and `Buffer` are used interchangeably, so we we can expect the replacing may fail when `Buffer` is provided - let _ = raw_document - .replace_identifier_paths( - identifier_paths - .into_iter() - .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS), - ReplaceWith::Bytes, - ) - .with_js_error(); - // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array + let mut raw_document = with_serde_to_platform_value(&js_raw_document)?; + + // let document_type = raw_document + // .get_string(extended_document_property_names::DOCUMENT_TYPE).map_err(ProtocolError::ValueError) + // .with_js_error()?; + // + // let (identifier_paths, _) = js_data_contract + // .inner() + // .get_identifiers_and_binary_paths(document_type) + // .with_js_error()?; + // + // // Errors are ignored. When `Buffer` crosses the WASM boundary it becomes an Array. + // // When `Identifier` crosses the WASM boundary it becomes a String. From perspective of JS + // // `Identifier` and `Buffer` are used interchangeably, so we we can expect the replacing may fail when `Buffer` is provided + // let _ = raw_document + // .replace_at_paths( + // identifier_paths + // .into_iter() + // .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS), + // ReplacementType::Identifier, + // ).map_err(ProtocolError::ValueError) + // .with_js_error()?; + // // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array let document = - ExtendedDocument::from_raw_document(raw_document, js_data_contract.to_owned().into()) + ExtendedDocument::from_platform_value(raw_document, js_data_contract.to_owned().into()) .with_js_error()?; Ok(document.into()) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 916232a277d..2b58c81a079 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -14,7 +14,7 @@ use dpp::{ self, document_create_transition, DocumentCreateTransition, DocumentTransitionObjectLike, }, prelude::{DataContract, Identifier}, - util::{json_schema::JsonSchemaExt}, + util::json_schema::JsonSchemaExt, ProtocolError, }; use serde::Serialize; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 69a58b7c05a..75a2a59bf37 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -13,7 +13,7 @@ use dpp::{ document_replace_transition, DocumentReplaceTransition, DocumentTransitionObjectLike, }, prelude::{DataContract, Identifier}, - util::{json_schema::JsonSchemaExt}, + util::json_schema::JsonSchemaExt, ProtocolError, }; use serde::Serialize; From 182e1bf821fe1f4c4c40ffba9bd0a243168ab1ad Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 02:58:24 +0700 Subject: [PATCH 080/228] more fixes --- .../document_transition/document_base_transition.rs | 5 +++-- .../validation/basic/validate_partial_compound_indices.rs | 5 +---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index 5c8f1ea7696..b1593f9afb9 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -198,8 +198,9 @@ impl DocumentTransitionObjectLike for DocumentBaseTransition { } fn to_json(&self) -> Result { - let value = serde_json::to_value(self)?; - Ok(value) + self.to_object()? + .try_into() + .map_err(ProtocolError::ValueError) } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index 06792aa6db7..0b3118928f6 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -7,10 +7,7 @@ use platform_value::Value; use crate::{ consensus::basic::BasicError, data_contract::DataContract, - util::{ - json_schema::{Index, JsonSchemaExt}, - json_value::JsonValueExt, - }, + util::json_schema::{Index, JsonSchemaExt}, validation::ValidationResult, ProtocolError, }; From df66bc00ab0dc872ab63b12f09fe70666bda35a8 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 09:43:28 +0700 Subject: [PATCH 081/228] fixed some warnings --- packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/extended_document.rs | 1 - .../document_transition/document_base_transition.rs | 5 +---- .../document_replace_transition.rs | 2 +- .../validation/basic/find_duplicates_by_indices.rs | 6 ++---- packages/wasm-dpp/src/document/extended_document.rs | 11 ++++------- .../document_transition/mod.rs | 1 - 7 files changed, 9 insertions(+), 19 deletions(-) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index b0441d0d656..e151db65213 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -12,7 +12,7 @@ use crate::util::hash::hash; use crate::ProtocolError; use crate::{ document::document_transition::DocumentTransition, get_from_transition, prelude::Identifier, - state_repository::StateRepositoryLike, util::json_value::JsonValueExt, + state_repository::StateRepositoryLike, }; use super::{create_error, DataTriggerExecutionContext, DataTriggerExecutionResult}; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index feea7e3bdad..bb1915e574c 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -12,7 +12,6 @@ use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; -use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::document::Document; use platform_value::btreemap_extensions::BTreeValueMapHelper; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index b1593f9afb9..40c1b68626a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -12,10 +12,7 @@ use serde_repr::*; use crate::document::document_transition::Action::{Create, Delete, Replace}; use crate::document::errors::DocumentError; -use crate::{ - data_contract::DataContract, errors::ProtocolError, identifier::Identifier, - util::json_value::JsonValueExt, -}; +use crate::{data_contract::DataContract, errors::ProtocolError, identifier::Identifier}; pub(self) mod property_names { pub const ID: &str = "$id"; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index da3b8f7d2b2..52e700769e9 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -10,7 +10,7 @@ use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::document::Document; use crate::identity::TimestampMillis; use crate::prelude::{ExtendedDocument, Revision}; -use crate::{data_contract::DataContract, errors::ProtocolError, util::json_value::JsonValueExt}; +use crate::{data_contract::DataContract, errors::ProtocolError}; use super::{document_base_transition::DocumentBaseTransition, DocumentTransitionObjectLike}; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index 9a3be338919..b6cbc76bb67 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -6,10 +6,8 @@ use std::collections::BTreeMap; use crate::data_contract::DriveContractExt; use crate::{ - document::document_transition::DocumentTransition, - prelude::DataContract, - util::{json_schema::Index, json_value::JsonValueExt}, - ProtocolError, + document::document_transition::DocumentTransition, prelude::DataContract, + util::json_schema::Index, ProtocolError, }; #[macro_export] diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 78d6e10b457..978a511f30e 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -1,12 +1,10 @@ use dpp::document::document_transition::document_base_transition::JsonValue; -use dpp::document::{ - extended_document_property_names, ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, -}; +use dpp::document::{ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS}; use dpp::platform_value::{ReplacementType, Value}; use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; -use dpp::util::json_value::{JsonValueExt, ReplaceWith}; +use dpp::util::json_value::JsonValueExt; use dpp::ProtocolError; use serde::{Deserialize, Serialize}; @@ -18,8 +16,7 @@ use crate::document::BinaryType; use crate::errors::RustConversionError; use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; use crate::lodash::lodash_set; -use crate::utils::{with_serde_to_json_value, ToSerdeJSONExt}; -use crate::utils::{with_serde_to_platform_value, WithJsError}; +use crate::utils::{with_serde_to_platform_value, ToSerdeJSONExt, WithJsError}; use crate::{with_js_error, ConversionOptions}; use crate::{DataContractWasm, MetadataWasm}; @@ -34,7 +31,7 @@ impl ExtendedDocumentWasm { js_raw_document: JsValue, js_data_contract: &DataContractWasm, ) -> Result { - let mut raw_document = with_serde_to_platform_value(&js_raw_document)?; + let raw_document = with_serde_to_platform_value(&js_raw_document)?; // let document_type = raw_document // .get_string(extended_document_property_names::DOCUMENT_TYPE).map_err(ProtocolError::ValueError) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index c631c8950ca..9ecbc131bc8 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -6,7 +6,6 @@ use anyhow::Context; pub use document_create_transition::*; pub use document_delete_transition::*; pub use document_replace_transition::*; -use std::convert::TryInto; use dpp::platform_value::Value; use dpp::{ From 42b4eccf1fc576347ee5f50127c2a415a6fe56e9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 10:50:12 +0700 Subject: [PATCH 082/228] more work --- .../rs-dpp/src/document/document_facade.rs | 2 +- .../rs-dpp/src/document/document_factory.rs | 26 +++++++++---------- .../document_base_transition.rs | 6 ++++- .../tests/fixtures/get_documents_fixture.rs | 20 +++++++------- .../fixtures/get_dpns_document_fixture.rs | 2 +- ...ternode_reward_shares_documents_fixture.rs | 2 +- .../rs-drive/src/drive/document/update.rs | 2 +- .../src/document/extended_document.rs | 18 +++++++++---- packages/wasm-dpp/src/document/factory.rs | 4 +-- packages/wasm-dpp/src/document/mod.rs | 26 ++++++++++++++----- .../document/DocumentFacade.spec.js | 18 +++++++------ 11 files changed, 76 insertions(+), 50 deletions(-) diff --git a/packages/rs-dpp/src/document/document_facade.rs b/packages/rs-dpp/src/document/document_facade.rs index e81ad53be90..9b7789a0765 100644 --- a/packages/rs-dpp/src/document/document_facade.rs +++ b/packages/rs-dpp/src/document/document_facade.rs @@ -57,7 +57,7 @@ where document_type_name: String, data: Value, ) -> Result { - self.factory.create_document_for_state_transition( + self.factory.create_extended_document_for_state_transition( data_contract, owner_id, document_type_name, diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index e4bb53f127d..6edb97402f6 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -106,7 +106,7 @@ where } } - pub fn create_document_for_state_transition( + pub fn create_extended_document_for_state_transition( &self, data_contract: DataContract, owner_id: Identifier, @@ -161,9 +161,9 @@ where }; let json_value = document.to_json_with_identifiers_using_bytes()?; - let validation_result = - self.document_validator - .validate(&json_value, &data_contract, document_type)?; + // let validation_result = + // self.document_validator + // .validate(&json_value, &data_contract, document_type)?; let extended_document = ExtendedDocument { protocol_version: self.protocol_version, @@ -175,14 +175,14 @@ where entropy: document_entropy, }; - if !validation_result.is_valid() { - return Err(ProtocolError::Document(Box::new( - DocumentError::InvalidDocumentError { - errors: validation_result.errors, - raw_document: json_value, - }, - ))); - } + // if !validation_result.is_valid() { + // return Err(ProtocolError::Document(Box::new( + // DocumentError::InvalidDocumentError { + // errors: validation_result.errors, + // raw_document: json_value, + // }, + // ))); + // } Ok(extended_document) } @@ -472,7 +472,7 @@ mod test { data_contract.id = contract_id; let document = factory - .create_document_for_state_transition( + .create_extended_document_for_state_transition( data_contract, owner_id, document_type.to_string(), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index 40c1b68626a..8242dba2614 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -120,7 +120,11 @@ impl DocumentBaseTransition { .remove_integer::(property_names::ACTION) .map_err(ProtocolError::ValueError)? .try_into()?, - data_contract_id: data_contract.id, + data_contract_id: Identifier::new( + map.remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID) + .map_err(ProtocolError::ValueError)? + .unwrap_or(data_contract.id.buffer), + ), data_contract, }) } diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index b220ff95c98..098845888a7 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -67,56 +67,56 @@ fn get_extended_documents( owner_id: Identifier, ) -> Result, ProtocolError> { let documents = vec![ - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "niceDocument".to_string(), json!({ "name": "Cutie" }).into(), )?, - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "prettyDocument".to_string(), json!({ "lastName": "Shiny" }).into(), )?, - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "prettyDocument".to_string(), json!({ "lastName": "Sweety" }).into(), )?, - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), json!( { "firstName": "William", "lastName": "Birkin" }).into(), )?, - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), json!( { "firstName": "Leon", "lastName": "Kennedy" }).into(), )?, - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "noTimeDocument".to_string(), json!({ "name": "ImOutOfTime" }).into(), )?, - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "uniqueDates".to_string(), json!({ "firstName": "John" }).into(), )?, - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), json!( { "firstName": "Bill", "lastName": "Gates" }).into(), )?, - factory.create_document_for_state_transition(data_contract.clone(), owner_id, "withByteArrays".to_string(), json!( { "byteArrayField": get_random_10_bytes(), "identifierField": gen_owner_id().to_buffer() }).into())?, - factory.create_document_for_state_transition( + factory.create_extended_document_for_state_transition(data_contract.clone(), owner_id, "withByteArrays".to_string(), json!( { "byteArrayField": get_random_10_bytes(), "identifierField": gen_owner_id().to_buffer() }).into())?, + factory.create_extended_document_for_state_transition( data_contract, owner_id, "optionalUniqueIndexedDocument".to_string(), diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs index 2fdcdfdd403..8c60782bec9 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs @@ -72,7 +72,7 @@ pub fn get_dpns_parent_document_fixture(options: ParentDocumentOptions) -> Exten ); document_factory - .create_document_for_state_transition( + .create_extended_document_for_state_transition( data_contract, options.owner_id, String::from("domain"), diff --git a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs index 71cb2af28ab..317ff0acc78 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs @@ -34,7 +34,7 @@ pub fn get_masternode_reward_shares_documents_fixture() -> (Vec Result<(), JsValue> { - self.0.document.properties = with_js_error!(serde_wasm_bindgen::from_value(d))?; + let properties_as_value = d.with_serde_to_platform_value()?; + self.0.document.properties = properties_as_value + .into_btree_map() + .map_err(ProtocolError::ValueError) + .with_js_error()?; Ok(()) } #[wasm_bindgen(js_name=getData)] pub fn get_data(&mut self) -> Result { - let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - - Ok(with_js_error!(self + let json_value: JsonValue = self .0 .document .properties - .serialize(&serializer))?) + .to_json_value() + .map_err(ProtocolError::ValueError) + .with_js_error()?; + + let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; + Ok(js_value) } #[wasm_bindgen(js_name=set)] diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 6169f4a432b..e83d2f5134f 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -109,10 +109,10 @@ impl DocumentFactoryWASM { data: &JsValue, ) -> Result { let owner_id = identifier_from_js_value(js_owner_id)?; - let dynamic_data = data.with_serde_to_json_value()?; + let dynamic_data = data.with_serde_to_platform_value()?; let document = self .0 - .create_document_for_state_transition( + .create_extended_document_for_state_transition( data_contract.into(), owner_id, document_type.to_string(), diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 89643bd5c2e..20323b2f747 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -36,6 +36,7 @@ pub use extended_document::ExtendedDocumentWasm; use dpp::document::extended_document::property_names; use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; use dpp::platform_value::ReplacementType; use dpp::platform_value::Value; use dpp::ProtocolError; @@ -129,16 +130,27 @@ impl DocumentWasm { self.0.revision.map(|r| r as u32) } - #[wasm_bindgen(js_name=setProperties)] - pub fn set_properties(&mut self, d: JsValue) -> Result<(), JsValue> { - self.0.properties = with_js_error!(serde_wasm_bindgen::from_value(d))?; + #[wasm_bindgen(js_name=setData)] + pub fn set_data(&mut self, d: JsValue) -> Result<(), JsValue> { + let properties_as_value = d.with_serde_to_platform_value()?; + self.0.properties = properties_as_value + .into_btree_map() + .map_err(ProtocolError::ValueError) + .with_js_error()?; Ok(()) } - #[wasm_bindgen(js_name=getProperties)] - pub fn get_properties(&mut self) -> Result { - let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - Ok(with_js_error!(self.0.properties.serialize(&serializer))?) + #[wasm_bindgen(js_name=getData)] + pub fn get_data(&mut self) -> Result { + let json_value: JsonValue = self + .0 + .properties + .to_json_value() + .map_err(ProtocolError::ValueError) + .with_js_error()?; + + let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; + Ok(js_value) } #[wasm_bindgen(js_name=set)] diff --git a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js index e99cb705041..78bf1521e4b 100644 --- a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js +++ b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js @@ -7,7 +7,7 @@ const getDocumentTransitionsFixture = require('@dashevo/dpp/lib/test/fixtures/ge const { default: loadWasmDpp } = require('../../../dist'); const getBlsAdapterMock = require('../../../lib/test/mocks/getBlsAdapterMock'); -let Document; +let ExtendedDocument; let DataContract; let Identifier; let ValidationResult; @@ -27,7 +27,7 @@ describe('DocumentFacade', () => { beforeEach(async function beforeEach() { ({ - Document, + ExtendedDocument, DataContract, Identifier, ValidationResult, @@ -49,7 +49,7 @@ describe('DocumentFacade', () => { documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { - const currentDocument = new Document(d.toObject(), dataContract.clone()); + const currentDocument = new ExtendedDocument(d.toObject(), dataContract.clone()); currentDocument.setEntropy(d.entropy); return currentDocument; }); @@ -58,14 +58,16 @@ describe('DocumentFacade', () => { describe('create', () => { it('should create Document - Rust', async () => { + const documentType = document.getType(); + const documentData = document.getData(); const result = dpp.document.create( dataContract, ownerId, - document.getType(), - document.getData(), + documentType, + documentData, ); - expect(result).to.be.an.instanceOf(Document); + expect(result).to.be.an.instanceOf(ExtendedDocument); expect(result.getType()).to.equal(document.getType()); expect(result.getData()).to.deep.equal(document.getData()); @@ -80,7 +82,7 @@ describe('DocumentFacade', () => { it('should create Document from plain object - Rust', async () => { const result = await dpp.document.createFromObject(document.toObject()); - expect(result).to.be.an.instanceOf(Document); + expect(result).to.be.an.instanceOf(ExtendedDocument); expect(result.toObject()).to.deep.equal(document.toObject()); }); @@ -94,7 +96,7 @@ describe('DocumentFacade', () => { it('should create Document from serialized - Rust', async () => { const result = await dpp.document.createFromBuffer(document.toBuffer()); - expect(result).to.be.an.instanceOf(Document); + expect(result).to.be.an.instanceOf(ExtendedDocument); expect(result.toObject()).to.deep.equal(document.toObject()); }); From c2f77cfc9a0eb154e98c13518c1b6a322a4a9e78 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 11:41:16 +0700 Subject: [PATCH 083/228] renamed classes --- packages/wasm-dpp/src/document/extended_document.rs | 4 ++-- packages/wasm-dpp/src/document/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index b5d8a30d5ed..b2e31f0fb5f 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -21,11 +21,11 @@ use crate::utils::{with_serde_to_platform_value, ToSerdeJSONExt, WithJsError}; use crate::{with_js_error, ConversionOptions}; use crate::{DataContractWasm, MetadataWasm}; -#[wasm_bindgen(js_name=ExtendedDocument)] +#[wasm_bindgen(js_name=Document)] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExtendedDocumentWasm(pub(crate) ExtendedDocument); -#[wasm_bindgen(js_class=ExtendedDocument)] +#[wasm_bindgen(js_class=Document)] impl ExtendedDocumentWasm { #[wasm_bindgen(constructor)] pub fn new( diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 20323b2f747..c7e8b189c1b 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -57,11 +57,11 @@ pub(super) enum BinaryType { None, } -#[wasm_bindgen(js_name=Document)] +#[wasm_bindgen(js_name=ReducedDocument)] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DocumentWasm(Document); -#[wasm_bindgen(js_class=Document)] +#[wasm_bindgen(js_class=ReducedDocument)] impl DocumentWasm { #[wasm_bindgen(constructor)] pub fn new( From 82510076d400f5ca38685730c3140d02c274f50a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 13:50:06 +0700 Subject: [PATCH 084/228] more fixes --- .../basic/find_duplicates_by_indices.rs | 4 +- packages/rs-platform-value/src/inner_value.rs | 37 +++++++++++++++++++ .../errors/data_contract_already_exists.rs | 1 - .../errors/data_contract_generic_error.rs | 23 ++++++++++++ .../wasm-dpp/src/data_contract/errors/mod.rs | 9 +++-- .../src/document/extended_document.rs | 4 +- packages/wasm-dpp/src/document/mod.rs | 4 +- .../basic/find_duplicates_by_indices.rs | 14 ++++++- packages/wasm-dpp/src/identifier/mod.rs | 2 +- .../basic/findDuplicatesByIndices.spec.js | 9 ++++- 10 files changed, 92 insertions(+), 15 deletions(-) delete mode 100644 packages/wasm-dpp/src/data_contract/errors/data_contract_already_exists.rs create mode 100644 packages/wasm-dpp/src/data_contract/errors/data_contract_generic_error.rs diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index b6cbc76bb67..2186fa33c2e 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -24,7 +24,7 @@ macro_rules! get_from_transition { /// Finds duplicates of indices in Document Transitions. pub fn find_duplicates_by_indices<'a>( - document_raw_transitions: impl IntoIterator, + raw_extended_documents: impl IntoIterator, data_contract: &'a DataContract, ) -> Result, ProtocolError> { #[derive(Debug)] @@ -34,7 +34,7 @@ pub fn find_duplicates_by_indices<'a>( } let mut groups: BTreeMap<&'a str, Group> = BTreeMap::new(); - for dt in document_raw_transitions.into_iter() { + for dt in raw_extended_documents.into_iter() { let document_type_name = dt.get_string("$type")?; let document_type = data_contract.document_type_for_name(document_type_name)?; match groups.entry(document_type_name) { diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 9a49531a5b0..8c7ffb2bbe4 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,3 +1,5 @@ +use crate::value_map::{ValueMap, ValueMapHelper}; +use crate::Value::Bool; use crate::{Error, Value}; use std::collections::BTreeMap; @@ -7,6 +9,16 @@ impl Value { Self::get_from_map(map, key) } + pub fn set_value(&mut self, key: &str, value: Value) -> Result<(), Error> { + let map = self.as_map_mut_ref()?; + Ok(Self::insert_in_map(map, key, value)) + } + + pub fn remove_value(&mut self, key: &str) -> Result, Error> { + let map = self.as_map_mut_ref()?; + Ok(map.remove_key(key)) + } + pub fn get_string<'a>(&'a self, key: &'a str) -> Result<&'a str, Error> { let map = self.to_map()?; Self::inner_text_value(map, key) @@ -167,4 +179,29 @@ impl Value { } None } + + /// Inserts into a map + /// If the element already existed it will replace it + pub fn insert_in_map<'a>( + map: &'a mut ValueMap, + inserting_key: &'a str, + inserting_value: Value, + ) { + let mut found_value = None; + for (key, value) in map.iter_mut() { + if !key.is_text() { + continue; + } + + if key.as_text().expect("confirmed as text") == inserting_key { + found_value = Some(value); + break; + } + } + if let Some(value) = found_value { + *value = inserting_value; + } else { + map.push((Value::Text(inserting_key.to_string()), inserting_value)) + } + } } diff --git a/packages/wasm-dpp/src/data_contract/errors/data_contract_already_exists.rs b/packages/wasm-dpp/src/data_contract/errors/data_contract_already_exists.rs deleted file mode 100644 index 0f01e7ca379..00000000000 --- a/packages/wasm-dpp/src/data_contract/errors/data_contract_already_exists.rs +++ /dev/null @@ -1 +0,0 @@ -// TODO: Implement diff --git a/packages/wasm-dpp/src/data_contract/errors/data_contract_generic_error.rs b/packages/wasm-dpp/src/data_contract/errors/data_contract_generic_error.rs new file mode 100644 index 00000000000..73abfcd0b8a --- /dev/null +++ b/packages/wasm-dpp/src/data_contract/errors/data_contract_generic_error.rs @@ -0,0 +1,23 @@ +use crate::errors::consensus_error::from_consensus_error_ref; +use dpp::consensus::ConsensusError; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(js_name=DataContractGenericError)] +#[derive(Debug)] +pub struct DataContractGenericError { + message: String, +} + +impl DataContractGenericError { + pub fn new(message: String) -> Self { + DataContractGenericError { message } + } +} + +#[wasm_bindgen(js_class=DataContractGenericError)] +impl DataContractGenericError { + #[wasm_bindgen(js_name=getMessage)] + pub fn get_message(&self) -> String { + self.message.clone() + } +} diff --git a/packages/wasm-dpp/src/data_contract/errors/mod.rs b/packages/wasm-dpp/src/data_contract/errors/mod.rs index aef56e812d7..c09904e9465 100644 --- a/packages/wasm-dpp/src/data_contract/errors/mod.rs +++ b/packages/wasm-dpp/src/data_contract/errors/mod.rs @@ -1,10 +1,10 @@ -mod data_contract_already_exists; +mod data_contract_generic_error; mod invalid_data_contract; mod invalid_document_type; use wasm_bindgen::prelude::*; -pub use data_contract_already_exists::*; +pub use data_contract_generic_error::*; use dpp::data_contract::errors::DataContractError; pub use invalid_data_contract::*; @@ -27,6 +27,9 @@ pub fn from_data_contract_to_js_error(e: DataContractError) -> JsValue { data_contract.into(), ) .into(), - _ => todo!(), + other => { + DataContractGenericError::new(format!("data contract error: {}", other.to_string())) + .into() + } } } diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index b2e31f0fb5f..b5d8a30d5ed 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -21,11 +21,11 @@ use crate::utils::{with_serde_to_platform_value, ToSerdeJSONExt, WithJsError}; use crate::{with_js_error, ConversionOptions}; use crate::{DataContractWasm, MetadataWasm}; -#[wasm_bindgen(js_name=Document)] +#[wasm_bindgen(js_name=ExtendedDocument)] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExtendedDocumentWasm(pub(crate) ExtendedDocument); -#[wasm_bindgen(js_class=Document)] +#[wasm_bindgen(js_class=ExtendedDocument)] impl ExtendedDocumentWasm { #[wasm_bindgen(constructor)] pub fn new( diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index c7e8b189c1b..20323b2f747 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -57,11 +57,11 @@ pub(super) enum BinaryType { None, } -#[wasm_bindgen(js_name=ReducedDocument)] +#[wasm_bindgen(js_name=Document)] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DocumentWasm(Document); -#[wasm_bindgen(js_class=ReducedDocument)] +#[wasm_bindgen(js_class=Document)] impl DocumentWasm { #[wasm_bindgen(constructor)] pub fn new( diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index 0f0011df616..be294096580 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -8,6 +8,8 @@ use itertools::Itertools; use js_sys::Array; use wasm_bindgen::prelude::*; +use crate::identifier::IdentifierWrapper; +use crate::utils::with_serde_to_platform_value; use crate::{ document_batch_transition::document_transition::to_object, utils::{ToSerdeJSONExt, WithJsError}, @@ -18,7 +20,9 @@ use crate::{ pub fn find_duplicates_by_indices_wasm( js_raw_transitions: &Array, data_contract: &DataContractWasm, + owner_id: &IdentifierWrapper, ) -> Result, JsValue> { + let mut owner_id_value: Value = Value::Identifier(owner_id.inner().buffer); let raw_transitions: Vec = js_raw_transitions .iter() .map(|transition| { @@ -30,18 +34,24 @@ pub fn find_duplicates_by_indices_wasm( ) .map_err(ProtocolError::ValueError) .with_js_error()?; + value.set_value("$ownerId", owner_id_value.clone()); Ok(value) }) .collect::, JsValue>>()?; - let result = + let mut result = find_duplicates_by_indices(&raw_transitions, data_contract.inner()).with_js_error()?; let duplicates: Vec = result .into_iter() .map(|v| { + let mut value = v.clone(); + value + .remove_value("$ownerId") + .map_err(ProtocolError::ValueError) + .with_js_error()?; to_object( - v.to_owned().into(), + value, &JsValue::NULL, document_base_transition::IDENTIFIER_FIELDS, document_create_transition::BINARY_FIELDS, diff --git a/packages/wasm-dpp/src/identifier/mod.rs b/packages/wasm-dpp/src/identifier/mod.rs index 29bd35e85ed..19f1916f214 100644 --- a/packages/wasm-dpp/src/identifier/mod.rs +++ b/packages/wasm-dpp/src/identifier/mod.rs @@ -138,7 +138,7 @@ impl IdentifierWrapper { } impl IdentifierWrapper { - pub fn inner(self) -> Identifier { + pub fn inner(&self) -> Identifier { self.wrapped } } diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js index 53a3586902b..9c81cbc432d 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesByIndices.spec.js @@ -8,6 +8,7 @@ const { generate: generateEntropy } = require('@dashevo/dpp/lib/util/entropyGene const { default: loadWasmDpp } = require('../../../../../../../dist'); let DataContract; +let Identifier; let findDuplicatesByIndices; describe('findDuplicatesByIndices', () => { @@ -20,6 +21,7 @@ describe('findDuplicatesByIndices', () => { ({ DataContract, findDuplicatesByIndices, + Identifier, } = await loadWasmDpp()); contractJs = getDataContractFixture(); contractJs.setDocumentSchema('nonUniqueIndexDocument', { @@ -108,12 +110,13 @@ describe('findDuplicatesByIndices', () => { const [, , , , leon] = documents; leon.set('lastName', 'Birkin'); + const ownerId = Identifier.from(leon.ownerId); documentTransitions = getDocumentTransitionsFixture({ create: documents, }).map((t) => t.toObject()); - const duplicates = findDuplicatesByIndices(documentTransitions, contract); + const duplicates = findDuplicatesByIndices(documentTransitions, contract, ownerId); expect(duplicates.length).to.equal(2); expect(duplicates).to.have.deep.members( @@ -125,7 +128,9 @@ describe('findDuplicatesByIndices', () => { }); it('should return an empty array of there are no duplicates - Rust', () => { - const duplicates = findDuplicatesByIndices(documentTransitions, contract); + const [, , , , leon] = documents; + const ownerId = Identifier.from(leon.ownerId); + const duplicates = findDuplicatesByIndices(documentTransitions, contract, ownerId); expect(duplicates.length).to.equal(0); }); From ad4edb00cd2bd949e12e77b2b8f7d3b9f091d121 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 14:46:20 +0700 Subject: [PATCH 085/228] fixes --- .../rs-dpp/src/document/extended_document.rs | 7 +- packages/rs-platform-value/src/error.rs | 2 +- packages/wasm-dpp/src/errors/from.rs | 2 + packages/wasm-dpp/src/errors/mod.rs | 1 + packages/wasm-dpp/src/errors/value_error.rs | 40 +++++++++ .../test/unit/document/Document.spec.js | 87 ++++++++++++++++--- ...plyDocumentsBatchTransitionFactory.spec.js | 2 +- 7 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 packages/wasm-dpp/src/errors/value_error.rs diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index bb1915e574c..0354fc8fe59 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -12,6 +12,7 @@ use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; +use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::document::Document; use platform_value::btreemap_extensions::BTreeValueMapHelper; @@ -169,9 +170,11 @@ impl ExtendedDocument { ..Default::default() }; + // if the protocol version is not set, use the current protocol version extended_document.protocol_version = properties - .remove_integer(property_names::PROTOCOL_VERSION) - .map_err(ProtocolError::ValueError)?; + .remove_optional_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)? + .unwrap_or(PROTOCOL_VERSION); extended_document.data_contract_id = Identifier::new( properties .remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index 7ef71fa9bf6..529f5157d1d 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -1,6 +1,6 @@ use thiserror::Error; -#[derive(Error, Eq, PartialEq, Debug)] +#[derive(Error, Clone, Eq, PartialEq, Debug)] pub enum Error { #[error("unsupported: {0}")] Unsupported(String), diff --git a/packages/wasm-dpp/src/errors/from.rs b/packages/wasm-dpp/src/errors/from.rs index c913db2d259..f6ea4d3a8ae 100644 --- a/packages/wasm-dpp/src/errors/from.rs +++ b/packages/wasm-dpp/src/errors/from.rs @@ -4,6 +4,7 @@ use dpp::errors::ProtocolError; use crate::data_contract::errors::from_data_contract_to_js_error; use crate::document::errors::from_document_to_js_error; +use crate::errors::value_error::PlatformValueErrorWasm; use super::consensus_error::from_consensus_error; use super::data_contract_not_present_error::DataContractNotPresentNotConsensusErrorWasm; @@ -28,6 +29,7 @@ pub fn from_dpp_err(pe: ProtocolError) -> JsValue { ProtocolError::DataContractNotPresentError { data_contract_id } => { DataContractNotPresentNotConsensusErrorWasm::new(data_contract_id).into() } + ProtocolError::ValueError(value_error) => PlatformValueErrorWasm::new(value_error).into(), _ => JsValue::from_str(&format!("Error conversion not implemented: {pe:#}",)), } } diff --git a/packages/wasm-dpp/src/errors/mod.rs b/packages/wasm-dpp/src/errors/mod.rs index 68db9899f60..5f0ee301a2d 100644 --- a/packages/wasm-dpp/src/errors/mod.rs +++ b/packages/wasm-dpp/src/errors/mod.rs @@ -13,3 +13,4 @@ pub use public_key_validation_error::*; pub mod data_contract_not_present_error; pub mod dpp_error; +mod value_error; diff --git a/packages/wasm-dpp/src/errors/value_error.rs b/packages/wasm-dpp/src/errors/value_error.rs new file mode 100644 index 00000000000..54286d17736 --- /dev/null +++ b/packages/wasm-dpp/src/errors/value_error.rs @@ -0,0 +1,40 @@ +use dpp::platform_value::Error as PlatformValueError; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsValue; + +#[wasm_bindgen(js_name=PlatformValueError)] +pub struct PlatformValueErrorWasm { + message: String, +} + +impl From for PlatformValueErrorWasm { + fn from(e: PlatformValueError) -> Self { + Self { + message: e.to_string(), + } + } +} + +impl From<&PlatformValueError> for PlatformValueErrorWasm { + fn from(e: &PlatformValueError) -> Self { + Self { + message: e.to_string(), + } + } +} + +impl PlatformValueErrorWasm { + pub fn new(e: PlatformValueError) -> Self { + PlatformValueErrorWasm { + message: e.to_string(), + } + } +} + +#[wasm_bindgen(js_class=PlatformValueError)] +impl PlatformValueErrorWasm { + #[wasm_bindgen(js_name=getMessage)] + pub fn get_message(&self) -> String { + self.message.clone() + } +} diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index 3b4816f0b59..6c5d824bf34 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -14,6 +14,7 @@ const { default: loadWasmDpp } = require('../../../dist'); let DataContractFactory; let DataContractValidator; +let PlatformValueError; let Identifier; let ExtendedDocument; @@ -30,7 +31,7 @@ describe('Document', () => { // eslint-disable-next-line prefer-arrow-callback beforeEach(async function beforeEach() { ({ - Identifier, DataContractFactory, DataContractValidator, ExtendedDocument, + Identifier, DataContractFactory, DataContractValidator, ExtendedDocument, PlatformValueError, } = await loadWasmDpp()); const now = new Date().getTime(); @@ -112,12 +113,13 @@ describe('Document', () => { }); describe('constructor', () => { - it('should create Document with $id and data if present', async () => { + it('should create ExtendedDocument with $id and data if present', async () => { const data = { test: 1, }; rawDocument = { + $ownerId: await generateRandomIdentifierAsync(), $id: await generateRandomIdentifierAsync(), $type: 'test', ...data, @@ -127,7 +129,7 @@ describe('Document', () => { expect(document.getId().toBuffer()).to.deep.equal(rawDocument.$id.toBuffer()); }); - it('should create Document with $type and data if present', () => { + it('should create DocumentCreateTransition with $type and data if present', () => { const data = { test: 1, }; @@ -142,45 +144,95 @@ describe('Document', () => { expect(document.getType()).to.equal(rawDocument.$type); }); - it('should create Document with $dataContractId and data if present', async () => { + it('should not create ExtendedDocument if $ownerId is missing', async () => { const data = { test: 1, }; rawDocument = { + $id: await generateRandomIdentifierAsync(), $dataContractId: await generateRandomIdentifierAsync(), $type: 'test', ...data, }; - document = new ExtendedDocument(rawDocument, dataContract); - - expect(document.getDataContractId().toBuffer()) - .to.deep.equal(rawDocument.$dataContractId.toBuffer()); + try { + document = new ExtendedDocument(rawDocument, dataContract); + } catch (e) { + expect(e).to.be.instanceOf(PlatformValueError); + expect(e.getMessage()).to.equal('structure error: unable to remove system hash256 property $ownerId'); + } }); - it('should create Document with $ownerId and data if present', async () => { + it('should not create ExtendedDocument if $id is missing', async () => { const data = { test: 1, }; rawDocument = { $ownerId: await generateRandomIdentifierAsync(), + $dataContractId: await generateRandomIdentifierAsync(), $type: 'test', ...data, }; - document = new ExtendedDocument(rawDocument, dataContract); + try { + document = new ExtendedDocument(rawDocument, dataContract); + } catch (e) { + expect(e).to.be.instanceOf(PlatformValueError); + expect(e.getMessage()).to.equal('structure error: unable to remove system hash256 property $id'); + } + }); - expect(document.getOwnerId().toBuffer()).to.deep.equal(rawDocument.$ownerId.toBuffer()); + it('should not create ExtendedDocument if $type is missing', async () => { + const data = { + test: 1, + }; + + rawDocument = { + $id: await generateRandomIdentifierAsync(), + $ownerId: await generateRandomIdentifierAsync(), + $dataContractId: await generateRandomIdentifierAsync(), + ...data, + }; + + try { + document = new ExtendedDocument(rawDocument, dataContract); + } catch (e) { + expect(e).to.be.instanceOf(PlatformValueError); + expect(e.getMessage()).to.equal('structure error: unable to remove string property $type'); + } + }); + + it('should not create ExtendedDocument if $dataContractId is missing', async () => { + const data = { + test: 1, + }; + + rawDocument = { + $id: await generateRandomIdentifierAsync(), + $ownerId: await generateRandomIdentifierAsync(), + $type: 'test', + ...data, + }; + + try { + document = new ExtendedDocument(rawDocument, dataContract); + } catch (e) { + expect(e).to.be.instanceOf(PlatformValueError); + expect(e.getMessage()).to.equal('structure error: unable to remove system hash256 property $dataContractId'); + } }); - it('should create Document with undefined action and data if present', () => { + it('should create Document with undefined action and data if present', async () => { const data = { test: 1, }; rawDocument = { + $id: await generateRandomIdentifierAsync(), + $ownerId: await generateRandomIdentifierAsync(), + $dataContractId: await generateRandomIdentifierAsync(), $type: 'test', ...data, }; @@ -189,12 +241,15 @@ describe('Document', () => { expect(document.get('action')).to.equal(undefined); }); - it('should create Document with $revision and data if present', () => { + it('should create Document with $revision and data if present', async () => { const data = { test: 1, }; rawDocument = { + $id: await generateRandomIdentifierAsync(), + $ownerId: await generateRandomIdentifierAsync(), + $dataContractId: await generateRandomIdentifierAsync(), $revision: 123, $type: 'test', ...data, @@ -213,6 +268,9 @@ describe('Document', () => { const createdAt = new Date().getTime(); rawDocument = { + $id: await generateRandomIdentifierAsync(), + $ownerId: await generateRandomIdentifierAsync(), + $dataContractId: await generateRandomIdentifierAsync(), $createdAt: createdAt, $type: 'test', ...data, @@ -231,6 +289,9 @@ describe('Document', () => { const updatedAt = new Date().getTime(); rawDocument = { + $dataContractId: await generateRandomIdentifierAsync(), + $ownerId: await generateRandomIdentifierAsync(), + $id: await generateRandomIdentifierAsync(), $updatedAt: updatedAt, $type: 'test', ...data, diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js index 648438e2874..d8adb7957ba 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js @@ -241,7 +241,7 @@ describe('applyDocumentsBatchTransitionFactory', () => { $id: documentTransition.getId(), $type: documentTransition.getType(), $dataContractId: documentTransition.getDataContractId(), - $ownerId: stateTransitionJs.getOwnerId(), + $ownerId: ownerId, $createdAt: blockTimeMs, ...documentTransition.getData(), }, documentTransition.getDataContract()); From adedff822f01ca663edc597e0773c27c3d97c1e5 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 15:27:11 +0700 Subject: [PATCH 086/228] more fixes --- .../apply_documents_batch_transition_factory.rs | 2 +- .../document_transition/document_replace_transition.rs | 8 +++++--- .../applyDocumentsBatchTransitionFactory.spec.js | 5 ++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 5d3ad42a8f9..6c83618c1c5 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -75,7 +75,7 @@ pub async fn apply_documents_batch_transition( DocumentTransition::Replace(document_replace_transition) => { if state_transition.execution_context.is_dry_run() { let document = - document_replace_transition.to_extended_document_for_dry_run()?; + document_replace_transition.to_extended_document_for_dry_run(state_transition.owner_id)?; state_repository .update_document(&document, state_transition.get_execution_context()) .await?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 52e700769e9..d39d8d313cd 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -11,6 +11,7 @@ use crate::document::Document; use crate::identity::TimestampMillis; use crate::prelude::{ExtendedDocument, Revision}; use crate::{data_contract::DataContract, errors::ProtocolError}; +use crate::identifier::Identifier; use super::{document_base_transition::DocumentBaseTransition, DocumentTransitionObjectLike}; @@ -36,11 +37,11 @@ pub struct DocumentReplaceTransition { } impl DocumentReplaceTransition { - pub(crate) fn to_document_for_dry_run(&self) -> Result { + pub(crate) fn to_document_for_dry_run(&self, owner_id: Identifier) -> Result { let properties = self.data.clone().unwrap_or_default(); Ok(Document { id: self.base.id.to_buffer(), - owner_id: [0; 32], //0s are fine here + owner_id: owner_id.buffer, properties, created_at: self.updated_at, // we can use the same time, as it can't be worse updated_at: self.updated_at, @@ -50,12 +51,13 @@ impl DocumentReplaceTransition { pub(crate) fn to_extended_document_for_dry_run( &self, + owner_id: Identifier, ) -> Result { Ok(ExtendedDocument { protocol_version: PROTOCOL_VERSION, document_type_name: self.base.document_type_name.clone(), data_contract_id: self.base.data_contract_id, - document: self.to_document_for_dry_run()?, + document: self.to_document_for_dry_run(owner_id)?, data_contract: self.base.data_contract.clone(), metadata: None, entropy: [0; 32], diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js index d8adb7957ba..99d16d84976 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js @@ -232,17 +232,16 @@ describe('applyDocumentsBatchTransitionFactory', () => { stateTransition.getExecutionContext().disableDryRun(); - expect(stateRepositoryMock.fetchLatestPlatformBlockTime).to.have.been.calledOnceWith(); - const [documentTransition] = stateTransition.getTransitions(); + // the owner_id are 0s in dry_run const newDocument = new ExtendedDocument({ $protocolVersion: stateTransitionJs.getProtocolVersion(), $id: documentTransition.getId(), $type: documentTransition.getType(), $dataContractId: documentTransition.getDataContractId(), $ownerId: ownerId, - $createdAt: blockTimeMs, + $createdAt: documentTransition.getUpdatedAt(), ...documentTransition.getData(), }, documentTransition.getDataContract()); From 1415c557b9b179e10c2aa4f7300d7713462d7f79 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 15:44:04 +0700 Subject: [PATCH 087/228] more fixes --- packages/rs-dpp/src/document/document_factory.rs | 4 ++-- packages/rs-dpp/src/document/extended_document.rs | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 6edb97402f6..00f83ad6890 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -332,7 +332,7 @@ where ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { - if document.needs_revision() { + if document.needs_revision()? { let Some(revision) = document.revision() else { return Err(DocumentError::RevisionAbsentError { document: Box::new(document), @@ -366,7 +366,7 @@ where ) -> Result, ProtocolError> { let mut raw_transitions = vec![]; for document in documents { - if !document.can_be_modified() { + if !document.can_be_modified()? { return Err(DocumentError::TryingToReplaceImmutableDocument { document: Box::new(document), } diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 0354fc8fe59..71c4ed92625 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -108,19 +108,18 @@ impl ExtendedDocument { Identifier::new(self.document.owner_id) } - pub fn document_type(&self) -> &DocumentType { + pub fn document_type(&self) -> Result<&DocumentType, ProtocolError> { // We can unwrap because the Document can not be created without a valid Document Type self.data_contract .document_type_for_name(self.document_type_name.as_str()) - .unwrap() } - pub fn can_be_modified(&self) -> bool { - self.document_type().documents_mutable + pub fn can_be_modified(&self) -> Result { + self.document_type().map(|document_type| document_type.documents_mutable) } - pub fn needs_revision(&self) -> bool { - self.document_type().documents_mutable + pub fn needs_revision(&self) -> Result { + self.document_type().map(|document_type| document_type.documents_mutable) } pub fn revision(&self) -> Option<&Revision> { From 40b352cd232598b6fdd1478999fd4affefac8515 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 16:13:45 +0700 Subject: [PATCH 088/228] another fix --- .../rs-dpp/src/data_contract/data_contract.rs | 53 ++++++++++++++++--- .../document_type/document_type.rs | 6 +-- .../rs-dpp/src/document/extended_document.rs | 8 +-- ...pply_documents_batch_transition_factory.rs | 4 +- .../document_delete_transition.rs | 6 +-- .../document_replace_transition.rs | 7 ++- 6 files changed, 63 insertions(+), 21 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 972ad11f04a..148a0e20fb4 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -113,18 +113,48 @@ impl DataContract { // TODO identifier_default_deserializer: default deserializer should be changed to bytes // Identifiers fields should be replaced with the string format to deserialize Data Contract raw_object.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Base58)?; + let value: Value = raw_object.clone().into(); + let data_contract_map = value.into_btree_map().map_err(ProtocolError::ValueError)?; let mut data_contract: DataContract = serde_json::from_value(raw_object)?; data_contract.generate_binary_properties(); + let mutability = get_contract_configuration_properties(&data_contract_map) + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + let definition_references = get_definitions(&data_contract_map)?; + let document_types = get_document_types( + &data_contract_map, + definition_references, + mutability.documents_keep_history_contract_default, + mutability.documents_mutable_contract_default, + ) + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + + data_contract.document_types = document_types; + Ok(data_contract) } pub fn from_json_object(mut json_value: JsonValue) -> Result { json_value.replace_binary_paths(BINARY_FIELDS, ReplaceWith::Bytes)?; + let value: Value = json_value.clone().into(); + let data_contract_map = value.into_btree_map().map_err(ProtocolError::ValueError)?; let mut data_contract: DataContract = serde_json::from_value(json_value)?; data_contract.generate_binary_properties(); + let mutability = get_contract_configuration_properties(&data_contract_map) + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + let definition_references = get_definitions(&data_contract_map)?; + let document_types = get_document_types( + &data_contract_map, + definition_references, + mutability.documents_keep_history_contract_default, + mutability.documents_mutable_contract_default, + ) + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + + data_contract.document_types = document_types; + Ok(data_contract) } @@ -393,14 +423,13 @@ pub fn get_document_types( documents_keep_history_contract_default: bool, documents_mutable_contract_default: bool, ) -> Result, ProtocolError> { - let documents_cbor_value = + let Some(documents_value) = contract - .get("documents") - .ok_or(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey("unable to get documents"), - ))?; + .get("documents") else { + return Ok(BTreeMap::new()); + }; let contract_document_types_raw = - documents_cbor_value + documents_value .as_map() .ok_or(ProtocolError::DataContractError( DataContractError::InvalidContractStructure("documents must be a map"), @@ -490,6 +519,10 @@ mod test { data_contract_restored.binary_properties ); assert_eq!(data_contract.documents, data_contract_restored.documents); + assert_eq!( + data_contract.document_types, + data_contract_restored.document_types + ); } #[test] @@ -518,6 +551,10 @@ mod test { data_contract_restored.binary_properties ); assert_eq!(data_contract.documents, data_contract_restored.documents); + assert_eq!( + data_contract.document_types, + data_contract_restored.document_types + ); } #[test] @@ -553,6 +590,10 @@ mod test { data_contract_restored.binary_properties ); assert_eq!(data_contract.documents, data_contract_restored.documents); + assert_eq!( + data_contract.document_types, + data_contract_restored.document_types + ); } #[test] diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index 1640d77d38c..17e33b52e84 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -218,11 +218,7 @@ impl DocumentType { // Extract the properties let property_values = Value::inner_optional_btree_map(document_type_value_map, property_names::PROPERTIES)? - .ok_or({ - ProtocolError::DataContractError(DataContractError::InvalidContractStructure( - "unable to get document properties from the contract", - )) - })?; + .unwrap_or_default(); let mut required_fields = Value::inner_optional_array_of_strings( document_type_value_map, diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 71c4ed92625..2aa1460c4e9 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -114,12 +114,14 @@ impl ExtendedDocument { .document_type_for_name(self.document_type_name.as_str()) } - pub fn can_be_modified(&self) -> Result { - self.document_type().map(|document_type| document_type.documents_mutable) + pub fn can_be_modified(&self) -> Result { + self.document_type() + .map(|document_type| document_type.documents_mutable) } pub fn needs_revision(&self) -> Result { - self.document_type().map(|document_type| document_type.documents_mutable) + self.document_type() + .map(|document_type| document_type.documents_mutable) } pub fn revision(&self) -> Option<&Revision> { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 6c83618c1c5..1f03682c534 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -74,8 +74,8 @@ pub async fn apply_documents_batch_transition( } DocumentTransition::Replace(document_replace_transition) => { if state_transition.execution_context.is_dry_run() { - let document = - document_replace_transition.to_extended_document_for_dry_run(state_transition.owner_id)?; + let document = document_replace_transition + .to_extended_document_for_dry_run(state_transition.owner_id)?; state_repository .update_document(&document, state_transition.get_execution_context()) .await?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs index ff9ef6274cc..54db8790a8f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs @@ -76,10 +76,10 @@ mod test { fn test_deserialize_serialize_to_json() { init(); let transition_json = r#"{ + "$action": 3, + "$dataContractId": "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8", "$id": "6oCKUeLVgjr7VZCyn1LdGbrepqKLmoabaff5WQqyTKYP", - "$type": "note", - "$action": 3, - "$dataContractId": "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8" + "$type": "note" }"#; let cdt: DocumentDeleteTransition = diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index d39d8d313cd..c73b95be9b6 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -8,10 +8,10 @@ use std::convert::TryInto; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::document::Document; +use crate::identifier::Identifier; use crate::identity::TimestampMillis; use crate::prelude::{ExtendedDocument, Revision}; use crate::{data_contract::DataContract, errors::ProtocolError}; -use crate::identifier::Identifier; use super::{document_base_transition::DocumentBaseTransition, DocumentTransitionObjectLike}; @@ -37,7 +37,10 @@ pub struct DocumentReplaceTransition { } impl DocumentReplaceTransition { - pub(crate) fn to_document_for_dry_run(&self, owner_id: Identifier) -> Result { + pub(crate) fn to_document_for_dry_run( + &self, + owner_id: Identifier, + ) -> Result { let properties = self.data.clone().unwrap_or_default(); Ok(Document { id: self.base.id.to_buffer(), From d3d611611b5561ac9c3a272305854b206de1c92f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 17:12:47 +0700 Subject: [PATCH 089/228] fixes for serialization --- .../rs-dpp/src/data_contract/data_contract.rs | 2 +- .../src/data_contract/data_contract_facade.rs | 3 +- .../data_contract/data_contract_factory.rs | 28 +++++++---------- .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- .../validation/data_contract_validator.rs | 2 +- .../src/decode_protocol_entity_factory.rs | 8 ++--- .../rs-dpp/src/document/document_facade.rs | 10 +++--- .../rs-dpp/src/document/document_factory.rs | 12 ++++--- .../rs-dpp/src/document/document_validator.rs | 4 +-- .../rs-dpp/src/document/extended_document.rs | 31 ++++--------------- .../document_create_transition.rs | 2 +- packages/rs-dpp/src/identity/factory.rs | 29 +++++++---------- ...e_documents_batch_transition_state_spec.rs | 8 +++-- .../src/data_contract/data_contract.rs | 29 ++++++++++------- .../src/data_contract/data_contract_facade.rs | 6 ++-- .../data_contract_factory.rs | 7 ++--- .../src/document/extended_document.rs | 2 +- packages/wasm-dpp/src/document/factory.rs | 11 ++++--- .../document/DocumentFacade.spec.js | 3 +- 20 files changed, 90 insertions(+), 111 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 148a0e20fb4..a96d34e3e9b 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -109,7 +109,7 @@ impl DataContract { Self::default() } - pub fn from_raw_object(mut raw_object: JsonValue) -> Result { + pub fn from_json_raw_object(mut raw_object: JsonValue) -> Result { // TODO identifier_default_deserializer: default deserializer should be changed to bytes // Identifiers fields should be replaced with the string format to deserialize Data Contract raw_object.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Base58)?; diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index 6abea896230..cae7b77d7d9 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -7,6 +7,7 @@ use crate::document::document_transition::document_base_transition::JsonValue; use crate::prelude::{Identifier, ValidationResult}; use crate::version::ProtocolVersionValidator; use crate::ProtocolError; +use platform_value::Value; use std::sync::Arc; pub struct DataContractFacade { @@ -39,7 +40,7 @@ impl DataContractFacade { /// Create Data Contract from plain object pub async fn create_from_object( &self, - raw_data_contract: JsonValue, + raw_data_contract: Value, skip_validation: bool, ) -> Result { let res = self diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index e15c8168696..ad9038f1e5b 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -1,8 +1,10 @@ use anyhow::anyhow; +use ciborium::Value as CborValue; use serde_json::{json, Map, Number, Value as JsonValue}; use std::sync::Arc; use data_contract::state_transition::property_names as st_prop; +use platform_value::Value; use crate::data_contract::property_names; use crate::util::serializer::value_to_cbor; @@ -107,20 +109,23 @@ impl DataContractFactory { /// Create Data Contract from plain object pub async fn create_from_object( &self, - raw_data_contract: JsonValue, + raw_data_contract: Value, skip_validation: bool, ) -> Result { + let json_value = raw_data_contract + .try_into_validating_json() + .map_err(ProtocolError::ValueError)?; if !skip_validation { - let result = self.validate_data_contract.validate(&raw_data_contract)?; + let result = self.validate_data_contract.validate(&json_value)?; if !result.is_valid() { return Err(ProtocolError::InvalidDataContractError { errors: result.errors, - raw_data_contract, + raw_data_contract: json_value, }); } } - DataContract::from_raw_object(raw_data_contract) + DataContract::from_json_raw_object(json_value) } /// Create Data Contract from buffer @@ -132,18 +137,7 @@ impl DataContractFactory { let (protocol_version, mut raw_data_contract) = DecodeProtocolEntity::decode_protocol_entity(buffer)?; - match raw_data_contract { - JsonValue::Object(ref mut m) => m.insert( - String::from("protocolVersion"), - JsonValue::Number(Number::from(protocol_version)), - ), - _ => { - return Err(ConsensusError::SerializedObjectParsingError { - parsing_error: anyhow!("the '{:?}' is not a map", raw_data_contract), - } - .into()) - } - }; + raw_data_contract.set_value("protocolVersion", Value::U32(protocol_version))?; self.create_from_object(raw_data_contract, skip_validation) .await @@ -246,7 +240,7 @@ mod tests { } = get_test_data(); let result = factory - .create_from_object(raw_data_contract, true) + .create_from_object(raw_data_contract.into(), true) .await .expect("Data Contract should be created"); diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index bd3d647b4df..6b18dee78a1 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -69,7 +69,7 @@ impl DataContractCreateTransition { .unwrap_or_else(|_| [0u8; 32].to_vec()) .try_into() .map_err(|_| anyhow!("entropy isn't 32 bytes long"))?, - data_contract: DataContract::from_raw_object( + data_contract: DataContract::from_json_raw_object( raw_data_contract_update_transition.remove(DATA_CONTRACT)?, )?, ..Default::default() diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 6392a036a0b..1b83a3124c0 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -59,7 +59,7 @@ impl DataContractUpdateTransition { signature_public_key_id: raw_data_contract_update_transition .get_u64(SIGNATURE_PUBLIC_KEY_ID) .unwrap_or_default() as KeyID, - data_contract: DataContract::from_raw_object( + data_contract: DataContract::from_json_raw_object( raw_data_contract_update_transition.remove(DATA_CONTRACT)?, )?, ..Default::default() diff --git a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs index 0e72de70702..2d3b2f54046 100644 --- a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs @@ -108,7 +108,7 @@ impl DataContractValidator { return Ok(result); } - let data_contract = DataContract::from_raw_object(raw_data_contract.clone())?; + let data_contract = DataContract::from_json_raw_object(raw_data_contract.clone())?; let enriched_data_contract = enrich_data_contract_with_base_schema( &data_contract, &BASE_DOCUMENT_SCHEMA, diff --git a/packages/rs-dpp/src/decode_protocol_entity_factory.rs b/packages/rs-dpp/src/decode_protocol_entity_factory.rs index 0cdd2c15e51..955a2cd852b 100644 --- a/packages/rs-dpp/src/decode_protocol_entity_factory.rs +++ b/packages/rs-dpp/src/decode_protocol_entity_factory.rs @@ -1,6 +1,7 @@ use anyhow::anyhow; use ciborium::value::Value as CborValue; +use platform_value::Value; use serde_json::Value as JsonValue; use crate::util::deserializer; @@ -11,9 +12,7 @@ use crate::{errors::consensus::ConsensusError, errors::ProtocolError}; pub struct DecodeProtocolEntity {} impl DecodeProtocolEntity { - pub fn decode_protocol_entity( - buffer: impl AsRef<[u8]>, - ) -> Result<(u32, JsonValue), ProtocolError> { + pub fn decode_protocol_entity(buffer: impl AsRef<[u8]>) -> Result<(u32, Value), ProtocolError> { let SplitProtocolVersionOutcome { protocol_version, main_message_bytes: document_bytes, @@ -25,7 +24,6 @@ impl DecodeProtocolEntity { } })?; - let json_value: JsonValue = serde_json::to_value(cbor_value).unwrap(); - Ok((protocol_version, json_value)) + Ok((protocol_version, cbor_value.into())) } } diff --git a/packages/rs-dpp/src/document/document_facade.rs b/packages/rs-dpp/src/document/document_facade.rs index 9b7789a0765..3d0c7d05151 100644 --- a/packages/rs-dpp/src/document/document_facade.rs +++ b/packages/rs-dpp/src/document/document_facade.rs @@ -1,8 +1,8 @@ use anyhow::anyhow; +use platform_value::Value; use std::sync::Arc; -use serde_json::Value; - +use crate::document::document_transition::document_base_transition::JsonValue; use crate::document::ExtendedDocument; use crate::{ data_contract::DataContract, prelude::Identifier, state_repository::StateRepositoryLike, @@ -61,7 +61,7 @@ where data_contract, owner_id, document_type_name, - data.into(), + data, ) } @@ -96,14 +96,14 @@ where &self, extended_document: &ExtendedDocument, ) -> Result, ProtocolError> { - let raw_extended_document = extended_document.to_object()?; + let raw_extended_document = extended_document.to_json_object_for_validation()?; self.validate_raw_document(&raw_extended_document).await } /// Creates Documents State Transition pub async fn validate_raw_document( &self, - raw_extended_document: &Value, + raw_extended_document: &JsonValue, ) -> Result, ProtocolError> { let result = self .data_contract_fetcher_and_validator diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 00f83ad6890..8ed0de7ee91 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -269,8 +269,7 @@ where } Err(err) => Err(err), Ok((version, mut raw_document)) => { - raw_document - .insert(property_names::PROTOCOL_VERSION.to_string(), json!(version))?; + raw_document.set_value(property_names::PROTOCOL_VERSION, Value::U32(version))?; self.create_from_object(raw_document, options).await } } @@ -278,14 +277,17 @@ where pub async fn create_from_object( &self, - raw_document: JsonValue, + raw_document: Value, options: FactoryOptions, ) -> Result { let data_contract = self - .validate_data_contract_for_extended_document(&raw_document, options) + .validate_data_contract_for_extended_document( + &raw_document.clone().try_into_validating_json()?, + options, + ) .await?; - ExtendedDocument::from_raw_document(raw_document, data_contract) + ExtendedDocument::from_platform_value(raw_document, data_contract) } async fn validate_data_contract_for_extended_document( diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 63a1c88f83a..ab64f361303 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -175,7 +175,7 @@ mod test { let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); let raw_document = documents .iter() - .map(|d| d.to_object()) + .map(|d| d.to_json_object_for_validation()) .next() .expect("at least one Document should be present") .expect("Document should be converted to Object"); @@ -522,7 +522,7 @@ mod test { let document = documents.get(8).unwrap(); let data = [0u8; 32]; - let mut raw_document = document.to_object().unwrap(); + let mut raw_document = document.to_json_object_for_validation().unwrap(); raw_document .insert("byteArrayField".to_string(), json!(data)) .unwrap(); diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 2aa1460c4e9..209073c93ef 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -330,29 +330,10 @@ impl ExtendedDocument { Ok(self.to_map_value()?.into()) } - // The skipIdentifierConversion option is removed as it doesn't make sense in the case of - // of Rust. Rust doesn't distinguish between `Buffer` and `Identifier` - pub fn to_object(&self) -> Result { - let mut json_object = self.document.to_json()?; - let value_mut = json_object.as_object_mut().unwrap(); - value_mut.insert( - property_names::PROTOCOL_VERSION.to_string(), - JsonValue::Number(self.protocol_version.into()), - ); - value_mut.insert( - property_names::DOCUMENT_TYPE.to_string(), - JsonValue::String(self.document_type_name.clone()), - ); - value_mut.insert( - property_names::DATA_CONTRACT_ID.to_string(), - json!(self.data_contract.id), - ); - - let (identifier_paths, binary_paths) = self.get_identifiers_and_binary_paths()?; - let _ = json_object.replace_identifier_paths(identifier_paths, ReplaceWith::Bytes); - let _ = json_object.replace_binary_paths(binary_paths, ReplaceWith::Bytes); - - Ok(json_object) + pub fn to_json_object_for_validation(&self) -> Result { + self.to_value()? + .try_into_validating_json() + .map_err(ProtocolError::ValueError) } pub fn to_buffer(&self) -> Result, ProtocolError> { @@ -474,7 +455,7 @@ mod test { } } }); - DataContract::from_raw_object(data_contract).unwrap() + DataContract::from_json_raw_object(data_contract).unwrap() } #[test] @@ -545,7 +526,7 @@ mod test { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json").unwrap(); let document = ExtendedDocument::from_json_string(&document_json).unwrap(); - let document_object = document.to_object().unwrap(); + let document_object = document.to_json_object_for_validation().unwrap(); for property in IDENTIFIER_FIELDS { let id = document_object diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 13a5198a0e7..abedb65ab53 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -238,7 +238,7 @@ mod test { } } }); - DataContract::from_raw_object(data_contract).unwrap() + DataContract::from_json_raw_object(data_contract).unwrap() } #[test] diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index f55ed5ba588..b925e3442e2 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -16,9 +16,11 @@ use anyhow::anyhow; use dashcore::{InstantLock, Transaction}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; -use serde_json::{Number, Value}; +use serde_json::{Number, Value as JsonValue}; use std::collections::BTreeMap; +use std::convert::TryInto; +use platform_value::Value; use std::sync::Arc; pub const IDENTITY_PROTOCOL_VERSION: u32 = 1; @@ -119,7 +121,7 @@ where pub fn create_from_object( &self, - raw_identity: Value, + raw_identity: JsonValue, skip_validation: bool, ) -> Result { if !skip_validation { @@ -143,21 +145,14 @@ where ) -> Result { let (protocol_version, mut raw_identity) = DecodeProtocolEntity::decode_protocol_entity(buffer)?; - - match raw_identity { - Value::Object(ref mut m) => m.insert( - String::from("protocolVersion"), - Value::Number(Number::from(protocol_version)), - ), - _ => { - return Err(ConsensusError::SerializedObjectParsingError { - parsing_error: anyhow!("the '{:?}' is not a map", raw_identity), - } - .into()) - } - }; - - self.create_from_object(raw_identity, skip_validation) + raw_identity + .set_value("protocolVersion", Value::U32(protocol_version)) + .map_err(ProtocolError::ValueError)?; + + self.create_from_object( + raw_identity.try_into().map_err(ProtocolError::ValueError)?, + skip_validation, + ) } pub fn create_instant_lock_proof( diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index f409fcbaf9a..a9e0077a243 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -212,7 +212,9 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace .collect::>(); let mut replace_document = ExtendedDocument::from_raw_document( - extended_documents[0].to_object().unwrap(), + extended_documents[0] + .to_json_object_for_validation() + .unwrap(), data_contract.clone(), ) .expect("document should be created"); @@ -280,7 +282,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace } = setup_test(); let mut replace_document = ExtendedDocument::from_raw_document( extended_documents[0] - .to_object() + .to_json_object_for_validation() .unwrap() .try_into() .unwrap(), @@ -291,7 +293,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let mut fetched_document = ExtendedDocument::from_raw_document( extended_documents[0] - .to_object() + .to_json_object_for_validation() .unwrap() .try_into() .unwrap(), diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index b090fb9f474..a57be951088 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -4,10 +4,11 @@ use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; pub use serde::{Deserialize, Serialize}; -use serde_json::Value; +use serde_json::Value as JsonValue; use wasm_bindgen::prelude::*; use dpp::data_contract::{DataContract, SCHEMA_URI}; +use dpp::platform_value::Value; use dpp::util::string_encoding::Encoding; use crate::errors::{from_dpp_err, RustConversionError}; @@ -68,13 +69,17 @@ pub(crate) struct DataContractParameters { _extras: serde_json::Value, // Captures excess fields to trigger validation failure later. } -pub fn js_value_to_serde_value(raw_parameters: JsValue) -> Result { +pub fn js_value_to_serde_value(object: JsValue) -> Result { let parameters: DataContractParameters = - with_js_error!(serde_wasm_bindgen::from_value(raw_parameters))?; + with_js_error!(serde_wasm_bindgen::from_value(object))?; serde_json::to_value(parameters).map_err(|e| e.to_string().into()) } +pub fn js_value_to_platform_value(raw_parameters: JsValue) -> Result { + Ok(js_value_to_serde_value(raw_parameters)?.into()) +} + #[wasm_bindgen(js_class=DataContract)] impl DataContractWasm { #[wasm_bindgen(constructor)] @@ -82,7 +87,7 @@ impl DataContractWasm { let parameters: DataContractParameters = with_js_error!(serde_wasm_bindgen::from_value(raw_parameters))?; - DataContract::from_raw_object( + DataContract::from_json_raw_object( serde_json::to_value(parameters).expect("Implements Serialize"), ) .map_err(from_dpp_err) @@ -140,10 +145,10 @@ impl DataContractWasm { } #[wasm_bindgen(js_name=setDocuments)] pub fn set_documents(&mut self, documents: JsValue) -> Result<(), JsValue> { - let json_value: Value = with_js_error!(serde_wasm_bindgen::from_value(documents))?; + let json_value: JsonValue = with_js_error!(serde_wasm_bindgen::from_value(documents))?; - let mut docs: BTreeMap = BTreeMap::new(); - if let Value::Object(o) = json_value { + let mut docs: BTreeMap = BTreeMap::new(); + if let JsonValue::Object(o) = json_value { for (k, v) in o.into_iter() { if !v.is_object() { bail_js!("is not an object") @@ -174,7 +179,7 @@ impl DataContractWasm { doc_type: String, schema: JsValue, ) -> Result<(), JsValue> { - let json_schema: Value = with_js_error!(serde_wasm_bindgen::from_value(schema))?; + let json_schema: JsonValue = with_js_error!(serde_wasm_bindgen::from_value(schema))?; self.0.set_document_schema(doc_type, json_schema); Ok(()) } @@ -198,9 +203,9 @@ impl DataContractWasm { #[wasm_bindgen(js_name=setDefinitions)] pub fn set_definitions(&mut self, definitions: JsValue) -> Result<(), JsValue> { - let json_value: Value = with_js_error!(serde_wasm_bindgen::from_value(definitions))?; - let mut definitions: BTreeMap = BTreeMap::new(); - if let Value::Object(o) = json_value { + let json_value: JsonValue = with_js_error!(serde_wasm_bindgen::from_value(definitions))?; + let mut definitions: BTreeMap = BTreeMap::new(); + if let JsonValue::Object(o) = json_value { for (k, v) in o.into_iter() { // v must be a Object if !v.is_object() { @@ -300,7 +305,7 @@ impl DataContractWasm { #[wasm_bindgen(js_name=from)] pub fn from_js_value(v: JsValue) -> Result { - let json_contract: Value = with_js_error!(serde_wasm_bindgen::from_value(v))?; + let json_contract: JsonValue = with_js_error!(serde_wasm_bindgen::from_value(v))?; Ok(DataContract::try_from(json_contract) .map_err(from_dpp_err)? .into()) diff --git a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs index 69c3368ff26..2d9d4f132eb 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs @@ -1,8 +1,8 @@ use crate::errors::protocol_error::from_protocol_error; use crate::{ - js_value_to_serde_value, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, - DataContractWasm, + js_value_to_platform_value, js_value_to_serde_value, DataContractCreateTransitionWasm, + DataContractUpdateTransitionWasm, DataContractWasm, }; use dpp::data_contract::DataContractFacade; use dpp::identifier::Identifier; @@ -63,7 +63,7 @@ impl DataContractFacadeWasm { self.0 .create_from_object( - js_value_to_serde_value(js_raw_data_contract)?, + js_value_to_platform_value(js_raw_data_contract)?, skip_validation, ) .await diff --git a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs index 7d11db2ba02..2c022c744df 100644 --- a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs +++ b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs @@ -14,6 +14,7 @@ use wasm_bindgen::prelude::*; use crate::{ data_contract::errors::InvalidDataContractError, errors::{from_dpp_err, protocol_error::from_protocol_error}, + js_value_to_platform_value, validation::ValidationResultWasm, with_js_error, DataContractCreateTransitionWasm, DataContractParameters, DataContractWasm, }; @@ -130,12 +131,10 @@ impl DataContractFactoryWasm { object: JsValue, skip_validation: Option, ) -> Result { - let parameters: DataContractParameters = - with_js_error!(serde_wasm_bindgen::from_value(object.clone()))?; - let parameters_json = serde_json::to_value(parameters).expect("Implements Serialize"); + let parameters_value = js_value_to_platform_value(object.clone())?; let result = self .0 - .create_from_object(parameters_json, skip_validation.unwrap_or(false)) + .create_from_object(parameters_value, skip_validation.unwrap_or(false)) .await; match result { Ok(data_contract) => Ok(data_contract.into()), diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index b5d8a30d5ed..fb43b6b6988 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -263,7 +263,7 @@ impl ExtendedDocumentWasm { } else { Default::default() }; - let mut value = self.0.to_object().with_js_error()?; + let mut value = self.0.to_json_object_for_validation().with_js_error()?; let (identifiers_paths, binary_paths) = self.0.get_identifiers_and_binary_paths().with_js_error()?; diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index e83d2f5134f..decb2bc9687 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -143,18 +143,19 @@ impl DocumentFactoryWASM { raw_document_js: JsValue, options: JsValue, ) -> Result { - let mut raw_document = raw_document_js.with_serde_to_json_value()?; + let mut raw_document = raw_document_js.with_serde_to_platform_value()?; let options: FactoryOptions = if !options.is_undefined() && options.is_object() { let raw_options = options.with_serde_to_json_value()?; serde_json::from_value(raw_options).with_js_error()? } else { Default::default() }; - // Errors are ignored. When `Buffer` crosses the WASM boundary it becomes an Array. - // When `Identifier` crosses the WASM boundary, it becomes a String. From perspective of JS - // `Identifier` and `Buffer` are used interchangeably, so we we can expect the replacing may fail when `Buffer` is provided raw_document - .replace_identifier_paths(extended_document::IDENTIFIER_FIELDS, ReplaceWith::Bytes) + .replace_at_paths( + extended_document::IDENTIFIER_FIELDS, + ReplacementType::Identifier, + ) + .map_err(ProtocolError::ValueError) .with_js_error()?; let mut document = self diff --git a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js index 78bf1521e4b..34f132a79cc 100644 --- a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js +++ b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js @@ -80,7 +80,8 @@ describe('DocumentFacade', () => { }); it('should create Document from plain object - Rust', async () => { - const result = await dpp.document.createFromObject(document.toObject()); + const a = document.toObject(); + const result = await dpp.document.createFromObject(a); expect(result).to.be.an.instanceOf(ExtendedDocument); From 206b09e5677e94a416e06c87db6446d52e112105 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Mar 2023 17:30:42 +0700 Subject: [PATCH 090/228] another fix --- .../wasm-dpp/test/unit/identity/IdentityFactory.spec.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js b/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js index 3a1e8ba3e1d..70ea57e0dcf 100644 --- a/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js +++ b/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js @@ -21,8 +21,9 @@ describe('IdentityFactory', () => { let IdentityUpdateTransition; let IdentityPublicKeyCreateTransition; let InvalidIdentityError; - let SerializedObjectParsingError; + let PlatformValueError; let UnsupportedProtocolVersionError; + let JsonSchemaError; let ChainAssetLockProof; before(async () => { @@ -30,7 +31,7 @@ describe('IdentityFactory', () => { Identity, IdentityFactory, IdentityValidator, InstantAssetLockProof, ChainAssetLockProof, IdentityUpdateTransition, IdentityCreateTransition, IdentityTopUpTransition, IdentityPublicKeyCreateTransition, - InvalidIdentityError, UnsupportedProtocolVersionError, SerializedObjectParsingError, + InvalidIdentityError, UnsupportedProtocolVersionError, PlatformValueError, JsonSchemaError, } = await loadWasmDpp()); }); @@ -138,7 +139,7 @@ describe('IdentityFactory', () => { expect(e).to.be.an.instanceOf(InvalidIdentityError); const [innerError] = e.getErrors(); - expect(innerError).to.be.instanceOf(UnsupportedProtocolVersionError); + expect(innerError).to.be.instanceOf(JsonSchemaError); } }); @@ -149,7 +150,7 @@ describe('IdentityFactory', () => { expect.fail('should throw an error'); } catch (e) { - expect(e).to.be.instanceOf(SerializedObjectParsingError); + expect(e).to.be.instanceOf(PlatformValueError); } }); }); From 236db0d9e8f270e4e1121ec26ad79a99dfda7bde Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Tue, 7 Mar 2023 21:04:28 +0800 Subject: [PATCH 091/228] fix errors produced by not being able to mock the validator any more --- packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js | 5 +++-- .../validation/basic/findDuplicatesById.spec.js | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js index b7be7f75198..001364ec28e 100644 --- a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js @@ -247,11 +247,12 @@ describe('DocumentFactory', () => { validateDocumentMock.returns(validationResult); try { - factory.create(dataContract, ownerId, rawDocumentJs.$type, {}); + factory.create(dataContract, ownerId, 'ivalidType', {}); expect.fail('InvalidDocumentError should be thrown'); } catch (e) { - expect(e).to.be.an.instanceOf(InvalidDocumentError); + console.log(e); + expect(e).to.be.an.instanceOf(InvalidDocumentTypeInDataContractError); } }); }); diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesById.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesById.spec.js index b6ab103fe1e..ef773982f59 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesById.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/basic/findDuplicatesById.spec.js @@ -23,6 +23,8 @@ describe('findDuplicatesById', () => { it('should return duplicated Documents - Rust', () => { rawDocumentTransitions.push(rawDocumentTransitions[0]); + console.dir(rawDocumentTransitions[0]); + const result = findDuplicatesById(rawDocumentTransitions); expect(result).to.be.an('array'); From e9294766ddb25dd68bbc45fd86a8f0b1e25feeff Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 8 Mar 2023 14:50:43 +0700 Subject: [PATCH 092/228] small typo fix --- packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js index 001364ec28e..cf834af3928 100644 --- a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js @@ -247,11 +247,10 @@ describe('DocumentFactory', () => { validateDocumentMock.returns(validationResult); try { - factory.create(dataContract, ownerId, 'ivalidType', {}); + factory.create(dataContract, ownerId, 'invalidType', {}); expect.fail('InvalidDocumentError should be thrown'); } catch (e) { - console.log(e); expect(e).to.be.an.instanceOf(InvalidDocumentTypeInDataContractError); } }); From f2c5b56443ea09fd583ae936a13eed5d63583d59 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 8 Mar 2023 15:26:09 +0700 Subject: [PATCH 093/228] another fix --- .../document_type/document_type.rs | 42 +++++++++---------- packages/wasm-dpp/src/document/mod.rs | 2 +- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index 17e33b52e84..cdf4f21ff64 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -422,28 +422,26 @@ fn insert_values( ); } "object" => { - let properties = inner_properties - .get(property_names::PROPERTIES) - .ok_or(ProtocolError::StructureError( - StructureError::KeyValueMustExist("object must have properties"), - ))? - .as_map() - .ok_or(ProtocolError::StructureError( - StructureError::ValueWrongType("properties must be a map"), - ))?; - - for (object_property_key, object_property_value) in properties.iter() { - let object_property_string = object_property_key - .as_text() - .ok_or(ProtocolError::StructureError(StructureError::KeyWrongType( - "property key must be a string", - )))? - .to_string(); - to_visit.push(( - Some(prefixed_property_key.clone()), - object_property_string, - object_property_value, - )); + if let Some(properties_as_value) = inner_properties + .get(property_names::PROPERTIES) { + let properties = properties_as_value.as_map() + .ok_or(ProtocolError::StructureError( + StructureError::ValueWrongType("properties must be a map"), + ))?; + + for (object_property_key, object_property_value) in properties.iter() { + let object_property_string = object_property_key + .as_text() + .ok_or(ProtocolError::StructureError(StructureError::KeyWrongType( + "property key must be a string", + )))? + .to_string(); + to_visit.push(( + Some(prefixed_property_key.clone()), + object_property_string, + object_property_value, + )); + } } } diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 1adced5085d..1e8ab284c26 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -72,7 +72,7 @@ impl DocumentWasm { let document_type_name = js_document_type_name .as_string() - .ok_or(anyhow!("expected a string for the document type")) + .ok_or(anyhow!("expected a string for the document type, got {:?}", js_document_type_name)) .with_js_error()?; let (identifier_paths, _) = js_data_contract From bf199b77d600233516f46068e0e614b107815bbf Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Wed, 8 Mar 2023 16:33:55 +0800 Subject: [PATCH 094/228] fix DocumentBatchTransition.spec.js --- .../DocumentBatchTransition.spec.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/DocumentBatchTransition.spec.js b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/DocumentBatchTransition.spec.js index c770149a458..b2ccef02df2 100644 --- a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/DocumentBatchTransition.spec.js +++ b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/DocumentBatchTransition.spec.js @@ -6,7 +6,7 @@ const getDocumentsFixture = require('@dashevo/dpp/lib/test/fixtures/getDocuments const { default: loadWasmDpp } = require('../../../../../dist'); -let Document; +let ExtendedDocument; let DataContract; let ProtocolVersionValidator; let DocumentValidator; @@ -24,12 +24,14 @@ describe('DocumentBatchTransition', () => { beforeEach(async function beforeEach() { ({ - Document, + ExtendedDocument, DataContract, ProtocolVersionValidator, DocumentFactory, DocumentValidator, } = await loadWasmDpp()); + + console.log(ExtendedDocument); const dataContractFixtureJs = getDataContractFixture(); dataContractFixtureJs.documents.niceDocument @@ -43,7 +45,7 @@ describe('DocumentBatchTransition', () => { // 1 and 2 are pretty documents, // 3 and 4 are indexed documents that do not have security level specified documentsFixture = getDocumentsFixture(dataContractFixtureJs).map((doc) => { - const document = new Document(doc.toObject(), dataContractFixture.clone()); + const document = new ExtendedDocument(doc.toObject(), dataContractFixture.clone()); document.setEntropy(doc.entropy); return document; }); From 4da3ec485334cdc4ea8a4d20850f84faa95f7f7f Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Wed, 8 Mar 2023 17:26:35 +0800 Subject: [PATCH 095/228] resolve merge conflicts --- packages/rs-dpp/src/data_contract/data_contract.rs | 6 +++--- packages/rs-dpp/src/data_contract/data_contract_factory.rs | 4 ++-- packages/rs-dpp/src/document/document_factory.rs | 2 +- .../validation/basic/validate_partial_compound_indices.rs | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index e9527539160..53496407715 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -18,9 +18,9 @@ use crate::data_contract::contract_config::{ }; use crate::data_contract::get_binary_properties_from_schema::get_binary_properties; -use crate::util::cbor_value::CborCanonicalMap; -use crate::util::deserializer; -use crate::util::deserializer::SplitProtocolVersionOutcome; + + + use crate::util::json_value::{JsonValueExt, ReplaceWith}; use crate::util::string_encoding::Encoding; use crate::{ diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 67c7fdc7972..8af40f52f59 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -1,5 +1,5 @@ -use anyhow::anyhow; -use ciborium::Value as CborValue; + + use serde_json::{json, Map, Number, Value as JsonValue}; use std::sync::Arc; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 42c148b2913..19d9032c97a 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -114,7 +114,7 @@ where document_type_name: String, data: JsonValue, ) -> Result { - if !data_contract.is_document_defined(&document_type) { + if !data_contract.is_document_defined(&document_type_name) { return Err(DataContractError::InvalidDocumentTypeError( InvalidDocumentTypeError::new(document_type_name, data_contract.id), ) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index 12d1c024cb0..cb11186af61 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -53,7 +53,7 @@ where { let properties = index.properties.iter().map(|property| &property.name); - if !are_all_properties_defined_or_undefined(properties.clone(), raw_transition) { + if !are_all_properties_defined_or_undefined(properties.clone(), raw_transition_map) { validation_result.add_error(BasicError::InconsistentCompoundIndexDataError( InconsistentCompoundIndexDataError::new( properties.map(ToOwned::to_owned).collect(), From ac1c8daabb7e977606201ae6f837c4a164c559d1 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Wed, 8 Mar 2023 17:42:45 +0800 Subject: [PATCH 096/228] resolve compilation errors --- .../rs-dpp/src/data_contract/data_contract_factory.rs | 6 +++--- packages/rs-dpp/src/decode_protocol_entity_factory.rs | 2 +- packages/rs-dpp/src/document/document_factory.rs | 8 ++++---- packages/rs-dpp/src/document/extended_document.rs | 3 +-- .../basic/validate_documents_batch_transition_basic.rs | 2 +- .../duplicate_document_transitions_with_ids_error.rs | 6 +++--- .../duplicate_document_transitions_with_indices_error.rs | 6 +++--- packages/rs-dpp/src/identity/factory.rs | 6 +++--- 8 files changed, 19 insertions(+), 20 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 8af40f52f59..50fc647931c 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -1,6 +1,6 @@ -use serde_json::{json, Map, Number, Value as JsonValue}; +use serde_json::{json, Map, Value as JsonValue}; use std::sync::Arc; use data_contract::state_transition::property_names as st_prop; @@ -12,7 +12,7 @@ use crate::util::serializer::value_to_cbor; use crate::{ data_contract::{self, generate_data_contract_id}, decode_protocol_entity_factory::DecodeProtocolEntity, - errors::{consensus::ConsensusError, ProtocolError}, + errors::ProtocolError, prelude::Identifier, util::entropy_generator, }; @@ -121,7 +121,7 @@ impl DataContractFactory { if !result.is_valid() { return Err(ProtocolError::InvalidDataContractError( - InvalidDataContractError::new(result.errors, raw_data_contract), + InvalidDataContractError::new(result.errors, json_value), )); } } diff --git a/packages/rs-dpp/src/decode_protocol_entity_factory.rs b/packages/rs-dpp/src/decode_protocol_entity_factory.rs index 955a2cd852b..f5f5b51a18d 100644 --- a/packages/rs-dpp/src/decode_protocol_entity_factory.rs +++ b/packages/rs-dpp/src/decode_protocol_entity_factory.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use ciborium::value::Value as CborValue; use platform_value::Value; -use serde_json::Value as JsonValue; + use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 19d9032c97a..891d40fd28e 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -8,7 +8,7 @@ use platform_value::Value; use rand::rngs::StdRng; use rand::SeedableRng; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value as JsonValue}; +use serde_json::{Value as JsonValue}; use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::document::extended_document::{property_names, ExtendedDocument}; @@ -23,7 +23,7 @@ use crate::{ prelude::Identifier, state_repository::StateRepositoryLike, util::entropy_generator, - util::json_value::JsonValueExt, + ProtocolError, }; @@ -112,7 +112,7 @@ where data_contract: DataContract, owner_id: Identifier, document_type_name: String, - data: JsonValue, + data: Value, ) -> Result { if !data_contract.is_document_defined(&document_type_name) { return Err(DataContractError::InvalidDocumentTypeError( @@ -160,7 +160,7 @@ where updated_at, }; - let json_value = document.to_json_with_identifiers_using_bytes()?; + // let json_value = document.to_json_with_identifiers_using_bytes()?; // let validation_result = // self.document_validator // .validate(&json_value, &data_contract, document_type)?; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 209073c93ef..0415e1a4569 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -7,7 +7,6 @@ use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::util::hash::hash; use crate::util::json_value::JsonValueExt; -use crate::util::json_value::ReplaceWith; use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; @@ -151,7 +150,7 @@ impl ExtendedDocument { } pub fn from_platform_value( - mut document_value: Value, + document_value: Value, data_contract: DataContract, ) -> Result { let mut properties = document_value diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 677168b112d..56f0433fb3b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -227,7 +227,7 @@ fn validate_raw_transitions<'a>( result.add_error(BasicError::InvalidDocumentTypeError( InvalidDocumentTypeError::new( document_type.to_string(), - data_contract.id().clone(), + data_contract.id.clone(), ), )); return Ok(result); diff --git a/packages/rs-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs b/packages/rs-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs index 7b2b684362f..f0e90afb55d 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs @@ -4,15 +4,15 @@ use thiserror::Error; #[derive(Error, Debug, Clone, PartialEq, Eq)] #[error("Document transitions with duplicate IDs {:?}", references)] pub struct DuplicateDocumentTransitionsWithIdsError { - references: Vec<(String, Vec)>, + references: Vec<(String, [u8; 32])>, } impl DuplicateDocumentTransitionsWithIdsError { - pub fn new(references: Vec<(String, Vec)>) -> Self { + pub fn new(references: Vec<(String, [u8; 32])>) -> Self { Self { references } } - pub fn references(&self) -> Vec<(String, Vec)> { + pub fn references(&self) -> Vec<(String, [u8; 32])> { self.references.clone() } } diff --git a/packages/rs-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs b/packages/rs-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs index 43996e1b714..b3b0f3b51d4 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs @@ -7,15 +7,15 @@ use thiserror::Error; references )] pub struct DuplicateDocumentTransitionsWithIndicesError { - references: Vec<(String, Vec)>, + references: Vec<(String, [u8; 32])>, } impl DuplicateDocumentTransitionsWithIndicesError { - pub fn new(references: Vec<(String, Vec)>) -> Self { + pub fn new(references: Vec<(String, [u8; 32])>) -> Self { Self { references } } - pub fn references(&self) -> Vec<(String, Vec)> { + pub fn references(&self) -> Vec<(String, [u8; 32])> { self.references.clone() } } diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index b925e3442e2..af803c0b321 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -1,4 +1,4 @@ -use crate::consensus::ConsensusError; + use crate::decode_protocol_entity_factory::DecodeProtocolEntity; use crate::identifier::Identifier; use crate::identity::identity_public_key::factory::KeyCount; @@ -12,11 +12,11 @@ use crate::identity::validation::{IdentityValidator, PublicKeysValidator}; use crate::identity::{Identity, IdentityPublicKey, KeyID, TimestampMillis}; use crate::{BlsModule, ProtocolError}; -use anyhow::anyhow; + use dashcore::{InstantLock, Transaction}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; -use serde_json::{Number, Value as JsonValue}; +use serde_json::{Value as JsonValue}; use std::collections::BTreeMap; use std::convert::TryInto; From 0805694f056cac0248ad15284300dca86abfc92c Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Wed, 8 Mar 2023 18:02:28 +0800 Subject: [PATCH 097/228] fix wrong constructor for the data triggers --- .../validation/state/executeDataTriggersFactory.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js index 6f874696379..42b8f906f96 100644 --- a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js @@ -14,7 +14,7 @@ let DataContract; let DocumentTransition; let DocumentCreateTransition; let DataTriggerExecutionContext; -let Document; +let ExtendedDocument; let DataTriggerExecutionResult; let StateTransitionExecutionContext; let getAllDataTriggers; @@ -38,7 +38,7 @@ describe('executeDataTriggersFactory', () => { DocumentTransition, DocumentCreateTransition, DataTriggerExecutionContext, - Document, + ExtendedDocument, DataTriggerExecutionResult, StateTransitionExecutionContext, executeDataTriggers, @@ -51,7 +51,7 @@ describe('executeDataTriggersFactory', () => { contractMock = new DataContract(getDpnsContractFixture().toObject()); childDocumentJs = dpnsDocumentFixture.getChildDocumentFixture(); - childDocument = new Document(childDocumentJs.toObject(), + childDocument = new ExtendedDocument(childDocumentJs.toObject(), dataContract.clone()); stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); From 5aa8f7be50292482ab018bc162abdd851b854036 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Wed, 8 Mar 2023 18:51:31 +0800 Subject: [PATCH 098/228] fix another test error --- .../state/executeDataTriggersFactory.spec.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js index 42b8f906f96..f3b2805d8cc 100644 --- a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/state/executeDataTriggersFactory.spec.js @@ -14,7 +14,7 @@ let DataContract; let DocumentTransition; let DocumentCreateTransition; let DataTriggerExecutionContext; -let ExtendedDocument; +let Document; let DataTriggerExecutionResult; let StateTransitionExecutionContext; let getAllDataTriggers; @@ -38,7 +38,7 @@ describe('executeDataTriggersFactory', () => { DocumentTransition, DocumentCreateTransition, DataTriggerExecutionContext, - ExtendedDocument, + Document, DataTriggerExecutionResult, StateTransitionExecutionContext, executeDataTriggers, @@ -51,8 +51,11 @@ describe('executeDataTriggersFactory', () => { contractMock = new DataContract(getDpnsContractFixture().toObject()); childDocumentJs = dpnsDocumentFixture.getChildDocumentFixture(); - childDocument = new ExtendedDocument(childDocumentJs.toObject(), - dataContract.clone()); + childDocument = new Document( + childDocumentJs.toObject(), + dataContract.clone(), + childDocumentJs.getType(), + ); stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); From 91fe05b7e147e6b76a3d4d04e3856b619932d969 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Wed, 8 Mar 2023 19:31:34 +0800 Subject: [PATCH 099/228] in porgress --- packages/rs-dpp/src/identity/factory.rs | 2 ++ .../test/integration/identity/IdentityFacade.spec.js | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index af803c0b321..c307c7092f3 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -149,6 +149,8 @@ where .set_value("protocolVersion", Value::U32(protocol_version)) .map_err(ProtocolError::ValueError)?; + // TODO: the error originates here due to id having a wrong type - should be a base58 for the schema + self.create_from_object( raw_identity.try_into().map_err(ProtocolError::ValueError)?, skip_validation, diff --git a/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js b/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js index 3c02d58e542..89cdbbf3080 100644 --- a/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js +++ b/packages/wasm-dpp/test/integration/identity/IdentityFacade.spec.js @@ -86,8 +86,13 @@ describe('IdentityFacade', () => { }); describe('#createFromBuffer', () => { - it('should create Identity from string', () => { - const result = dpp.identity.createFromBuffer(identity.toBuffer()); + it('should create Identity from a Buffer', () => { + let result; + try { + result = dpp.identity.createFromBuffer(identity.toBuffer()); + } catch (e) { + console.dir(e.getErrors()[0].toString()); + } expect(result).to.be.an.instanceOf(Identity); From 11968c616ceed2552b2020e56e2fb714383440ac Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 10 Mar 2023 00:24:04 +0700 Subject: [PATCH 100/228] sledgehammer --- packages/rs-dpp/src/convertible.rs | 2 +- .../rs-dpp/src/data_contract/data_contract.rs | 111 ++- .../data_contract/data_contract_factory.rs | 33 +- .../data_contract_create_transition/mod.rs | 50 +- .../data_contract_update_transition/mod.rs | 53 +- ...e_data_contract_update_transition_basic.rs | 2 +- .../errors/missing_data_contract_id_error.rs | 9 +- packages/rs-dpp/src/document/document.rs | 33 + .../rs-dpp/src/document/document_facade.rs | 4 +- .../rs-dpp/src/document/document_factory.rs | 7 +- .../rs-dpp/src/document/document_validator.rs | 43 +- packages/rs-dpp/src/document/errors.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 41 ++ .../fetch_and_validate_data_contract.rs | 19 +- ...lidate_documents_batch_transition_basic.rs | 95 ++- .../validate_partial_compound_indices.rs | 2 +- .../state_transition/asset_lock_proof/mod.rs | 43 +- .../identity_create_transition.rs | 26 +- .../identity_public_key_transitions.rs | 64 +- .../identity_update_transition.rs | 2 +- .../validate_public_key_signatures.rs | 2 +- .../state_transition_factory.rs | 20 +- .../data_contract_validator_spec.rs | 2 +- .../src/validation/json_schema_validator.rs | 20 +- packages/rs-platform-value/Cargo.toml | 9 +- .../src/btreemap_extensions.rs | 160 +---- .../src/btreemap_path_extensions.rs | 8 +- .../src/btreemap_removal_extensions.rs | 303 +++++++++ ...btreemap_removal_inner_value_extensions.rs | 37 + .../src/converter/ciborium.rs | 22 +- .../src/converter/serde_json.rs | 143 +++- packages/rs-platform-value/src/display.rs | 1 - packages/rs-platform-value/src/error.rs | 12 + packages/rs-platform-value/src/inner_value.rs | 151 +++- packages/rs-platform-value/src/lib.rs | 124 ++-- packages/rs-platform-value/src/ser.rs | 643 ++++++++++++++++++ .../rs-platform-value/src/system_bytes.rs | 16 +- packages/rs-platform-value/src/value_map.rs | 17 +- .../basic/find_duplicates_by_indices.rs | 2 +- ...lidate_documents_batch_transition_basic.rs | 2 +- .../identity_public_key_transitions.rs | 2 +- 41 files changed, 1828 insertions(+), 509 deletions(-) create mode 100644 packages/rs-platform-value/src/btreemap_removal_extensions.rs create mode 100644 packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs create mode 100644 packages/rs-platform-value/src/ser.rs diff --git a/packages/rs-dpp/src/convertible.rs b/packages/rs-dpp/src/convertible.rs index 513cb7c2efa..5c3c494e6e3 100644 --- a/packages/rs-dpp/src/convertible.rs +++ b/packages/rs-dpp/src/convertible.rs @@ -5,7 +5,7 @@ use crate::ProtocolError; pub trait Convertible { /// Returns the [`serde_json::Value`] instance that preserves the `Vec` representation /// for Identifiers and binary data - fn to_object(&self) -> Result; + fn to_json_object(&self) -> Result; /// Returns the [`serde_json::Value`] instance that encodes: /// - Identifiers - with base58 /// - Binary data - with base64 diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 53496407715..46239961bd9 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -1,5 +1,5 @@ use std::collections::{BTreeMap, HashSet}; -use std::convert::TryFrom; +use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::consensus::basic::document::InvalidDocumentTypeError; -use crate::data_contract::contract_config; +use crate::data_contract::{contract_config, DriveContractExt}; use crate::data_contract::contract_config::{ ContractConfig, DEFAULT_CONTRACT_CAN_BE_DELETED, DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY, DEFAULT_CONTRACT_DOCUMENT_MUTABILITY, DEFAULT_CONTRACT_KEEPS_HISTORY, @@ -47,7 +47,7 @@ pub const IDENTIFIER_FIELDS: [&str; 2] = [property_names::ID, property_names::OW pub const BINARY_FIELDS: [&str; 1] = [property_names::ENTROPY]; impl Convertible for DataContract { - fn to_object(&self) -> Result { + fn to_json_object(&self) -> Result { let mut json_object = serde_json::to_value(self)?; if !json_object.is_object() { return Err(anyhow!("the Data Contract isn't a JSON Value Object").into()); @@ -66,7 +66,7 @@ impl Convertible for DataContract { fn to_buffer(&self) -> Result, ProtocolError> { let protocol_version = self.protocol_version; // what means skip_identifiers_conversion - let mut json_object = self.to_object(true)?; + let mut json_object = self.to_json_object(true)?; if let JsonValue::Object(ref mut o) = json_object { o.remove("protocolVersion"); @@ -112,14 +112,8 @@ impl DataContract { Self::default() } - pub fn from_json_raw_object(mut raw_object: JsonValue) -> Result { - // TODO identifier_default_deserializer: default deserializer should be changed to bytes - // Identifiers fields should be replaced with the string format to deserialize Data Contract - raw_object.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Base58)?; - let value: Value = raw_object.clone().into(); - let data_contract_map = value.into_btree_map().map_err(ProtocolError::ValueError)?; - let mut data_contract: DataContract = serde_json::from_value(raw_object)?; - data_contract.generate_binary_properties(); + pub fn from_raw_object(raw_object: Value) -> Result { + let mut data_contract_map = raw_object.into_btree_map().map_err(ProtocolError::ValueError)?; let mutability = get_contract_configuration_properties(&data_contract_map) .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; @@ -130,9 +124,35 @@ impl DataContract { mutability.documents_keep_history_contract_default, mutability.documents_mutable_contract_default, ) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; - data_contract.document_types = document_types; + let documents = data_contract_map.remove(property_names::DOCUMENTS).map(|value | value.try_into_validating_btree_map_json()).transpose()? + .unwrap_or_default(); + + let mutability = get_contract_configuration_properties(&data_contract_map) + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + + // Defs + let defs = + data_contract_map.get_optional_inner_str_json_value_map::>("$defs")?; + + let mut data_contract = DataContract { + protocol_version: 0, + id: Identifier::from(data_contract_map.remove_hash256_bytes(property_names::ID).map_err(ProtocolError::ValueError)?), + schema: data_contract_map.remove_string(property_names::SCHEMA).map_err(ProtocolError::ValueError)?, + version: data_contract_map.remove_integer(property_names::VERSION).map_err(ProtocolError::ValueError)?, + owner_id: Identifier::from(data_contract_map.remove_hash256_bytes(property_names::OWNER_ID).map_err(ProtocolError::ValueError)?), + document_types, + metadata: None, + config: mutability, + documents, + defs, + entropy: data_contract_map.remove_hash256_bytes(property_names::ENTROPY).map_err(ProtocolError::ValueError)?, + binary_properties: documents + .iter() + .map(|(doc_type, schema)| (String::from(doc_type), get_binary_properties(schema))) + .collect() + }; Ok(data_contract) } @@ -165,7 +185,39 @@ impl DataContract { Self::from_cbor(b) } - pub fn to_object(&self, skip_identifiers_conversion: bool) -> Result { + pub fn to_object(&self) -> Result { + let mut raw_object = BTreeMap::from([ + (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), + (property_names::ID.to_string(), Value::Identifier(self.id.buffer)), + (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.buffer)), + (property_names::SCHEMA.to_string(), Value::Text(self.schema.clone())), + (property_names::VERSION.to_string(), Value::U32(self.version)), + (property_names::DOCUMENTS.to_string(), self.documents.into()), + (property_names::ENTROPY.to_string(), Value::Bytes32(self.entropy))]); + if let Some(defs) = &self.defs { + raw_object.insert(property_names::DEFINITIONS.to_string(), defs.into()) + } + + Ok(raw_object.into()) + } + + pub fn into_object(self) -> Result { + let mut raw_object = BTreeMap::from([ + (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), + (property_names::ID.to_string(), Value::Identifier(self.id.buffer)), + (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.buffer)), + (property_names::SCHEMA.to_string(), Value::Text(self.schema)), + (property_names::VERSION.to_string(), Value::U32(self.version)), + (property_names::DOCUMENTS.to_string(), self.documents.into()), + (property_names::ENTROPY.to_string(), Value::Bytes32(self.entropy))]); + if let Some(defs) = &self.defs { + raw_object.insert(property_names::DEFINITIONS.to_string(), defs.into()) + } + + Ok(raw_object.into()) + } + + pub fn to_json_object(&self, skip_identifiers_conversion: bool) -> Result { let mut json_object = serde_json::to_value(self)?; if !json_object.is_object() { return Err(anyhow!("the Data Contract isn't a JSON Value Object").into()); @@ -202,8 +254,8 @@ impl DataContract { } /// Returns true if document type is defined - pub fn is_document_defined(&self, doc_type: &str) -> bool { - self.documents.contains_key(doc_type) + pub fn is_document_defined(&self, document_type_name: &str) -> bool { + self.document_types.get(document_type_name).is_some() } pub fn set_document_schema(&mut self, doc_type: String, schema: JsonSchema) { @@ -363,6 +415,29 @@ impl TryFrom for DataContract { } } +impl TryFrom for DataContract { + type Error = ProtocolError; + fn try_from(value: Value) -> Result { + DataContract::from_raw_object(value) + } +} + +impl TryInto for DataContract { + type Error = ProtocolError; + + fn try_into(self) -> Result { + self.into_object() + } +} + +impl TryInto for &DataContract { + type Error = ProtocolError; + + fn try_into(self) -> Result { + self.to_object() + } +} + impl TryFrom<&str> for DataContract { type Error = ProtocolError; fn try_from(v: &str) -> Result { @@ -644,7 +719,7 @@ mod test { let string_contract = get_data_from_file("src/tests/payloads/contract_example.json")?; let data_contract: DataContract = serde_json::from_str(&string_contract)?; - let raw_data_contract = data_contract.to_object(false)?; + let raw_data_contract = data_contract.to_json_object(false)?; for path in IDENTIFIER_FIELDS { assert!(raw_data_contract .get(path) diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 50fc647931c..21c06df1502 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -1,5 +1,5 @@ - - +use std::collections::BTreeMap; +use std::convert::TryInto; use serde_json::{json, Map, Value as JsonValue}; use std::sync::Arc; @@ -114,7 +114,7 @@ impl DataContractFactory { skip_validation: bool, ) -> Result { let json_value = raw_data_contract - .try_into_validating_json() + .try_to_validating_json() .map_err(ProtocolError::ValueError)?; if !skip_validation { let result = self.validate_data_contract.validate(&json_value)?; @@ -125,7 +125,7 @@ impl DataContractFactory { )); } } - DataContract::from_json_raw_object(json_value) + DataContract::from_raw_object(raw_data_contract) } /// Create Data Contract from buffer @@ -147,21 +147,24 @@ impl DataContractFactory { &self, data_contract: DataContract, ) -> Result { - DataContractCreateTransition::from_raw_object(json!({ - st_prop::PROTOCOL_VERSION: self.protocol_version, - st_prop::DATA_CONTRACT: data_contract.to_object(false)?, - st_prop::ENTROPY: data_contract.entropy, - })) + let raw_object = BTreeMap::from([ + (st_prop::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), + (st_prop::DATA_CONTRACT.to_string(), data_contract.try_into()?), + (st_prop::ENTROPY.to_string(), Value::Bytes32(data_contract.entropy)) + ]); + DataContractCreateTransition::from_value_map(raw_object) } pub fn create_data_contract_update_transition( &self, data_contract: DataContract, ) -> Result { - DataContractUpdateTransition::from_raw_object(json!({ - st_prop::PROTOCOL_VERSION: self.protocol_version, - st_prop::DATA_CONTRACT: data_contract.to_object(false)?, - })) + let raw_object = BTreeMap::from([ + (st_prop::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), + (st_prop::DATA_CONTRACT.to_string(), data_contract.try_into()?) + ]); + + DataContractUpdateTransition::from_value_map(raw_object) } } @@ -180,7 +183,7 @@ mod tests { fn get_test_data() -> TestData { let data_contract = get_data_contract_fixture(None); - let raw_data_contract = data_contract.to_object(false).unwrap(); + let raw_data_contract = data_contract.to_json_object(false).unwrap(); let protocol_version_validator = ProtocolVersionValidator::new( LATEST_VERSION, LATEST_VERSION, @@ -295,7 +298,7 @@ mod tests { assert_eq!(&data_contract.entropy, result.get_entropy()); assert_eq!( raw_data_contract, - result.data_contract.to_object(false).unwrap() + result.data_contract.to_json_object(false).unwrap() ); } } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 6b18dee78a1..d5ac7790095 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -1,8 +1,11 @@ +use std::collections::BTreeMap; use std::convert::TryInto; use anyhow::anyhow; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; use crate::{ data_contract::DataContract, @@ -54,23 +57,42 @@ impl std::default::Default for DataContractCreateTransition { impl DataContractCreateTransition { pub fn from_raw_object( - mut raw_data_contract_update_transition: JsonValue, + mut raw_data_contract_update_transition: Value, ) -> Result { Ok(DataContractCreateTransition { - protocol_version: raw_data_contract_update_transition.get_u64(PROTOCOL_VERSION)? as u32, + protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION)?, signature: raw_data_contract_update_transition - .remove_into(SIGNATURE) + .remove_optional_bytes(SIGNATURE).map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition - .get_u64(SIGNATURE_PUBLIC_KEY_ID) - .unwrap_or_default() as KeyID, + .get_optional_integer(SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)? + .unwrap_or_default(), + entropy: raw_data_contract_update_transition + .remove_optional_hash256_bytes(ENTROPY).map_err(ProtocolError::ValueError)? + .unwrap_or_default(), + data_contract: DataContract::from_raw_object( + raw_data_contract_update_transition.remove(DATA_CONTRACT).ok_or(ProtocolError::DecodingError("data contract missing on state transition".to_string()))?, + )?, + ..Default::default() + }) + } + + pub fn from_value_map( + mut raw_data_contract_update_transition: BTreeMap, + ) -> Result { + Ok(DataContractCreateTransition { + protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION).map_err(ProtocolError::ValueError)?, + signature: raw_data_contract_update_transition + .remove_optional_bytes(SIGNATURE).map_err(ProtocolError::ValueError)? + .unwrap_or_default(), + signature_public_key_id: raw_data_contract_update_transition + .remove_optional_integer(SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)? + .unwrap_or_default(), entropy: raw_data_contract_update_transition - .get_bytes(ENTROPY) - .unwrap_or_else(|_| [0u8; 32].to_vec()) - .try_into() - .map_err(|_| anyhow!("entropy isn't 32 bytes long"))?, - data_contract: DataContract::from_json_raw_object( - raw_data_contract_update_transition.remove(DATA_CONTRACT)?, + .remove_optional_hash256_bytes(ENTROPY).map_err(ProtocolError::ValueError)? + .unwrap_or_default(), + data_contract: DataContract::from_raw_object( + raw_data_contract_update_transition.remove(DATA_CONTRACT).ok_or(ProtocolError::DecodingError("data contract missing on state transition".to_string()))?, )?, ..Default::default() }) @@ -187,7 +209,7 @@ impl StateTransitionConvert for DataContractCreateTransition { } json_object.insert( String::from(DATA_CONTRACT), - self.data_contract.to_object(false)?, + self.data_contract.to_json_object(false)?, )?; Ok(json_object) } @@ -249,10 +271,10 @@ mod test { assert_eq!( data.state_transition .get_data_contract() - .to_object(false) + .to_json_object(false) .expect("conversion to object shouldn't fail"), data.data_contract - .to_object(false) + .to_json_object(false) .expect("conversion to object shouldn't fail") ); } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 1b83a3124c0..b981c294fed 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -1,5 +1,8 @@ +use std::collections::BTreeMap; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; use crate::{ data_contract::DataContract, @@ -49,18 +52,36 @@ impl std::default::Default for DataContractUpdateTransition { impl DataContractUpdateTransition { pub fn from_raw_object( - mut raw_data_contract_update_transition: JsonValue, + mut raw_data_contract_update_transition: Value, ) -> Result { Ok(DataContractUpdateTransition { - protocol_version: raw_data_contract_update_transition.get_u64(PROTOCOL_VERSION)? as u32, + protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION)?, signature: raw_data_contract_update_transition - .remove_into(SIGNATURE) + .remove_optional_bytes(SIGNATURE).map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition - .get_u64(SIGNATURE_PUBLIC_KEY_ID) - .unwrap_or_default() as KeyID, - data_contract: DataContract::from_json_raw_object( - raw_data_contract_update_transition.remove(DATA_CONTRACT)?, + .get_optional_integer(SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)? + .unwrap_or_default(), + data_contract: DataContract::from_raw_object( + raw_data_contract_update_transition.remove(DATA_CONTRACT).ok_or(ProtocolError::DecodingError("data contract missing on state transition".to_string()))?, + )?, + ..Default::default() + }) + } + + pub fn from_value_map( + mut raw_data_contract_update_transition: BTreeMap, + ) -> Result { + Ok(DataContractUpdateTransition { + protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION).map_err(ProtocolError::ValueError)?, + signature: raw_data_contract_update_transition + .remove_optional_bytes(SIGNATURE).map_err(ProtocolError::ValueError)? + .unwrap_or_default(), + signature_public_key_id: raw_data_contract_update_transition + .remove_optional_integer(SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)? + .unwrap_or_default(), + data_contract: DataContract::from_raw_object( + raw_data_contract_update_transition.remove(DATA_CONTRACT).ok_or(ProtocolError::DecodingError("data contract missing on state transition".to_string()))?, )?, ..Default::default() }) @@ -169,7 +190,7 @@ impl StateTransitionConvert for DataContractUpdateTransition { } json_object.insert( String::from(DATA_CONTRACT), - self.data_contract.to_object(false)?, + self.data_contract.to_json_object(false)?, )?; Ok(json_object) } @@ -177,6 +198,7 @@ impl StateTransitionConvert for DataContractUpdateTransition { #[cfg(test)] mod test { + use std::convert::TryInto; use integer_encoding::VarInt; use serde_json::json; @@ -193,10 +215,13 @@ mod test { fn get_test_data() -> TestData { let data_contract = get_data_contract_fixture(None); - let state_transition = DataContractUpdateTransition::from_raw_object(json!({ - PROTOCOL_VERSION: version::LATEST_VERSION, - DATA_CONTRACT : data_contract.to_object(false).unwrap(), - })) + let value_map = BTreeMap::from([ + (PROTOCOL_VERSION.to_string(), Value::U32(version::LATEST_VERSION)), + (DATA_CONTRACT.to_string(), data_contract.try_into().unwrap()) + ]); + + + let state_transition = DataContractUpdateTransition::from_value_map(value_map) .expect("state transition should be created without errors"); TestData { @@ -230,10 +255,10 @@ mod test { assert_eq!( data.state_transition .get_data_contract() - .to_object(false) + .to_json_object(false) .expect("conversion to object shouldn't fail"), data.data_contract - .to_object(false) + .to_json_object(false) .expect("conversion to object shouldn't fail") ); } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 8b1b10afc27..57def77c640 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -135,7 +135,7 @@ where InvalidDataContractVersionError::new(old_version + 1, new_version), )) } - let raw_existing_data_contract = existing_data_contract.to_object(false)?; + let raw_existing_data_contract = existing_data_contract.to_json_object(false)?; let mut old_base_data_contract = raw_existing_data_contract; diff --git a/packages/rs-dpp/src/data_contract/state_transition/errors/missing_data_contract_id_error.rs b/packages/rs-dpp/src/data_contract/state_transition/errors/missing_data_contract_id_error.rs index 1962ea3c8bd..28cb2bc2c91 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/errors/missing_data_contract_id_error.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/errors/missing_data_contract_id_error.rs @@ -1,22 +1,21 @@ use crate::consensus::basic::BasicError; use thiserror::Error; - -use crate::document::document_transition::document_base_transition::JsonValue; +use platform_value::Value; #[derive(Error, Debug, Clone, PartialEq, Eq)] #[error("$dataContractId is not present")] pub struct MissingDataContractIdError { - raw_document_transition: JsonValue, + raw_document_transition: Value, } impl MissingDataContractIdError { - pub fn new(raw_document_transition: JsonValue) -> Self { + pub fn new(raw_document_transition: Value) -> Self { Self { raw_document_transition, } } - pub fn raw_document_transition(&self) -> JsonValue { + pub fn raw_document_transition(&self) -> Value { self.raw_document_transition.clone() } } diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 2ea37eae252..1de751670cc 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -352,6 +352,39 @@ impl Document { Ok(map) } + pub fn into_map_value(self) -> Result, ProtocolError> { + let mut map: BTreeMap = BTreeMap::new(); + map.insert(property_names::ID.to_string(), Value::Identifier(self.id)); + map.insert( + property_names::OWNER_ID.to_string(), + Value::Identifier(self.owner_id), + ); + + if let Some(created_at) = self.created_at { + map.insert( + property_names::CREATED_AT.to_string(), + Value::U64(created_at), + ); + } + if let Some(updated_at) = self.updated_at { + map.insert( + property_names::UPDATED_AT.to_string(), + Value::U64(updated_at), + ); + } + if let Some(revision) = self.revision { + map.insert(property_names::REVISION.to_string(), Value::U64(revision)); + } + + map.extend(self.properties); + + Ok(map) + } + + pub fn into_value(self) -> Result { + Ok(self.into_map_value()?.into()) + } + pub fn to_value(&self) -> Result { Ok(self.to_map_value()?.into()) } diff --git a/packages/rs-dpp/src/document/document_facade.rs b/packages/rs-dpp/src/document/document_facade.rs index 3d0c7d05151..d480d898e42 100644 --- a/packages/rs-dpp/src/document/document_facade.rs +++ b/packages/rs-dpp/src/document/document_facade.rs @@ -96,14 +96,14 @@ where &self, extended_document: &ExtendedDocument, ) -> Result, ProtocolError> { - let raw_extended_document = extended_document.to_json_object_for_validation()?; + let raw_extended_document = extended_document.to_value()?; self.validate_raw_document(&raw_extended_document).await } /// Creates Documents State Transition pub async fn validate_raw_document( &self, - raw_extended_document: &JsonValue, + raw_extended_document: &Value, ) -> Result, ProtocolError> { let result = self .data_contract_fetcher_and_validator diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 891d40fd28e..10e62d1c4b0 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -263,7 +263,7 @@ where Err(ProtocolError::AbstractConsensusError(err)) => { Err(DocumentError::InvalidDocumentError { errors: vec![*err], - raw_document: JsonValue::Null, + raw_document: Value::Null, } .into()) } @@ -282,7 +282,7 @@ where ) -> Result { let data_contract = self .validate_data_contract_for_extended_document( - &raw_document.clone().try_into_validating_json()?, + &raw_document, options, ) .await?; @@ -292,7 +292,7 @@ where async fn validate_data_contract_for_extended_document( &self, - raw_document: &JsonValue, + raw_document: &Value, options: FactoryOptions, ) -> Result { let mut result = self @@ -434,6 +434,7 @@ where mod test { use platform_value::btreemap_extensions::BTreeValueMapHelper; use std::sync::Arc; + use serde_json::json; use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index b6ae900f553..523badb29b6 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use anyhow::anyhow; use lazy_static::lazy_static; use serde_json::Value as JsonValue; +use platform_value::Value; use crate::data_contract::document_type::DocumentType; use crate::consensus::basic::document::InvalidDocumentTypeError; @@ -17,6 +18,7 @@ use crate::{ version::ProtocolVersionValidator, ProtocolError, }; +use crate::data_contract::DriveContractExt; const PROPERTY_PROTOCOL_VERSION: &str = "$protocolVersion"; const PROPERTY_DOCUMENT_TYPE: &str = "$type"; @@ -83,33 +85,18 @@ impl DocumentValidator { pub fn validate_extended( &self, - raw_document: &JsonValue, + raw_document: &Value, data_contract: &DataContract, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); - let maybe_document_type = raw_document.get(PROPERTY_DOCUMENT_TYPE); - if maybe_document_type.is_none() { + let Some(document_type_name) = raw_document.get_optional_str(PROPERTY_DOCUMENT_TYPE).map_err(ProtocolError::ValueError)? else { result.add_error(BasicError::MissingDocumentTypeError); return Ok(result); - } + }; - let document_type = maybe_document_type.unwrap().as_str().ok_or_else(|| { - anyhow!( - "the document type '{:?}' cannot be converted into the string", - maybe_document_type - ) - })?; - - if !data_contract.is_document_defined(document_type) { - result.add_error(BasicError::InvalidDocumentTypeError( - InvalidDocumentTypeError::new( - document_type.to_owned(), - data_contract.id.to_owned(), - ), - )); - return Ok(result); - } + /// check if there is a document type + data_contract.document_type_for_name(document_type_name)?; let enriched_data_contract = enrich_data_contract_with_base_schema( data_contract, @@ -118,7 +105,7 @@ impl DocumentValidator { &[], )?; let document_schema = enriched_data_contract - .get_document_schema(document_type)? + .get_document_schema(document_type_name)? .to_owned(); let json_schema_validator = if let Some(defs) = &data_contract.defs { @@ -128,14 +115,15 @@ impl DocumentValidator { } .map_err(|e| anyhow!("unable to process the contract: {}", e))?; - let json_schema_validation_result = json_schema_validator.validate(raw_document)?; + let json_value = raw_document.try_into_validating_json().map_err(ProtocolError::ValueError)?; + let json_schema_validation_result = json_schema_validator.validate(&json_value)?; result.merge(json_schema_validation_result); if !result.is_valid() { return Ok(result); } - let protocol_version = raw_document.get_u64(PROPERTY_PROTOCOL_VERSION)? as u32; + let protocol_version = raw_document.get_integer(PROPERTY_PROTOCOL_VERSION).map_err(ProtocolError::ValueError)?; result.merge(self.protocol_version_validator.validate(protocol_version)?); Ok(result) @@ -153,6 +141,7 @@ mod test { use serde_json::json; use serde_json::Value as JsonValue; use test_case::test_case; + use platform_value::Value; use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ @@ -169,7 +158,7 @@ mod test { struct TestData { data_contract: DataContract, - raw_document: JsonValue, + raw_document: Value, document_validator: DocumentValidator, } @@ -178,7 +167,7 @@ mod test { let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); let raw_document = documents .iter() - .map(|d| d.to_json_object_for_validation()) + .map(|d| d.to_value()) .next() .expect("at least one Document should be present") .expect("Document should be converted to Object"); @@ -525,9 +514,9 @@ mod test { let document = documents.get(8).unwrap(); let data = [0u8; 32]; - let mut raw_document = document.to_json_object_for_validation().unwrap(); + let mut raw_document = document.to_value().unwrap(); raw_document - .insert("byteArrayField".to_string(), json!(data)) + .set_value("byteArrayField", Value::Bytes32(data)) .unwrap(); let result = document_validator diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index ba97a618423..3fc08bed364 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -1,5 +1,5 @@ -use serde_json::Value; use thiserror::Error; +use platform_value::Value; use crate::errors::consensus::ConsensusError; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 0415e1a4569..d499e207da6 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -325,6 +325,31 @@ impl ExtendedDocument { Ok(object) } + pub fn into_map_value(self) -> Result, ProtocolError> { + let ExtendedDocument { + protocol_version, document_type_name, data_contract_id, document, .. + } = self; + + let mut object = document.into_map_value()?; + object.insert( + property_names::PROTOCOL_VERSION.to_string(), + Value::U32(protocol_version), + ); + object.insert( + property_names::DOCUMENT_TYPE.to_string(), + Value::Text(document_type_name), + ); + object.insert( + property_names::DATA_CONTRACT_ID.to_string(), + Value::Identifier(data_contract_id.to_buffer()), + ); + Ok(object) + } + + pub fn into_value(self) -> Result { + Ok(self.into_map_value()?.into()) + } + pub fn to_value(&self) -> Result { Ok(self.to_map_value()?.into()) } @@ -408,6 +433,22 @@ impl ExtendedDocument { } } +impl TryInto for ExtendedDocument { + type Error = ProtocolError; + + fn try_into(self) -> Result { + self.into_value() + } +} + +impl TryInto for &ExtendedDocument { + type Error = ProtocolError; + + fn try_into(self) -> Result { + self.to_value() + } +} + #[cfg(test)] mod test { use anyhow::Result; diff --git a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs index e8a271f261f..cd0786c99f7 100644 --- a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs +++ b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs @@ -1,6 +1,7 @@ use std::{convert::TryInto, sync::Arc}; -use serde_json::Value; +use serde_json::Value as JsonValue; +use platform_value::Value; use crate::consensus::basic::invalid_identifier_error::InvalidIdentifierError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; @@ -60,7 +61,7 @@ pub async fn fetch_and_validate_data_contract( ) -> Result, ProtocolError> { let mut validation_result = ValidationResult::::default(); - let id_bytes = if let Ok(id_bytes) = raw_extended_document.get_bytes(property_names::DATA_CONTRACT_ID) { + let id_bytes = if let Some(id_bytes) = raw_extended_document.get_optional_hash256(property_names::DATA_CONTRACT_ID).map_err(ProtocolError::ValueError)? { id_bytes } else { validation_result.add_error(ConsensusError::BasicError(Box::new( @@ -71,19 +72,7 @@ pub async fn fetch_and_validate_data_contract( return Ok(validation_result); }; - let data_contract_id = match Identifier::from_bytes(&id_bytes) { - Ok(id) => id, - - Err(e) => { - let id_base58 = bs58::encode(id_bytes).into_string(); - let consensus_error = - ConsensusError::BasicError(Box::new(BasicError::InvalidIdentifierError( - InvalidIdentifierError::new(id_base58, e.to_string()), - ))); - validation_result.add_error(consensus_error); - return Ok(validation_result); - } - }; + let data_contract_id = Identifier::from(id_bytes); let maybe_data_contract = state_repository .fetch_data_contract(&data_contract_id, execution_context) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 56f0433fb3b..a9eaf6b6dd8 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -2,6 +2,8 @@ use std::{ collections::{hash_map::Entry, HashMap}, convert::{TryFrom, TryInto}, }; +use std::collections::BTreeMap; +use std::iter::Map; use crate::consensus::basic::document::{ DuplicateDocumentTransitionsWithIdsError, DuplicateDocumentTransitionsWithIndicesError, @@ -32,6 +34,9 @@ use anyhow::anyhow; use lazy_static::lazy_static; use platform_value::Value; use serde_json::Value as JsonValue; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use crate::document::state_transition::documents_batch_transition::property_names; use super::{ find_duplicates_by_indices::find_duplicates_by_indices, @@ -63,7 +68,7 @@ pub trait Validator { pub async fn validate_documents_batch_transition_basic( protocol_version_validator: &ProtocolVersionValidator, - raw_state_transition: &JsonValue, + raw_state_transition: &Value, state_repository: &impl StateRepositoryLike, execution_context: &StateTransitionExecutionContext, ) -> Result, ProtocolError> { @@ -76,47 +81,40 @@ pub async fn validate_documents_batch_transition_basic( ) })?; - let validation_result = validator.validate(raw_state_transition)?; + let raw_state_transition_json = raw_state_transition.clone().try_into_validating_json().map_err(ProtocolError::ValueError)?; + let validation_result = validator.validate(&raw_state_transition_json)?; result.merge(validation_result); if !result.is_valid() { return Ok(result); } - let protocol_version = raw_state_transition.get_u64("protocolVersion")? as u32; + let state_transition_map = raw_state_transition.to_btree_ref_map().map_err(ProtocolError::ValueError)?; + + let owner_id = Identifier::from(state_transition_map.get_hash256_bytes(property_names::OWNER_ID).map_err(ProtocolError::ValueError)?); + + let protocol_version = state_transition_map.get_integer(property_names::PROTOCOL_VERSION)?; let validation_result = protocol_version_validator.validate(protocol_version)?; result.merge(validation_result); if !result.is_valid() { return Ok(result); } - let raw_document_transitions = raw_state_transition - .get("transitions") - .ok_or_else(|| anyhow!("transitions property doesn't exist"))? - .as_array() - .ok_or_else(|| anyhow!("transitions property isn't an array"))?; - let mut document_transitions_by_contracts: HashMap> = + let raw_document_transitions : Vec> = state_transition_map + .get_inner_map_in_array(property_names::TRANSITIONS).map_err(ProtocolError::ValueError)?; + let mut document_transitions_by_contracts: HashMap>> = HashMap::new(); for raw_document_transition in raw_document_transitions { - let data_contract_id_bytes = match raw_document_transition.get_bytes("$dataContractId") { - Err(_) => { - result.add_error(BasicError::MissingDataContractIdError( - MissingDataContractIdError::new(raw_document_transition.clone()), + let data_contract_id_bytes = match raw_document_transition.get_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? { + None => { result.add_error(BasicError::MissingDataContractIdError( + MissingDataContractIdError::new(raw_document_transition.into()), )); continue; } - Ok(id) => id, + Some(id) => { id} }; - let identifier = match Identifier::from_bytes(&data_contract_id_bytes) { - Ok(identifier) => identifier, - Err(e) => { - result.add_error(BasicError::InvalidIdentifierError( - InvalidIdentifierError::new(String::from("$dataContractId"), e.to_string()), - )); - continue; - } - }; + let identifier = Identifier::from(data_contract_id_bytes); match document_transitions_by_contracts.entry(identifier) { Entry::Vacant(vacant) => { @@ -148,8 +146,6 @@ pub async fn validate_documents_batch_transition_basic( Some(data_contract) => data_contract, }; - let owner_id = Identifier::from_bytes(&raw_state_transition.get_bytes("ownerId")?)?; - let validation_result = validate_document_transitions(&data_contract, &owner_id, transitions)?; result.merge(validation_result); @@ -161,7 +157,7 @@ pub async fn validate_documents_batch_transition_basic( fn validate_document_transitions<'a>( data_contract: &DataContract, owner_id: &Identifier, - raw_document_transitions: impl IntoIterator, + raw_document_transitions: impl IntoIterator>, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); let enriched_contracts_by_action = get_enriched_contracts_by_action(data_contract)?; @@ -205,46 +201,37 @@ fn get_enriched_contracts_by_action( Ok(enriched_contracts_by_action) } -//todo: switch to platform Value fn validate_raw_transitions<'a>( data_contract: &DataContract, - raw_document_transitions: impl IntoIterator, + raw_document_transitions: Vec>, enriched_contracts_by_action: &HashMap, owner_id: &Identifier, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); - let raw_document_transitions: Vec<&JsonValue> = raw_document_transitions.into_iter().collect(); + for raw_document_transition in raw_document_transitions.iter() { - let document_type = match raw_document_transition.get_string("$type") { - Err(_) => { + let Some(document_type) = raw_document_transition.get_optional_str("$type").map_err(ProtocolError::ValueError) else { result.add_error(BasicError::MissingDocumentTransitionTypeError); return Ok(result); - } - - Ok(document_type) => { - if !data_contract.is_document_defined(document_type) { - result.add_error(BasicError::InvalidDocumentTypeError( - InvalidDocumentTypeError::new( - document_type.to_string(), - data_contract.id.clone(), - ), - )); - return Ok(result); - } - document_type - } }; - let document_action = match raw_document_transition.get_u64("$action") { - Ok(action) => action, - Err(_) => { - result.add_error(BasicError::MissingDocumentTransitionActionError); - return Ok(result); - } + if !data_contract.is_document_defined(document_type) { + result.add_error(BasicError::InvalidDocumentTypeError( + InvalidDocumentTypeError::new( + document_type.to_string(), + data_contract.id.clone(), + ), + )); + return Ok(result); + } + + let Some(document_action) = raw_document_transition.get_optional_integer::("$action") else { + result.add_error(BasicError::MissingDocumentTransitionActionError); + return Ok(result); }; - let action = match Action::try_from(document_action as u8) { + let action = match Action::try_from(document_action) { Ok(action) => action, Err(_) => { result.add_error(BasicError::InvalidDocumentTransitionActionError( @@ -266,7 +253,7 @@ fn validate_raw_transitions<'a>( } .map_err(|e| anyhow!("unable to compile enriched schema: {}", e))?; - let schema_result = schema_validator.validate(raw_document_transition)?; + let schema_result = schema_validator.validate(raw_document_transition.into())?; if !schema_result.is_valid() { result.merge(schema_result); return Ok(result); @@ -351,7 +338,7 @@ fn validate_raw_transitions<'a>( let validation_result = validate_partial_compound_indices( raw_document_transitions_as_value_iter .clone() - .filter(|t| action_is_not_delete(t.get_string("$action").unwrap_or_default())), + .filter(|t| action_is_not_delete(t.get_str("$action").unwrap_or_default())), data_contract, )?; result.merge(validation_result); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index cb11186af61..4f630d98512 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -20,7 +20,7 @@ pub fn validate_partial_compound_indices<'a>( let mut result = ValidationResult::default(); for transition in raw_document_transitions { - let document_type = transition.get_string("$type")?; + let document_type = transition.get_str("$type")?; let document_schema = data_contract.get_document_schema(document_type)?; let indices = document_schema.get_indices::>().unwrap_or_default(); diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index 9716f2b9aa6..813ea7eccf6 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -1,4 +1,4 @@ -use std::convert::TryFrom; +use std::convert::{TryFrom, TryInto}; use dashcore::Transaction; use serde::de::Error as DeError; @@ -11,11 +11,12 @@ pub use asset_lock_transaction_output_fetcher::*; pub use asset_lock_transaction_validator::*; pub use chain::*; pub use instant::*; +use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; use crate::prelude::Identifier; use crate::util::json_value::JsonValueExt; -use crate::{NonConsensusError, SerdeParsingError}; +use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; mod asset_lock_proof_validator; mod asset_lock_public_key_hash_fetcher; @@ -83,10 +84,10 @@ pub enum AssetLockProofType { Chain = 1, } -impl TryFrom for AssetLockProofType { +impl TryFrom for AssetLockProofType { type Error = SerdeParsingError; - fn try_from(value: u64) -> Result { + fn try_from(value: u8) -> Result { match value { 0 => Ok(Self::Instant), 1 => Ok(Self::Chain), @@ -137,29 +138,39 @@ impl AssetLockProof { } } -impl TryFrom<&JsonValue> for AssetLockProof { - type Error = SerdeParsingError; +impl TryFrom<&Value> for AssetLockProof { + type Error = ProtocolError; - fn try_from(value: &JsonValue) -> Result { - let proof_type_int = value - .get_u64("type") - .map_err(|e| SerdeParsingError::new(e.to_string()))?; + fn try_from(value: &Value) -> Result { + let proof_type_int: u8 = value + .get_integer("type").map_err(ProtocolError::ValueError)?; let proof_type = AssetLockProofType::try_from(proof_type_int)?; match proof_type { AssetLockProofType::Instant => { - Ok(Self::Instant(serde_json::from_value(value.clone())?)) + Ok(Self::Instant(value.try_into()?)) } - AssetLockProofType::Chain => Ok(Self::Chain(serde_json::from_value(value.clone())?)), + AssetLockProofType::Chain => Ok(Self::Chain(value.try_into()?)), } } } -impl TryFrom for JsonValue { - type Error = serde_json::Error; +impl TryInto for AssetLockProof { + type Error = ProtocolError; - fn try_from(asset_lock_proof: AssetLockProof) -> Result { - match asset_lock_proof { + fn try_into(self) -> Result { + match self { + AssetLockProof::Instant(instant_proof) => serde_json::to_value(instant_proof), + AssetLockProof::Chain(chain_proof) => serde_json::to_value(chain_proof), + } + } +} + +impl TryInto for &AssetLockProof { + type Error = ProtocolError; + + fn try_into(self) -> Result { + match self { AssetLockProof::Instant(instant_proof) => serde_json::to_value(instant_proof), AssetLockProof::Chain(chain_proof) => serde_json::to_value(chain_proof), } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 236e5d7a23a..87a8e8bac71 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -4,6 +4,9 @@ use serde::de::Error as DeError; use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; @@ -90,20 +93,15 @@ impl<'de> Deserialize<'de> for IdentityCreateTransition { /// Main state transition functionality implementation impl IdentityCreateTransition { - pub fn new(raw_state_transition: serde_json::Value) -> Result { + pub fn new(raw_state_transition: Value) -> Result { let mut state_transition = Self::default(); - let transition_map = raw_state_transition.as_object().ok_or_else(|| { - SerdeParsingError::new("Expected raw identity transition to be a map") - })?; - if let Some(keys_value) = transition_map.get(property_names::PUBLIC_KEYS) { - let keys_value_arr = keys_value - .as_array() - .ok_or_else(|| SerdeParsingError::new("Expected public keys to be an array"))?; - let keys = keys_value_arr - .iter() - .map(|val| serde_json::from_value(val.clone())) - .collect::, serde_json::Error>>()?; + let mut transition_map = raw_state_transition.into_btree_map().map_err(ProtocolError::ValueError)?; + if let Some(keys_value_array) = transition_map.remove_optional_inner_value_array::>(property_names::PUBLIC_KEYS).map_err(ProtocolError::ValueError)? { + let keys = keys_value_array + .into_iter() + .map(|val| val.try_into()) + .collect::, ProtocolError>>()?; state_transition.set_public_keys(keys); } @@ -111,9 +109,7 @@ impl IdentityCreateTransition { state_transition.set_asset_lock_proof(AssetLockProof::try_from(proof)?)?; } - if let Some(protocol_version) = transition_map.get(property_names::PROTOCOL_VERSION) { - state_transition.protocol_version = protocol_version.as_u64().unwrap() as u32; - } + state_transition.protocol_version = transition_map.get_integer(property_names::PROTOCOL_VERSION)?; Ok(state_transition) } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index eeec6bb8507..dfe9adac08e 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -1,9 +1,12 @@ +use std::collections::BTreeMap; use crate::identity::{IdentityPublicKey, KeyID, KeyType, Purpose, SecurityLevel}; use ciborium::value::Value as CborValue; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::Value; use crate::errors::ProtocolError; use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; @@ -48,7 +51,31 @@ impl IdentityPublicKeyCreateTransition { } } - pub fn from_raw_object(raw_object: JsonValue) -> Result { + pub fn from_raw_object(mut raw_object: Value) -> Result { + Ok(Self { + id: raw_object.get_integer("id").map_err(ProtocolError::ValueError)?, + purpose: raw_object.get_integer("purpose").map_err(ProtocolError::ValueError)?, + security_level: raw_object.get_integer("securityLevel").map_err(ProtocolError::ValueError)?, + key_type: raw_object.get_integer("keyType").map_err(ProtocolError::ValueError)?, + data: raw_object.remove_bytes("data").map_err(ProtocolError::ValueError)?, + read_only: raw_object.get_bool("readOnly").map_err(ProtocolError::ValueError)?, + signature: raw_object.remove_bytes("signature").map_err(ProtocolError::ValueError)?, + }) + } + + pub fn from_value_map(mut value_map: BTreeMap) -> Result { + Ok(Self { + id: value_map.get_integer("id").map_err(ProtocolError::ValueError)?, + purpose: value_map.get_integer("purpose").map_err(ProtocolError::ValueError)?, + security_level: value_map.get_integer("securityLevel").map_err(ProtocolError::ValueError)?, + key_type: value_map.get_integer("keyType").map_err(ProtocolError::ValueError)?, + data: value_map.remove_bytes("data").map_err(ProtocolError::ValueError)?, + read_only: value_map.get_bool("readOnly").map_err(ProtocolError::ValueError)?, + signature: value_map.remove_bytes("signature").map_err(ProtocolError::ValueError)?, + }) + } + + pub fn from_raw_json_object(raw_object: JsonValue) -> Result { let identity_public_key: Self = serde_json::from_value(raw_object)?; Ok(identity_public_key) } @@ -60,6 +87,23 @@ impl IdentityPublicKeyCreateTransition { Ok(identity_public_key) } + /// Return raw data, with all binary fields represented as arrays + pub fn to_raw_object(&self, skip_signature: bool) -> Result { + let mut map = BTreeMap::from([("id".to_string(), Value::U32(self.id)), + ("purpose".to_string(), Value::U8(self.purpose as u8)), + ("securityLevel".to_string(), Value::U8(self.security_level as u8)), + ("keyType".to_string(), Value::U8(self.key_type as u8)), + ("data".to_string(), Value::Bytes(self.data.clone())), + ("readOnly".to_string(), Value::Bool(self.read_only)), + ]); + + if !skip_signature && !self.signature.is_empty() { + map.insert("signature".to_string(), Value::Bytes(self.signature.clone())) + } + + Ok(value) + } + /// Return raw data, with all binary fields represented as arrays pub fn to_raw_json_object(&self, skip_signature: bool) -> Result { let mut value = serde_json::to_value(self)?; @@ -154,3 +198,19 @@ impl From<&IdentityPublicKeyCreateTransition> for IdentityPublicKey { } } } + +impl TryFrom for IdentityPublicKeyCreateTransition { + type Error = ProtocolError; + + fn try_from(value: Value) -> Result { + IdentityPublicKeyCreateTransition::from_raw_object(value) + } +} + +impl TryInto for IdentityPublicKeyCreateTransition { + type Error = ProtocolError; + + fn try_into(self) -> Result { + self.to_raw_object(false) + } +} diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index c04b570807b..e3dbd6b2e6e 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -198,7 +198,7 @@ fn get_list_of_public_keys( if let Ok(maybe_list) = value.remove(property_names::ADD_PUBLIC_KEYS) { if let JsonValue::Array(list) = maybe_list { for maybe_public_key in list { - identity_public_keys.push(IdentityPublicKeyCreateTransition::from_raw_object( + identity_public_keys.push(IdentityPublicKeyCreateTransition::from_raw_json_object( maybe_public_key, )?); } diff --git a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 07ada1f637f..f968e8025f8 100644 --- a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -88,7 +88,7 @@ pub fn validate_public_key_signatures<'a, T: BlsModule>( let add_public_key_transitions: Vec = raw_public_keys .into_iter() .map(|k| { - IdentityPublicKeyCreateTransition::from_raw_object(k.to_owned()) + IdentityPublicKeyCreateTransition::from_raw_json_object(k.to_owned()) .map_err(|e| NonConsensusError::IdentityPublicKeyCreateError(format!("{:#}", e))) }) .collect::>()?; diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 4f0f42711f7..40504c68434 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -22,16 +22,16 @@ use crate::{ ProtocolError, }; use serde_json::Value as JsonValue; +use platform_value::Value; use super::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, StateTransitionType, }; -//todo: change from JsonValue to Platform Value pub async fn create_state_transition( state_repository: &impl StateRepositoryLike, - raw_state_transition: JsonValue, + raw_state_transition: Value, ) -> Result { let transition_type = try_get_transition_type(&raw_state_transition)?; let execution_context = StateTransitionExecutionContext::default(); @@ -86,7 +86,7 @@ pub async fn create_state_transition( async fn fetch_data_contracts_for_document_transition( state_repository: &impl StateRepositoryLike, - raw_document_transitions: impl IntoIterator, + raw_document_transitions: impl IntoIterator, execution_context: &StateTransitionExecutionContext, ) -> Result, ProtocolError> { let mut data_contracts = vec![]; @@ -117,14 +117,14 @@ async fn fetch_data_contracts_for_document_transition( } pub fn try_get_transition_type( - raw_state_transition: &JsonValue, + raw_state_transition: &Value, ) -> Result { - let transition_type = raw_state_transition - .get_u64("type") - .map_err(|_| missing_state_transition_error())?; - StateTransitionType::try_from(transition_type as u8).map_err(|_| { + let transition_type : u8 = raw_state_transition + .get_optional_integer("type") + .map_err(ProtocolError::ValueError)?.ok_or(missing_state_transition_error())?; + StateTransitionType::try_from(transition_type).map_err(|_| { ProtocolError::InvalidStateTransitionTypeError(InvalidStateTransitionTypeError::new( - transition_type as u8, + transition_type, )) }) } @@ -186,7 +186,7 @@ mod test { assert!( matches!(result, StateTransition::DataContractCreate(transition) if { - transition.get_data_contract().to_object(false).unwrap() == data_contract.to_object(false).unwrap() + transition.get_data_contract().to_json_object(false).unwrap() == data_contract.to_json_object(false).unwrap() }) ) } diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index d8c7c211e78..2eb9578f237 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -26,7 +26,7 @@ fn setup_test() -> TestData { init(); let data_contract = get_data_contract_fixture(None); - let raw_data_contract = data_contract.to_object(false).unwrap(); + let raw_data_contract = data_contract.to_json_object(false).unwrap(); let protocol_version_validator = ProtocolVersionValidator::new(LATEST_VERSION, LATEST_VERSION, COMPATIBILITY_MAP.clone()); diff --git a/packages/rs-dpp/src/validation/json_schema_validator.rs b/packages/rs-dpp/src/validation/json_schema_validator.rs index a07c349556c..6030875982a 100644 --- a/packages/rs-dpp/src/validation/json_schema_validator.rs +++ b/packages/rs-dpp/src/validation/json_schema_validator.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use anyhow::Context; use jsonschema::{JSONSchema, KeywordDefinition}; -use serde_json::{json, Value}; +use serde_json::{json, Value as JsonValue}; use crate::consensus::ConsensusError; use crate::util::json_value::JsonValueExt; @@ -13,12 +13,12 @@ use crate::{DashPlatformProtocolInitError, NonConsensusError, SerdeParsingError} use super::meta_validators; pub struct JsonSchemaValidator { - raw_schema_json: Value, + raw_schema_json: JsonValue, schema: Option, } impl DataValidator for JsonSchemaValidator { - type Item = Value; + type Item = JsonValue; fn validate( &self, data: &Self::Item, @@ -31,7 +31,7 @@ impl DataValidator for JsonSchemaValidator { } impl JsonSchemaValidator { - pub fn new(schema_json: Value) -> Result { + pub fn new(schema_json: JsonValue) -> Result { let mut json_schema_validator = Self { raw_schema_json: schema_json, schema: None, @@ -48,10 +48,10 @@ impl JsonSchemaValidator { /// creates a new json schema validator from the json schema and allows to add the definitions pub fn new_with_definitions<'a>( - mut schema_json: Value, - definitions: impl IntoIterator, + mut schema_json: JsonValue, + definitions: impl IntoIterator, ) -> Result { - let defs: HashMap<&str, &'a Value> = definitions + let defs: HashMap<&str, &'a JsonValue> = definitions .into_iter() .map(|(k, v)| (k.as_ref(), v)) .collect(); @@ -69,7 +69,7 @@ impl JsonSchemaValidator { Ok(json_schema_validator) } - pub fn validate(&self, object: &Value) -> Result, NonConsensusError> { + pub fn validate(&self, object: &JsonValue) -> Result, NonConsensusError> { // TODO: create better error messages let res = self .schema @@ -91,7 +91,7 @@ impl JsonSchemaValidator { } /// validates schema through compilation - pub fn validate_schema(schema: &Value) -> ValidationResult<()> { + pub fn validate_schema(schema: &JsonValue) -> ValidationResult<()> { let mut validation_result = ValidationResult::new(None); let res = JSONSchema::options() @@ -108,7 +108,7 @@ impl JsonSchemaValidator { } /// Uses predefined meta-schemas to validate data contract schema - pub fn validate_data_contract_schema(data_contract_schema: &Value) -> ValidationResult<()> { + pub fn validate_data_contract_schema(data_contract_schema: &JsonValue) -> ValidationResult<()> { let mut validation_result = ValidationResult::new(None); let res = meta_validators::DATA_CONTRACT_META_SCHEMA.validate(data_contract_schema); diff --git a/packages/rs-platform-value/Cargo.toml b/packages/rs-platform-value/Cargo.toml index c99d1a86daa..444fa5c7f1a 100644 --- a/packages/rs-platform-value/Cargo.toml +++ b/packages/rs-platform-value/Cargo.toml @@ -13,4 +13,11 @@ bs58 = "0.4.0" base64 = "0.13.0" hex = "0.4.3" serde = { version = "1.0.152", features = ["derive"] } -serde_json = { version="1.0", features=["preserve_order"] } \ No newline at end of file +serde_json = { version="1.0", features=["preserve_order"] } + +### FEATURES ################################################################# + +[features] +default = ["std"] + +std = ["serde/std"] \ No newline at end of file diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 7317a49f377..92fcaa7abe0 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -86,46 +86,12 @@ pub trait BTreeValueMapHelper { &self, key: &str, ) -> Result; - fn get_optional_system_hash256_bytes(&self, key: &str) -> Result, Error>; + fn get_optional_hash256_bytes(&self, key: &str) -> Result, Error>; fn get_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error>; fn get_optional_identifier_bytes(&self, key: &str) -> Result>, Error>; fn get_identifier_bytes(&self, key: &str) -> Result, Error>; - fn remove_optional_string(&mut self, key: &str) -> Result, Error>; - fn remove_string(&mut self, key: &str) -> Result; - fn remove_optional_float(&mut self, key: &str) -> Result, Error>; - fn remove_float(&mut self, key: &str) -> Result; - fn remove_optional_integer(&mut self, key: &str) -> Result, Error> - where - T: TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom; - fn remove_integer(&mut self, key: &str) -> Result - where - T: TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom; - fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error>; - fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error>; - fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error>; - fn remove_bytes(&mut self, key: &str) -> Result, Error>; fn get_optional_bytes(&self, key: &str) -> Result>, Error>; fn get_bytes(&self, key: &str) -> Result, Error>; - fn remove_optional_bool(&mut self, key: &str) -> Result, Error>; - fn remove_bool(&mut self, key: &str) -> Result; fn get_optional_binary_bytes(&self, key: &str) -> Result>, Error>; fn get_binary_bytes(&self, key: &str) -> Result, Error>; } @@ -217,49 +183,6 @@ where .ok_or_else(|| Error::StructureError(format!("unable to get integer property {key}"))) } - fn remove_optional_integer(&mut self, key: &str) -> Result, Error> - where - T: TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom, - { - self.remove(key) - .and_then(|v| { - let borrowed = v.borrow(); - if borrowed.is_null() { - None - } else { - Some(v.borrow().to_integer()) - } - }) - .transpose() - } - - fn remove_integer(&mut self, key: &str) -> Result - where - T: TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom - + TryFrom, - { - self.remove_optional_integer(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to remove integer property {key}")) - }) - } - fn get_optional_bool(&self, key: &str) -> Result, Error> { self.get(key) .and_then(|v| { @@ -438,13 +361,13 @@ where }) } - fn get_optional_system_hash256_bytes(&self, key: &str) -> Result, Error> { + fn get_optional_hash256_bytes(&self, key: &str) -> Result, Error> { self.get(key).map(|v| v.borrow().to_hash256()).transpose() } fn get_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error> { - self.get_optional_system_hash256_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get system hash256 property {key}")) + self.get_optional_hash256_bytes(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to get hash256 property {key}")) }) } @@ -454,7 +377,7 @@ where fn get_bytes(&self, key: &str) -> Result, Error> { self.get_optional_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get system bytes property {key}")) + Error::StructureError(format!("unable to get bytes property {key}")) }) } @@ -466,7 +389,7 @@ where fn get_identifier_bytes(&self, key: &str) -> Result, Error> { self.get_optional_identifier_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get system bytes property {key}")) + Error::StructureError(format!("unable to get bytes property {key}")) }) } @@ -478,79 +401,10 @@ where fn get_binary_bytes(&self, key: &str) -> Result, Error> { self.get_optional_binary_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get system bytes property {key}")) - }) - } - - fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { - self.remove(key) - .map(|v| v.borrow().to_hash256()) - .transpose() - } - - fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error> { - self.remove_optional_hash256_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to remove system hash256 property {key}")) + Error::StructureError(format!("unable to get bytes property {key}")) }) } - fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { - self.remove(key) - .map(|v| v.borrow().to_identifier_bytes()) - .transpose() - } - - fn remove_bytes(&mut self, key: &str) -> Result, Error> { - self.remove_optional_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to remove system bytes property {key}")) - }) - } - - fn remove_optional_string(&mut self, key: &str) -> Result, Error> { - self.remove(key).map(|v| v.borrow().to_text()).transpose() - } - - fn remove_string(&mut self, key: &str) -> Result { - self.remove_optional_string(key)? - .ok_or_else(|| Error::StructureError(format!("unable to remove string property {key}"))) - } - - fn remove_optional_float(&mut self, key: &str) -> Result, Error> { - self.remove(key) - .and_then(|v| { - let borrowed = v.borrow(); - if borrowed.is_null() { - None - } else { - Some(v.borrow().to_float()) - } - }) - .transpose() - } - - fn remove_float(&mut self, key: &str) -> Result { - self.remove_optional_float(key)? - .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) - } - - fn remove_optional_bool(&mut self, key: &str) -> Result, Error> { - self.remove(key) - .and_then(|v| { - let borrowed = v.borrow(); - if borrowed.is_null() { - None - } else { - Some(v.borrow().to_bool()) - } - }) - .transpose() - } - - fn remove_bool(&mut self, key: &str) -> Result { - self.remove_optional_bool(key)? - .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) - } - fn get_optional_float(&self, key: &str) -> Result, Error> { self.get(key) .and_then(|v| { diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_path_extensions.rs index 0b99414eaeb..fad78a7df8e 100644 --- a/packages/rs-platform-value/src/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_extensions.rs @@ -81,7 +81,7 @@ pub trait BTreeValueMapPathHelper { &self, path: &str, ) -> Result; - fn get_optional_system_hash256_bytes_at_path( + fn get_optional_hash256_bytes_at_path( &self, path: &str, ) -> Result, Error>; @@ -463,7 +463,7 @@ where }) } - fn get_optional_system_hash256_bytes_at_path( + fn get_optional_hash256_bytes_at_path( &self, path: &str, ) -> Result, Error> { @@ -473,9 +473,9 @@ where } fn get_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error> { - self.get_optional_system_hash256_bytes_at_path(path)? + self.get_optional_hash256_bytes_at_path(path)? .ok_or_else(|| { - Error::StructureError(format!("unable to get system hash256 property {path}")) + Error::StructureError(format!("unable to get hash256 property {path}")) }) } diff --git a/packages/rs-platform-value/src/btreemap_removal_extensions.rs b/packages/rs-platform-value/src/btreemap_removal_extensions.rs new file mode 100644 index 00000000000..ca902bd0794 --- /dev/null +++ b/packages/rs-platform-value/src/btreemap_removal_extensions.rs @@ -0,0 +1,303 @@ +use std::collections::BTreeMap; +use crate::{Error, Value}; + +pub trait BTreeValueRemoveFromMapHelper { + fn remove_optional_string(&mut self, key: &str) -> Result, Error>; + fn remove_string(&mut self, key: &str) -> Result; + fn remove_optional_float(&mut self, key: &str) -> Result, Error>; + fn remove_float(&mut self, key: &str) -> Result; + fn remove_optional_integer(&mut self, key: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom; + fn remove_integer(&mut self, key: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom; + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error>; + fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error>; + fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error>; + fn remove_bytes(&mut self, key: &str) -> Result, Error>; + fn remove_optional_bool(&mut self, key: &str) -> Result, Error>; + fn remove_bool(&mut self, key: &str) -> Result; +} + +impl BTreeValueRemoveFromMapHelper for BTreeMap { + fn remove_optional_integer(&mut self, key: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_integer()) + } + }) + .transpose() + } + + fn remove_integer(&mut self, key: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + self.remove_optional_integer(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove integer property {key}")) + }) + } + + + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_hash256()) + } + }) + .transpose() + } + + fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error> { + self.remove_optional_hash256_bytes(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove hash256 property {key}")) + }) + } + + fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_identifier_bytes()) + } + }) + .transpose() + } + + fn remove_bytes(&mut self, key: &str) -> Result, Error> { + self.remove_optional_bytes(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove bytes property {key}")) + }) + } + + fn remove_optional_string(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_text()) + } + }) + .transpose() + } + + fn remove_string(&mut self, key: &str) -> Result { + self.remove_optional_string(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove string property {key}"))) + } + + fn remove_optional_float(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_float()) + } + }) + .transpose() + } + + fn remove_float(&mut self, key: &str) -> Result { + self.remove_optional_float(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) + } + + fn remove_optional_bool(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_bool()) + } + }) + .transpose() + } + + fn remove_bool(&mut self, key: &str) -> Result { + self.remove_optional_bool(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) + } +} + +impl BTreeValueRemoveFromMapHelper for BTreeMap { + fn remove_optional_integer(&mut self, key: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_integer()) + } + }) + .transpose() + } + + fn remove_integer(&mut self, key: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + self.remove_optional_integer(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove integer property {key}")) + }) + } + + + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_hash256()) + } + }) + .transpose() + } + + fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error> { + self.remove_optional_hash256_bytes(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove hash256 property {key}")) + }) + } + + fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_identifier_bytes()) + } + }) + .transpose() + } + + fn remove_bytes(&mut self, key: &str) -> Result, Error> { + self.remove_optional_bytes(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove bytes property {key}")) + }) + } + + fn remove_optional_string(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_text()) + } + }) + .transpose() + } + + fn remove_string(&mut self, key: &str) -> Result { + self.remove_optional_string(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove string property {key}"))) + } + + fn remove_optional_float(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_float()) + } + }) + .transpose() + } + + fn remove_float(&mut self, key: &str) -> Result { + self.remove_optional_float(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) + } + + fn remove_optional_bool(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_bool()) + } + }) + .transpose() + } + + fn remove_bool(&mut self, key: &str) -> Result { + self.remove_optional_bool(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs b/packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs new file mode 100644 index 00000000000..56a8d941498 --- /dev/null +++ b/packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs @@ -0,0 +1,37 @@ +use std::collections::BTreeMap; +use crate::{Error, Value}; + +pub trait BTreeValueRemoveInnerValueFromMapHelper { + fn remove_optional_inner_value_array>( + &mut self, + key: &str, + ) -> Result, Error>; + fn remove_inner_value_array>( + &mut self, + key: &str, + ) -> Result; +} + +impl BTreeValueRemoveInnerValueFromMapHelper for BTreeMap { + fn remove_optional_inner_value_array>( + &mut self, + key: &str, + ) -> Result, Error> { + self.remove(key) + .map(|v| { + v + .into_array() + .map(|vec| vec.into_iter().collect()) + }) + .transpose() + } + + fn remove_inner_value_array>( + &mut self, + key: &str, + ) -> Result { + self.remove_optional_inner_value_array(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) + } + +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 35525f627f2..29b9a6849e2 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -1,15 +1,16 @@ use crate::{Error, Value}; use ciborium::value::Integer; use ciborium::Value as CborValue; +use crate::value_map::ValueMap; impl Value { - pub fn convert_from_cbor_map(map: I) -> R + pub fn convert_from_cbor_map(map: I) -> Result where I: IntoIterator, R: FromIterator<(String, Value)>, { map.into_iter() - .map(|(key, cbor_value)| (key, cbor_value.into())) + .map(|(key, cbor_value)| Ok((key, cbor_value.try_into()?))) .collect() } @@ -24,16 +25,18 @@ impl Value { } } -impl From for Value { - fn from(value: CborValue) -> Self { - match value { +impl TryFrom for Value { + type Error = Error; + + fn try_from(value: CborValue) -> Result { + Ok(match value { CborValue::Integer(integer) => Self::I128(integer.into()), CborValue::Bytes(bytes) => Self::Bytes(bytes), CborValue::Float(float) => Self::Float(float), CborValue::Text(string) => Self::Text(string), CborValue::Bool(value) => Self::Bool(value), CborValue::Null => Self::Null, - CborValue::Tag(int, value) => Self::Tag(int, value.into()), + CborValue::Tag(int, value) => { return Err(Error::Unsupported("conversion from cbor tags are currently not supported".to_string())) }, CborValue::Array(array) => { if !array.is_empty() && array.iter().all(|v| { @@ -51,14 +54,14 @@ impl From for Value { .collect(), ) } else { - Self::Array(array.into_iter().map(|v| v.into()).collect()) + Self::Array(array.into_iter().map(|v| v.try_into()).collect::, Error>>()?) } } CborValue::Map(map) => { - Self::Map(map.into_iter().map(|(k, v)| (k.into(), v.into())).collect()) + Self::Map(map.into_iter().map(|(k, v)| Ok((k.try_into()?, v.try_into()?))).collect::>()?) } _ => panic!("unsupported"), - } + }) } } @@ -89,7 +92,6 @@ impl TryInto for Value { Value::Text(string) => CborValue::Text(string), Value::Bool(value) => CborValue::Bool(value), Value::Null => CborValue::Null, - Value::Tag(i, v) => CborValue::Tag(i, v.try_into()?), Value::Array(array) => CborValue::Array( array .into_iter() diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index a669cf0c4f8..7bf8f9e9870 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -1,6 +1,7 @@ use crate::{Error, Value}; use serde_json::{Map, Number, Value as JsonValue}; use std::collections::BTreeMap; +use crate::value_map::ValueMap; impl Value { pub fn convert_from_serde_json_map(map: I) -> R @@ -15,8 +16,21 @@ impl Value { pub fn try_into_validating_json(self) -> Result { Ok(match self { - Value::U128(i) => JsonValue::Number((i as u64).into()), - Value::I128(i) => JsonValue::Number((i as i64).into()), + Value::U128(i) => { + if i > u64::MAX as u128 { + return Err(Error::IntegerSizeError) + } + JsonValue::Number((i as u64).into()) + }, + Value::I128(i) => { + if i > i64::MAX as i128 { + return Err(Error::IntegerSizeError) + } + if i < i64::MIN as i128 { + return Err(Error::IntegerSizeError) + } + JsonValue::Number((i as i64).into()) + }, Value::U64(i) => JsonValue::Number(i.into()), Value::I64(i) => JsonValue::Number(i.into()), Value::U32(i) => JsonValue::Number(i.into()), @@ -29,10 +43,6 @@ impl Value { Value::Text(string) => JsonValue::String(string), Value::Bool(value) => JsonValue::Bool(value), Value::Null => JsonValue::Null, - //todo support tags - Value::Tag(_, _) => { - return Err(Error::Unsupported("tags not yet supported".to_string())); - } Value::Array(array) => JsonValue::Array( array .into_iter() @@ -71,10 +81,27 @@ impl Value { }) } + pub fn try_into_validating_btree_map_json(self) -> Result, Error> { + self.into_btree_map()?.into_iter().map(|(key, value)| Ok((key, value.try_into_validating_json()?))).collect() + } + pub fn try_to_validating_json(&self) -> Result { Ok(match self { - Value::U128(i) => JsonValue::Number(((*i) as u64).into()), - Value::I128(i) => JsonValue::Number(((*i) as i64).into()), + Value::U128(i) => { + if *i > u64::MAX as u128 { + return Err(Error::IntegerSizeError) + } + JsonValue::Number((*i as u64).into()) + }, + Value::I128(i) => { + if *i > i64::MAX as i128 { + return Err(Error::IntegerSizeError) + } + if *i < i64::MIN as i128 { + return Err(Error::IntegerSizeError) + } + JsonValue::Number((*i as i64).into()) + }, Value::U64(i) => JsonValue::Number((*i).into()), Value::I64(i) => JsonValue::Number((*i).into()), Value::U32(i) => JsonValue::Number((*i).into()), @@ -87,10 +114,6 @@ impl Value { Value::Text(string) => JsonValue::String(string.clone()), Value::Bool(value) => JsonValue::Bool(*value), Value::Null => JsonValue::Null, - //todo support tags - Value::Tag(_, _) => { - return Err(Error::Unsupported("tags not yet supported".to_string())); - } Value::Array(array) => JsonValue::Array( array .iter() @@ -174,6 +197,50 @@ impl From for Value { } } +impl From<&JsonValue> for Value { + fn from(value: &JsonValue) -> Self { + match value { + JsonValue::Null => Self::Null, + JsonValue::Bool(value) => Self::Bool(*value), + JsonValue::Number(number) => { + if let Some(value) = number.as_u64() { + return Self::U64(value); + } else if let Some(value) = number.as_i64() { + return Self::I64(value); + } else if let Some(value) = number.as_f64() { + return Self::Float(value); + } + unreachable!("this shouldn't be reachable") + } + JsonValue::String(string) => Self::Text(string.clone()), + JsonValue::Array(array) => { + let u8_max = u8::MAX as u64; + if !array.is_empty() + && array.iter().all(|v| { + let Some(int) = v.as_u64() else { + return false; + }; + int.le(&u8_max) + }) + { + //this is an array of bytes + Self::Bytes( + array + .into_iter() + .map(|v| v.as_u64().unwrap() as u8) + .collect(), + ) + } else { + Self::Array(array.into_iter().map(|v| v.into()).collect()) + } + } + JsonValue::Object(map) => { + Self::Map(map.into_iter().map(|(k, v)| (k.clone().into(), v.into())).collect()) + } + } + } +} + impl From> for Box { fn from(value: Box) -> Self { value.into() @@ -201,10 +268,6 @@ impl TryInto for Value { Value::Text(string) => JsonValue::String(string), Value::Bool(value) => JsonValue::Bool(value), Value::Null => JsonValue::Null, - //todo support tags - Value::Tag(_, _) => { - return Err(Error::Unsupported("tags not yet supported".to_string())); - } Value::Array(array) => JsonValue::Array( array .into_iter() @@ -228,7 +291,9 @@ impl TryInto for Value { pub trait BTreeValueJsonConverter { fn into_json_value(self) -> Result; + fn into_validating_json_value(self) -> Result; fn to_json_value(&self) -> Result; + fn to_validating_json_value(&self) -> Result; fn from_json_value(value: JsonValue) -> Result where Self: Sized; @@ -243,6 +308,14 @@ impl BTreeValueJsonConverter for BTreeMap { )) } + fn into_validating_json_value(self) -> Result { + Ok(JsonValue::Object( + self.into_iter() + .map(|(key, value)| Ok((key, value.try_into_validating_json()?))) + .collect::, Error>>()?, + )) + } + fn to_json_value(&self) -> Result { Ok(JsonValue::Object( self.iter() @@ -251,6 +324,14 @@ impl BTreeValueJsonConverter for BTreeMap { )) } + fn to_validating_json_value(&self) -> Result { + Ok(JsonValue::Object( + self.iter() + .map(|(key, value)| Ok((key.to_owned(), value.try_to_validating_json()?))) + .collect::, Error>>()?, + )) + } + fn from_json_value(value: JsonValue) -> Result { let platform_value: Value = value.into(); platform_value.into_btree_map() @@ -259,6 +340,7 @@ impl BTreeValueJsonConverter for BTreeMap { pub trait BTreeValueRefJsonConverter { fn to_json_value(self) -> Result; + fn to_validating_json_value(&self) -> Result; } impl BTreeValueRefJsonConverter for BTreeMap { @@ -269,4 +351,33 @@ impl BTreeValueRefJsonConverter for BTreeMap { .collect::, Error>>()?, )) } + + fn to_validating_json_value(&self) -> Result { + Ok(JsonValue::Object( + self.iter() + .map(|(key, value)| Ok((key.to_owned(), value.try_to_validating_json()?))) + .collect::, Error>>()?, + )) + } +} + +impl From> for Value { + fn from(value: BTreeMap) -> Self { + let map : ValueMap = value.into_iter().map(|(key, json_value)|{ + let value : Value = json_value.into(); + (Value::Text(key), value) + } ).collect(); + Value::Map(map) + } +} + + +impl From<&BTreeMap> for Value { + fn from(value: &BTreeMap) -> Self { + let map : ValueMap = value.iter().map(|(key, json_value)|{ + let value : Value = json_value.into(); + (Value::Text(key.clone()), value) + } ).collect(); + Value::Map(map) + } } diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index 0469c264143..bf1dd273692 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -27,7 +27,6 @@ impl Value { format!("{}", b) } Value::Null => "Null".to_string(), - Value::Tag(_, _) => "Tag".to_string(), Value::Array(value) => { let inner_values = value .iter() diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index 529f5157d1d..25fb6722655 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -1,3 +1,5 @@ +use std::error; +use std::fmt::Display; use thiserror::Error; #[derive(Error, Clone, Eq, PartialEq, Debug)] @@ -14,6 +16,16 @@ pub enum Error { #[error("integer out of bounds")] IntegerSizeError, + #[error("key must be a string")] + KeyMustBeAString, + #[error("byte length not 32 bytes error")] ByteLengthNot32BytesError, } + +impl serde::ser::Error for Error { + fn custom(msg: T) -> Self where T: Display { + todo!() + } +} + diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 8c7ffb2bbe4..7c73e30d3b7 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -9,21 +9,128 @@ impl Value { Self::get_from_map(map, key) } + pub fn get_optional_value<'a>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Ok(Self::get_optional_from_map(map, key)) + } + pub fn set_value(&mut self, key: &str, value: Value) -> Result<(), Error> { let map = self.as_map_mut_ref()?; Ok(Self::insert_in_map(map, key, value)) } - pub fn remove_value(&mut self, key: &str) -> Result, Error> { + pub fn remove_value(&mut self, key: &str) -> Result { + let map = self.as_map_mut_ref()?; + map.remove_key(key) + } + + pub fn remove_optional_value(&mut self, key: &str) -> Result, Error> { + let map = self.as_map_mut_ref()?; + Ok(map.remove_optional_key(key)) + } + + pub fn remove_integer(&mut self, key: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom { + let map = self.as_map_mut_ref()?; + let value = map.remove_key(key)?; + value.into_integer() + } + + pub fn remove_optional_integer(&mut self, key: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom { + let map = self.as_map_mut_ref()?; + map.remove_optional_key(key).map(|v| v.into_integer()).transpose() + } + + pub fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8;32], Error> { + let map = self.as_map_mut_ref()?; + let value = map.remove_key(key)?; + value.into_hash256() + } + + pub fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { + let map = self.as_map_mut_ref()?; + map.remove_optional_key(key).map(|v| v.into_hash256()).transpose() + } + + pub fn remove_bytes(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; - Ok(map.remove_key(key)) + let value = map.remove_key(key)?; + value.into_bytes() } - pub fn get_string<'a>(&'a self, key: &'a str) -> Result<&'a str, Error> { + pub fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { + let map = self.as_map_mut_ref()?; + map.remove_optional_key(key).map(|v| v.into_bytes()).transpose() + } + + pub fn get_optional_integer(&self, key: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom { + let map = self.to_map()?; + Self::inner_optional_integer_value(map, key) + } + + pub fn get_integer(&self, key: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom { + let map = self.to_map()?; + Self::inner_integer_value(map, key) + } + + pub fn get_optional_str<'a>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Self::inner_optional_text_value(map, key) + } + + pub fn get_str<'a>(&'a self, key: &'a str) -> Result<&'a str, Error> { let map = self.to_map()?; Self::inner_text_value(map, key) } + pub fn get_optional_hash256<'a>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Self::inner_optional_hash256_value(map, key) + } + pub fn get_hash256<'a>(&'a self, key: &'a str) -> Result<[u8; 32], Error> { let map = self.to_map()?; Self::inner_hash256_value(map, key) @@ -35,11 +142,6 @@ impl Value { Ok(bs58::encode(value).into_string()) } - pub fn get_optional_value<'a>(&'a self, key: &'a str) -> Result, Error> { - let map = self.to_map()?; - Ok(Self::get_optional_from_map(map, key)) - } - /// Retrieves the value of a key from a map if it's an array of strings. pub fn inner_optional_array_of_strings<'a, I: FromIterator>( document_type: &'a [(Value, Value)], @@ -87,6 +189,39 @@ impl Value { None } + /// Gets the inner integer value from a map if it exists + pub fn inner_optional_integer_value(document_type: &[(Value, Value)], key: &str) -> Result, Error> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom { + Self::get_optional_from_map(document_type, key).map(|key_value| key_value.to_integer()).transpose() + } + + /// Gets the inner integer value from a map + pub fn inner_integer_value(document_type: &[(Value, Value)], key: &str) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom { + let key_value = Self::get_from_map(document_type, key)?; + key_value.to_integer() + } + /// Retrieves the value of a key from a map if it's a string. pub fn inner_optional_text_value<'a>( document_type: &'a [(Value, Value)], diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index db2b88f25ed..d1d94890c8d 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -17,19 +17,24 @@ pub mod inner_value; mod integer; pub mod system_bytes; pub mod value_map; +mod btreemap_removal_extensions; +mod btreemap_removal_inner_value_extensions; +mod ser; use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; pub use integer::Integer; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; +use serde::de::DeserializeOwned; pub type Hash256 = [u8; 32]; pub use btreemap_field_replacement::ReplacementType; +use crate::ser::Serializer; /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)] +#[derive(Deserialize, Clone, Debug, PartialEq, PartialOrd)] #[serde(untagged)] pub enum Value { /// A u128 integer @@ -85,9 +90,6 @@ pub enum Value { /// Null Null, - /// Tag - Tag(u64, Box), - /// An array Array(Vec), @@ -646,78 +648,6 @@ impl Value { matches!(self, Value::Null) } - /// Returns true if the `Value` is a `Tag`. Returns false otherwise. - /// - /// ``` - /// # use platform_value::Value; - /// # - /// let value = Value::Tag(61, Box::from(Value::Null)); - /// - /// assert!(value.is_tag()); - /// ``` - pub fn is_tag(&self) -> bool { - self.as_tag().is_some() - } - - /// If the `Value` is a `Tag`, returns the associated tag value and a reference to the tag `Value`. - /// Returns None otherwise. - /// - /// ``` - /// # use platform_value::Value; - /// # - /// let value = Value::Tag(61, Box::from(Value::Bytes(vec![104, 101, 108, 108, 111]))); - /// - /// let (tag, data) = value.as_tag().unwrap(); - /// assert_eq!(tag, 61); - /// assert_eq!(data, &Value::Bytes(vec![104, 101, 108, 108, 111])); - /// ``` - pub fn as_tag(&self) -> Option<(u64, &Value)> { - match self { - Value::Tag(tag, data) => Some((*tag, data)), - _ => None, - } - } - - /// If the `Value` is a `Tag`, returns the associated tag value and a mutable reference - /// to the tag `Value`. Returns None otherwise. - /// - /// ``` - /// # use platform_value::Value; - /// # - /// let mut value = Value::Tag(61, Box::from(Value::Bytes(vec![104, 101, 108, 108, 111]))); - /// - /// let (tag, mut data) = value.as_tag_mut().unwrap(); - /// data.as_bytes_mut().unwrap().clear(); - /// assert_eq!(tag, &61); - /// assert_eq!(data, &Value::Bytes(vec![])); - /// ``` - pub fn as_tag_mut(&mut self) -> Option<(&mut u64, &mut Value)> { - match self { - Value::Tag(tag, data) => Some((tag, data.as_mut())), - _ => None, - } - } - - /// If the `Value` is a `Tag`, returns a the associated pair of `u64` and `Box` data as `Ok`. - /// Returns `Err(Error::Structure("reason"))` otherwise. - /// - /// ``` - /// # use platform_value::Value; - /// # use platform_value::Error; - /// # - /// let value = Value::Tag(7, Box::new(Value::Float(12.))); - /// assert_eq!(value.into_tag(), Ok((7, Box::new(Value::Float(12.))))); - /// - /// let value = Value::Bool(true); - /// assert_eq!(value.into_tag(), Err(Error::StructureError("value is not a tag".to_string()))); - /// ``` - pub fn into_tag(self) -> Result<(u64, Box), Error> { - match self { - Value::Tag(tag, value) => Ok((tag, value)), - _other => Err(Error::StructureError("value is not a tag".to_string())), - } - } - /// Returns true if the `Value` is an Array. Returns false otherwise. /// /// ``` @@ -803,6 +733,30 @@ impl Value { .ok_or(Error::StructureError("value is not an array".to_string())) } + /// If the `Value` is a `Array`, returns a the associated `Vec` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Value, Integer, Error}; + /// # + /// let mut value = Value::Array( + /// vec![ + /// Value::U64(17), + /// Value::Float(18.), + /// ] + /// ); + /// assert_eq!(value.to_array(), Ok(vec![Value::U64(17), Value::Float(18.)])); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_array(), Err(Error::StructureError("value is not an array".to_string()))); + /// ``` + pub fn to_array(&self) -> Result, Error> { + match self { + Value::Array(vec) => Ok(vec.clone()), + _other => Err(Error::StructureError("value is not an array".to_string())), + } + } + /// If the `Value` is a `Array`, returns a the associated `Vec` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. /// @@ -1108,6 +1062,17 @@ impl From> for Value { } } +impl From> for Value { + fn from(value: BTreeMap) -> Self { + Value::Map( + value + .into_iter() + .map(|(key, value)| (Value::Text(key), value.clone())) + .collect(), + ) + } +} + impl From for Value { #[inline] fn from(value: char) -> Self { @@ -1116,3 +1081,10 @@ impl From for Value { Value::Text(v) } } + +pub fn to_value(value: T) -> Result + where + T: Serialize, +{ + value.serialize(Serializer) +} diff --git a/packages/rs-platform-value/src/ser.rs b/packages/rs-platform-value/src/ser.rs new file mode 100644 index 00000000000..9ef59d7975d --- /dev/null +++ b/packages/rs-platform-value/src/ser.rs @@ -0,0 +1,643 @@ +use std::fmt::Display; +use crate::error::Error; +use serde::ser::{Impossible, Serialize}; +use crate::{to_value, Value}; +use crate::value_map::ValueMap; + +// We only use our own error type; no need for From conversions provided by the +// standard library's try! macro. This reduces lines of LLVM IR by 4%. +macro_rules! tri { + ($e:expr $(,)?) => { + match $e { + core::result::Result::Ok(val) => val, + core::result::Result::Err(err) => return core::result::Result::Err(err), + } + }; +} + +impl Serialize for Value { + #[inline] + fn serialize(&self, serializer: S) -> Result + where + S: ::serde::Serializer, + { + match self { + Value::Null => serializer.serialize_unit(), + Value::Bool(b) => serializer.serialize_bool(*b), + Value::Array(v) => v.serialize(serializer), + Value::Map(m) => { + use serde::ser::SerializeMap; + let mut map = tri!(serializer.serialize_map(Some(m.len()))); + for (k, v) in m { + tri!(map.serialize_entry(k, v)); + } + map.end() + } + Value::U128(i) => serializer.serialize_u128(*i), + Value::I128(i) => serializer.serialize_i128(*i), + Value::U64(i) => serializer.serialize_u64(*i), + Value::I64(i) => serializer.serialize_i64(*i), + Value::U32(i) => serializer.serialize_u32(*i), + Value::I32(i) => serializer.serialize_i32(*i), + Value::U16(i) => serializer.serialize_u16(*i), + Value::I16(i) => serializer.serialize_i16(*i), + Value::U8(i) => serializer.serialize_u8(*i), + Value::I8(i) => serializer.serialize_i8(*i), + Value::Bytes(bytes) => serializer.serialize_bytes(bytes), + Value::Bytes32(bytes) => serializer.serialize_bytes(bytes), + Value::Identifier(bytes) => serializer.serialize_bytes(bytes), + Value::Float(f64) => serializer.serialize_f64(*f64), + Value::Text(string) => serializer.serialize_str(string), + } + } +} + +/// Serializer whose output is a `Value`. +/// +/// This is the serializer that backs [`platform_value::to_value`][crate::to_value]. +/// Unlike the main platform_value serializer which goes from some serializable +/// value of type `T` to JSON text, this one goes from `T` to +/// `platform_value::Value`. +/// +/// The `to_value` function is implementable as: +/// +/// ``` +/// use serde::Serialize; +/// use serde_json::{Error, Value}; +/// +/// pub fn to_value(input: T) -> Result +/// where +/// T: Serialize, +/// { +/// input.serialize(serde_json::value::Serializer) +/// } +/// ``` +pub struct Serializer; + +impl serde::Serializer for Serializer { + type Ok = Value; + type Error = Error; + + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeMap; + type SerializeStructVariant = SerializeStructVariant; + + #[inline] + fn serialize_bool(self, value: bool) -> Result { + Ok(Value::Bool(value)) + } + + #[inline] + fn serialize_i8(self, value: i8) -> Result { + Ok(Value::I8(value)) + } + + #[inline] + fn serialize_i16(self, value: i16) -> Result { + Ok(Value::I16(value)) + } + + #[inline] + fn serialize_i32(self, value: i32) -> Result { + Ok(Value::I32(value)) + } + + #[inline] + fn serialize_i64(self, value: i64) -> Result { + Ok(Value::I64(value)) + } + + #[inline] + fn serialize_i128(self, value: i128) -> Result { + Ok(Value::I128(value)) + } + + #[inline] + fn serialize_u8(self, value: u8) -> Result { + Ok(Value::U8(value)) + } + + #[inline] + fn serialize_u16(self, value: u16) -> Result { + Ok(Value::U16(value)) + } + + #[inline] + fn serialize_u32(self, value: u32) -> Result { + Ok(Value::U32(value)) + } + + #[inline] + fn serialize_u64(self, value: u64) -> Result { + Ok(Value::U64(value)) + } + + #[inline] + fn serialize_u128(self, value: u128) -> Result { + Ok(Value::U128(value)) + } + + #[inline] + fn serialize_f32(self, value: f32) -> Result { + self.serialize_f64(value as f64) + } + + #[inline] + fn serialize_f64(self, value: f64) -> Result { + Ok(Value::Float(value)) + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + let mut s = String::new(); + s.push(value); + Ok(Value::Text(s)) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(Value::Text(value.to_owned())) + } + + #[inline] + fn serialize_bytes(self, value: &[u8]) -> Result { + Ok(Value::Bytes(value.to_vec())) + } + + #[inline] + fn serialize_unit(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + self.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + let mut values = ValueMap::new(); + values.push((Value::Text(String::from(variant)), tri!(to_value(value)))); + Ok(Value::Map(values)) + } + + #[inline] + fn serialize_none(self) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + Ok(SerializeVec { + vec: Vec::with_capacity(len.unwrap_or(0)), + }) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(SerializeTupleVariant { + name: String::from(variant), + vec: Vec::with_capacity(len), + }) + } + + fn serialize_map(self, _len: Option) -> Result { + Ok(SerializeMap::Map { + map: Vec::new(), + next_key: None, + }) + } + + fn serialize_struct(self, name: &'static str, len: usize) -> Result { + match name { + _ => self.serialize_map(Some(len)), + } + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + Ok(SerializeStructVariant { + name: String::from(variant), + map: Vec::new(), + }) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + Ok(Value::Text(value.to_string())) + } +} + +pub struct SerializeVec { + vec: Vec, +} + +pub struct SerializeTupleVariant { + name: String, + vec: Vec, +} + +pub enum SerializeMap { + Map { + map: ValueMap, + next_key: Option, + }, +} + +pub struct SerializeStructVariant { + name: String, + map: ValueMap, +} + +impl serde::ser::SerializeSeq for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + self.vec.push(tri!(to_value(value))); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Array(self.vec)) + } +} + +impl serde::ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + self.vec.push(tri!(to_value(value))); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Vec::new(); + + object.push((Value::Text(self.name), Value::Array(self.vec))); + + Ok(Value::Map(object)) + } +} + +impl serde::ser::SerializeMap for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { next_key, .. } => { + *next_key = Some(tri!(key.serialize(MapKeySerializer))); + Ok(()) + } + } + } + + fn serialize_value(&mut self, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { map, next_key } => { + let key = next_key.take(); + // Panic because this indicates a bug in the program rather than an + // expected failure. + let key = key.expect("serialize_value called before serialize_key"); + map.push((Value::Text(key), tri!(to_value(value)))); + Ok(()) + } + } + } + + fn end(self) -> Result { + match self { + SerializeMap::Map { map, .. } => Ok(Value::Map(map)), + } + } +} + +struct MapKeySerializer; + +fn key_must_be_a_string() -> Error { + Error::KeyMustBeAString +} + +impl serde::Serializer for MapKeySerializer { + type Ok = String; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + Ok(variant.to_owned()) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_bool(self, _value: bool) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_i8(self, value: i8) -> Result { + Ok(value.to_string()) + } + + fn serialize_i16(self, value: i16) -> Result { + Ok(value.to_string()) + } + + fn serialize_i32(self, value: i32) -> Result { + Ok(value.to_string()) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(value.to_string()) + } + + fn serialize_u8(self, value: u8) -> Result { + Ok(value.to_string()) + } + + fn serialize_u16(self, value: u16) -> Result { + Ok(value.to_string()) + } + + fn serialize_u32(self, value: u32) -> Result { + Ok(value.to_string()) + } + + fn serialize_u64(self, value: u64) -> Result { + Ok(value.to_string()) + } + + fn serialize_f32(self, _value: f32) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_f64(self, _value: f64) -> Result { + Err(key_must_be_a_string()) + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + Ok({ + let mut s = String::new(); + s.push(value); + s + }) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(value.to_owned()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_none(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + Ok(value.to_string()) + } +} + +impl serde::ser::SerializeStruct for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { .. } => serde::ser::SerializeMap::serialize_entry(self, key, value), + } + } + + fn end(self) -> Result { + match self { + SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self), + } + } +} + +impl serde::ser::SerializeStructVariant for SerializeStructVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> + where + T: ?Sized + Serialize, + { + self.map.push((Value::Text(String::from(key)), tri!(to_value(value)))); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Vec::new(); + + object.push((Value::Text(self.name), Value::Map(self.map))); + + Ok(Value::Map(object)) + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index 5e89e3c4395..4d0ea964816 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -193,27 +193,27 @@ impl Value { /// # use platform_value::{Error, Value}; /// # /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]); - /// assert_eq!(value.into_system_hash256(), Ok([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50])); /// + /// assert_eq!(value.into_hash256(), Ok([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50])); /// /// /// let value = Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string()); - /// assert_eq!(value.into_system_hash256(), Ok([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117])); + /// assert_eq!(value.into_hash256(), Ok([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117])); /// /// let value = Value::Text("a811".to_string()); - /// assert_eq!(value.into_system_hash256(), Err(Error::StructureError("value was a string, could be decoded from base 58, but was not 32 bytes long".to_string()))); + /// assert_eq!(value.into_hash256(), Err(Error::StructureError("value was a string, could be decoded from base 58, but was not 32 bytes long".to_string()))); /// /// let value = Value::Text("a811Ii".to_string()); - /// assert_eq!(value.into_system_hash256(), Err(Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))); + /// assert_eq!(value.into_hash256(), Err(Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))); /// /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); - /// assert_eq!(value.into_system_hash256(), Ok([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101])); + /// assert_eq!(value.into_hash256(), Ok([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101])); /// /// let value = Value::Identifier([5u8;32]); - /// assert_eq!(value.into_system_hash256(), Ok([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// assert_eq!(value.into_hash256(), Ok([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.into_system_hash256(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// assert_eq!(value.into_hash256(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); /// ``` - pub fn into_system_hash256(self) -> Result<[u8; 32], Error> { + pub fn into_hash256(self) -> Result<[u8; 32], Error> { match self { Value::Text(text) => { bs58::decode(text).into_vec() diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 5dedf0b1d72..b6e2f86e1f6 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -7,7 +7,8 @@ pub trait ValueMapHelper { fn get_key(&self, key: &str) -> Option<&Value>; fn get_key_mut(&mut self, key: &str) -> Option<&mut Value>; fn get_key_mut_or_insert(&mut self, key: &str, value: Value) -> &mut Value; - fn remove_key(&mut self, key: &str) -> Option; + fn remove_key(&mut self, search_key: &str) -> Result; + fn remove_optional_key(&mut self, key: &str) -> Option; } impl ValueMapHelper for ValueMap { @@ -60,7 +61,19 @@ impl ValueMapHelper for ValueMap { } } - fn remove_key(&mut self, search_key: &str) -> Option { + fn remove_key(&mut self, search_key: &str) -> Result { + self.iter() + .position(|(key, _)| { + if let Value::Text(text) = key { + text == search_key + } else { + false + } + }) + .map(|pos| self.remove(pos).1).ok_or(Error::StructureError(format!("trying to remove a key {} from a ValueMap that was not found", search_key))) + } + + fn remove_optional_key(&mut self, search_key: &str) -> Option { self.iter() .position(|(key, _)| { if let Value::Text(text) = key { diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index f520fdb73d1..d2b465179e0 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -47,7 +47,7 @@ pub fn find_duplicates_by_indices_wasm( .map(|v| { let mut value = v.clone(); value - .remove_value("$ownerId") + .remove_optional_value("$ownerId") .map_err(ProtocolError::ValueError) .with_js_error()?; to_object( diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 999a8404d57..77745e0c42d 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -17,7 +17,7 @@ pub async fn validate_documents_batch_transition_basic_wasm( execution_context: StateTransitionExecutionContextWasm, ) -> Result { let wrapped_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository); - let raw_state_transition = js_raw_state_transition.with_serde_to_json_value()?; + let raw_state_transition = js_raw_state_transition.with_serde_to_platform_value()?; let validation_result = validate_documents_batch_transition_basic::validate_documents_batch_transition_basic( diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs index c1f40c05c53..2fff3a75751 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -195,7 +195,7 @@ impl TryFrom for IdentityPublicKeyCreateTransitionWasm { let str = String::from(js_sys::JSON::stringify(&value)?); let val = serde_json::from_str(&str).map_err(|e| from_dpp_err(e.into()))?; Ok(Self( - IdentityPublicKeyCreateTransition::from_raw_object(val).map_err(from_dpp_err)?, + IdentityPublicKeyCreateTransition::from_raw_json_object(val).map_err(from_dpp_err)?, )) } } From 0418d3104e097b858e5c8e4b68ced686101d6afa Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 10 Mar 2023 11:52:34 +0700 Subject: [PATCH 101/228] more work --- Cargo.lock | 1 + .../rs-dpp/src/data_contract/data_contract.rs | 57 ++++++------- .../data_trigger/get_data_triggers_factory.rs | 2 +- .../reward_share_data_triggers/mod.rs | 9 ++- .../src/decode_protocol_entity_factory.rs | 3 +- .../rs-dpp/src/document/document_factory.rs | 13 ++- .../rs-dpp/src/document/extended_document.rs | 2 +- .../document_base_transition.rs | 1 + .../document_create_transition.rs | 1 + .../documents_batch_transition/mod.rs | 8 +- .../basic/find_duplicates_by_indices.rs | 5 +- .../state/fetch_extended_documents.rs | 3 +- ...alidate_documents_uniqueness_by_indices.rs | 8 +- packages/rs-dpp/src/identifier/mod.rs | 1 - packages/rs-dpp/src/identity/core_script.rs | 6 +- .../state_transition/asset_lock_proof/mod.rs | 12 +-- .../identity_create_transition.rs | 2 +- .../mod.rs | 4 +- .../identity_public_key_transitions.rs | 17 ++-- .../identity_topup_transition.rs | 20 ++--- ...stract_state_transition_identity_signed.rs | 2 +- ...validate_state_transition_key_signature.rs | 4 +- ..._documents_batch_transitions_basic_spec.rs | 2 +- ...te_documents_uniqueness_by_indices_spec.rs | 3 +- .../identity_create_transition_fixture.rs | 42 +++++----- ...ty_credit_withdrawal_transition_fixture.rs | 2 +- .../src/tests/fixtures/identity_fixture.rs | 6 +- .../identity_topup_transition_fixture.rs | 20 ++--- packages/rs-dpp/src/tests/identifier_spec.rs | 2 +- .../src/tests/identity/identity_spec.rs | 4 +- .../identity_update_transition_spec.rs | 6 +- ...rpose_and_security_level_validator_spec.rs | 6 +- .../rs-dpp/src/util/cbor_value/canonical.rs | 5 +- packages/rs-dpp/src/util/json_value/mod.rs | 3 +- packages/rs-dpp/src/util/mod.rs | 1 - packages/rs-drive-abci/src/state/genesis.rs | 2 +- packages/rs-platform-value/Cargo.toml | 1 + packages/rs-platform-value/src/error.rs | 3 + .../src}/identifier.rs | 0 packages/rs-platform-value/src/inner_value.rs | 19 +++++ packages/rs-platform-value/src/lib.rs | 79 ++++++++++++++++++- .../src}/string_encoding.rs | 9 +-- .../src/data_contract/data_contract.rs | 2 +- packages/wasm-dpp/src/identifier/mod.rs | 2 +- .../chain/chain_asset_lock_proof.rs | 4 +- .../instant/instant_asset_lock_proof.rs | 4 +- .../identity_create_transition.rs | 4 +- .../identity_topup_transition.rs | 4 +- .../identity_update_transition.rs | 8 +- 49 files changed, 264 insertions(+), 160 deletions(-) rename packages/{rs-dpp/src/identifier => rs-platform-value/src}/identifier.rs (100%) rename packages/{rs-dpp/src/util => rs-platform-value/src}/string_encoding.rs (70%) diff --git a/Cargo.lock b/Cargo.lock index e3f1f6e05f6..39f840f83cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2220,6 +2220,7 @@ dependencies = [ "bs58", "ciborium", "hex", + "rand", "serde", "serde_json", "thiserror", diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 46239961bd9..8595bb31f86 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -8,6 +8,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::data_contract::{contract_config, DriveContractExt}; @@ -22,7 +23,7 @@ use crate::data_contract::get_binary_properties_from_schema::get_binary_properti use crate::util::json_value::{JsonValueExt, ReplaceWith}; -use crate::util::string_encoding::Encoding; +use platform_value::string_encoding::Encoding; use crate::{ errors::ProtocolError, identifier::Identifier, @@ -186,35 +187,37 @@ impl DataContract { } pub fn to_object(&self) -> Result { - let mut raw_object = BTreeMap::from([ - (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), - (property_names::ID.to_string(), Value::Identifier(self.id.buffer)), - (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.buffer)), - (property_names::SCHEMA.to_string(), Value::Text(self.schema.clone())), - (property_names::VERSION.to_string(), Value::U32(self.version)), - (property_names::DOCUMENTS.to_string(), self.documents.into()), - (property_names::ENTROPY.to_string(), Value::Bytes32(self.entropy))]); - if let Some(defs) = &self.defs { - raw_object.insert(property_names::DEFINITIONS.to_string(), defs.into()) - } - - Ok(raw_object.into()) + platform_value::to_value(self).map_err(ProtocolError::ValueError) + // let mut raw_object = BTreeMap::from([ + // (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), + // (property_names::ID.to_string(), Value::Identifier(self.id.buffer)), + // (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.buffer)), + // (property_names::SCHEMA.to_string(), Value::Text(self.schema.clone())), + // (property_names::VERSION.to_string(), Value::U32(self.version)), + // (property_names::DOCUMENTS.to_string(), self.documents.into()), + // (property_names::ENTROPY.to_string(), Value::Bytes32(self.entropy))]); + // if let Some(defs) = &self.defs { + // raw_object.insert(property_names::DEFINITIONS.to_string(), defs.into()) + // } + // + // Ok(raw_object.into()) } pub fn into_object(self) -> Result { - let mut raw_object = BTreeMap::from([ - (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), - (property_names::ID.to_string(), Value::Identifier(self.id.buffer)), - (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.buffer)), - (property_names::SCHEMA.to_string(), Value::Text(self.schema)), - (property_names::VERSION.to_string(), Value::U32(self.version)), - (property_names::DOCUMENTS.to_string(), self.documents.into()), - (property_names::ENTROPY.to_string(), Value::Bytes32(self.entropy))]); - if let Some(defs) = &self.defs { - raw_object.insert(property_names::DEFINITIONS.to_string(), defs.into()) - } - - Ok(raw_object.into()) + platform_value::to_value(self).map_err(ProtocolError::ValueError) + // let mut raw_object = BTreeMap::from([ + // (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), + // (property_names::ID.to_string(), Value::Identifier(self.id.buffer)), + // (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.buffer)), + // (property_names::SCHEMA.to_string(), Value::Text(self.schema)), + // (property_names::VERSION.to_string(), Value::U32(self.version)), + // (property_names::DOCUMENTS.to_string(), self.documents.into()), + // (property_names::ENTROPY.to_string(), Value::Bytes32(self.entropy))]); + // if let Some(defs) = &self.defs { + // raw_object.insert(property_names::DEFINITIONS.to_string(), defs.into()) + // } + // + // Ok(raw_object.into()) } pub fn to_json_object(&self, skip_identifiers_conversion: bool) -> Result { diff --git a/packages/rs-dpp/src/data_trigger/get_data_triggers_factory.rs b/packages/rs-dpp/src/data_trigger/get_data_triggers_factory.rs index 3491b8129ea..87837735cbe 100644 --- a/packages/rs-dpp/src/data_trigger/get_data_triggers_factory.rs +++ b/packages/rs-dpp/src/data_trigger/get_data_triggers_factory.rs @@ -1,6 +1,7 @@ use std::vec; use lazy_static::__Deref; +use platform_value::string_encoding::Encoding; use crate::{ contracts::{ @@ -10,7 +11,6 @@ use crate::{ document::document_transition::Action, errors::ProtocolError, prelude::Identifier, - util::string_encoding::Encoding, }; use super::{DataTrigger, DataTriggerKind}; diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 256585cb969..1ca8b6326b2 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -4,12 +4,13 @@ use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use serde_json::json; +use platform_value::string_encoding::Encoding; use crate::document::Document; use crate::{ data_trigger::create_error, document::document_transition::DocumentTransition, get_from_transition, mocks::SMLStore, prelude::Identifier, - state_repository::StateRepositoryLike, util::string_encoding::Encoding, ProtocolError, + ProtocolError, state_repository::StateRepositoryLike, }; use super::{DataTriggerExecutionContext, DataTriggerExecutionResult}; @@ -149,18 +150,18 @@ mod test { use crate::{ data_contract::DataContract, data_trigger::DataTriggerExecutionContext, + DataTriggerError, document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, - mocks::{SMLEntry, SMLStore, SimplifiedMNList}, + mocks::{SimplifiedMNList, SMLEntry, SMLStore}, prelude::Identifier, state_repository::MockStateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, - tests::{ + StateError, tests::{ fixtures::{ get_document_transitions_fixture, get_masternode_reward_shares_documents_fixture, }, utils::generate_random_identifier_struct, }, - DataTriggerError, StateError, }; struct TestData { diff --git a/packages/rs-dpp/src/decode_protocol_entity_factory.rs b/packages/rs-dpp/src/decode_protocol_entity_factory.rs index f5f5b51a18d..dccf0e90e44 100644 --- a/packages/rs-dpp/src/decode_protocol_entity_factory.rs +++ b/packages/rs-dpp/src/decode_protocol_entity_factory.rs @@ -1,3 +1,4 @@ +use std::convert::TryInto; use anyhow::anyhow; use ciborium::value::Value as CborValue; @@ -24,6 +25,6 @@ impl DecodeProtocolEntity { } })?; - Ok((protocol_version, cbor_value.into())) + Ok((protocol_version, cbor_value.try_into().map_err(ProtocolError::ValueError)?)) } } diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 10e62d1c4b0..faa6e5c83ff 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -8,32 +8,31 @@ use platform_value::Value; use rand::rngs::StdRng; use rand::SeedableRng; use serde::{Deserialize, Serialize}; -use serde_json::{Value as JsonValue}; +use serde_json::Value as JsonValue; use crate::consensus::basic::document::InvalidDocumentTypeError; -use crate::document::extended_document::{property_names, ExtendedDocument}; +use crate::document::extended_document::{ExtendedDocument, property_names}; use crate::data_contract::DriveContractExt; use crate::document::document_transition::INITIAL_REVISION; use crate::document::Document; use crate::identity::TimestampMillis; use crate::{ - data_contract::{errors::DataContractError, DataContract}, + data_contract::{DataContract, errors::DataContractError}, decode_protocol_entity_factory::DecodeProtocolEntity, prelude::Identifier, + ProtocolError, state_repository::StateRepositoryLike, util::entropy_generator, - - ProtocolError, }; use super::{ document_transition::{self, Action}, document_validator::DocumentValidator, + DocumentsBatchTransition, errors::DocumentError, fetch_and_validate_data_contract::DataContractFetcherAndValidator, generate_document_id::generate_document_id, - DocumentsBatchTransition, }; // TODO remove these const and use ones from super::document::property_names @@ -435,6 +434,7 @@ mod test { use platform_value::btreemap_extensions::BTreeValueMapHelper; use std::sync::Arc; use serde_json::json; + use platform_value::string_encoding::Encoding; use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ @@ -444,7 +444,6 @@ mod test { fixtures::{get_data_contract_fixture, get_document_validator_fixture}, utils::generate_random_identifier_struct, }, - util::string_encoding::Encoding, }; use super::*; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index d499e207da6..f887d0f1a4b 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -460,7 +460,7 @@ mod test { use crate::document::Document; use crate::identifier::Identifier; use crate::tests::utils::*; - use crate::util::string_encoding::Encoding; + use platform_value::string_encoding::Encoding; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::Value; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index 8242dba2614..c692b629b7b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -4,6 +4,7 @@ use std::convert::{TryFrom, TryInto}; use anyhow::bail; use num_enum::IntoPrimitive; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; pub use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index abedb65ab53..5ae5ad6d0c8 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -6,6 +6,7 @@ use serde_json::Value as JsonValue; use std::collections::BTreeMap; use std::convert::TryInto; use std::string::ToString; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::document::{Document, ExtendedDocument}; use crate::identity::TimestampMillis; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 85d4be63d53..fde709e8c6c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -19,7 +19,7 @@ use crate::prelude::{DocumentTransition, Identifier}; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::util::cbor_value::{CborCanonicalMap, FieldType, ReplacePaths, ValuesCollection}; use crate::util::json_value::{JsonValueExt, ReplaceWith}; -use crate::util::string_encoding::Encoding; +use platform_value::string_encoding::Encoding; use crate::version::LATEST_VERSION; use crate::ProtocolError; use crate::{ @@ -375,10 +375,10 @@ impl StateTransitionConvert for DocumentsBatchTransition { Ok(json_value) } - fn to_object(&self, skip_signature: bool) -> Result { - let mut json_object: JsonValue = serde_json::to_value(self)?; + fn to_object(&self, skip_signature: bool) -> Result { + let mut json_object: Value = platform_value::to_value(self)?; json_object - .replace_identifier_paths(Self::identifiers_property_paths(), ReplaceWith::Bytes)?; + .replace_at_paths(Self::identifiers_property_paths(), ReplacementType::Identifier)?; if skip_signature { for path in Self::signature_property_paths() { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index 2186fa33c2e..d7ef3c0e663 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -7,7 +7,7 @@ use std::collections::BTreeMap; use crate::data_contract::DriveContractExt; use crate::{ document::document_transition::DocumentTransition, prelude::DataContract, - util::json_schema::Index, ProtocolError, + ProtocolError, util::json_schema::Index, }; #[macro_export] @@ -114,9 +114,10 @@ mod test { use serde_json::json; use std::collections::BTreeMap; use std::convert::TryInto; + use platform_value::string_encoding::Encoding; use crate::data_contract::document_type::DocumentType; - use crate::{prelude::*, util::string_encoding::Encoding}; + use crate::{prelude::*}; use super::find_duplicates_by_indices; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs index b9905f4a106..815beb735d7 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs @@ -6,13 +6,14 @@ use std::{ use futures::future::join_all; use itertools::Itertools; use serde_json::json; +use platform_value::string_encoding::Encoding; use crate::document::ExtendedDocument; use crate::{ document::document_transition::DocumentTransition, get_from_transition, + ProtocolError, state_repository::StateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, - util::string_encoding::Encoding, ProtocolError, }; pub async fn fetch_extended_documents( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs index ae055f4ac2d..023a2e36bed 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs @@ -3,19 +3,19 @@ use std::convert::TryInto; use futures::future::join_all; use itertools::Itertools; use serde_json::{json, Value as JsonValue}; +use platform_value::string_encoding::Encoding; use crate::document::Document; use crate::{ document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, prelude::{DataContract, Identifier}, + ProtocolError, state_repository::StateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, + StateError, util::{ json_schema::{Index, JsonSchemaExt}, - string_encoding::Encoding, - }, - validation::ValidationResult, - ProtocolError, StateError, + }, validation::ValidationResult, }; struct QueryDefinition<'a> { diff --git a/packages/rs-dpp/src/identifier/mod.rs b/packages/rs-dpp/src/identifier/mod.rs index 4cb48711264..25038faacdc 100644 --- a/packages/rs-dpp/src/identifier/mod.rs +++ b/packages/rs-dpp/src/identifier/mod.rs @@ -1,3 +1,2 @@ pub use identifier::*; -mod identifier; diff --git a/packages/rs-dpp/src/identity/core_script.rs b/packages/rs-dpp/src/identity/core_script.rs index d57d84a8f3e..8c4c51b577c 100644 --- a/packages/rs-dpp/src/identity/core_script.rs +++ b/packages/rs-dpp/src/identity/core_script.rs @@ -2,11 +2,9 @@ use std::ops::Deref; use dashcore::Script as DashcoreScript; use serde::{Deserialize, Serialize}; +use platform_value::string_encoding::{self, Encoding}; -use crate::{ - util::string_encoding::{self, Encoding}, - ProtocolError, -}; +use crate::ProtocolError; #[derive(Clone, Debug, Eq, PartialEq, Default)] pub struct CoreScript(DashcoreScript); diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index 813ea7eccf6..7964a93336f 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -60,20 +60,20 @@ impl<'de> Deserialize<'de> for AssetLockProof { where D: Deserializer<'de>, { - let value = serde_json::Value::deserialize(deserializer)?; + let value = platform_value::Value::deserialize(deserializer)?; let proof_type_int = value - .get_u64("type") + .get_integer("type") .map_err(|e| D::Error::custom(e.to_string()))?; let proof_type = AssetLockProofType::try_from(proof_type_int) .map_err(|e| D::Error::custom(e.to_string()))?; match proof_type { AssetLockProofType::Instant => Ok(Self::Instant( - serde_json::from_value(value).map_err(|e| D::Error::custom(e.to_string()))?, + platform_value::from_value(value).map_err(|e| D::Error::custom(e.to_string()))?, )), AssetLockProofType::Chain => Ok(Self::Chain( - serde_json::from_value(value).map_err(|e| D::Error::custom(e.to_string()))?, + platform_value::from_value(value).map_err(|e| D::Error::custom(e.to_string()))?, )), } } @@ -97,8 +97,8 @@ impl TryFrom for AssetLockProofType { } impl AssetLockProof { - pub fn type_from_raw_value(value: &JsonValue) -> Option { - let proof_type_res = value.get_u64("type"); + pub fn type_from_raw_value(value: &Value) -> Option { + let proof_type_res = value.get_integer::("type"); match proof_type_res { Ok(proof_type_int) => { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 87a8e8bac71..b528c2eda9d 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -16,7 +16,7 @@ use crate::state_transition::{ StateTransition, StateTransitionConvert, StateTransitionLike, StateTransitionType, }; use crate::util::json_value::JsonValueExt; -use crate::util::string_encoding::Encoding; +use platform_value::string_encoding::Encoding; use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; mod property_names { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index 04972f7f0b8..6f9395b8f7e 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -2,11 +2,13 @@ use anyhow::anyhow; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use serde_repr::{Deserialize_repr, Serialize_repr}; +use platform_value::string_encoding::{self, Encoding}; use crate::version::LATEST_VERSION; use crate::{ identity::{core_script::CoreScript, KeyID}, prelude::{Identifier, Revision}, + ProtocolError, state_transition::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, @@ -14,9 +16,7 @@ use crate::{ }, util::{ json_value::{JsonValueExt, ReplaceWith}, - string_encoding::{self, Encoding}, }, - ProtocolError, }; use super::properties::{ diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index dfe9adac08e..969ca9a72d3 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -6,6 +6,7 @@ use std::convert::{TryFrom, TryInto}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use crate::errors::ProtocolError; @@ -54,9 +55,9 @@ impl IdentityPublicKeyCreateTransition { pub fn from_raw_object(mut raw_object: Value) -> Result { Ok(Self { id: raw_object.get_integer("id").map_err(ProtocolError::ValueError)?, - purpose: raw_object.get_integer("purpose").map_err(ProtocolError::ValueError)?, - security_level: raw_object.get_integer("securityLevel").map_err(ProtocolError::ValueError)?, - key_type: raw_object.get_integer("keyType").map_err(ProtocolError::ValueError)?, + purpose: raw_object.get_integer::("purpose").map_err(ProtocolError::ValueError)?.try_into()?, + security_level: raw_object.get_integer::("securityLevel").map_err(ProtocolError::ValueError)?.try_into()?, + key_type: raw_object.get_integer::("keyType").map_err(ProtocolError::ValueError)?.try_into()?, data: raw_object.remove_bytes("data").map_err(ProtocolError::ValueError)?, read_only: raw_object.get_bool("readOnly").map_err(ProtocolError::ValueError)?, signature: raw_object.remove_bytes("signature").map_err(ProtocolError::ValueError)?, @@ -66,9 +67,9 @@ impl IdentityPublicKeyCreateTransition { pub fn from_value_map(mut value_map: BTreeMap) -> Result { Ok(Self { id: value_map.get_integer("id").map_err(ProtocolError::ValueError)?, - purpose: value_map.get_integer("purpose").map_err(ProtocolError::ValueError)?, - security_level: value_map.get_integer("securityLevel").map_err(ProtocolError::ValueError)?, - key_type: value_map.get_integer("keyType").map_err(ProtocolError::ValueError)?, + purpose: value_map.get_integer::("purpose").map_err(ProtocolError::ValueError)?.try_into()?, + security_level: value_map.get_integer::("securityLevel").map_err(ProtocolError::ValueError)?.try_into()?, + key_type: value_map.get_integer::("keyType").map_err(ProtocolError::ValueError)?.try_into()?, data: value_map.remove_bytes("data").map_err(ProtocolError::ValueError)?, read_only: value_map.get_bool("readOnly").map_err(ProtocolError::ValueError)?, signature: value_map.remove_bytes("signature").map_err(ProtocolError::ValueError)?, @@ -98,10 +99,10 @@ impl IdentityPublicKeyCreateTransition { ]); if !skip_signature && !self.signature.is_empty() { - map.insert("signature".to_string(), Value::Bytes(self.signature.clone())) + map.insert("signature".to_string(), Value::Bytes(self.signature.clone())); } - Ok(value) + Ok(map.into()) } /// Return raw data, with all binary fields represented as arrays diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 4e5be8f1d87..ff45bdf9f9f 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -4,6 +4,7 @@ use serde::de::Error as DeError; use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; +use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; use crate::identity::state_transition::identity_create_transition::SerializationOptions; @@ -13,7 +14,7 @@ use crate::state_transition::{ StateTransition, StateTransitionConvert, StateTransitionLike, StateTransitionType, }; use crate::util::json_value::JsonValueExt; -use crate::util::string_encoding::Encoding; +use platform_value::string_encoding::Encoding; use crate::version::LATEST_VERSION; use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; @@ -74,7 +75,7 @@ impl<'de> Deserialize<'de> for IdentityTopUpTransition { where D: Deserializer<'de>, { - let value = serde_json::Value::deserialize(deserializer)?; + let value = platform_value::Value::deserialize(deserializer)?; Self::new(value).map_err(|e| D::Error::custom(e.to_string())) } @@ -82,25 +83,24 @@ impl<'de> Deserialize<'de> for IdentityTopUpTransition { /// Main state transition functionality implementation impl IdentityTopUpTransition { - pub fn new(raw_state_transition: serde_json::Value) -> Result { + pub fn new(raw_state_transition: Value) -> Result { Self::from_raw_object(raw_state_transition) } pub fn from_raw_object( - raw_object: JsonValue, + raw_object: Value, ) -> Result { let protocol_version = raw_object - .get_u64(property_names::PROTOCOL_VERSION) - .unwrap_or(LATEST_VERSION as u64) as u32; + .get_optional_integer(property_names::PROTOCOL_VERSION).map_err(ProtocolError::ValueError)? + .unwrap_or(LATEST_VERSION); let signature = raw_object - .get_bytes(property_names::SIGNATURE) + .get_optional_bytes(property_names::SIGNATURE).map_err(ProtocolError::ValueError)? .unwrap_or_default(); let identity_id = - Identifier::from_bytes(&raw_object.get_bytes(property_names::IDENTITY_ID)?)?; + Identifier::from(raw_object.get_hash256(property_names::IDENTITY_ID).map_err(ProtocolError::ValueError)?); let raw_asset_lock_proof = raw_object - .get(property_names::ASSET_LOCK_PROOF) - .ok_or_else(|| ProtocolError::Generic("Asset lock proof is missing".to_string()))?; + .get_value(property_names::ASSET_LOCK_PROOF).map_err(ProtocolError::ValueError)?; let asset_lock_proof = AssetLockProof::try_from(raw_asset_lock_proof)?; Ok(IdentityTopUpTransition { diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index 77c85d3a2ab..7b7eb2fe4d1 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -189,7 +189,7 @@ mod test { use crate::document::DocumentsBatchTransition; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; - use crate::util::string_encoding::Encoding; + use platform_value::string_encoding::Encoding; use crate::{ assert_error_contains, identity::{KeyID, SecurityLevel}, diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs index 1b1d424cbd7..b157e24ea0f 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs @@ -218,7 +218,7 @@ mod test { let private_key = PrivateKey::new(secret_key, Network::Testnet); let mut state_transition: StateTransition = IdentityCreateTransition::new( - identity_create_transition_fixture_json(Some(private_key)), + identity_create_transition_fixture_json(Some(private_key)).into(), ) .unwrap() .into(); @@ -255,7 +255,7 @@ mod test { let private_key = PrivateKey::new(secret_key, Network::Testnet); let mut state_transition: StateTransition = IdentityCreateTransition::new( - identity_create_transition_fixture_json(Some(private_key)), + identity_create_transition_fixture_json(Some(private_key)).into(), ) .unwrap() .into(); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 7bebc36f25d..4c5e035f971 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -31,7 +31,7 @@ use test_case::test_case; struct TestData { data_contract: DataContract, state_transition: DocumentsBatchTransition, - raw_state_transition: JsonValue, + raw_state_transition: Value, protocol_version_validator: ProtocolVersionValidator, state_repository_mock: MockStateRepositoryLike, } diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 60dc1663f32..2b6a9fbea8d 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -1,6 +1,7 @@ use futures::StreamExt; use mockall::predicate; use serde_json::json; +use platform_value::string_encoding::Encoding; use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ document_transition::{Action, DocumentTransition}, @@ -10,7 +11,7 @@ use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ get_data_contract_fixture, get_document_transitions_fixture, }, utils::generate_random_identifier_struct, -}, util::string_encoding::Encoding, validation::ValidationResult}; +}, validation::ValidationResult}; use crate::document::{Document, ExtendedDocument}; use crate::tests::fixtures::get_extended_documents_fixture; diff --git a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs index 06e1933e544..34498e0cf9b 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs @@ -1,11 +1,12 @@ +use std::convert::TryInto; use std::str::FromStr; use dashcore::PrivateKey; -use serde_json::{json, Value}; +use platform_value::Value; use crate::identity::{KeyType, Purpose, SecurityLevel}; use crate::tests::fixtures::instant_asset_lock_proof_fixture; -use crate::util::string_encoding::{decode, Encoding}; +use platform_value::string_encoding::{decode, Encoding}; use crate::version; //3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT @@ -13,27 +14,22 @@ use crate::version; pub fn identity_create_transition_fixture_json( one_time_private_key: Option, -) -> serde_json::Value { +) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); - let asset_lock_string = serde_json::ser::to_string(&asset_lock_proof).unwrap(); - let asset_lock_proof_json = Value::from_str(&asset_lock_string).unwrap(); + let read_only = false; + let signature = vec![0_u8; 65]; - json!({ - "protocolVersion": version::LATEST_VERSION, - // TODO: change to a const - "type": 2, - "assetLockProof": asset_lock_proof_json, - "publicKeys": [ - { - "id": 0, - "type": KeyType::ECDSA_SECP256K1, - "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), - "purpose": Purpose::AUTHENTICATION, - "securityLevel": SecurityLevel::MASTER, - "readOnly": false, - "signature": vec![0_u8; 65] - }, - ], - "signature": vec![0_u8; 65] - }) + let public_keys = vec![Value::from([("id", Value::U32(version::LATEST_VERSION)), + ("type", Value::U8(2)), + ("data", Value::Bytes(decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap())), + ("purpose": Value::U8(Purpose::AUTHENTICATION)), + ("securityLevel": Value::U8(SecurityLevel::MASTER)), + ("readOnly": Value::Bool(read_only)), + ("signature": Value::Bytes(signature))])]; + + Value::from([("protocolVersion", Value::U32(version::LATEST_VERSION)), + ("type", Value::U8(2)), + ("assetLockProof", asset_lock_proof.try_into().unwrap()), + ("publicKeys": Value::Array(public_keys)), + ("signature": Value::Bytes(signature))]) } diff --git a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs index e23914ab606..5841b4b4c2e 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs @@ -1,10 +1,10 @@ use dashcore::{hashes::hex::FromHex, PubkeyHash, Script}; use serde_json::{json, Value}; +use platform_value::string_encoding::{encode, Encoding}; use crate::{ identity::state_transition::identity_credit_withdrawal_transition::Pooling, state_transition::StateTransitionType, - util::string_encoding::{encode, Encoding}, version, }; diff --git a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs index c639d9b2059..1733891be85 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs @@ -1,9 +1,7 @@ use serde_json::json; +use platform_value::string_encoding::{decode, Encoding}; -use crate::{ - prelude::Identity, - util::string_encoding::{decode, Encoding}, -}; +use crate::prelude::Identity; //3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT //[198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237] diff --git a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs index 8e5de1f3a46..9a5cc406607 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs @@ -1,7 +1,9 @@ +use std::convert::TryInto; use std::str::FromStr; use dashcore::PrivateKey; use serde_json::{json, Value as JsonValue}; +use platform_value::Value; use crate::state_transition::StateTransitionType; use crate::tests::fixtures::instant_asset_lock_proof_fixture; @@ -12,16 +14,14 @@ use crate::version; pub fn identity_topup_transition_fixture_json( one_time_private_key: Option, -) -> JsonValue { +) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); - let asset_lock_string = serde_json::ser::to_string(&asset_lock_proof).unwrap(); - let asset_lock_proof_json = JsonValue::from_str(&asset_lock_string).unwrap(); + let identity = Value::Identifier([198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237]); + let signature = vec![0_u8; 65]; - json!({ - "protocolVersion": version::LATEST_VERSION, - "type": StateTransitionType::IdentityTopUp, - "assetLockProof": asset_lock_proof_json, - "identityId": [198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237], - "signature": vec![0_u8; 65] - }) + Value::from([("protocolVersion", Value::U32(version::LATEST_VERSION)), + ("type", Value::U8(2)), + ("assetLockProof", asset_lock_proof.try_into().unwrap()), + ("identityId": Value::Array(public_keys)), + ("signature": Value::Bytes(signature))]) } diff --git a/packages/rs-dpp/src/tests/identifier_spec.rs b/packages/rs-dpp/src/tests/identifier_spec.rs index d3c2e69c658..d0efafa1dc8 100644 --- a/packages/rs-dpp/src/tests/identifier_spec.rs +++ b/packages/rs-dpp/src/tests/identifier_spec.rs @@ -1,5 +1,5 @@ use crate::identifier::Identifier; -use crate::util::string_encoding::Encoding; +use platform_value::string_encoding::Encoding; #[test] pub fn from_string() { diff --git a/packages/rs-dpp/src/tests/identity/identity_spec.rs b/packages/rs-dpp/src/tests/identity/identity_spec.rs index a527df4e828..b3c08e9abdb 100644 --- a/packages/rs-dpp/src/tests/identity/identity_spec.rs +++ b/packages/rs-dpp/src/tests/identity/identity_spec.rs @@ -128,8 +128,8 @@ mod from_buffer { mod conversions { use crate::prelude::Identity; use crate::tests::fixtures::{identity_fixture_json, identity_fixture_raw_object}; - use crate::util::string_encoding; - use crate::util::string_encoding::Encoding; + use platform_value::string_encoding; + use platform_value::string_encoding::Encoding; #[test] fn from_json() { diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index 60ddaf9290c..71172ccb627 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -1,11 +1,12 @@ use chrono::Utc; use serde_json::{json, Value as JsonValue}; +use platform_value::string_encoding::Encoding; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; use crate::{ identity::{ - state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, - KeyType, Purpose, SecurityLevel, + KeyType, + Purpose, SecurityLevel, state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, }, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionType, @@ -13,7 +14,6 @@ use crate::{ tests::{ fixtures::get_identity_update_transition_fixture, utils::generate_random_identifier_struct, }, - util::string_encoding::Encoding, }; struct TestData { diff --git a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs index e93f1c0000e..4c1b9aaf2d2 100644 --- a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs @@ -1,11 +1,11 @@ use crate::{ identity::{ - validation::{RequiredPurposeAndSecurityLevelValidator, TPublicKeysValidator}, - KeyType, Purpose, SecurityLevel, + KeyType, + Purpose, SecurityLevel, validation::{RequiredPurposeAndSecurityLevelValidator, TPublicKeysValidator}, }, - util::string_encoding::{decode, Encoding}, }; use serde_json::json; +use platform_value::string_encoding::{decode, Encoding}; #[test] fn should_return_invalid_result_if_state_transition_does_not_contain_master_key() { diff --git a/packages/rs-dpp/src/util/cbor_value/canonical.rs b/packages/rs-dpp/src/util/cbor_value/canonical.rs index b3e72838b32..71b326e1189 100644 --- a/packages/rs-dpp/src/util/cbor_value/canonical.rs +++ b/packages/rs-dpp/src/util/cbor_value/canonical.rs @@ -7,15 +7,16 @@ use std::{ use anyhow::anyhow; use ciborium::value::Value as CborValue; use serde::Serialize; +use platform_value::string_encoding::Encoding; use crate::{ prelude::Identifier, - util::{json_value::ReplaceWith, string_encoding::Encoding}, ProtocolError, + util::json_value::ReplaceWith, }; use super::{ - convert::convert_to, get_from_cbor_map, to_path_of_cbors, FieldType, ReplacePaths, + convert::convert_to, FieldType, get_from_cbor_map, ReplacePaths, to_path_of_cbors, ValuesCollection, }; diff --git a/packages/rs-dpp/src/util/json_value/mod.rs b/packages/rs-dpp/src/util/json_value/mod.rs index 30a360b824b..4b42a8b2269 100644 --- a/packages/rs-dpp/src/util/json_value/mod.rs +++ b/packages/rs-dpp/src/util/json_value/mod.rs @@ -12,11 +12,12 @@ use crate::{ use super::{ json_path::{JsonPath, JsonPathLiteral, JsonPathStep}, - string_encoding::Encoding, }; mod insert_with_path; use insert_with_path::*; +use platform_value::string_encoding::Encoding; + mod remove_path; use remove_path::*; diff --git a/packages/rs-dpp/src/util/mod.rs b/packages/rs-dpp/src/util/mod.rs index c0833ed07e3..23269436dc4 100644 --- a/packages/rs-dpp/src/util/mod.rs +++ b/packages/rs-dpp/src/util/mod.rs @@ -8,5 +8,4 @@ pub mod json_schema; pub mod json_value; pub mod protocol_data; pub mod serializer; -pub mod string_encoding; pub mod vec; diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index d3f33ee6f06..794c282b30b 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -43,7 +43,7 @@ use drive::dpp::identity::{ }; use drive::dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; -use drive::dpp::util::string_encoding::{encode, Encoding}; +use platform_value::string_encoding::{encode, Encoding}; use drive::drive::batch::{ ContractOperationType, DocumentOperationType, DriveOperationType, IdentityOperationType, }; diff --git a/packages/rs-platform-value/Cargo.toml b/packages/rs-platform-value/Cargo.toml index 444fa5c7f1a..ae71e65cd45 100644 --- a/packages/rs-platform-value/Cargo.toml +++ b/packages/rs-platform-value/Cargo.toml @@ -14,6 +14,7 @@ base64 = "0.13.0" hex = "0.4.3" serde = { version = "1.0.152", features = ["derive"] } serde_json = { version="1.0", features=["preserve_order"] } +rand = { version = "0.8.4", features = ["small_rng"] } ### FEATURES ################################################################# diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index 25fb6722655..081e4ae321e 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -16,6 +16,9 @@ pub enum Error { #[error("integer out of bounds")] IntegerSizeError, + #[error("string decoding error {0}")] + StringDecodingError(String), + #[error("key must be a string")] KeyMustBeAString, diff --git a/packages/rs-dpp/src/identifier/identifier.rs b/packages/rs-platform-value/src/identifier.rs similarity index 100% rename from packages/rs-dpp/src/identifier/identifier.rs rename to packages/rs-platform-value/src/identifier.rs diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 7c73e30d3b7..2978f3a41cf 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -126,6 +126,16 @@ impl Value { Self::inner_text_value(map, key) } + pub fn get_optional_bytes<'a>(&'a self, key: &'a str) -> Result>, Error> { + let map = self.to_map()?; + Self::inner_optional_bytes_value(map, key) + } + + pub fn get_bytes<'a>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Self::inner_bytes_value(map, key) + } + pub fn get_optional_hash256<'a>(&'a self, key: &'a str) -> Result, Error> { let map = self.to_map()?; Self::inner_optional_hash256_value(map, key) @@ -268,6 +278,15 @@ impl Value { .transpose() } + /// Retrieves the value of a key from a map if it's a byte array. + pub fn inner_bytes_value<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result, Error> { + Self::get_from_map(document_type, key) + .map(|v| v.to_bytes())? + } + /// Retrieves the value of a key from a map if it's a byte array. pub fn inner_optional_bytes_slice_value<'a>( document_type: &'a [(Value, Value)], diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index d1d94890c8d..ba7bd41e9bd 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -17,9 +17,11 @@ pub mod inner_value; mod integer; pub mod system_bytes; pub mod value_map; -mod btreemap_removal_extensions; +pub mod btreemap_removal_extensions; mod btreemap_removal_inner_value_extensions; mod ser; +pub mod identifier; +pub mod string_encoding; use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; @@ -1062,6 +1064,81 @@ impl From> for Value { } } +impl From<[(Value, Value); N]> for Value { + /// Converts a `[(Value, Value); N]` into a `Value`. + /// + /// ``` + /// use platform_value::Value; + /// + /// let map1 = Value::from([(1, 2), (3, 4)]); + /// let map2: Value = [(1, 2), (3, 4)].into(); + /// assert_eq!(map1, map2); + /// ``` + fn from(mut arr: [(Value, Value); N]) -> Self { + if N == 0 { + return Value::Map(vec![]); + } + + Value::Map( + arr + .into_iter() + .collect(), + ) + } +} + +impl From<[(String, Value); N]> for Value { + /// Converts a `[(String, Value); N]` into a `Value`. + /// + /// ``` + /// use platform_value::Value; + /// + /// let map1 = Value::from([("1".to_string(), 2), ("3".to_string(), 4)]); + /// let map2: Value = [("1".to_string(), 2), ("3".to_string(), 4)].into(); + /// assert_eq!(map1, map2); + /// ``` + fn from(mut arr: [(String, Value); N]) -> Self { + if N == 0 { + return Value::Map(vec![]); + } + + // use stable sort to preserve the insertion order. + arr.sort_by(|a, b| a.0.cmp(&b.0)); + Value::Map( + arr + .into_iter() + .map(|(k,v)| (k.into(), v)) + .collect(), + ) + } +} + +impl From<[(&str, Value); N]> for Value { + /// Converts a `[($str, Value); N]` into a `Value`. + /// + /// ``` + /// use platform_value::Value; + /// + /// let map1 = Value::from([("1", 2), ("3", 4)]); + /// let map2: Value = [("1", 2), ("3", 4)].into(); + /// assert_eq!(map1, map2); + /// ``` + fn from(mut arr: [(&str, Value); N]) -> Self { + if N == 0 { + return Value::Map(vec![]); + } + + // use stable sort to preserve the insertion order. + arr.sort_by(|a, b| a.0.cmp(&b.0)); + Value::Map( + arr + .into_iter() + .map(|(k,v)| (k.into(), v)) + .collect(), + ) + } +} + impl From> for Value { fn from(value: BTreeMap) -> Self { Value::Map( diff --git a/packages/rs-dpp/src/util/string_encoding.rs b/packages/rs-platform-value/src/string_encoding.rs similarity index 70% rename from packages/rs-dpp/src/util/string_encoding.rs rename to packages/rs-platform-value/src/string_encoding.rs index 3c99f7cdcaf..40bb7275582 100644 --- a/packages/rs-dpp/src/util/string_encoding.rs +++ b/packages/rs-platform-value/src/string_encoding.rs @@ -1,20 +1,19 @@ use base64; use bs58; - -use crate::errors::ProtocolError; +use crate::Error; pub enum Encoding { Base58, Base64, } -pub fn decode(encoded_value: &str, encoding: Encoding) -> Result, ProtocolError> { +pub fn decode(encoded_value: &str, encoding: Encoding) -> Result, Error> { match encoding { Encoding::Base58 => Ok(bs58::decode(encoded_value) .into_vec() - .map_err(|e| ProtocolError::StringDecodeError(e.to_string()))?), + .map_err(|e| Error::StringDecodingError(e.to_string()))?), Encoding::Base64 => Ok(base64::decode(encoded_value) - .map_err(|e| ProtocolError::StringDecodeError(e.to_string()))?), + .map_err(|e| Error::StringDecodingError(e.to_string()))?), } } diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index ca616d1d447..5a2280363e0 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -9,7 +9,7 @@ use wasm_bindgen::prelude::*; use dpp::data_contract::{DataContract, SCHEMA_URI}; use dpp::platform_value::Value; -use dpp::util::string_encoding::Encoding; +use platform_value::string_encoding::Encoding; use crate::errors::{from_dpp_err, RustConversionError}; use crate::identifier::identifier_from_js_value; diff --git a/packages/wasm-dpp/src/identifier/mod.rs b/packages/wasm-dpp/src/identifier/mod.rs index 3afc65df00b..f4bd64e9e84 100644 --- a/packages/wasm-dpp/src/identifier/mod.rs +++ b/packages/wasm-dpp/src/identifier/mod.rs @@ -1,5 +1,5 @@ use dpp::prelude::Identifier; -use dpp::util::string_encoding::Encoding; +use platform_value::string_encoding::Encoding; use itertools::Itertools; pub use serde::{Deserialize, Serialize}; use serde_json::Value; diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index 8cdcbcf7ee3..87770ec15dc 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -9,8 +9,8 @@ use crate::{ with_js_error, }; use dpp::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; -use dpp::util::string_encoding; -use dpp::util::string_encoding::Encoding; +use platform_value::string_encoding; +use platform_value::string_encoding::Encoding; #[wasm_bindgen(js_name=ChainAssetLockProof)] #[derive(Clone)] diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs index 44dcc7dae9b..43ea83c6b81 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs @@ -3,8 +3,6 @@ use dpp::{ blockdata::{script::Script, transaction::txout::TxOut}, consensus::encode::serialize, }, - util::string_encoding, - util::string_encoding::Encoding, }; use serde::{Deserialize, Serialize}; @@ -20,6 +18,8 @@ use crate::{ use dpp::identity::state_transition::asset_lock_proof::instant::{ InstantAssetLockProof, RawInstantLock, }; +use platform_value::string_encoding; +use platform_value::string_encoding::Encoding; #[derive(Serialize, Deserialize)] #[serde(remote = "TxOut")] diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index cf7700c445e..1147904e453 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -28,9 +28,9 @@ use dpp::{ identity_public_key_transitions::IdentityPublicKeyCreateTransition, }, state_transition::StateTransitionLike, - util::string_encoding, - util::string_encoding::Encoding, }; +use platform_value::string_encoding; +use platform_value::string_encoding::Encoding; #[wasm_bindgen(js_name=IdentityCreateTransition)] #[derive(Clone)] diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 495f5bc4ccf..ecfd45c8100 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -27,9 +27,9 @@ use dpp::{ asset_lock_proof::AssetLockProof, identity_topup_transition::IdentityTopUpTransition, }, state_transition::StateTransitionLike, - util::string_encoding, - util::string_encoding::Encoding, }; +use platform_value::string_encoding; +use platform_value::string_encoding::Encoding; #[wasm_bindgen(js_name=IdentityTopUpTransition)] #[derive(Clone)] diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index d052b7e10ce..4d2a990d8f4 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -9,8 +9,8 @@ use crate::identifier::IdentifierWrapper; use crate::{ buffer::Buffer, errors::RustConversionError, - identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransitionWasm, - identity::IdentityPublicKeyWasm, state_transition::StateTransitionExecutionContextWasm, + identity::IdentityPublicKeyWasm, + identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransitionWasm, state_transition::StateTransitionExecutionContextWasm, with_js_error, }; @@ -24,8 +24,10 @@ use dpp::state_transition::StateTransitionIdentitySigned; use dpp::{ identifier::Identifier, identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, - state_transition::StateTransitionLike, util::string_encoding, util::string_encoding::Encoding, + state_transition::StateTransitionLike, }; +use platform_value::string_encoding; +use platform_value::string_encoding::Encoding; #[wasm_bindgen(js_name=IdentityUpdateTransition)] #[derive(Clone)] From b14c4a8543d4548eff02146f408b14d4b73d4002 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 11 Mar 2023 20:31:05 +0700 Subject: [PATCH 102/228] more work --- .../rs-dpp/src/data_contract/data_contract.rs | 52 +++++--- .../data_contract/data_contract_factory.rs | 29 +++-- .../document_type/document_factory.rs | 2 +- .../document_type/document_type.rs | 14 ++- .../errors/data_contract_not_present_error.rs | 2 +- .../errors/identity_not_present_error.rs | 2 +- .../src/data_contract/serialization/cbor.rs | 2 +- .../data_contract_create_transition/mod.rs | 38 ++++-- .../data_contract_update_transition/mod.rs | 46 ++++--- .../errors/missing_data_contract_id_error.rs | 4 +- .../reward_share_data_triggers/mod.rs | 10 +- .../src/decode_protocol_entity_factory.rs | 8 +- .../rs-dpp/src/document/document_factory.rs | 17 ++- .../rs-dpp/src/document/document_validator.rs | 16 ++- packages/rs-dpp/src/document/errors.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 8 +- .../fetch_and_validate_data_contract.rs | 7 +- .../document_create_transition.rs | 76 ++++++++---- .../documents_batch_transition/mod.rs | 8 +- .../basic/find_duplicates_by_indices.rs | 6 +- ...lidate_documents_batch_transition_basic.rs | 45 ++++--- .../state/fetch_extended_documents.rs | 4 +- ...lidate_documents_batch_transition_state.rs | 2 +- ...alidate_documents_uniqueness_by_indices.rs | 10 +- packages/rs-dpp/src/identifier/mod.rs | 4 +- packages/rs-dpp/src/identity/core_script.rs | 2 +- packages/rs-dpp/src/identity/factory.rs | 3 +- .../state_transition/asset_lock_proof/mod.rs | 39 ++++-- .../identity_create_transition.rs | 20 +-- .../mod.rs | 8 +- .../identity_public_key_transitions.rs | 81 ++++++++++--- .../identity_topup_transition.rs | 24 ++-- .../identity_update_transition.rs | 84 +++++-------- .../validate_public_key_signatures.rs | 3 +- ...stract_state_transition_identity_signed.rs | 2 +- .../state_transition_factory.rs | 7 +- ...te_documents_uniqueness_by_indices_spec.rs | 2 +- .../validate_partial_compound_indices_spec.rs | 2 - .../identity_create_transition_fixture.rs | 48 +++++--- ...ty_credit_withdrawal_transition_fixture.rs | 5 +- .../src/tests/fixtures/identity_fixture.rs | 2 +- .../identity_topup_transition_fixture.rs | 22 ++-- ...edit_withdrawal_transition_factory_spec.rs | 1 - .../identity_update_transition_spec.rs | 6 +- ...rpose_and_security_level_validator_spec.rs | 10 +- .../rs-dpp/src/util/cbor_value/canonical.rs | 10 +- packages/rs-dpp/src/util/json_value/mod.rs | 4 +- packages/rs-drive-abci/src/state/genesis.rs | 2 +- .../src/btreemap_extensions.rs | 20 ++- .../src/btreemap_field_replacement.rs | 18 ++- .../src/btreemap_path_extensions.rs | 14 +-- .../src/btreemap_removal_extensions.rs | 56 +++------ ...btreemap_removal_inner_value_extensions.rs | 21 +--- .../src/converter/ciborium.rs | 23 +++- .../src/converter/serde_json.rs | 64 +++++----- packages/rs-platform-value/src/error.rs | 10 +- packages/rs-platform-value/src/identifier.rs | 22 ++-- packages/rs-platform-value/src/inner_value.rs | 114 +++++++++++++----- packages/rs-platform-value/src/lib.rs | 38 ++---- packages/rs-platform-value/src/ser.rs | 91 +++++++------- .../rs-platform-value/src/string_encoding.rs | 8 +- packages/rs-platform-value/src/value_map.rs | 6 +- .../wasm-dpp/src/data_contract/errors/mod.rs | 2 +- .../src/document/extended_document.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 9 +- .../basic/find_duplicates_by_indices.rs | 2 +- packages/wasm-dpp/src/identifier/mod.rs | 3 +- .../instant/instant_asset_lock_proof.rs | 8 +- .../identity_update_transition.rs | 4 +- 69 files changed, 758 insertions(+), 578 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 8595bb31f86..631f4bcb57f 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -5,32 +5,30 @@ use anyhow::anyhow; use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::identifier::Identifier; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::consensus::basic::document::InvalidDocumentTypeError; -use crate::data_contract::{contract_config, DriveContractExt}; use crate::data_contract::contract_config::{ ContractConfig, DEFAULT_CONTRACT_CAN_BE_DELETED, DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY, DEFAULT_CONTRACT_DOCUMENT_MUTABILITY, DEFAULT_CONTRACT_KEEPS_HISTORY, DEFAULT_CONTRACT_MUTABILITY, }; +use crate::data_contract::{contract_config, DriveContractExt}; use crate::data_contract::get_binary_properties_from_schema::get_binary_properties; - - use crate::util::json_value::{JsonValueExt, ReplaceWith}; -use platform_value::string_encoding::Encoding; use crate::{ errors::ProtocolError, - identifier::Identifier, metadata::Metadata, util::{hash::hash, serializer}, }; use crate::{identifier, Convertible}; +use platform_value::string_encoding::Encoding; use super::document_type::DocumentType; use super::errors::*; @@ -114,7 +112,9 @@ impl DataContract { } pub fn from_raw_object(raw_object: Value) -> Result { - let mut data_contract_map = raw_object.into_btree_map().map_err(ProtocolError::ValueError)?; + let mut data_contract_map = raw_object + .into_btree_map() + .map_err(ProtocolError::ValueError)?; let mutability = get_contract_configuration_properties(&data_contract_map) .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; @@ -125,9 +125,12 @@ impl DataContract { mutability.documents_keep_history_contract_default, mutability.documents_mutable_contract_default, ) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; - let documents = data_contract_map.remove(property_names::DOCUMENTS).map(|value | value.try_into_validating_btree_map_json()).transpose()? + let documents = data_contract_map + .remove(property_names::DOCUMENTS) + .map(|value| value.try_into_validating_btree_map_json()) + .transpose()? .unwrap_or_default(); let mutability = get_contract_configuration_properties(&data_contract_map) @@ -139,20 +142,34 @@ impl DataContract { let mut data_contract = DataContract { protocol_version: 0, - id: Identifier::from(data_contract_map.remove_hash256_bytes(property_names::ID).map_err(ProtocolError::ValueError)?), - schema: data_contract_map.remove_string(property_names::SCHEMA).map_err(ProtocolError::ValueError)?, - version: data_contract_map.remove_integer(property_names::VERSION).map_err(ProtocolError::ValueError)?, - owner_id: Identifier::from(data_contract_map.remove_hash256_bytes(property_names::OWNER_ID).map_err(ProtocolError::ValueError)?), + id: Identifier::from( + data_contract_map + .remove_hash256_bytes(property_names::ID) + .map_err(ProtocolError::ValueError)?, + ), + schema: data_contract_map + .remove_string(property_names::SCHEMA) + .map_err(ProtocolError::ValueError)?, + version: data_contract_map + .remove_integer(property_names::VERSION) + .map_err(ProtocolError::ValueError)?, + owner_id: Identifier::from( + data_contract_map + .remove_hash256_bytes(property_names::OWNER_ID) + .map_err(ProtocolError::ValueError)?, + ), document_types, metadata: None, config: mutability, documents, defs, - entropy: data_contract_map.remove_hash256_bytes(property_names::ENTROPY).map_err(ProtocolError::ValueError)?, + entropy: data_contract_map + .remove_hash256_bytes(property_names::ENTROPY) + .map_err(ProtocolError::ValueError)?, binary_properties: documents .iter() .map(|(doc_type, schema)| (String::from(doc_type), get_binary_properties(schema))) - .collect() + .collect(), }; Ok(data_contract) @@ -220,7 +237,10 @@ impl DataContract { // Ok(raw_object.into()) } - pub fn to_json_object(&self, skip_identifiers_conversion: bool) -> Result { + pub fn to_json_object( + &self, + skip_identifiers_conversion: bool, + ) -> Result { let mut json_object = serde_json::to_value(self)?; if !json_object.is_object() { return Err(anyhow!("the Data Contract isn't a JSON Value Object").into()); diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 21c06df1502..e8a038c91b9 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -1,6 +1,6 @@ +use serde_json::{json, Map, Value as JsonValue}; use std::collections::BTreeMap; use std::convert::TryInto; -use serde_json::{json, Map, Value as JsonValue}; use std::sync::Arc; use data_contract::state_transition::property_names as st_prop; @@ -148,10 +148,19 @@ impl DataContractFactory { data_contract: DataContract, ) -> Result { let raw_object = BTreeMap::from([ - (st_prop::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), - (st_prop::DATA_CONTRACT.to_string(), data_contract.try_into()?), - (st_prop::ENTROPY.to_string(), Value::Bytes32(data_contract.entropy)) - ]); + ( + st_prop::PROTOCOL_VERSION.to_string(), + Value::U32(self.protocol_version), + ), + ( + st_prop::DATA_CONTRACT.to_string(), + data_contract.try_into()?, + ), + ( + st_prop::ENTROPY.to_string(), + Value::Bytes32(data_contract.entropy), + ), + ]); DataContractCreateTransition::from_value_map(raw_object) } @@ -160,8 +169,14 @@ impl DataContractFactory { data_contract: DataContract, ) -> Result { let raw_object = BTreeMap::from([ - (st_prop::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), - (st_prop::DATA_CONTRACT.to_string(), data_contract.try_into()?) + ( + st_prop::PROTOCOL_VERSION.to_string(), + Value::U32(self.protocol_version), + ), + ( + st_prop::DATA_CONTRACT.to_string(), + data_contract.try_into()?, + ), ]); DataContractUpdateTransition::from_value_map(raw_object) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs index b46852af33b..125422cbaed 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs @@ -2,12 +2,12 @@ use crate::data_contract::document_type::property_names::{CREATED_AT, UPDATED_AT use crate::data_contract::document_type::DocumentType; use crate::document::document_transition::INITIAL_REVISION; use crate::document::Document; -use crate::identifier::Identifier; use crate::prelude::TimestampMillis; use crate::ProtocolError; use chrono::Utc; use platform_value::Value; +use platform_value::identifier::Identifier; use std::collections::BTreeMap; impl DocumentType { diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index cdf4f21ff64..73ff065c499 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -422,12 +422,14 @@ fn insert_values( ); } "object" => { - if let Some(properties_as_value) = inner_properties - .get(property_names::PROPERTIES) { - let properties = properties_as_value.as_map() - .ok_or(ProtocolError::StructureError( - StructureError::ValueWrongType("properties must be a map"), - ))?; + if let Some(properties_as_value) = inner_properties.get(property_names::PROPERTIES) + { + let properties = + properties_as_value + .as_map() + .ok_or(ProtocolError::StructureError( + StructureError::ValueWrongType("properties must be a map"), + ))?; for (object_property_key, object_property_value) in properties.iter() { let object_property_string = object_property_key diff --git a/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs b/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs index 1e590d832c3..133d508a3cb 100644 --- a/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs +++ b/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs @@ -1,6 +1,6 @@ +use platform_value::identifier::Identifier; use thiserror::Error; -use crate::identifier::Identifier; use crate::ProtocolError; #[derive(Error, Debug, Clone, PartialEq, Eq)] diff --git a/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs b/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs index 1870dbcbb69..520407d445d 100644 --- a/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs +++ b/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs @@ -1,6 +1,6 @@ +use platform_value::identifier::Identifier; use thiserror::Error; -use crate::identifier::Identifier; use crate::ProtocolError; #[derive(Error, Debug, Clone, PartialEq, Eq)] diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index ffc007225f2..b4bc3e69b67 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -28,7 +28,7 @@ impl DataContract { })?; let data_contract_map: BTreeMap = - Value::convert_from_cbor_map(data_contract_cbor_map); + Value::convert_from_cbor_map(data_contract_cbor_map)?; let contract_id: [u8; 32] = data_contract_map.get_identifier(property_names::ID)?; let owner_id: [u8; 32] = data_contract_map.get_identifier(property_names::OWNER_ID)?; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index d5ac7790095..d67a3b2dafe 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -2,10 +2,10 @@ use std::collections::BTreeMap; use std::convert::TryInto; use anyhow::anyhow; -use serde::{Deserialize, Serialize}; -use serde_json::Value as JsonValue; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; use crate::{ data_contract::DataContract, @@ -62,16 +62,23 @@ impl DataContractCreateTransition { Ok(DataContractCreateTransition { protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION)?, signature: raw_data_contract_update_transition - .remove_optional_bytes(SIGNATURE).map_err(ProtocolError::ValueError)? + .remove_optional_bytes(SIGNATURE) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition - .get_optional_integer(SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)? + .get_optional_integer(SIGNATURE_PUBLIC_KEY_ID) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), entropy: raw_data_contract_update_transition - .remove_optional_hash256_bytes(ENTROPY).map_err(ProtocolError::ValueError)? + .remove_optional_hash256_bytes(ENTROPY) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), data_contract: DataContract::from_raw_object( - raw_data_contract_update_transition.remove(DATA_CONTRACT).ok_or(ProtocolError::DecodingError("data contract missing on state transition".to_string()))?, + raw_data_contract_update_transition + .remove(DATA_CONTRACT) + .ok_or(ProtocolError::DecodingError( + "data contract missing on state transition".to_string(), + ))?, )?, ..Default::default() }) @@ -81,18 +88,27 @@ impl DataContractCreateTransition { mut raw_data_contract_update_transition: BTreeMap, ) -> Result { Ok(DataContractCreateTransition { - protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION).map_err(ProtocolError::ValueError)?, + protocol_version: raw_data_contract_update_transition + .get_integer(PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)?, signature: raw_data_contract_update_transition - .remove_optional_bytes(SIGNATURE).map_err(ProtocolError::ValueError)? + .remove_optional_bytes(SIGNATURE) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition - .remove_optional_integer(SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)? + .remove_optional_integer(SIGNATURE_PUBLIC_KEY_ID) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), entropy: raw_data_contract_update_transition - .remove_optional_hash256_bytes(ENTROPY).map_err(ProtocolError::ValueError)? + .remove_optional_hash256_bytes(ENTROPY) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), data_contract: DataContract::from_raw_object( - raw_data_contract_update_transition.remove(DATA_CONTRACT).ok_or(ProtocolError::DecodingError("data contract missing on state transition".to_string()))?, + raw_data_contract_update_transition + .remove(DATA_CONTRACT) + .ok_or(ProtocolError::DecodingError( + "data contract missing on state transition".to_string(), + ))?, )?, ..Default::default() }) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index b981c294fed..34cef04f09f 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -1,8 +1,8 @@ -use std::collections::BTreeMap; -use serde::{Deserialize, Serialize}; -use serde_json::Value as JsonValue; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; +use std::collections::BTreeMap; use crate::{ data_contract::DataContract, @@ -57,13 +57,19 @@ impl DataContractUpdateTransition { Ok(DataContractUpdateTransition { protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION)?, signature: raw_data_contract_update_transition - .remove_optional_bytes(SIGNATURE).map_err(ProtocolError::ValueError)? + .remove_optional_bytes(SIGNATURE) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition - .get_optional_integer(SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)? + .get_optional_integer(SIGNATURE_PUBLIC_KEY_ID) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), data_contract: DataContract::from_raw_object( - raw_data_contract_update_transition.remove(DATA_CONTRACT).ok_or(ProtocolError::DecodingError("data contract missing on state transition".to_string()))?, + raw_data_contract_update_transition + .remove(DATA_CONTRACT) + .ok_or(ProtocolError::DecodingError( + "data contract missing on state transition".to_string(), + ))?, )?, ..Default::default() }) @@ -73,15 +79,23 @@ impl DataContractUpdateTransition { mut raw_data_contract_update_transition: BTreeMap, ) -> Result { Ok(DataContractUpdateTransition { - protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION).map_err(ProtocolError::ValueError)?, + protocol_version: raw_data_contract_update_transition + .get_integer(PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)?, signature: raw_data_contract_update_transition - .remove_optional_bytes(SIGNATURE).map_err(ProtocolError::ValueError)? + .remove_optional_bytes(SIGNATURE) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition - .remove_optional_integer(SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)? + .remove_optional_integer(SIGNATURE_PUBLIC_KEY_ID) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(), data_contract: DataContract::from_raw_object( - raw_data_contract_update_transition.remove(DATA_CONTRACT).ok_or(ProtocolError::DecodingError("data contract missing on state transition".to_string()))?, + raw_data_contract_update_transition + .remove(DATA_CONTRACT) + .ok_or(ProtocolError::DecodingError( + "data contract missing on state transition".to_string(), + ))?, )?, ..Default::default() }) @@ -198,9 +212,9 @@ impl StateTransitionConvert for DataContractUpdateTransition { #[cfg(test)] mod test { - use std::convert::TryInto; use integer_encoding::VarInt; use serde_json::json; + use std::convert::TryInto; use crate::tests::fixtures::get_data_contract_fixture; use crate::version; @@ -216,13 +230,15 @@ mod test { let data_contract = get_data_contract_fixture(None); let value_map = BTreeMap::from([ - (PROTOCOL_VERSION.to_string(), Value::U32(version::LATEST_VERSION)), - (DATA_CONTRACT.to_string(), data_contract.try_into().unwrap()) + ( + PROTOCOL_VERSION.to_string(), + Value::U32(version::LATEST_VERSION), + ), + (DATA_CONTRACT.to_string(), data_contract.try_into().unwrap()), ]); - let state_transition = DataContractUpdateTransition::from_value_map(value_map) - .expect("state transition should be created without errors"); + .expect("state transition should be created without errors"); TestData { data_contract, diff --git a/packages/rs-dpp/src/data_contract/state_transition/errors/missing_data_contract_id_error.rs b/packages/rs-dpp/src/data_contract/state_transition/errors/missing_data_contract_id_error.rs index 28cb2bc2c91..f3d50e2c46e 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/errors/missing_data_contract_id_error.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/errors/missing_data_contract_id_error.rs @@ -1,8 +1,8 @@ use crate::consensus::basic::BasicError; -use thiserror::Error; use platform_value::Value; +use thiserror::Error; -#[derive(Error, Debug, Clone, PartialEq, Eq)] +#[derive(Error, Debug, Clone)] #[error("$dataContractId is not present")] pub struct MissingDataContractIdError { raw_document_transition: Value, diff --git a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs index 1ca8b6326b2..b9cd94ffca0 100644 --- a/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/reward_share_data_triggers/mod.rs @@ -3,14 +3,14 @@ use std::convert::TryInto; use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use serde_json::json; use platform_value::string_encoding::Encoding; +use serde_json::json; use crate::document::Document; use crate::{ data_trigger::create_error, document::document_transition::DocumentTransition, get_from_transition, mocks::SMLStore, prelude::Identifier, - ProtocolError, state_repository::StateRepositoryLike, + state_repository::StateRepositoryLike, ProtocolError, }; use super::{DataTriggerExecutionContext, DataTriggerExecutionResult}; @@ -150,18 +150,18 @@ mod test { use crate::{ data_contract::DataContract, data_trigger::DataTriggerExecutionContext, - DataTriggerError, document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, - mocks::{SimplifiedMNList, SMLEntry, SMLStore}, + mocks::{SMLEntry, SMLStore, SimplifiedMNList}, prelude::Identifier, state_repository::MockStateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, - StateError, tests::{ + tests::{ fixtures::{ get_document_transitions_fixture, get_masternode_reward_shares_documents_fixture, }, utils::generate_random_identifier_struct, }, + DataTriggerError, StateError, }; struct TestData { diff --git a/packages/rs-dpp/src/decode_protocol_entity_factory.rs b/packages/rs-dpp/src/decode_protocol_entity_factory.rs index dccf0e90e44..a993af75685 100644 --- a/packages/rs-dpp/src/decode_protocol_entity_factory.rs +++ b/packages/rs-dpp/src/decode_protocol_entity_factory.rs @@ -1,10 +1,9 @@ -use std::convert::TryInto; use anyhow::anyhow; use ciborium::value::Value as CborValue; +use std::convert::TryInto; use platform_value::Value; - use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::{errors::consensus::ConsensusError, errors::ProtocolError}; @@ -25,6 +24,9 @@ impl DecodeProtocolEntity { } })?; - Ok((protocol_version, cbor_value.try_into().map_err(ProtocolError::ValueError)?)) + Ok(( + protocol_version, + cbor_value.try_into().map_err(ProtocolError::ValueError)?, + )) } } diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index faa6e5c83ff..318f7b369b9 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -11,28 +11,28 @@ use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::consensus::basic::document::InvalidDocumentTypeError; -use crate::document::extended_document::{ExtendedDocument, property_names}; +use crate::document::extended_document::{property_names, ExtendedDocument}; use crate::data_contract::DriveContractExt; use crate::document::document_transition::INITIAL_REVISION; use crate::document::Document; use crate::identity::TimestampMillis; use crate::{ - data_contract::{DataContract, errors::DataContractError}, + data_contract::{errors::DataContractError, DataContract}, decode_protocol_entity_factory::DecodeProtocolEntity, prelude::Identifier, - ProtocolError, state_repository::StateRepositoryLike, util::entropy_generator, + ProtocolError, }; use super::{ document_transition::{self, Action}, document_validator::DocumentValidator, - DocumentsBatchTransition, errors::DocumentError, fetch_and_validate_data_contract::DataContractFetcherAndValidator, generate_document_id::generate_document_id, + DocumentsBatchTransition, }; // TODO remove these const and use ones from super::document::property_names @@ -280,10 +280,7 @@ where options: FactoryOptions, ) -> Result { let data_contract = self - .validate_data_contract_for_extended_document( - &raw_document, - options, - ) + .validate_data_contract_for_extended_document(&raw_document, options) .await?; ExtendedDocument::from_platform_value(raw_document, data_contract) @@ -432,9 +429,9 @@ where #[cfg(test)] mod test { use platform_value::btreemap_extensions::BTreeValueMapHelper; - use std::sync::Arc; - use serde_json::json; use platform_value::string_encoding::Encoding; + use serde_json::json; + use std::sync::Arc; use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 523badb29b6..c69b8e26301 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -2,11 +2,12 @@ use std::sync::Arc; use anyhow::anyhow; use lazy_static::lazy_static; -use serde_json::Value as JsonValue; use platform_value::Value; +use serde_json::Value as JsonValue; -use crate::data_contract::document_type::DocumentType; use crate::consensus::basic::document::InvalidDocumentTypeError; +use crate::data_contract::document_type::DocumentType; +use crate::data_contract::DriveContractExt; use crate::{ consensus::basic::BasicError, data_contract::{ @@ -18,7 +19,6 @@ use crate::{ version::ProtocolVersionValidator, ProtocolError, }; -use crate::data_contract::DriveContractExt; const PROPERTY_PROTOCOL_VERSION: &str = "$protocolVersion"; const PROPERTY_DOCUMENT_TYPE: &str = "$type"; @@ -115,7 +115,9 @@ impl DocumentValidator { } .map_err(|e| anyhow!("unable to process the contract: {}", e))?; - let json_value = raw_document.try_into_validating_json().map_err(ProtocolError::ValueError)?; + let json_value = raw_document + .try_into_validating_json() + .map_err(ProtocolError::ValueError)?; let json_schema_validation_result = json_schema_validator.validate(&json_value)?; result.merge(json_schema_validation_result); @@ -123,7 +125,9 @@ impl DocumentValidator { return Ok(result); } - let protocol_version = raw_document.get_integer(PROPERTY_PROTOCOL_VERSION).map_err(ProtocolError::ValueError)?; + let protocol_version = raw_document + .get_integer(PROPERTY_PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)?; result.merge(self.protocol_version_validator.validate(protocol_version)?); Ok(result) @@ -138,10 +142,10 @@ mod test { error::{TypeKind, ValidationErrorKind}, primitive_type::PrimitiveType, }; + use platform_value::Value; use serde_json::json; use serde_json::Value as JsonValue; use test_case::test_case; - use platform_value::Value; use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index 3fc08bed364..1a87c731ba8 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -1,5 +1,5 @@ -use thiserror::Error; use platform_value::Value; +use thiserror::Error; use crate::errors::consensus::ConsensusError; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index f887d0f1a4b..0bae0c16420 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -327,7 +327,11 @@ impl ExtendedDocument { pub fn into_map_value(self) -> Result, ProtocolError> { let ExtendedDocument { - protocol_version, document_type_name, data_contract_id, document, .. + protocol_version, + document_type_name, + data_contract_id, + document, + .. } = self; let mut object = document.into_map_value()?; @@ -460,9 +464,9 @@ mod test { use crate::document::Document; use crate::identifier::Identifier; use crate::tests::utils::*; - use platform_value::string_encoding::Encoding; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; + use platform_value::string_encoding::Encoding; use platform_value::Value; use pretty_assertions::assert_eq; diff --git a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs index cd0786c99f7..1ad12647e9d 100644 --- a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs +++ b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs @@ -1,7 +1,7 @@ use std::{convert::TryInto, sync::Arc}; -use serde_json::Value as JsonValue; use platform_value::Value; +use serde_json::Value as JsonValue; use crate::consensus::basic::invalid_identifier_error::InvalidIdentifierError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; @@ -61,7 +61,10 @@ pub async fn fetch_and_validate_data_contract( ) -> Result, ProtocolError> { let mut validation_result = ValidationResult::::default(); - let id_bytes = if let Some(id_bytes) = raw_extended_document.get_optional_hash256(property_names::DATA_CONTRACT_ID).map_err(ProtocolError::ValueError)? { + let id_bytes = if let Some(id_bytes) = raw_extended_document + .get_optional_hash256(property_names::DATA_CONTRACT_ID) + .map_err(ProtocolError::ValueError)? + { id_bytes } else { validation_result.add_error(ConsensusError::BasicError(Box::new( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 5ae5ad6d0c8..2b302e7972f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,12 +1,12 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; use std::convert::TryInto; use std::string::ToString; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::document::{Document, ExtendedDocument}; use crate::identity::TimestampMillis; @@ -217,29 +217,57 @@ mod test { } fn data_contract_with_dynamic_properties() -> DataContract { - let data_contract = json!({ - "protocolVersion" :0, - "$id" : vec![0_u8;32], - "$schema" : "schema", - "version" : 0, - "ownerId" : vec![0_u8;32], - "documents" : { - "test" : { - "properties" : { - "alphaIdentifier" : { - "type": "array", - "byteArray": true, - "contentMediaType": "application/x.dash.dpp.identifier", - }, - "alphaBinary" : { - "type": "array", - "byteArray": true, - } - } - } - } - }); - DataContract::from_json_raw_object(data_contract).unwrap() + // The following is equivalent to the data contract + // { + // "protocolVersion" :0, + // "$id" : vec![0_u8;32], + // "$schema" : "schema", + // "version" : 0, + // "ownerId" : vec![0_u8;32], + // "documents" : { + // "test" : { + // "properties" : { + // "alphaIdentifier" : { + // "type": "array", + // "byteArray": true, + // "contentMediaType": "application/x.dash.dpp.identifier", + // }, + // "alphaBinary" : { + // "type": "array", + // "byteArray": true, + // } + // } + // } + // } + // } + let test_document_properties_alpha_identifier = Value::from([ + ("type", Value::Text("array".to_string())), + ("byteArray", Value::Bool(true)), + ]); + let test_document_properties_alpha_binary = Value::from([ + ("type", Value::Text("array".to_string())), + ("byteArray", Value::Bool(true)), + ( + "contentMediaType", + Value::Text("application/x.dash.dpp.identifier".to_string()), + ), + ]); + let test_document_properties = Value::from([ + ("alphaIdentifier", test_document_properties_alpha_identifier), + ("alphaBinary", test_document_properties_alpha_binary), + ]); + let test_document = Value::from([("properties", test_document_properties)]); + let documents = Value::from([("test", test_document)]); + Value::from([ + ("protocolVersion", Value::U32(1)), + ("$id", Value::Identifier([0_u8; 32])), + ("$schema", Value::Text("schema".to_string())), + ("version", Value::U32(0)), + ("$ownerId", Value::Identifier([0_u8; 32])), + ("documents", documents), + ]) + .try_into() + .unwrap() } #[test] diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index fde709e8c6c..c860e593786 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -19,7 +19,6 @@ use crate::prelude::{DocumentTransition, Identifier}; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::util::cbor_value::{CborCanonicalMap, FieldType, ReplacePaths, ValuesCollection}; use crate::util::json_value::{JsonValueExt, ReplaceWith}; -use platform_value::string_encoding::Encoding; use crate::version::LATEST_VERSION; use crate::ProtocolError; use crate::{ @@ -29,6 +28,7 @@ use crate::{ StateTransitionType, }, }; +use platform_value::string_encoding::Encoding; use self::document_transition::{ document_base_transition, document_create_transition, DocumentTransitionExt, @@ -377,8 +377,10 @@ impl StateTransitionConvert for DocumentsBatchTransition { fn to_object(&self, skip_signature: bool) -> Result { let mut json_object: Value = platform_value::to_value(self)?; - json_object - .replace_at_paths(Self::identifiers_property_paths(), ReplacementType::Identifier)?; + json_object.replace_at_paths( + Self::identifiers_property_paths(), + ReplacementType::Identifier, + )?; if skip_signature { for path in Self::signature_property_paths() { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index d7ef3c0e663..e4c562dc9e3 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -7,7 +7,7 @@ use std::collections::BTreeMap; use crate::data_contract::DriveContractExt; use crate::{ document::document_transition::DocumentTransition, prelude::DataContract, - ProtocolError, util::json_schema::Index, + util::json_schema::Index, ProtocolError, }; #[macro_export] @@ -110,14 +110,14 @@ fn is_duplicate_by_indices(object1: &ValueMap, object2: &ValueMap, type_indices: #[cfg(test)] mod test { + use platform_value::string_encoding::Encoding; use platform_value::Value; use serde_json::json; use std::collections::BTreeMap; use std::convert::TryInto; - use platform_value::string_encoding::Encoding; use crate::data_contract::document_type::DocumentType; - use crate::{prelude::*}; + use crate::prelude::*; use super::find_duplicates_by_indices; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index a9eaf6b6dd8..a3bf07f8572 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -1,9 +1,9 @@ +use std::collections::BTreeMap; +use std::iter::Map; use std::{ collections::{hash_map::Entry, HashMap}, convert::{TryFrom, TryInto}, }; -use std::collections::BTreeMap; -use std::iter::Map; use crate::consensus::basic::document::{ DuplicateDocumentTransitionsWithIdsError, DuplicateDocumentTransitionsWithIndicesError, @@ -12,6 +12,7 @@ use crate::consensus::basic::document::{ }; use crate::consensus::basic::invalid_identifier_error::InvalidIdentifierError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; +use crate::document::state_transition::documents_batch_transition::property_names; use crate::document::validation::basic::find_duplicates_by_id::find_duplicates_by_id; use crate::{ consensus::basic::BasicError, @@ -32,11 +33,10 @@ use crate::{ }; use anyhow::anyhow; use lazy_static::lazy_static; -use platform_value::Value; -use serde_json::Value as JsonValue; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; -use crate::document::state_transition::documents_batch_transition::property_names; +use platform_value::Value; +use serde_json::Value as JsonValue; use super::{ find_duplicates_by_indices::find_duplicates_by_indices, @@ -81,16 +81,25 @@ pub async fn validate_documents_batch_transition_basic( ) })?; - let raw_state_transition_json = raw_state_transition.clone().try_into_validating_json().map_err(ProtocolError::ValueError)?; + let raw_state_transition_json = raw_state_transition + .clone() + .try_into_validating_json() + .map_err(ProtocolError::ValueError)?; let validation_result = validator.validate(&raw_state_transition_json)?; result.merge(validation_result); if !result.is_valid() { return Ok(result); } - let state_transition_map = raw_state_transition.to_btree_ref_map().map_err(ProtocolError::ValueError)?; + let state_transition_map = raw_state_transition + .to_btree_ref_map() + .map_err(ProtocolError::ValueError)?; - let owner_id = Identifier::from(state_transition_map.get_hash256_bytes(property_names::OWNER_ID).map_err(ProtocolError::ValueError)?); + let owner_id = Identifier::from( + state_transition_map + .get_hash256_bytes(property_names::OWNER_ID) + .map_err(ProtocolError::ValueError)?, + ); let protocol_version = state_transition_map.get_integer(property_names::PROTOCOL_VERSION)?; let validation_result = protocol_version_validator.validate(protocol_version)?; @@ -99,19 +108,23 @@ pub async fn validate_documents_batch_transition_basic( return Ok(result); } - let raw_document_transitions : Vec> = state_transition_map - .get_inner_map_in_array(property_names::TRANSITIONS).map_err(ProtocolError::ValueError)?; + let raw_document_transitions: Vec> = state_transition_map + .get_inner_map_in_array(property_names::TRANSITIONS) + .map_err(ProtocolError::ValueError)?; let mut document_transitions_by_contracts: HashMap>> = HashMap::new(); for raw_document_transition in raw_document_transitions { - let data_contract_id_bytes = match raw_document_transition.get_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? { - None => { result.add_error(BasicError::MissingDataContractIdError( + let data_contract_id_bytes = match raw_document_transition + .get_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? + { + None => { + result.add_error(BasicError::MissingDataContractIdError( MissingDataContractIdError::new(raw_document_transition.into()), )); continue; } - Some(id) => { id} + Some(id) => id, }; let identifier = Identifier::from(data_contract_id_bytes); @@ -209,7 +222,6 @@ fn validate_raw_transitions<'a>( ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); - for raw_document_transition in raw_document_transitions.iter() { let Some(document_type) = raw_document_transition.get_optional_str("$type").map_err(ProtocolError::ValueError) else { result.add_error(BasicError::MissingDocumentTransitionTypeError); @@ -218,10 +230,7 @@ fn validate_raw_transitions<'a>( if !data_contract.is_document_defined(document_type) { result.add_error(BasicError::InvalidDocumentTypeError( - InvalidDocumentTypeError::new( - document_type.to_string(), - data_contract.id.clone(), - ), + InvalidDocumentTypeError::new(document_type.to_string(), data_contract.id.clone()), )); return Ok(result); } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs index 815beb735d7..e0d59e90eca 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/fetch_extended_documents.rs @@ -5,15 +5,15 @@ use std::{ use futures::future::join_all; use itertools::Itertools; -use serde_json::json; use platform_value::string_encoding::Encoding; +use serde_json::json; use crate::document::ExtendedDocument; use crate::{ document::document_transition::DocumentTransition, get_from_transition, - ProtocolError, state_repository::StateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, + ProtocolError, }; pub async fn fetch_extended_documents( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index 061b962893b..02c5a75784c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -3,8 +3,8 @@ use std::convert::TryInto; use futures::future::join_all; use itertools::Itertools; -use crate::document::ExtendedDocument; use crate::data_contract::errors::DataContractNotPresentError; +use crate::document::ExtendedDocument; use crate::{ block_time_window::validate_time_in_block_time_window::validate_time_in_block_time_window, consensus::ConsensusError, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs index 023a2e36bed..ee84e831331 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs @@ -2,20 +2,18 @@ use std::convert::TryInto; use futures::future::join_all; use itertools::Itertools; -use serde_json::{json, Value as JsonValue}; use platform_value::string_encoding::Encoding; +use serde_json::{json, Value as JsonValue}; use crate::document::Document; use crate::{ document::document_transition::{Action, DocumentTransition, DocumentTransitionExt}, prelude::{DataContract, Identifier}, - ProtocolError, state_repository::StateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, - StateError, - util::{ - json_schema::{Index, JsonSchemaExt}, - }, validation::ValidationResult, + util::json_schema::{Index, JsonSchemaExt}, + validation::ValidationResult, + ProtocolError, StateError, }; struct QueryDefinition<'a> { diff --git a/packages/rs-dpp/src/identifier/mod.rs b/packages/rs-dpp/src/identifier/mod.rs index 25038faacdc..f270a7cd0fb 100644 --- a/packages/rs-dpp/src/identifier/mod.rs +++ b/packages/rs-dpp/src/identifier/mod.rs @@ -1,2 +1,2 @@ -pub use identifier::*; - +pub use platform_value::identifier::Identifier; +pub use platform_value::identifier::MEDIA_TYPE; diff --git a/packages/rs-dpp/src/identity/core_script.rs b/packages/rs-dpp/src/identity/core_script.rs index 8c4c51b577c..892dedc8863 100644 --- a/packages/rs-dpp/src/identity/core_script.rs +++ b/packages/rs-dpp/src/identity/core_script.rs @@ -1,8 +1,8 @@ use std::ops::Deref; use dashcore::Script as DashcoreScript; -use serde::{Deserialize, Serialize}; use platform_value::string_encoding::{self, Encoding}; +use serde::{Deserialize, Serialize}; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index c307c7092f3..07195ef8539 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -1,4 +1,3 @@ - use crate::decode_protocol_entity_factory::DecodeProtocolEntity; use crate::identifier::Identifier; use crate::identity::identity_public_key::factory::KeyCount; @@ -16,7 +15,7 @@ use crate::{BlsModule, ProtocolError}; use dashcore::{InstantLock, Transaction}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; -use serde_json::{Value as JsonValue}; +use serde_json::Value as JsonValue; use std::collections::BTreeMap; use std::convert::TryInto; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index 7964a93336f..a3470342f66 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -143,13 +143,28 @@ impl TryFrom<&Value> for AssetLockProof { fn try_from(value: &Value) -> Result { let proof_type_int: u8 = value - .get_integer("type").map_err(ProtocolError::ValueError)?; + .get_integer("type") + .map_err(ProtocolError::ValueError)?; let proof_type = AssetLockProofType::try_from(proof_type_int)?; match proof_type { - AssetLockProofType::Instant => { - Ok(Self::Instant(value.try_into()?)) - } + AssetLockProofType::Instant => Ok(Self::Instant(value.clone().try_into()?)), + AssetLockProofType::Chain => Ok(Self::Chain(value.clone().try_into()?)), + } + } +} + +impl TryFrom for AssetLockProof { + type Error = ProtocolError; + + fn try_from(value: Value) -> Result { + let proof_type_int: u8 = value + .get_integer("type") + .map_err(ProtocolError::ValueError)?; + let proof_type = AssetLockProofType::try_from(proof_type_int)?; + + match proof_type { + AssetLockProofType::Instant => Ok(Self::Instant(value.try_into()?)), AssetLockProofType::Chain => Ok(Self::Chain(value.try_into()?)), } } @@ -160,8 +175,8 @@ impl TryInto for AssetLockProof { fn try_into(self) -> Result { match self { - AssetLockProof::Instant(instant_proof) => serde_json::to_value(instant_proof), - AssetLockProof::Chain(chain_proof) => serde_json::to_value(chain_proof), + AssetLockProof::Instant(instant_proof) => platform_value::to_value(instant_proof), + AssetLockProof::Chain(chain_proof) => platform_value::to_value(chain_proof), } } } @@ -171,19 +186,19 @@ impl TryInto for &AssetLockProof { fn try_into(self) -> Result { match self { - AssetLockProof::Instant(instant_proof) => serde_json::to_value(instant_proof), - AssetLockProof::Chain(chain_proof) => serde_json::to_value(chain_proof), + AssetLockProof::Instant(instant_proof) => platform_value::to_value(instant_proof), + AssetLockProof::Chain(chain_proof) => platform_value::to_value(chain_proof), } } } -impl TryFrom<&AssetLockProof> for JsonValue { - type Error = serde_json::Error; +impl TryFrom<&AssetLockProof> for Value { + type Error = ProtocolError; fn try_from(asset_lock_proof: &AssetLockProof) -> Result { match asset_lock_proof { - AssetLockProof::Instant(instant_proof) => serde_json::to_value(instant_proof), - AssetLockProof::Chain(chain_proof) => serde_json::to_value(chain_proof), + AssetLockProof::Instant(instant_proof) => platform_value::to_value(instant_proof), + AssetLockProof::Chain(chain_proof) => platform_value::to_value(chain_proof), } } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index b528c2eda9d..6e90a7310f1 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -1,12 +1,12 @@ use std::convert::{TryFrom, TryInto}; +use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use platform_value::Value; use serde::de::Error as DeError; use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; -use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; -use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; @@ -16,8 +16,8 @@ use crate::state_transition::{ StateTransition, StateTransitionConvert, StateTransitionLike, StateTransitionType, }; use crate::util::json_value::JsonValueExt; -use platform_value::string_encoding::Encoding; use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; +use platform_value::string_encoding::Encoding; mod property_names { pub const PUBLIC_KEYS: &str = "publicKeys"; @@ -96,8 +96,13 @@ impl IdentityCreateTransition { pub fn new(raw_state_transition: Value) -> Result { let mut state_transition = Self::default(); - let mut transition_map = raw_state_transition.into_btree_map().map_err(ProtocolError::ValueError)?; - if let Some(keys_value_array) = transition_map.remove_optional_inner_value_array::>(property_names::PUBLIC_KEYS).map_err(ProtocolError::ValueError)? { + let mut transition_map = raw_state_transition + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + if let Some(keys_value_array) = transition_map + .remove_optional_inner_value_array::>(property_names::PUBLIC_KEYS) + .map_err(ProtocolError::ValueError)? + { let keys = keys_value_array .into_iter() .map(|val| val.try_into()) @@ -109,7 +114,8 @@ impl IdentityCreateTransition { state_transition.set_asset_lock_proof(AssetLockProof::try_from(proof)?)?; } - state_transition.protocol_version = transition_map.get_integer(property_names::PROTOCOL_VERSION)?; + state_transition.protocol_version = + transition_map.get_integer(property_names::PROTOCOL_VERSION)?; Ok(state_transition) } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index 6f9395b8f7e..aa2fd4796a0 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -1,22 +1,20 @@ use anyhow::anyhow; +use platform_value::string_encoding::{self, Encoding}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use serde_repr::{Deserialize_repr, Serialize_repr}; -use platform_value::string_encoding::{self, Encoding}; use crate::version::LATEST_VERSION; use crate::{ identity::{core_script::CoreScript, KeyID}, prelude::{Identifier, Revision}, - ProtocolError, state_transition::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::{ - json_value::{JsonValueExt, ReplaceWith}, - }, + util::json_value::{JsonValueExt, ReplaceWith}, + ProtocolError, }; use super::properties::{ diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 969ca9a72d3..ee063b8b4ba 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -1,13 +1,13 @@ -use std::collections::BTreeMap; use crate::identity::{IdentityPublicKey, KeyID, KeyType, Purpose, SecurityLevel}; use ciborium::value::Value as CborValue; +use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; -use serde::{Deserialize, Serialize}; -use serde_json::Value as JsonValue; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; use crate::errors::ProtocolError; use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; @@ -54,25 +54,59 @@ impl IdentityPublicKeyCreateTransition { pub fn from_raw_object(mut raw_object: Value) -> Result { Ok(Self { - id: raw_object.get_integer("id").map_err(ProtocolError::ValueError)?, - purpose: raw_object.get_integer::("purpose").map_err(ProtocolError::ValueError)?.try_into()?, - security_level: raw_object.get_integer::("securityLevel").map_err(ProtocolError::ValueError)?.try_into()?, - key_type: raw_object.get_integer::("keyType").map_err(ProtocolError::ValueError)?.try_into()?, - data: raw_object.remove_bytes("data").map_err(ProtocolError::ValueError)?, - read_only: raw_object.get_bool("readOnly").map_err(ProtocolError::ValueError)?, - signature: raw_object.remove_bytes("signature").map_err(ProtocolError::ValueError)?, + id: raw_object + .get_integer("id") + .map_err(ProtocolError::ValueError)?, + purpose: raw_object + .get_integer::("purpose") + .map_err(ProtocolError::ValueError)? + .try_into()?, + security_level: raw_object + .get_integer::("securityLevel") + .map_err(ProtocolError::ValueError)? + .try_into()?, + key_type: raw_object + .get_integer::("keyType") + .map_err(ProtocolError::ValueError)? + .try_into()?, + data: raw_object + .remove_bytes("data") + .map_err(ProtocolError::ValueError)?, + read_only: raw_object + .get_bool("readOnly") + .map_err(ProtocolError::ValueError)?, + signature: raw_object + .remove_bytes("signature") + .map_err(ProtocolError::ValueError)?, }) } pub fn from_value_map(mut value_map: BTreeMap) -> Result { Ok(Self { - id: value_map.get_integer("id").map_err(ProtocolError::ValueError)?, - purpose: value_map.get_integer::("purpose").map_err(ProtocolError::ValueError)?.try_into()?, - security_level: value_map.get_integer::("securityLevel").map_err(ProtocolError::ValueError)?.try_into()?, - key_type: value_map.get_integer::("keyType").map_err(ProtocolError::ValueError)?.try_into()?, - data: value_map.remove_bytes("data").map_err(ProtocolError::ValueError)?, - read_only: value_map.get_bool("readOnly").map_err(ProtocolError::ValueError)?, - signature: value_map.remove_bytes("signature").map_err(ProtocolError::ValueError)?, + id: value_map + .get_integer("id") + .map_err(ProtocolError::ValueError)?, + purpose: value_map + .get_integer::("purpose") + .map_err(ProtocolError::ValueError)? + .try_into()?, + security_level: value_map + .get_integer::("securityLevel") + .map_err(ProtocolError::ValueError)? + .try_into()?, + key_type: value_map + .get_integer::("keyType") + .map_err(ProtocolError::ValueError)? + .try_into()?, + data: value_map + .remove_bytes("data") + .map_err(ProtocolError::ValueError)?, + read_only: value_map + .get_bool("readOnly") + .map_err(ProtocolError::ValueError)?, + signature: value_map + .remove_bytes("signature") + .map_err(ProtocolError::ValueError)?, }) } @@ -90,16 +124,23 @@ impl IdentityPublicKeyCreateTransition { /// Return raw data, with all binary fields represented as arrays pub fn to_raw_object(&self, skip_signature: bool) -> Result { - let mut map = BTreeMap::from([("id".to_string(), Value::U32(self.id)), + let mut map = BTreeMap::from([ + ("id".to_string(), Value::U32(self.id)), ("purpose".to_string(), Value::U8(self.purpose as u8)), - ("securityLevel".to_string(), Value::U8(self.security_level as u8)), + ( + "securityLevel".to_string(), + Value::U8(self.security_level as u8), + ), ("keyType".to_string(), Value::U8(self.key_type as u8)), ("data".to_string(), Value::Bytes(self.data.clone())), ("readOnly".to_string(), Value::Bool(self.read_only)), ]); if !skip_signature && !self.signature.is_empty() { - map.insert("signature".to_string(), Value::Bytes(self.signature.clone())); + map.insert( + "signature".to_string(), + Value::Bytes(self.signature.clone()), + ); } Ok(map.into()) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index ff45bdf9f9f..41d2dff1dba 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -1,10 +1,10 @@ use std::convert::{TryFrom, TryInto}; +use platform_value::Value; use serde::de::Error as DeError; use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; -use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; use crate::identity::state_transition::identity_create_transition::SerializationOptions; @@ -14,9 +14,9 @@ use crate::state_transition::{ StateTransition, StateTransitionConvert, StateTransitionLike, StateTransitionType, }; use crate::util::json_value::JsonValueExt; -use platform_value::string_encoding::Encoding; use crate::version::LATEST_VERSION; use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; +use platform_value::string_encoding::Encoding; mod property_names { pub const ASSET_LOCK_PROOF: &str = "assetLockProof"; @@ -87,20 +87,24 @@ impl IdentityTopUpTransition { Self::from_raw_object(raw_state_transition) } - pub fn from_raw_object( - raw_object: Value, - ) -> Result { + pub fn from_raw_object(raw_object: Value) -> Result { let protocol_version = raw_object - .get_optional_integer(property_names::PROTOCOL_VERSION).map_err(ProtocolError::ValueError)? + .get_optional_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)? .unwrap_or(LATEST_VERSION); let signature = raw_object - .get_optional_bytes(property_names::SIGNATURE).map_err(ProtocolError::ValueError)? + .get_optional_bytes(property_names::SIGNATURE) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(); - let identity_id = - Identifier::from(raw_object.get_hash256(property_names::IDENTITY_ID).map_err(ProtocolError::ValueError)?); + let identity_id = Identifier::from( + raw_object + .get_hash256(property_names::IDENTITY_ID) + .map_err(ProtocolError::ValueError)?, + ); let raw_asset_lock_proof = raw_object - .get_value(property_names::ASSET_LOCK_PROOF).map_err(ProtocolError::ValueError)?; + .get_value(property_names::ASSET_LOCK_PROOF) + .map_err(ProtocolError::ValueError)?; let asset_lock_proof = AssetLockProof::try_from(raw_asset_lock_proof)?; Ok(IdentityTopUpTransition { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index e3dbd6b2e6e..4c0c1940766 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -1,6 +1,8 @@ use anyhow::anyhow; +use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use std::convert::TryInto; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; use crate::{ @@ -82,29 +84,35 @@ impl Default for IdentityUpdateTransition { } impl IdentityUpdateTransition { - pub fn new(raw_state_transition: serde_json::Value) -> Result { + pub fn new(raw_state_transition: Value) -> Result { IdentityUpdateTransition::from_raw_object(raw_state_transition) } pub fn from_raw_object( - mut raw_object: JsonValue, + mut raw_object: Value, ) -> Result { let protocol_version = raw_object - .get_u64(property_names::PROTOCOL_VERSION) - .unwrap_or(LATEST_VERSION as u64) as u32; + .get_optional_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)? + .unwrap_or(LATEST_VERSION); let signature = raw_object - .get_bytes(property_names::SIGNATURE) + .get_optional_bytes(property_names::SIGNATURE) + .map_err(ProtocolError::ValueError)? .unwrap_or_default(); let signature_public_key_id = raw_object .get_u64(property_names::SIGNATURE_PUBLIC_KEY_ID) .unwrap_or_default() as KeyID; - let identity_id = - Identifier::from_bytes(&raw_object.get_bytes(property_names::IDENTITY_ID)?)?; - let revision = raw_object.get_u64(property_names::REVISION)?; - let add_public_keys = - get_list_of_public_keys(&mut raw_object, property_names::ADD_PUBLIC_KEYS)?; - let disable_public_keys = - get_list_of_public_key_ids(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; + let identity_id = Identifier::from( + raw_object + .get_hash256(property_names::IDENTITY_ID) + .map_err(ProtocolError::ValueError)?, + ); + + let revision = raw_object + .get_integer(property_names::REVISION) + .map_err(ProtocolError::ValueError)?; + let add_public_keys = get_list(&mut raw_object, property_names::ADD_PUBLIC_KEYS)?; + let disable_public_keys = get_list(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; let public_keys_disabled_at = raw_object .remove_into::(property_names::PUBLIC_KEYS_DISABLED_AT) .ok(); @@ -190,50 +198,14 @@ impl IdentityUpdateTransition { /// if the property isn't present the empty list is returned. If property is defined, the function /// might return some serialization-related errors -fn get_list_of_public_keys( - value: &mut JsonValue, - property_name: &str, -) -> Result, ProtocolError> { - let mut identity_public_keys = vec![]; - if let Ok(maybe_list) = value.remove(property_names::ADD_PUBLIC_KEYS) { - if let JsonValue::Array(list) = maybe_list { - for maybe_public_key in list { - identity_public_keys.push(IdentityPublicKeyCreateTransition::from_raw_json_object( - maybe_public_key, - )?); - } - } else { - return Err(anyhow!("The property '{}' isn't a list", property_name).into()); - } - } else { - return Ok(vec![]); - } - - Ok(identity_public_keys) -} - -fn get_list_of_public_key_ids( - value: &mut JsonValue, - property_name: &str, -) -> Result, ProtocolError> { - if let Ok(maybe_key_ids) = value.remove(property_name) { - let key_ids: Vec = serde_json::from_value(maybe_key_ids)?; - Ok(key_ids) - } else { - Ok(vec![]) - } -} - -fn get_list_of_timestamps( - value: &mut JsonValue, - property_name: &str, -) -> Result, ProtocolError> { - if let Ok(maybe_timestamps) = value.remove(property_name) { - let timestamps: Vec = serde_json::from_value(maybe_timestamps)?; - Ok(timestamps) - } else { - Ok(vec![]) - } +fn get_list(value: &mut Value, property_name: &str) -> Result, ProtocolError> { + value + .remove_optional_array(property_name) + .map_err(ProtocolError::ValueError)? + .unwrap_or_default() + .into_iter() + .map(|value| value.try_into()) + .collect() } impl StateTransitionConvert for IdentityUpdateTransition { diff --git a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs index f968e8025f8..3a8b5f81630 100644 --- a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -1,4 +1,5 @@ -use serde_json::Value; +use platform_value::Value; +use serde_json::Value as JsonValue; use crate::consensus::basic::identity::InvalidIdentityKeySignatureError; use crate::consensus::basic::state_transition::InvalidStateTransitionTypeError; diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index 7b7eb2fe4d1..f7e8f9f6190 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -189,7 +189,6 @@ mod test { use crate::document::DocumentsBatchTransition; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; - use platform_value::string_encoding::Encoding; use crate::{ assert_error_contains, identity::{KeyID, SecurityLevel}, @@ -199,6 +198,7 @@ mod test { util::hash::ripemd160_sha256, NativeBlsModule, }; + use platform_value::string_encoding::Encoding; use super::StateTransitionIdentitySigned; use super::*; diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 40504c68434..49cf7209bb9 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -21,8 +21,8 @@ use crate::{ util::json_value::JsonValueExt, ProtocolError, }; -use serde_json::Value as JsonValue; use platform_value::Value; +use serde_json::Value as JsonValue; use super::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, @@ -119,9 +119,10 @@ async fn fetch_data_contracts_for_document_transition( pub fn try_get_transition_type( raw_state_transition: &Value, ) -> Result { - let transition_type : u8 = raw_state_transition + let transition_type: u8 = raw_state_transition .get_optional_integer("type") - .map_err(ProtocolError::ValueError)?.ok_or(missing_state_transition_error())?; + .map_err(ProtocolError::ValueError)? + .ok_or(missing_state_transition_error())?; StateTransitionType::try_from(transition_type).map_err(|_| { ProtocolError::InvalidStateTransitionTypeError(InvalidStateTransitionTypeError::new( transition_type, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 2b6a9fbea8d..86f66a019ae 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -1,7 +1,7 @@ use futures::StreamExt; use mockall::predicate; -use serde_json::json; use platform_value::string_encoding::Encoding; +use serde_json::json; use crate::{consensus::ConsensusError, data_contract::DataContract, document::{ document_transition::{Action, DocumentTransition}, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs index 5cbfa3b4cd3..3bf46f3f9dc 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_partial_compound_indices_spec.rs @@ -1,6 +1,4 @@ use platform_value::Value; -use serde_json::Value as JsonValue; -use std::convert::TryInto; use crate::{ consensus::{basic::BasicError, ConsensusError}, diff --git a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs index 34498e0cf9b..7e45ee31314 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs @@ -1,35 +1,43 @@ use std::convert::TryInto; -use std::str::FromStr; use dashcore::PrivateKey; use platform_value::Value; use crate::identity::{KeyType, Purpose, SecurityLevel}; use crate::tests::fixtures::instant_asset_lock_proof_fixture; -use platform_value::string_encoding::{decode, Encoding}; use crate::version; +use platform_value::string_encoding::{decode, Encoding}; //3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT //[198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237] -pub fn identity_create_transition_fixture_json( - one_time_private_key: Option, -) -> Value { +pub fn identity_create_transition_fixture_json(one_time_private_key: Option) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); - let read_only = false; - let signature = vec![0_u8; 65]; - - let public_keys = vec![Value::from([("id", Value::U32(version::LATEST_VERSION)), - ("type", Value::U8(2)), - ("data", Value::Bytes(decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap())), - ("purpose": Value::U8(Purpose::AUTHENTICATION)), - ("securityLevel": Value::U8(SecurityLevel::MASTER)), - ("readOnly": Value::Bool(read_only)), - ("signature": Value::Bytes(signature))])]; + let public_keys = vec![Value::from([ + ("id", Value::U32(0)), + ("type", Value::U8(2)), + ( + "data", + Value::Bytes( + decode( + "AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", + Encoding::Base64, + ) + .unwrap(), + ), + ), + ("purpose", Value::U8(Purpose::AUTHENTICATION as u8)), + ("keyType", Value::U8(KeyType::ECDSA_SECP256K1 as u8)), + ("securityLevel", Value::U8(SecurityLevel::MASTER as u8)), + ("readOnly", Value::Bool(false)), + ("signature", Value::Bytes(vec![0_u8; 65])), + ])]; - Value::from([("protocolVersion", Value::U32(version::LATEST_VERSION)), - ("type", Value::U8(2)), - ("assetLockProof", asset_lock_proof.try_into().unwrap()), - ("publicKeys": Value::Array(public_keys)), - ("signature": Value::Bytes(signature))]) + Value::from([ + ("protocolVersion", Value::U32(version::LATEST_VERSION)), + ("type", Value::U8(2)), + ("assetLockProof", asset_lock_proof.try_into().unwrap()), + ("publicKeys", Value::Array(public_keys)), + ("signature", Value::Bytes(vec![0_u8; 65])), + ]) } diff --git a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs index 5841b4b4c2e..6ce9abe37ab 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs @@ -1,11 +1,10 @@ use dashcore::{hashes::hex::FromHex, PubkeyHash, Script}; -use serde_json::{json, Value}; use platform_value::string_encoding::{encode, Encoding}; +use serde_json::{json, Value}; use crate::{ identity::state_transition::identity_credit_withdrawal_transition::Pooling, - state_transition::StateTransitionType, - version, + state_transition::StateTransitionType, version, }; pub fn identity_credit_withdrawal_transition_fixture_raw_object() -> Value { diff --git a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs index 1733891be85..1c902cc4bf4 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs @@ -1,5 +1,5 @@ -use serde_json::json; use platform_value::string_encoding::{decode, Encoding}; +use serde_json::json; use crate::prelude::Identity; diff --git a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs index 9a5cc406607..a8fd1ee7697 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs @@ -1,8 +1,6 @@ use std::convert::TryInto; -use std::str::FromStr; use dashcore::PrivateKey; -use serde_json::{json, Value as JsonValue}; use platform_value::Value; use crate::state_transition::StateTransitionType; @@ -12,16 +10,20 @@ use crate::version; //3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT //[198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237] -pub fn identity_topup_transition_fixture_json( - one_time_private_key: Option, -) -> Value { +pub fn identity_topup_transition_fixture_json(one_time_private_key: Option) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); - let identity = Value::Identifier([198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237]); - let signature = vec![0_u8; 65]; - Value::from([("protocolVersion", Value::U32(version::LATEST_VERSION)), + Value::from([ + ("protocolVersion", Value::U32(version::LATEST_VERSION)), ("type", Value::U8(2)), ("assetLockProof", asset_lock_proof.try_into().unwrap()), - ("identityId": Value::Array(public_keys)), - ("signature": Value::Bytes(signature))]) + ( + "identityId", + Value::Identifier([ + 198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, + 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237, + ]), + ), + ("signature", Value::Bytes(vec![0_u8; 65])), + ]) } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs index 752fd4a9cc1..1933e3dc60f 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory_spec.rs @@ -10,7 +10,6 @@ mod apply_identity_credit_withdrawal_transition_factory { use crate::document::ExtendedDocument; use crate::{ contracts::withdrawals_contract, - document::Document, identity::state_transition::identity_credit_withdrawal_transition::{ apply_identity_credit_withdrawal_transition_factory::ApplyIdentityCreditWithdrawalTransition, IdentityCreditWithdrawalTransition, Pooling, diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index 71172ccb627..e8b54b27a16 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -1,12 +1,12 @@ use chrono::Utc; -use serde_json::{json, Value as JsonValue}; use platform_value::string_encoding::Encoding; +use serde_json::{json, Value as JsonValue}; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; use crate::{ identity::{ - KeyType, - Purpose, SecurityLevel, state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, + state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, + KeyType, Purpose, SecurityLevel, }, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionType, diff --git a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs index 4c1b9aaf2d2..b734b134599 100644 --- a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs @@ -1,11 +1,9 @@ -use crate::{ - identity::{ - KeyType, - Purpose, SecurityLevel, validation::{RequiredPurposeAndSecurityLevelValidator, TPublicKeysValidator}, - }, +use crate::identity::{ + validation::{RequiredPurposeAndSecurityLevelValidator, TPublicKeysValidator}, + KeyType, Purpose, SecurityLevel, }; -use serde_json::json; use platform_value::string_encoding::{decode, Encoding}; +use serde_json::json; #[test] fn should_return_invalid_result_if_state_transition_does_not_contain_master_key() { diff --git a/packages/rs-dpp/src/util/cbor_value/canonical.rs b/packages/rs-dpp/src/util/cbor_value/canonical.rs index 71b326e1189..c645f65b14b 100644 --- a/packages/rs-dpp/src/util/cbor_value/canonical.rs +++ b/packages/rs-dpp/src/util/cbor_value/canonical.rs @@ -6,17 +6,13 @@ use std::{ use anyhow::anyhow; use ciborium::value::Value as CborValue; -use serde::Serialize; use platform_value::string_encoding::Encoding; +use serde::Serialize; -use crate::{ - prelude::Identifier, - ProtocolError, - util::json_value::ReplaceWith, -}; +use crate::{prelude::Identifier, util::json_value::ReplaceWith, ProtocolError}; use super::{ - convert::convert_to, FieldType, get_from_cbor_map, ReplacePaths, to_path_of_cbors, + convert::convert_to, get_from_cbor_map, to_path_of_cbors, FieldType, ReplacePaths, ValuesCollection, }; diff --git a/packages/rs-dpp/src/util/json_value/mod.rs b/packages/rs-dpp/src/util/json_value/mod.rs index 4b42a8b2269..0ebe99b8ba8 100644 --- a/packages/rs-dpp/src/util/json_value/mod.rs +++ b/packages/rs-dpp/src/util/json_value/mod.rs @@ -10,9 +10,7 @@ use crate::{ identifier::{self, Identifier}, }; -use super::{ - json_path::{JsonPath, JsonPathLiteral, JsonPathStep}, -}; +use super::json_path::{JsonPath, JsonPathLiteral, JsonPathStep}; mod insert_with_path; use insert_with_path::*; diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 794c282b30b..35f516e8310 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -43,7 +43,6 @@ use drive::dpp::identity::{ }; use drive::dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; -use platform_value::string_encoding::{encode, Encoding}; use drive::drive::batch::{ ContractOperationType, DocumentOperationType, DriveOperationType, IdentityOperationType, }; @@ -51,6 +50,7 @@ use drive::drive::block_info::BlockInfo; use drive::drive::defaults::PROTOCOL_VERSION; use drive::drive::object_size_info::{DocumentAndContractInfo, DocumentInfo, OwnedDocumentInfo}; use drive::query::TransactionArg; +use platform_value::string_encoding::{encode, Encoding}; use serde_json::json; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet}; diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions.rs index 92fcaa7abe0..83cf6936ddc 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions.rs @@ -366,9 +366,8 @@ where } fn get_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error> { - self.get_optional_hash256_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get hash256 property {key}")) - }) + self.get_optional_hash256_bytes(key)? + .ok_or_else(|| Error::StructureError(format!("unable to get hash256 property {key}"))) } fn get_optional_bytes(&self, key: &str) -> Result>, Error> { @@ -376,9 +375,8 @@ where } fn get_bytes(&self, key: &str) -> Result, Error> { - self.get_optional_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get bytes property {key}")) - }) + self.get_optional_bytes(key)? + .ok_or_else(|| Error::StructureError(format!("unable to get bytes property {key}"))) } fn get_optional_identifier_bytes(&self, key: &str) -> Result>, Error> { @@ -388,9 +386,8 @@ where } fn get_identifier_bytes(&self, key: &str) -> Result, Error> { - self.get_optional_identifier_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get bytes property {key}")) - }) + self.get_optional_identifier_bytes(key)? + .ok_or_else(|| Error::StructureError(format!("unable to get bytes property {key}"))) } fn get_optional_binary_bytes(&self, key: &str) -> Result>, Error> { @@ -400,9 +397,8 @@ where } fn get_binary_bytes(&self, key: &str) -> Result, Error> { - self.get_optional_binary_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to get bytes property {key}")) - }) + self.get_optional_binary_bytes(key)? + .ok_or_else(|| Error::StructureError(format!("unable to get bytes property {key}"))) } fn get_optional_float(&self, key: &str) -> Result, Error> { diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_field_replacement.rs index 13b7d7e4359..a71ea025a15 100644 --- a/packages/rs-platform-value/src/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_field_replacement.rs @@ -16,11 +16,13 @@ pub enum ReplacementType { impl ReplacementType { pub fn replace_for_bytes(&self, bytes: Vec) -> Result { match self { - ReplacementType::Identifier => Ok(Value::Identifier( - bytes - .try_into() - .map_err(|_| Error::ByteLengthNot32BytesError)?, - )), + ReplacementType::Identifier => { + Ok(Value::Identifier(bytes.try_into().map_err(|_| { + Error::ByteLengthNot32BytesError(String::from( + "Trying to replace into an identifier, but not 32 bytes long", + )) + })?)) + } ReplacementType::Bytes => Ok(Value::Bytes(bytes)), ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), @@ -29,11 +31,7 @@ impl ReplacementType { pub fn replace_for_bytes_32(&self, bytes: [u8; 32]) -> Result { match self { - ReplacementType::Identifier => Ok(Value::Identifier( - bytes - .try_into() - .map_err(|_| Error::ByteLengthNot32BytesError)?, - )), + ReplacementType::Identifier => Ok(Value::Identifier(bytes)), ReplacementType::Bytes => Ok(Value::Bytes32(bytes)), ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_path_extensions.rs index fad78a7df8e..c56c659f085 100644 --- a/packages/rs-platform-value/src/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_path_extensions.rs @@ -81,10 +81,7 @@ pub trait BTreeValueMapPathHelper { &self, path: &str, ) -> Result; - fn get_optional_hash256_bytes_at_path( - &self, - path: &str, - ) -> Result, Error>; + fn get_optional_hash256_bytes_at_path(&self, path: &str) -> Result, Error>; fn get_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error>; fn get_optional_identifier_bytes_at_path(&self, path: &str) -> Result>, Error>; fn get_identifier_bytes_at_path(&self, path: &str) -> Result, Error>; @@ -463,10 +460,7 @@ where }) } - fn get_optional_hash256_bytes_at_path( - &self, - path: &str, - ) -> Result, Error> { + fn get_optional_hash256_bytes_at_path(&self, path: &str) -> Result, Error> { self.get_optional_at_path(path)? .map(|v| v.borrow().to_hash256()) .transpose() @@ -474,9 +468,7 @@ where fn get_hash256_bytes_at_path(&self, path: &str) -> Result<[u8; 32], Error> { self.get_optional_hash256_bytes_at_path(path)? - .ok_or_else(|| { - Error::StructureError(format!("unable to get hash256 property {path}")) - }) + .ok_or_else(|| Error::StructureError(format!("unable to get hash256 property {path}"))) } fn get_optional_bytes_at_path(&self, path: &str) -> Result>, Error> { diff --git a/packages/rs-platform-value/src/btreemap_removal_extensions.rs b/packages/rs-platform-value/src/btreemap_removal_extensions.rs index ca902bd0794..3df915d54ff 100644 --- a/packages/rs-platform-value/src/btreemap_removal_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_removal_extensions.rs @@ -1,5 +1,5 @@ -use std::collections::BTreeMap; use crate::{Error, Value}; +use std::collections::BTreeMap; pub trait BTreeValueRemoveFromMapHelper { fn remove_optional_string(&mut self, key: &str) -> Result, Error>; @@ -7,8 +7,8 @@ pub trait BTreeValueRemoveFromMapHelper { fn remove_optional_float(&mut self, key: &str) -> Result, Error>; fn remove_float(&mut self, key: &str) -> Result; fn remove_optional_integer(&mut self, key: &str) -> Result, Error> - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -19,8 +19,8 @@ pub trait BTreeValueRemoveFromMapHelper { + TryFrom + TryFrom; fn remove_integer(&mut self, key: &str) -> Result - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -40,8 +40,8 @@ pub trait BTreeValueRemoveFromMapHelper { impl BTreeValueRemoveFromMapHelper for BTreeMap { fn remove_optional_integer(&mut self, key: &str) -> Result, Error> - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -64,8 +64,8 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { } fn remove_integer(&mut self, key: &str) -> Result - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -81,7 +81,6 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { }) } - fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { self.remove(key) .and_then(|v| { @@ -113,20 +112,13 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { } fn remove_bytes(&mut self, key: &str) -> Result, Error> { - self.remove_optional_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to remove bytes property {key}")) - }) + self.remove_optional_bytes(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove bytes property {key}"))) } fn remove_optional_string(&mut self, key: &str) -> Result, Error> { self.remove(key) - .and_then(|v| { - if v.is_null() { - None - } else { - Some(v.to_text()) - } - }) + .and_then(|v| if v.is_null() { None } else { Some(v.to_text()) }) .transpose() } @@ -154,13 +146,7 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { fn remove_optional_bool(&mut self, key: &str) -> Result, Error> { self.remove(key) - .and_then(|v| { - if v.is_null() { - None - } else { - Some(v.to_bool()) - } - }) + .and_then(|v| if v.is_null() { None } else { Some(v.to_bool()) }) .transpose() } @@ -172,8 +158,8 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { impl BTreeValueRemoveFromMapHelper for BTreeMap { fn remove_optional_integer(&mut self, key: &str) -> Result, Error> - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -196,8 +182,8 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { } fn remove_integer(&mut self, key: &str) -> Result - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -213,7 +199,6 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { }) } - fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { self.remove(key) .and_then(|v| { @@ -245,9 +230,8 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { } fn remove_bytes(&mut self, key: &str) -> Result, Error> { - self.remove_optional_bytes(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to remove bytes property {key}")) - }) + self.remove_optional_bytes(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove bytes property {key}"))) } fn remove_optional_string(&mut self, key: &str) -> Result, Error> { @@ -300,4 +284,4 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { self.remove_optional_bool(key)? .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs b/packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs index 56a8d941498..7af5130201c 100644 --- a/packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs @@ -1,15 +1,12 @@ -use std::collections::BTreeMap; use crate::{Error, Value}; +use std::collections::BTreeMap; pub trait BTreeValueRemoveInnerValueFromMapHelper { fn remove_optional_inner_value_array>( &mut self, key: &str, ) -> Result, Error>; - fn remove_inner_value_array>( - &mut self, - key: &str, - ) -> Result; + fn remove_inner_value_array>(&mut self, key: &str) -> Result; } impl BTreeValueRemoveInnerValueFromMapHelper for BTreeMap { @@ -18,20 +15,12 @@ impl BTreeValueRemoveInnerValueFromMapHelper for BTreeMap { key: &str, ) -> Result, Error> { self.remove(key) - .map(|v| { - v - .into_array() - .map(|vec| vec.into_iter().collect()) - }) + .map(|v| v.into_array().map(|vec| vec.into_iter().collect())) .transpose() } - fn remove_inner_value_array>( - &mut self, - key: &str, - ) -> Result { + fn remove_inner_value_array>(&mut self, key: &str) -> Result { self.remove_optional_inner_value_array(key)? .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) } - -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 29b9a6849e2..231aab16ec3 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -1,7 +1,7 @@ +use crate::value_map::ValueMap; use crate::{Error, Value}; use ciborium::value::Integer; use ciborium::Value as CborValue; -use crate::value_map::ValueMap; impl Value { pub fn convert_from_cbor_map(map: I) -> Result @@ -36,7 +36,11 @@ impl TryFrom for Value { CborValue::Text(string) => Self::Text(string), CborValue::Bool(value) => Self::Bool(value), CborValue::Null => Self::Null, - CborValue::Tag(int, value) => { return Err(Error::Unsupported("conversion from cbor tags are currently not supported".to_string())) }, + CborValue::Tag(int, value) => { + return Err(Error::Unsupported( + "conversion from cbor tags are currently not supported".to_string(), + )) + } CborValue::Array(array) => { if !array.is_empty() && array.iter().all(|v| { @@ -54,12 +58,19 @@ impl TryFrom for Value { .collect(), ) } else { - Self::Array(array.into_iter().map(|v| v.try_into()).collect::, Error>>()?) + Self::Array( + array + .into_iter() + .map(|v| v.try_into()) + .collect::, Error>>()?, + ) } } - CborValue::Map(map) => { - Self::Map(map.into_iter().map(|(k, v)| Ok((k.try_into()?, v.try_into()?))).collect::>()?) - } + CborValue::Map(map) => Self::Map( + map.into_iter() + .map(|(k, v)| Ok((k.try_into()?, v.try_into()?))) + .collect::>()?, + ), _ => panic!("unsupported"), }) } diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 7bf8f9e9870..cccabbddef7 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -1,7 +1,7 @@ +use crate::value_map::ValueMap; use crate::{Error, Value}; use serde_json::{Map, Number, Value as JsonValue}; use std::collections::BTreeMap; -use crate::value_map::ValueMap; impl Value { pub fn convert_from_serde_json_map(map: I) -> R @@ -18,19 +18,19 @@ impl Value { Ok(match self { Value::U128(i) => { if i > u64::MAX as u128 { - return Err(Error::IntegerSizeError) + return Err(Error::IntegerSizeError); } JsonValue::Number((i as u64).into()) - }, + } Value::I128(i) => { if i > i64::MAX as i128 { - return Err(Error::IntegerSizeError) + return Err(Error::IntegerSizeError); } if i < i64::MIN as i128 { - return Err(Error::IntegerSizeError) + return Err(Error::IntegerSizeError); } JsonValue::Number((i as i64).into()) - }, + } Value::U64(i) => JsonValue::Number(i.into()), Value::I64(i) => JsonValue::Number(i.into()), Value::U32(i) => JsonValue::Number(i.into()), @@ -82,26 +82,29 @@ impl Value { } pub fn try_into_validating_btree_map_json(self) -> Result, Error> { - self.into_btree_map()?.into_iter().map(|(key, value)| Ok((key, value.try_into_validating_json()?))).collect() + self.into_btree_map()? + .into_iter() + .map(|(key, value)| Ok((key, value.try_into_validating_json()?))) + .collect() } pub fn try_to_validating_json(&self) -> Result { Ok(match self { Value::U128(i) => { if *i > u64::MAX as u128 { - return Err(Error::IntegerSizeError) + return Err(Error::IntegerSizeError); } JsonValue::Number((*i as u64).into()) - }, + } Value::I128(i) => { if *i > i64::MAX as i128 { - return Err(Error::IntegerSizeError) + return Err(Error::IntegerSizeError); } if *i < i64::MIN as i128 { - return Err(Error::IntegerSizeError) + return Err(Error::IntegerSizeError); } JsonValue::Number((*i as i64).into()) - }, + } Value::U64(i) => JsonValue::Number((*i).into()), Value::I64(i) => JsonValue::Number((*i).into()), Value::U32(i) => JsonValue::Number((*i).into()), @@ -217,11 +220,11 @@ impl From<&JsonValue> for Value { let u8_max = u8::MAX as u64; if !array.is_empty() && array.iter().all(|v| { - let Some(int) = v.as_u64() else { + let Some(int) = v.as_u64() else { return false; }; - int.le(&u8_max) - }) + int.le(&u8_max) + }) { //this is an array of bytes Self::Bytes( @@ -234,9 +237,11 @@ impl From<&JsonValue> for Value { Self::Array(array.into_iter().map(|v| v.into()).collect()) } } - JsonValue::Object(map) => { - Self::Map(map.into_iter().map(|(k, v)| (k.clone().into(), v.into())).collect()) - } + JsonValue::Object(map) => Self::Map( + map.into_iter() + .map(|(k, v)| (k.clone().into(), v.into())) + .collect(), + ), } } } @@ -363,21 +368,26 @@ impl BTreeValueRefJsonConverter for BTreeMap { impl From> for Value { fn from(value: BTreeMap) -> Self { - let map : ValueMap = value.into_iter().map(|(key, json_value)|{ - let value : Value = json_value.into(); - (Value::Text(key), value) - } ).collect(); + let map: ValueMap = value + .into_iter() + .map(|(key, json_value)| { + let value: Value = json_value.into(); + (Value::Text(key), value) + }) + .collect(); Value::Map(map) } } - impl From<&BTreeMap> for Value { fn from(value: &BTreeMap) -> Self { - let map : ValueMap = value.iter().map(|(key, json_value)|{ - let value : Value = json_value.into(); - (Value::Text(key.clone()), value) - } ).collect(); + let map: ValueMap = value + .iter() + .map(|(key, json_value)| { + let value: Value = json_value.into(); + (Value::Text(key.clone()), value) + }) + .collect(); Value::Map(map) } } diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index 081e4ae321e..089f25faf3f 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -22,13 +22,15 @@ pub enum Error { #[error("key must be a string")] KeyMustBeAString, - #[error("byte length not 32 bytes error")] - ByteLengthNot32BytesError, + #[error("byte length not 32 bytes error: {0}")] + ByteLengthNot32BytesError(String), } impl serde::ser::Error for Error { - fn custom(msg: T) -> Self where T: Display { + fn custom(msg: T) -> Self + where + T: Display, + { todo!() } } - diff --git a/packages/rs-platform-value/src/identifier.rs b/packages/rs-platform-value/src/identifier.rs index 5b84b5fbc8e..3df17301932 100644 --- a/packages/rs-platform-value/src/identifier.rs +++ b/packages/rs-platform-value/src/identifier.rs @@ -5,9 +5,8 @@ use std::convert::{TryFrom, TryInto}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; -use crate::errors::ProtocolError; -use crate::util::string_encoding; -use crate::util::string_encoding::Encoding; +use crate::string_encoding::Encoding; +use crate::{string_encoding, Error}; pub const MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; @@ -47,10 +46,7 @@ impl Identifier { self.buffer.as_slice() } - pub fn from_string( - encoded_value: &str, - encoding: Encoding, - ) -> Result { + pub fn from_string(encoded_value: &str, encoding: Encoding) -> Result { let vec = string_encoding::decode(encoded_value, encoding)?; Identifier::from_bytes(&vec) @@ -59,16 +55,16 @@ impl Identifier { pub fn from_string_with_encoding_string( encoded_value: &str, encoding_string: Option<&str>, - ) -> Result { + ) -> Result { let encoding = encoding_string_to_encoding(encoding_string); Identifier::from_string(encoded_value, encoding) } // TODO the constructor "From" shouldn't use the reference to collection - pub fn from_bytes(bytes: &[u8]) -> Result { + pub fn from_bytes(bytes: &[u8]) -> Result { if bytes.len() != 32 { - return Err(ProtocolError::IdentifierError(String::from( + return Err(Error::ByteLengthNot32BytesError(String::from( "Identifier must be 32 bytes long", ))); } @@ -106,7 +102,7 @@ impl Identifier { } impl TryFrom<&[u8]> for Identifier { - type Error = ProtocolError; + type Error = Error; fn try_from(bytes: &[u8]) -> Result { Self::from_bytes(bytes) @@ -114,7 +110,7 @@ impl TryFrom<&[u8]> for Identifier { } impl TryFrom> for Identifier { - type Error = ProtocolError; + type Error = Error; fn try_from(bytes: Vec) -> Result { Self::from_bytes(&bytes) @@ -122,7 +118,7 @@ impl TryFrom> for Identifier { } impl TryFrom for Identifier { - type Error = ProtocolError; + type Error = Error; fn try_from(data: String) -> Result { Self::from_string(&data, Encoding::Base58) diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 2978f3a41cf..7611b9082c0 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -30,8 +30,8 @@ impl Value { } pub fn remove_integer(&mut self, key: &str) -> Result - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -40,15 +40,16 @@ impl Value { + TryFrom + TryFrom + TryFrom - + TryFrom { + + TryFrom, + { let map = self.as_map_mut_ref()?; let value = map.remove_key(key)?; value.into_integer() } pub fn remove_optional_integer(&mut self, key: &str) -> Result, Error> - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -57,20 +58,28 @@ impl Value { + TryFrom + TryFrom + TryFrom - + TryFrom { + + TryFrom, + { let map = self.as_map_mut_ref()?; - map.remove_optional_key(key).map(|v| v.into_integer()).transpose() + map.remove_optional_key(key) + .map(|v| v.into_integer()) + .transpose() } - pub fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8;32], Error> { + pub fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error> { let map = self.as_map_mut_ref()?; let value = map.remove_key(key)?; value.into_hash256() } - pub fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { + pub fn remove_optional_hash256_bytes( + &mut self, + key: &str, + ) -> Result, Error> { let map = self.as_map_mut_ref()?; - map.remove_optional_key(key).map(|v| v.into_hash256()).transpose() + map.remove_optional_key(key) + .map(|v| v.into_hash256()) + .transpose() } pub fn remove_bytes(&mut self, key: &str) -> Result, Error> { @@ -81,12 +90,27 @@ impl Value { pub fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { let map = self.as_map_mut_ref()?; - map.remove_optional_key(key).map(|v| v.into_bytes()).transpose() + map.remove_optional_key(key) + .map(|v| v.into_bytes()) + .transpose() + } + + pub fn remove_array(&mut self, key: &str) -> Result, Error> { + let map = self.as_map_mut_ref()?; + let value = map.remove_key(key)?; + value.to_array() + } + + pub fn remove_optional_array(&mut self, key: &str) -> Result>, Error> { + let map = self.as_map_mut_ref()?; + map.remove_optional_key(key) + .map(|v| v.to_array()) + .transpose() } pub fn get_optional_integer(&self, key: &str) -> Result, Error> - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -95,14 +119,15 @@ impl Value { + TryFrom + TryFrom + TryFrom - + TryFrom { + + TryFrom, + { let map = self.to_map()?; Self::inner_optional_integer_value(map, key) } pub fn get_integer(&self, key: &str) -> Result - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -111,7 +136,8 @@ impl Value { + TryFrom + TryFrom + TryFrom - + TryFrom { + + TryFrom, + { let map = self.to_map()?; Self::inner_integer_value(map, key) } @@ -126,6 +152,16 @@ impl Value { Self::inner_text_value(map, key) } + pub fn get_optional_bool(&self, key: &str) -> Result, Error> { + let map = self.to_map()?; + Self::inner_optional_bool_value(map, key) + } + + pub fn get_bool<'a>(&'a self, key: &'a str) -> Result { + let map = self.to_map()?; + Self::inner_bool_value(map, key) + } + pub fn get_optional_bytes<'a>(&'a self, key: &'a str) -> Result>, Error> { let map = self.to_map()?; Self::inner_optional_bytes_value(map, key) @@ -191,18 +227,27 @@ impl Value { } /// Gets the inner bool value from a map - pub fn inner_optional_bool_value(document_type: &[(Value, Value)], key: &str) -> Option { - let key_value = Self::get_optional_from_map(document_type, key)?; - if let Value::Bool(bool_value) = key_value { - return Some(*bool_value); - } - None + pub fn inner_optional_bool_value( + document_type: &[(Value, Value)], + key: &str, + ) -> Result, Error> { + Self::get_optional_from_map(document_type, key) + .map(|value| value.to_bool()) + .transpose() + } + + /// Gets the inner bool value from a map + pub fn inner_bool_value(document_type: &[(Value, Value)], key: &str) -> Result { + Self::get_from_map(document_type, key).map(|value| value.to_bool())? } /// Gets the inner integer value from a map if it exists - pub fn inner_optional_integer_value(document_type: &[(Value, Value)], key: &str) -> Result, Error> - where - T: TryFrom + pub fn inner_optional_integer_value( + document_type: &[(Value, Value)], + key: &str, + ) -> Result, Error> + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -211,14 +256,17 @@ impl Value { + TryFrom + TryFrom + TryFrom - + TryFrom { - Self::get_optional_from_map(document_type, key).map(|key_value| key_value.to_integer()).transpose() + + TryFrom, + { + Self::get_optional_from_map(document_type, key) + .map(|key_value| key_value.to_integer()) + .transpose() } /// Gets the inner integer value from a map pub fn inner_integer_value(document_type: &[(Value, Value)], key: &str) -> Result - where - T: TryFrom + where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -227,7 +275,8 @@ impl Value { + TryFrom + TryFrom + TryFrom - + TryFrom { + + TryFrom, + { let key_value = Self::get_from_map(document_type, key)?; key_value.to_integer() } @@ -283,8 +332,7 @@ impl Value { document_type: &'a [(Value, Value)], key: &'a str, ) -> Result, Error> { - Self::get_from_map(document_type, key) - .map(|v| v.to_bytes())? + Self::get_from_map(document_type, key).map(|v| v.to_bytes())? } /// Retrieves the value of a key from a map if it's a byte array. diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index ba7bd41e9bd..b0c499e9fee 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -10,29 +10,29 @@ pub mod btreemap_field_replacement; mod btreemap_mut_value_extensions; pub mod btreemap_path_extensions; pub mod btreemap_path_insertion_extensions; +pub mod btreemap_removal_extensions; +mod btreemap_removal_inner_value_extensions; pub mod converter; pub mod display; mod error; +pub mod identifier; pub mod inner_value; mod integer; -pub mod system_bytes; -pub mod value_map; -pub mod btreemap_removal_extensions; -mod btreemap_removal_inner_value_extensions; mod ser; -pub mod identifier; pub mod string_encoding; +pub mod system_bytes; +pub mod value_map; use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; pub use integer::Integer; +use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; -use serde::de::DeserializeOwned; pub type Hash256 = [u8; 32]; -pub use btreemap_field_replacement::ReplacementType; use crate::ser::Serializer; +pub use btreemap_field_replacement::ReplacementType; /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] @@ -1079,11 +1079,7 @@ impl From<[(Value, Value); N]> for Value { return Value::Map(vec![]); } - Value::Map( - arr - .into_iter() - .collect(), - ) + Value::Map(arr.into_iter().collect()) } } @@ -1104,12 +1100,7 @@ impl From<[(String, Value); N]> for Value { // use stable sort to preserve the insertion order. arr.sort_by(|a, b| a.0.cmp(&b.0)); - Value::Map( - arr - .into_iter() - .map(|(k,v)| (k.into(), v)) - .collect(), - ) + Value::Map(arr.into_iter().map(|(k, v)| (k.into(), v)).collect()) } } @@ -1130,12 +1121,7 @@ impl From<[(&str, Value); N]> for Value { // use stable sort to preserve the insertion order. arr.sort_by(|a, b| a.0.cmp(&b.0)); - Value::Map( - arr - .into_iter() - .map(|(k,v)| (k.into(), v)) - .collect(), - ) + Value::Map(arr.into_iter().map(|(k, v)| (k.into(), v)).collect()) } } @@ -1160,8 +1146,8 @@ impl From for Value { } pub fn to_value(value: T) -> Result - where - T: Serialize, +where + T: Serialize, { value.serialize(Serializer) } diff --git a/packages/rs-platform-value/src/ser.rs b/packages/rs-platform-value/src/ser.rs index 9ef59d7975d..1169be215dc 100644 --- a/packages/rs-platform-value/src/ser.rs +++ b/packages/rs-platform-value/src/ser.rs @@ -1,8 +1,8 @@ -use std::fmt::Display; use crate::error::Error; -use serde::ser::{Impossible, Serialize}; -use crate::{to_value, Value}; use crate::value_map::ValueMap; +use crate::{to_value, Value}; +use serde::ser::{Impossible, Serialize}; +use std::fmt::Display; // We only use our own error type; no need for From conversions provided by the // standard library's try! macro. This reduces lines of LLVM IR by 4%. @@ -18,8 +18,8 @@ macro_rules! tri { impl Serialize for Value { #[inline] fn serialize(&self, serializer: S) -> Result - where - S: ::serde::Serializer, + where + S: ::serde::Serializer, { match self { Value::Null => serializer.serialize_unit(), @@ -190,8 +190,8 @@ impl serde::Serializer for Serializer { #[inline] fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { value.serialize(self) } @@ -203,8 +203,8 @@ impl serde::Serializer for Serializer { variant: &'static str, value: &T, ) -> Result - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { let mut values = ValueMap::new(); values.push((Value::Text(String::from(variant)), tri!(to_value(value)))); @@ -218,8 +218,8 @@ impl serde::Serializer for Serializer { #[inline] fn serialize_some(self, value: &T) -> Result - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { value.serialize(self) } @@ -262,7 +262,11 @@ impl serde::Serializer for Serializer { }) } - fn serialize_struct(self, name: &'static str, len: usize) -> Result { + fn serialize_struct( + self, + name: &'static str, + len: usize, + ) -> Result { match name { _ => self.serialize_map(Some(len)), } @@ -282,8 +286,8 @@ impl serde::Serializer for Serializer { } fn collect_str(self, value: &T) -> Result - where - T: ?Sized + Display, + where + T: ?Sized + Display, { Ok(Value::Text(value.to_string())) } @@ -315,8 +319,8 @@ impl serde::ser::SerializeSeq for SerializeVec { type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Error> - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { self.vec.push(tri!(to_value(value))); Ok(()) @@ -332,8 +336,8 @@ impl serde::ser::SerializeTuple for SerializeVec { type Error = Error; fn serialize_element(&mut self, value: &T) -> Result<(), Error> - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { serde::ser::SerializeSeq::serialize_element(self, value) } @@ -348,8 +352,8 @@ impl serde::ser::SerializeTupleStruct for SerializeVec { type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Error> - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { serde::ser::SerializeSeq::serialize_element(self, value) } @@ -364,8 +368,8 @@ impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { type Error = Error; fn serialize_field(&mut self, value: &T) -> Result<(), Error> - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { self.vec.push(tri!(to_value(value))); Ok(()) @@ -385,8 +389,8 @@ impl serde::ser::SerializeMap for SerializeMap { type Error = Error; fn serialize_key(&mut self, key: &T) -> Result<(), Error> - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { match self { SerializeMap::Map { next_key, .. } => { @@ -397,8 +401,8 @@ impl serde::ser::SerializeMap for SerializeMap { } fn serialize_value(&mut self, value: &T) -> Result<(), Error> - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { match self { SerializeMap::Map { map, next_key } => { @@ -449,8 +453,8 @@ impl serde::Serializer for MapKeySerializer { #[inline] fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { value.serialize(self) } @@ -532,8 +536,8 @@ impl serde::Serializer for MapKeySerializer { _variant: &'static str, _value: &T, ) -> Result - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { Err(key_must_be_a_string()) } @@ -543,8 +547,8 @@ impl serde::Serializer for MapKeySerializer { } fn serialize_some(self, _value: &T) -> Result - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { Err(key_must_be_a_string()) } @@ -579,7 +583,11 @@ impl serde::Serializer for MapKeySerializer { Err(key_must_be_a_string()) } - fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + fn serialize_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { Err(key_must_be_a_string()) } @@ -594,8 +602,8 @@ impl serde::Serializer for MapKeySerializer { } fn collect_str(self, value: &T) -> Result - where - T: ?Sized + Display, + where + T: ?Sized + Display, { Ok(value.to_string()) } @@ -606,8 +614,8 @@ impl serde::ser::SerializeStruct for SerializeMap { type Error = Error; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { match self { SerializeMap::Map { .. } => serde::ser::SerializeMap::serialize_entry(self, key, value), @@ -626,10 +634,11 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant { type Error = Error; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> - where - T: ?Sized + Serialize, + where + T: ?Sized + Serialize, { - self.map.push((Value::Text(String::from(key)), tri!(to_value(value)))); + self.map + .push((Value::Text(String::from(key)), tri!(to_value(value)))); Ok(()) } @@ -640,4 +649,4 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant { Ok(Value::Map(object)) } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/string_encoding.rs b/packages/rs-platform-value/src/string_encoding.rs index 40bb7275582..7d40dfade1b 100644 --- a/packages/rs-platform-value/src/string_encoding.rs +++ b/packages/rs-platform-value/src/string_encoding.rs @@ -1,6 +1,6 @@ +use crate::Error; use base64; use bs58; -use crate::Error; pub enum Encoding { Base58, @@ -12,8 +12,10 @@ pub fn decode(encoded_value: &str, encoding: Encoding) -> Result, Error> Encoding::Base58 => Ok(bs58::decode(encoded_value) .into_vec() .map_err(|e| Error::StringDecodingError(e.to_string()))?), - Encoding::Base64 => Ok(base64::decode(encoded_value) - .map_err(|e| Error::StringDecodingError(e.to_string()))?), + Encoding::Base64 => { + Ok(base64::decode(encoded_value) + .map_err(|e| Error::StringDecodingError(e.to_string()))?) + } } } diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index b6e2f86e1f6..6db087c5c21 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -70,7 +70,11 @@ impl ValueMapHelper for ValueMap { false } }) - .map(|pos| self.remove(pos).1).ok_or(Error::StructureError(format!("trying to remove a key {} from a ValueMap that was not found", search_key))) + .map(|pos| self.remove(pos).1) + .ok_or(Error::StructureError(format!( + "trying to remove a key {} from a ValueMap that was not found", + search_key + ))) } fn remove_optional_key(&mut self, search_key: &str) -> Option { diff --git a/packages/wasm-dpp/src/data_contract/errors/mod.rs b/packages/wasm-dpp/src/data_contract/errors/mod.rs index e04f4feb8e9..ec4864a2726 100644 --- a/packages/wasm-dpp/src/data_contract/errors/mod.rs +++ b/packages/wasm-dpp/src/data_contract/errors/mod.rs @@ -25,7 +25,7 @@ pub fn from_data_contract_to_js_error(e: DataContractError) -> JsValue { err.data_contract_id().into(), ) .into() - }, + } other => { DataContractGenericError::new(format!("data contract error: {}", other.to_string())) .into() diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index e6a3d682a7f..89741e26edb 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -17,7 +17,7 @@ use crate::document::BinaryType; use crate::errors::RustConversionError; use crate::identifier::{identifier_from_js_value, IdentifierWrapper}; use crate::lodash::lodash_set; -use crate::utils::{with_serde_to_platform_value, ToSerdeJSONExt, WithJsError, Inner}; +use crate::utils::{with_serde_to_platform_value, Inner, ToSerdeJSONExt, WithJsError}; use crate::{with_js_error, ConversionOptions}; use crate::{DataContractWasm, MetadataWasm}; diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 1e8ab284c26..b01e8d5fc42 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -12,7 +12,9 @@ use crate::buffer::Buffer; use crate::identifier::IdentifierWrapper; use crate::lodash::lodash_set; -use crate::utils::{replace_identifiers_with_bytes_without_failing, Inner, with_serde_to_json_value, ToSerdeJSONExt}; +use crate::utils::{ + replace_identifiers_with_bytes_without_failing, with_serde_to_json_value, Inner, ToSerdeJSONExt, +}; use crate::utils::{try_to_u64, WithJsError}; use crate::with_js_error; use crate::DataContractWasm; @@ -72,7 +74,10 @@ impl DocumentWasm { let document_type_name = js_document_type_name .as_string() - .ok_or(anyhow!("expected a string for the document type, got {:?}", js_document_type_name)) + .ok_or(anyhow!( + "expected a string for the document type, got {:?}", + js_document_type_name + )) .with_js_error()?; let (identifier_paths, _) = js_data_contract diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index d2b465179e0..ed08c591bac 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -9,7 +9,7 @@ use js_sys::Array; use wasm_bindgen::prelude::*; use crate::identifier::IdentifierWrapper; -use crate::utils::{Inner, with_serde_to_platform_value}; +use crate::utils::{with_serde_to_platform_value, Inner}; use crate::{ document_batch_transition::document_transition::to_object, utils::{ToSerdeJSONExt, WithJsError}, diff --git a/packages/wasm-dpp/src/identifier/mod.rs b/packages/wasm-dpp/src/identifier/mod.rs index f4bd64e9e84..d7d3915bbeb 100644 --- a/packages/wasm-dpp/src/identifier/mod.rs +++ b/packages/wasm-dpp/src/identifier/mod.rs @@ -1,6 +1,6 @@ use dpp::prelude::Identifier; -use platform_value::string_encoding::Encoding; use itertools::Itertools; +use platform_value::string_encoding::Encoding; pub use serde::{Deserialize, Serialize}; use serde_json::Value; use wasm_bindgen::prelude::*; @@ -142,7 +142,6 @@ impl Inner for IdentifierWrapper { type InnerItem = Identifier; fn into_inner(self) -> Identifier { - self.wrapped } diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs index 43ea83c6b81..1815c96a21d 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs @@ -1,8 +1,6 @@ -use dpp::{ - dashcore::{ - blockdata::{script::Script, transaction::txout::TxOut}, - consensus::encode::serialize, - }, +use dpp::dashcore::{ + blockdata::{script::Script, transaction::txout::TxOut}, + consensus::encode::serialize, }; use serde::{Deserialize, Serialize}; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 4d2a990d8f4..5ccef15804f 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -9,8 +9,8 @@ use crate::identifier::IdentifierWrapper; use crate::{ buffer::Buffer, errors::RustConversionError, - identity::IdentityPublicKeyWasm, - identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransitionWasm, state_transition::StateTransitionExecutionContextWasm, + identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransitionWasm, + identity::IdentityPublicKeyWasm, state_transition::StateTransitionExecutionContextWasm, with_js_error, }; From ec570139dac04ffde1610264790b364d1a5f0570 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 12 Mar 2023 02:19:52 +0700 Subject: [PATCH 103/228] more break makes sam happy --- .../document_type/document_type.rs | 4 +- .../src/data_contract/document_type/index.rs | 2 +- .../data_contract_create_transition/mod.rs | 15 +- .../data_contract_update_transition/mod.rs | 3 +- .../validation/data_contract_validator.rs | 7 +- .../validation/multi_validator.rs | 57 ++-- .../validate_data_contract_max_depth.rs | 72 ++--- packages/rs-dpp/src/document/document.rs | 1 + .../rs-dpp/src/document/document_validator.rs | 18 +- .../rs-dpp/src/document/extended_document.rs | 81 +++-- .../state_transition/asset_lock_proof/mod.rs | 13 +- .../data_contract_validator_spec.rs | 190 +++++------ ..._documents_batch_transitions_basic_spec.rs | 62 ++-- packages/rs-platform-value/src/index.rs | 271 ++++++++++++++++ packages/rs-platform-value/src/inner_value.rs | 36 ++- .../src/inner_value_at_path.rs | 80 +++++ packages/rs-platform-value/src/lib.rs | 53 +++- packages/rs-platform-value/src/macros.rs | 298 ++++++++++++++++++ packages/rs-platform-value/src/value_map.rs | 1 + 19 files changed, 1004 insertions(+), 260 deletions(-) create mode 100644 packages/rs-platform-value/src/index.rs create mode 100644 packages/rs-platform-value/src/inner_value_at_path.rs create mode 100644 packages/rs-platform-value/src/macros.rs diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index 73ff065c499..e1344893100 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -183,12 +183,12 @@ impl DocumentType { // Do documents of this type keep history? (Overrides contract value) let documents_keep_history: bool = - Value::inner_optional_bool_value(document_type_value_map, "documentsKeepHistory") + Value::inner_optional_bool_value(document_type_value_map, "documentsKeepHistory").map_err(ProtocolError::ValueError)? .unwrap_or(default_keeps_history); // Are documents of this type mutable? (Overrides contract value) let documents_mutable: bool = - Value::inner_optional_bool_value(document_type_value_map, "documentsMutable") + Value::inner_optional_bool_value(document_type_value_map, "documentsMutable").map_err(ProtocolError::ValueError)? .unwrap_or(default_mutability); let index_values = Value::inner_optional_array_slice_value( diff --git a/packages/rs-dpp/src/data_contract/document_type/index.rs b/packages/rs-dpp/src/data_contract/document_type/index.rs index b3f5abe48af..0368d08b574 100644 --- a/packages/rs-dpp/src/data_contract/document_type/index.rs +++ b/packages/rs-dpp/src/data_contract/document_type/index.rs @@ -199,7 +199,7 @@ impl TryFrom<&[(Value, Value)]> for Index { let mut index_properties: Vec = Vec::new(); for (key_value, value_value) in index_type_value_map { - let key = key_value.as_str().map_err(ProtocolError::ValueError)?; + let key = key_value.to_str().map_err(ProtocolError::ValueError)?; match key { "name" => { diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index d67a3b2dafe..83564ebc56e 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -6,6 +6,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::{ data_contract::DataContract, @@ -76,7 +77,7 @@ impl DataContractCreateTransition { data_contract: DataContract::from_raw_object( raw_data_contract_update_transition .remove(DATA_CONTRACT) - .ok_or(ProtocolError::DecodingError( + .map_err(|_| ProtocolError::DecodingError( "data contract missing on state transition".to_string(), ))?, )?, @@ -249,12 +250,12 @@ mod test { fn get_test_data() -> TestData { let data_contract = get_data_contract_fixture(None); - let state_transition = DataContractCreateTransition::from_raw_object(json!({ - PROTOCOL_VERSION: version::LATEST_VERSION, - ENTROPY : data_contract.entropy, - DATA_CONTRACT : data_contract.to_object(false).unwrap(), - })) - .expect("state transition should be created without errors"); + let state_transition = DataContractCreateTransition::from_raw_object( + Value::from([(PROTOCOL_VERSION, version::LATEST_VERSION.into()), + (ENTROPY, Value::Bytes32(data_contract.entropy)), + (DATA_CONTRACT, data_contract.to_object().unwrap()), + ]) + ).expect("state transition should be created without errors"); TestData { data_contract, diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 34cef04f09f..9c3fa736145 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -3,6 +3,7 @@ use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::{ data_contract::DataContract, @@ -67,7 +68,7 @@ impl DataContractUpdateTransition { data_contract: DataContract::from_raw_object( raw_data_contract_update_transition .remove(DATA_CONTRACT) - .ok_or(ProtocolError::DecodingError( + .map_err(|_| ProtocolError::DecodingError( "data contract missing on state transition".to_string(), ))?, )?, diff --git a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs index a3b2d945f9c..6650babacbe 100644 --- a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs @@ -5,6 +5,7 @@ use itertools::Itertools; use lazy_static::lazy_static; use log::trace; use serde_json::Value as JsonValue; +use platform_value::Value; use crate::consensus::basic::data_contract::{ DuplicateIndexError, DuplicateIndexNameError, InvalidCompoundIndexError, @@ -71,13 +72,13 @@ impl DataContractValidator { pub fn validate( &self, - raw_data_contract: &JsonValue, + raw_data_contract: &Value, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); trace!("validating against data contract meta validator"); result.merge(JsonSchemaValidator::validate_data_contract_schema( - raw_data_contract, + raw_data_contract.into(), )); if !result.is_valid() { return Ok(result); @@ -114,7 +115,7 @@ impl DataContractValidator { return Ok(result); } - let data_contract = DataContract::from_json_raw_object(raw_data_contract.clone())?; + let data_contract = DataContract::from_raw_object(raw_data_contract.clone())?; let enriched_data_contract = enrich_data_contract_with_base_schema( &data_contract, &BASE_DOCUMENT_SCHEMA, diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index c0584ac25d1..70668ae426b 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -1,41 +1,38 @@ use regex::Regex; -use serde_json::Value as JsonValue; +use platform_value::Value; use crate::consensus::basic::data_contract::IncompatibleRe2PatternError; -use crate::{ - consensus::{basic::BasicError, ConsensusError}, - validation::ValidationResult, -}; +use crate::{consensus::{basic::BasicError, ConsensusError}, ProtocolError, validation::ValidationResult}; pub type SubValidator = fn( path: &str, key: &str, - parent: &JsonValue, - value: &JsonValue, + parent: &Value, + value: &Value, result: &mut ValidationResult<()>, ); pub fn validate( - raw_data_contract: &JsonValue, + raw_data_contract: &Value, validators: &[SubValidator], ) -> ValidationResult<()> { let mut result = ValidationResult::default(); - let mut values_queue: Vec<(&JsonValue, String)> = vec![(raw_data_contract, String::from(""))]; + let mut values_queue: Vec<(&Value, String)> = vec![(raw_data_contract, String::from(""))]; while let Some((value, path)) = values_queue.pop() { match value { - JsonValue::Object(current_map) => { + Value::Map(current_map) => { for (key, current_value) in current_map.iter() { if current_value.is_object() || current_value.is_array() { let new_path = format!("{}/{}", path, key); values_queue.push((current_value, new_path)) } for validator in validators { - validator(&path, key, value, current_value, &mut result); + validator(&path, key.to_str().map_err(ProtocolError::ValueError)?, value, current_value, &mut result); } } } - JsonValue::Array(arr) => { + Value::Array(arr) => { for (i, value) in arr.iter().enumerate() { if value.is_object() { let new_path = format!("{}/[{}]", path, i); @@ -52,8 +49,8 @@ pub fn validate( pub fn pattern_is_valid_regex_validator( path: &str, key: &str, - _parent: &JsonValue, - value: &JsonValue, + _parent: &Value, + value: &Value, result: &mut ValidationResult<()>, ) { if key == "pattern" { @@ -67,6 +64,14 @@ pub fn pattern_is_valid_regex_validator( ), )); } + } else { + result.add_error(ConsensusError::IncompatibleRe2PatternError( + IncompatibleRe2PatternError::new( + String::new(), + path.to_string(), + format!("{} is not a string", string), + ), + )); } } } @@ -74,12 +79,12 @@ pub fn pattern_is_valid_regex_validator( pub fn byte_array_has_no_items_as_parent_validator( path: &str, key: &str, - parent: &JsonValue, - value: &JsonValue, + parent: &Value, + value: &Value, result: &mut ValidationResult<()>, ) { if key == "byteArray" - && value.is_boolean() + && value.is_bool() && (parent.get("items").is_some() || parent.get("prefixItems").is_some()) { result.add_error(BasicError::JsonSchemaCompilationError(format!( @@ -103,7 +108,7 @@ mod test { #[test] fn should_return_error_if_bytes_array_parent_contains_items_or_prefix_items() { - let schema = json!( + let schema : Value = json!( { "type": "object", "properties": { @@ -118,7 +123,7 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ); + ).into(); let mut result = validate(&schema, &[byte_array_has_no_items_as_parent_validator]); assert_eq!(2, result.errors().len()); let first_error = get_basic_error(result.errors.pop().unwrap()); @@ -136,7 +141,7 @@ mod test { #[test] fn should_return_valid_result() { - let schema = json!( + let schema : Value = json!( { "type": "object", "properties": { @@ -149,14 +154,14 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ); + ).into(); assert!(validate(&schema, &[pattern_is_valid_regex_validator]).is_valid()) } #[test] fn should_return_invalid_result() { - let schema = json!({ + let schema : Value = json!({ "type": "object", "properties": { "foo": { "type": "integer" }, @@ -168,7 +173,7 @@ mod test { "required": ["foo"], "additionalProperties": false, - }); + }).into(); let result = validate(&schema, &[pattern_is_valid_regex_validator]); let consensus_error = result.errors.get(0).expect("the error should be returned"); @@ -241,7 +246,7 @@ mod test { } } - fn get_document_schema() -> JsonValue { + fn get_document_schema() -> Value { json!({ "properties": { "simple": { @@ -318,13 +323,13 @@ mod test { ] } } - }) + }).into() } fn get_basic_error(error: ConsensusError) -> BasicError { if let ConsensusError::BasicError(err) = error { return *err; } - panic!("the error: {} isn't a BasicError", error) + panic!("the error: {:?} isn't a BasicError", error) } } diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index 9784faa9a0d..4d0fcfe7c48 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -1,18 +1,18 @@ use std::collections::BTreeSet; use anyhow::bail; -use serde_json::Value as JsonValue; +use platform_value::Value; use crate::consensus::basic::data_contract::InvalidJsonSchemaRefError; use crate::{ - consensus::basic::BasicError, util::json_value::JsonValueExt, validation::ValidationResult, + consensus::basic::BasicError, validation::ValidationResult, }; const MAX_DEPTH: usize = 500; -pub fn validate_data_contract_max_depth(raw_data_contract: &JsonValue) -> ValidationResult<()> { +pub fn validate_data_contract_max_depth(data_contract_object: &Value) -> ValidationResult<()> { let mut result = ValidationResult::default(); - let schema_depth = match calc_max_depth(raw_data_contract) { + let schema_depth = match calc_max_depth(data_contract_object) { Ok(depth) => depth, Err(err) => { result.add_error(err); @@ -26,14 +26,14 @@ pub fn validate_data_contract_max_depth(raw_data_contract: &JsonValue) -> Valida result } -fn calc_max_depth(json_value: &JsonValue) -> Result { - let mut values_depth_queue: Vec<(&JsonValue, usize)> = vec![(json_value, 0)]; +fn calc_max_depth(value: &Value) -> Result { + let mut values_depth_queue: Vec<(&Value, usize)> = vec![(value, 0)]; let mut max_depth: usize = 0; - let mut visited: BTreeSet<*const JsonValue> = BTreeSet::new(); + let mut visited: BTreeSet<*const Value> = BTreeSet::new(); while let Some((value, depth)) = values_depth_queue.pop() { match value { - JsonValue::Object(map) => { + Value::Map(map) => { let new_depth = depth + 1; if max_depth < new_depth { max_depth = new_depth @@ -42,7 +42,7 @@ fn calc_max_depth(json_value: &JsonValue) -> Result { // handling the internal references if property_name == "$ref" { if let Some(uri) = v.as_str() { - let resolved = resolve_uri(json_value, uri).map_err(|e| { + let resolved = resolve_uri(value, uri).map_err(|e| { BasicError::InvalidJsonSchemaRefError( InvalidJsonSchemaRefError::new(format!( "invalid ref '{}': {}", @@ -51,7 +51,7 @@ fn calc_max_depth(json_value: &JsonValue) -> Result { ) })?; - if visited.contains(&(resolved as *const JsonValue)) { + if visited.contains(&(resolved as *const Value)) { return Err(BasicError::InvalidJsonSchemaRefError( InvalidJsonSchemaRefError::new(format!( "the ref '{}' contains cycles", @@ -60,24 +60,24 @@ fn calc_max_depth(json_value: &JsonValue) -> Result { )); } - visited.insert(resolved as *const JsonValue); + visited.insert(resolved as *const Value); values_depth_queue.push((resolved, new_depth)); continue; } } - if v.is_object() || v.is_array() { + if v.is_map() || v.is_array() { values_depth_queue.push((v, new_depth)) } } } - JsonValue::Array(array) => { + Value::Array(array) => { let new_depth = depth + 1; if max_depth < new_depth { max_depth = new_depth } for v in array { - if v.is_object() || v.is_array() { + if v.is_map() || v.is_array() { values_depth_queue.push((v, new_depth)) } } @@ -89,13 +89,13 @@ fn calc_max_depth(json_value: &JsonValue) -> Result { Ok(max_depth) } -fn resolve_uri<'a>(json: &'a JsonValue, uri: &str) -> Result<&'a JsonValue, anyhow::Error> { +fn resolve_uri<'a>(value: &'a Value, uri: &str) -> Result<&'a Value, anyhow::Error> { if !uri.starts_with("#/") { bail!("only local references are allowed") } let string_path = uri.strip_prefix("#/").unwrap().replace('/', "."); - json.get_value(&string_path) + value.get_at_path(&string_path) } #[cfg(test)] @@ -106,7 +106,7 @@ mod test { #[test] fn should_return_error_when_cycle_is_spotted() { - let schema = json!( + let schema : Value = json!( { "$defs" : { "object": { @@ -130,7 +130,7 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ); + ).into(); let result = calc_max_depth(&schema); let err = get_ref_error(result); @@ -142,7 +142,7 @@ mod test { #[test] fn should_calculate_valid_depth_with_included_ref() { - let schema = json!( + let schema : Value = json!( { "$defs" : { "object": { @@ -165,14 +165,14 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ); + ).into(); let result = calc_max_depth(&schema); assert!(matches!(result, Ok(5))); } #[test] fn should_return_error_with_non_existing_ref() { - let schema = json!( + let schema : Value = json!( { "type": "object", "properties": { @@ -188,21 +188,16 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ); + ).into(); let result = calc_max_depth(&schema); let err = get_ref_error(result); assert!(err.ref_error().starts_with("invalid ref '#/$defs/object'")); - // println!("the result is {:#?}", result); - // assert!(matches!( - // result, - // Err(BasicError::InvalidJsonSchemaRefError { ref_error }) if ref_error.starts_with("invalid ref '#/$defs/object'") - // )); } #[test] fn should_return_error_with_external_ref() { - let schema = json!( + let schema : Value = json!( { "type": "object", "properties": { @@ -218,7 +213,7 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ); + ).into(); let result = calc_max_depth(&schema); let err = get_ref_error(result); @@ -227,16 +222,11 @@ mod test { "invalid ref 'https://json-schema.org/some': only local references are allowed" .to_string() ); - - // assert!(matches!( - // result, - // Err(BasicError::InvalidJsonSchemaRefError { ref_error }) if ref_error == "invalid ref 'https://json-schema.org/some': only local references are allowed" - // )); } #[test] fn should_return_error_with_empty_ref() { - let schema = json!( + let schema : Value = json!( { "type": "object", "properties": { @@ -252,7 +242,7 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ); + ).into(); let result = calc_max_depth(&schema); let err = get_ref_error(result); @@ -264,7 +254,7 @@ mod test { #[test] fn should_calculate_valid_depth() { - let schema = json!( + let schema : Value = json!( { "type": "object", "properties": { @@ -277,19 +267,19 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ); + ).into(); assert!(matches!(calc_max_depth(&schema), Ok(3))); } #[test] fn should_calculate_valid_depth_for_empty_json() { - let schema = json!({}); + let schema : Value = json!({}).into(); assert!(matches!(calc_max_depth(&schema), Ok(1))); } #[test] fn should_calculate_valid_depth_for_schema_containing_array() { - let schema = json!({ + let schema : Value = json!({ "type": "object", "properties": { "foo": { "type": "integer" }, @@ -300,7 +290,7 @@ mod test { }, "required": [ { "alpha": "value_alpha"}, { "bravo" : { "a" : "b"} }], - }); + }).into(); assert!(matches!(calc_max_depth(&schema), Ok(4))); } diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 1de751670cc..767dbc9e614 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -45,6 +45,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType}; use crate::data_contract::errors::DataContractError; diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index c69b8e26301..18e74f8a33d 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -229,7 +229,7 @@ mod test { } = get_test_data(); raw_document - .insert(String::from(property_name), json!("string")) + .insert(String::from(property_name), Value::Text("string".to_string())) .unwrap(); let result = document_validator @@ -266,7 +266,7 @@ mod test { let too_short_id = [0u8; 31]; raw_document - .insert(String::from(property_name), json!(too_short_id)) + .insert(String::from(property_name), Value::Bytes(too_short_id.to_vec())) .unwrap(); let result = document_validator @@ -303,7 +303,7 @@ mod test { raw_document .insert( String::from(property_name), - serde_json::to_value(too_long_id).unwrap(), + Value::Bytes(too_long_id.to_vec()), ) .unwrap(); @@ -335,7 +335,7 @@ mod test { } = get_test_data(); raw_document - .insert(String::from("$protocolVersion"), json!("1")) + .insert(String::from("$protocolVersion"), Value::Text("1".to_string())) .unwrap(); let result = document_validator @@ -386,7 +386,7 @@ mod test { } = get_test_data(); raw_document - .insert("$type".to_string(), json!("undefinedDocument")) + .insert("$type".to_string(), Value::Text("undefinedDocument".to_string())) .unwrap(); let result = document_validator @@ -405,7 +405,7 @@ mod test { } = get_test_data(); raw_document - .insert(String::from("$revision"), json!("string")) + .insert(String::from("$revision"), Value::Text("string".to_string())) .unwrap(); let result = document_validator @@ -431,7 +431,7 @@ mod test { } = get_test_data(); raw_document - .insert(String::from("$revision"), json!(1.1)) + .insert(String::from("$revision"), Value::Float(1.1)) .unwrap(); let result = document_validator @@ -460,7 +460,7 @@ mod test { data_contract, } = get_test_data(); - raw_document.insert(String::from("name"), json!(1)).unwrap(); + raw_document.insert(String::from("name"), Value::U64(1)).unwrap(); let result = document_validator .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); @@ -487,7 +487,7 @@ mod test { } = get_test_data(); raw_document - .insert(String::from("undefined"), json!(1)) + .insert(String::from("undefined"), Value::U64(1)) .unwrap(); let result = document_validator diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 0bae0c16420..0f6c7bf8e3b 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -24,6 +24,7 @@ use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; use std::collections::{BTreeMap, HashSet}; use std::convert::TryInto; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; pub mod property_names { pub const PROTOCOL_VERSION: &str = "$protocolVersion"; @@ -288,7 +289,7 @@ impl ExtendedDocument { .map_err(|e| ProtocolError::EncodingError(format!("{}", e)))?; let mut document_map: BTreeMap = - Value::convert_from_cbor_map(document_cbor_map); + Value::convert_from_cbor_map(document_cbor_map)?; let data_contract_id = Identifier::new( document_map @@ -455,6 +456,7 @@ impl TryInto for &ExtendedDocument { #[cfg(test)] mod test { + use std::convert::TryInto; use anyhow::Result; use serde_json::{json, Value as JsonValue}; @@ -475,31 +477,58 @@ mod test { .filter_level(log::LevelFilter::Debug) .try_init(); } - - fn data_contract_with_dynamic_properties() -> DataContract { - let data_contract = json!({ - "protocolVersion" :0, - "$id" : vec![0_u8;32], - "$schema" : "schema", - "version" : 0, - "ownerId" : vec![0_u8;32], - "documents" : { - "test" : { - "properties" : { - "alphaIdentifier" : { - "type": "array", - "byteArray": true, - "contentMediaType": "application/x.dash.dpp.identifier", - }, - "alphaBinary" : { - "type": "array", - "byteArray": true, - } - } - } - } - }); - DataContract::from_json_raw_object(data_contract).unwrap() + pub(crate) fn data_contract_with_dynamic_properties() -> DataContract { + // The following is equivalent to the data contract + // { + // "protocolVersion" :0, + // "$id" : vec![0_u8;32], + // "$schema" : "schema", + // "version" : 0, + // "ownerId" : vec![0_u8;32], + // "documents" : { + // "test" : { + // "properties" : { + // "alphaIdentifier" : { + // "type": "array", + // "byteArray": true, + // "contentMediaType": "application/x.dash.dpp.identifier", + // }, + // "alphaBinary" : { + // "type": "array", + // "byteArray": true, + // } + // } + // } + // } + // } + let test_document_properties_alpha_identifier = Value::from([ + ("type", Value::Text("array".to_string())), + ("byteArray", Value::Bool(true)), + ]); + let test_document_properties_alpha_binary = Value::from([ + ("type", Value::Text("array".to_string())), + ("byteArray", Value::Bool(true)), + ( + "contentMediaType", + Value::Text("application/x.dash.dpp.identifier".to_string()), + ), + ]); + let test_document_properties = Value::from([ + ("alphaIdentifier", test_document_properties_alpha_identifier), + ("alphaBinary", test_document_properties_alpha_binary), + ]); + let test_document = Value::from([("properties", test_document_properties)]); + let documents = Value::from([("test", test_document)]); + Value::from([ + ("protocolVersion", Value::U32(1)), + ("$id", Value::Identifier([0_u8; 32])), + ("$schema", Value::Text("schema".to_string())), + ("version", Value::U32(0)), + ("$ownerId", Value::Identifier([0_u8; 32])), + ("documents", documents), + ]) + .try_into() + .unwrap() } #[test] diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index a3470342f66..868e76f2501 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -190,15 +190,4 @@ impl TryInto for &AssetLockProof { AssetLockProof::Chain(chain_proof) => platform_value::to_value(chain_proof), } } -} - -impl TryFrom<&AssetLockProof> for Value { - type Error = ProtocolError; - - fn try_from(asset_lock_proof: &AssetLockProof) -> Result { - match asset_lock_proof { - AssetLockProof::Instant(instant_proof) => platform_value::to_value(instant_proof), - AssetLockProof::Chain(chain_proof) => platform_value::to_value(chain_proof), - } - } -} +} \ No newline at end of file diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index 2eb9578f237..6cc70f0bb7a 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -4,6 +4,7 @@ use jsonschema::error::ValidationErrorKind; use log::trace; use serde_json::{json, Value as JsonValue}; use test_case::test_case; +use platform_value::{platform_value, Value}; use crate::{ codes::ErrorWithCode, @@ -19,14 +20,14 @@ use crate::{ struct TestData { data_contract_validator: DataContractValidator, data_contract: DataContract, - raw_data_contract: JsonValue, + raw_data_contract: Value, } fn setup_test() -> TestData { init(); let data_contract = get_data_contract_fixture(None); - let raw_data_contract = data_contract.to_json_object(false).unwrap(); + let raw_data_contract = data_contract.into_object().unwrap(); let protocol_version_validator = ProtocolVersionValidator::new(LATEST_VERSION, LATEST_VERSION, COMPATIBILITY_MAP.clone()); @@ -125,7 +126,7 @@ mod protocol { .. } = setup_test(); - raw_data_contract["protocolVersion"] = json!("1"); + raw_data_contract.set_value("protocolVersion", "1".into()).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -144,7 +145,7 @@ mod protocol { .. } = setup_test(); - raw_data_contract["protocolVersion"] = json!(-1); + raw_data_contract.set_value("protocolVersion", Value::I8(-1)).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -164,7 +165,8 @@ fn defs_should_be_object() { data_contract_validator, .. } = setup_test(); - raw_data_contract["$defs"] = json!(1); + + raw_data_contract.set_value("$defs", Value::U32(1)).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -177,6 +179,7 @@ fn defs_should_be_object() { } mod defs { + use platform_value::platform_value; use super::*; #[test] @@ -186,7 +189,7 @@ mod defs { data_contract_validator, .. } = setup_test(); - raw_data_contract["$defs"] = json!({}); + raw_data_contract.set_value("$defs", Value::Map(vec![])).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -205,7 +208,7 @@ mod defs { data_contract_validator, .. } = setup_test(); - raw_data_contract["$defs"] = json!({ "$subSchema" : {}}); + raw_data_contract.set_value("$defs", Value::Map(vec![(Value::Text("$subSchema".to_string()), Value::Map(vec![]))])).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -251,7 +254,7 @@ mod defs { ]; for property_name in valid_names { - raw_data_contract["$defs"][property_name] = json!({"type" : "string"}) + raw_data_contract.set_value_at_path("$defs", property_name, platform_value!({"type" : "string"})).expect("expected to set value"); } let result = data_contract_validator @@ -279,7 +282,7 @@ mod defs { "ab", ]; for property_name in invalid_names { - raw_data_contract["$defs"][property_name] = json!({"type" : "string"}) + raw_data_contract.set_value_at_path("$defs", property_name, platform_value!({"type" : "string"})).expect("expected to set value"); } let result = data_contract_validator @@ -300,7 +303,7 @@ mod defs { } = setup_test(); for i in 1..101 { - raw_data_contract["$defs"][format!("def_{}", i)] = json!({"type" : "string"}) + raw_data_contract.set_value_at_path("$defs", format!("def_{}", i).as_str(), platform_value!({"type" : "string"}).into()).expect("expected to set value"); } let result = data_contract_validator @@ -324,7 +327,7 @@ mod schema { .. } = setup_test(); - raw_data_contract["$schema"] = json!(1); + raw_data_contract.set_value("$schema", Value::U64(1)).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -343,7 +346,7 @@ mod schema { .. } = setup_test(); - raw_data_contract["$schema"] = json!("wrong"); + raw_data_contract.set_value("$schema", Value::Text("wrong".to_string())).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -366,7 +369,7 @@ fn owner_id_should_be_byte_array(property_name: &str) { } = setup_test(); let array = ["string"; 32]; - raw_data_contract[property_name] = json!(array); + raw_data_contract.set_value(property_name, platform_value!(array).into()).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -396,7 +399,7 @@ fn owner_id_should_be_no_less_32_bytes(property_name: &str) { } = setup_test(); let array = [0u8; 31]; - raw_data_contract[property_name] = json!(array); + raw_data_contract.set_value(property_name, platform_value!(array).into()).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -421,7 +424,7 @@ fn owner_id_should_be_no_longer_32_bytes(property_name: &str) { let mut too_long_id = Vec::new(); too_long_id.resize(33, 0u8); - raw_data_contract[property_name] = json!(too_long_id); + raw_data_contract.set_value(property_name, platform_value!(too_long_id).into()).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -446,7 +449,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"] = json!(1); + raw_data_contract.set_value("documents", platform_value!(1).into()).expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -466,7 +469,8 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"] = json!({}); + raw_data_contract.set_value("documents", platform_value!({}).into()).expect("expected to set value"); + raw_data_contract["documents"] = platform_value!({}); let result = data_contract_validator .validate(&raw_data_contract) @@ -487,7 +491,7 @@ mod documents { } = setup_test(); let nice_document_data_contract = raw_data_contract["documents"]["niceDocument"].clone(); - raw_data_contract["documents"] = json!({}); + raw_data_contract["documents"] = platform_value!({}); let valid_names = [ "validName", @@ -522,7 +526,7 @@ mod documents { } = setup_test(); let nice_document_data_contract = raw_data_contract["documents"]["niceDocument"].clone(); - raw_data_contract["documents"] = json!({}); + raw_data_contract["documents"] = platform_value!({}); let invalid_names = [ "-invalidname", "_invalidname", @@ -578,7 +582,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["niceDocument"]["properties"] = json!({}); + raw_data_contract["documents"]["niceDocument"]["properties"] = platform_value!({}); let result = data_contract_validator .validate(&raw_data_contract) @@ -600,7 +604,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["niceDocument"]["type"] = json!("string"); + raw_data_contract["documents"]["niceDocument"]["type"] = platform_value!("string"); let result = data_contract_validator .validate(&raw_data_contract) @@ -652,7 +656,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["niceDocument"]["properties"]["object"] = json!({ + raw_data_contract["documents"]["niceDocument"]["properties"]["object"] = platform_value!({ "type": "array", "prefixItems": [ { @@ -710,7 +714,7 @@ mod documents { for property_name in valid_names { raw_data_contract["documents"]["niceDocument"]["properties"][property_name] = - json!({ "type" : "string"}) + platform_value!({ "type" : "string"}) } let result = data_contract_validator @@ -728,7 +732,7 @@ mod documents { } = setup_test(); raw_data_contract["documents"]["niceDocument"]["properties"]["something"] = - json!({"type": "object", "properties": json!({}), "additionalProperties" : false}); + platform_value!({"type": "object", "properties": platform_value!({}), "additionalProperties" : false}); let valid_names = [ "validName", @@ -746,7 +750,7 @@ mod documents { for property_name in valid_names { raw_data_contract["documents"]["niceDocument"]["properties"]["something"] - ["properties"][property_name] = json!({ "type" : "string"}) + ["properties"][property_name] = platform_value!({ "type" : "string"}) } let result = data_contract_validator @@ -766,7 +770,7 @@ mod documents { let invalid_names = ["*(*&^", "$test", ".", ".a"]; for property_name in invalid_names { - raw_data_contract["documents"]["niceDocument"]["properties"][property_name] = json!({}) + raw_data_contract["documents"]["niceDocument"]["properties"][property_name] = platform_value!({}) } let result = data_contract_validator @@ -791,15 +795,15 @@ mod documents { let invalid_names = ["*(*&^", "$test", ".", ".a"]; - raw_data_contract["documents"]["niceDocument"]["properties"]["something"] = json!({ - "properties" : json!({}), + raw_data_contract["documents"]["niceDocument"]["properties"]["something"] = platform_value!({ + "properties" : platform_value!({}), "additionalProperties" : false, }); for property_name in invalid_names { raw_data_contract["documents"]["niceDocument"]["properties"]["something"] - ["properties"][property_name] = json!({}); + ["properties"][property_name] = platform_value!({}); let result = data_contract_validator .validate(&raw_data_contract) @@ -858,7 +862,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["niceDocument"]["additionalProperties"] = json!(true); + raw_data_contract["documents"]["niceDocument"]["additionalProperties"] = platform_value!(true); let result = data_contract_validator .validate(&raw_data_contract) @@ -881,7 +885,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["additionalProperty"] = json!({}); + raw_data_contract["additionalProperty"] = platform_value!({}); let result = data_contract_validator .validate(&raw_data_contract) @@ -900,10 +904,10 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["niceDocument"]["properties"] = json!({}); + raw_data_contract["documents"]["niceDocument"]["properties"] = platform_value!({}); for i in 0..101 { - raw_data_contract["documents"]["niceDocument"]["properties"][format!("p_{}", i)] = json!({ + raw_data_contract["documents"]["niceDocument"]["properties"][format!("p_{}", i)] = platform_value!({ "properties": { "something" : { "type" : "string" @@ -933,7 +937,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["new"] = json!( { + raw_data_contract["documents"]["new"] = platform_value!( { "properties": { "something": { "type": "array", @@ -970,7 +974,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["new"] = json!({ + raw_data_contract["documents"]["new"] = platform_value!({ "type": "object", "properties": { "something": { @@ -1015,7 +1019,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["new"] = json!({ + raw_data_contract["documents"]["new"] = platform_value!({ "properties": { "something": { "type": "array", @@ -1054,7 +1058,7 @@ mod documents { } = setup_test(); raw_data_contract["documents"]["indexedDocument"]["properties"]["firstName"]["default"] = - json!("1"); + platform_value!("1"); let result = data_contract_validator .validate(&raw_data_contract) @@ -1079,7 +1083,7 @@ mod documents { } = setup_test(); raw_data_contract["documents"]["indexedDocument"] = - json!({"$ref" : "http://remote.com/schema#"}); + platform_value!({"$ref" : "http://remote.com/schema#"}); let result = data_contract_validator .validate(&raw_data_contract) @@ -1101,7 +1105,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "something": { @@ -1135,7 +1139,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "something": { @@ -1172,7 +1176,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!( + raw_data_contract["documents"]["indexedDocument"] = platform_value!( { "type": "object", "properties": { @@ -1215,7 +1219,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "something": { @@ -1253,7 +1257,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "something": { @@ -1291,7 +1295,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "something": { @@ -1324,7 +1328,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "something": { @@ -1378,7 +1382,7 @@ mod byte_array { } = setup_test(); raw_data_contract["documents"]["withByteArrays"]["properties"]["byteArrayField"] - ["byteArray"] = json!(1); + ["byteArray"] = platform_value!(1); let result = data_contract_validator .validate(&raw_data_contract) @@ -1401,7 +1405,7 @@ mod byte_array { } = setup_test(); raw_data_contract["documents"]["withByteArrays"]["properties"]["byteArrayField"] - ["byteArray"] = json!(false); + ["byteArray"] = platform_value!(false); let result = data_contract_validator .validate(&raw_data_contract) @@ -1424,7 +1428,7 @@ mod byte_array { } = setup_test(); raw_data_contract["documents"]["withByteArrays"]["properties"]["byteArrayField"]["type"] = - json!("string"); + platform_value!("string"); let result = data_contract_validator .validate(&raw_data_contract) @@ -1447,7 +1451,7 @@ mod byte_array { } = setup_test(); raw_data_contract["documents"]["withByteArrays"]["properties"]["byteArrayField"]["items"] = - json!({ "type" : "string"}); + platform_value!({ "type" : "string"}); let result = data_contract_validator .validate(&raw_data_contract) @@ -1494,7 +1498,7 @@ mod identifier { } = setup_test(); raw_data_contract["documents"]["withByteArrays"]["properties"]["identifierField"] - ["minItems"] = json!(31); + ["minItems"] = platform_value!(31); let result = data_contract_validator .validate(&raw_data_contract) @@ -1517,7 +1521,7 @@ mod identifier { } = setup_test(); raw_data_contract["documents"]["withByteArrays"]["properties"]["identifierField"] - ["maxItems"] = json!(31); + ["maxItems"] = platform_value!(31); let result = data_contract_validator .validate(&raw_data_contract) @@ -1545,7 +1549,7 @@ mod indices { } = setup_test(); raw_data_contract["documents"]["indexedDocument"]["indices"] = - json!("definitely not an array"); + platform_value!("definitely not an array"); let result = data_contract_validator .validate(&raw_data_contract) @@ -1567,7 +1571,7 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"] = json!([]); + raw_data_contract["documents"]["indexedDocument"]["indices"] = platform_value!([]); let result = data_contract_validator .validate(&raw_data_contract) @@ -1591,7 +1595,7 @@ mod indices { let mut index_definition = raw_data_contract["documents"]["indexedDocument"]["indices"][0].clone(); - index_definition["name"] = json!("otherIndexName"); + index_definition["name"] = platform_value!("otherIndexName"); if let Some(JsonValue::Array(ref mut arr)) = raw_data_contract["documents"]["indexedDocument"].get_mut("indices") @@ -1664,7 +1668,7 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"] = json!(["something else"]); + raw_data_contract["documents"]["indexedDocument"]["indices"] = platform_value!(["something else"]); let result = data_contract_validator .validate(&raw_data_contract) .expect("validation result should be returned"); @@ -1686,7 +1690,7 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"] = json!([{}]); + raw_data_contract["documents"]["indexedDocument"]["indices"] = platform_value!([{}]); let result = data_contract_validator .validate(&raw_data_contract) .expect("validation result should be returned"); @@ -1715,7 +1719,7 @@ mod indices { } = setup_test(); raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = - json!("something else"); + platform_value!("something else"); let result = data_contract_validator .validate(&raw_data_contract) @@ -1737,7 +1741,7 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = json!([]); + raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = platform_value!([]); let result = data_contract_validator .validate(&raw_data_contract) @@ -1765,7 +1769,7 @@ mod indices { .get_mut("properties") { let field_name = format!("field{}", i); - properties.push(json!({ + properties.push(platform_value!({ field_name : "asc" })) } @@ -1792,7 +1796,7 @@ mod indices { } = setup_test(); raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"][0] = - json!("something else"); + platform_value!("something else"); let result = data_contract_validator .validate(&raw_data_contract) @@ -1814,7 +1818,7 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = json!([]); + raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = platform_value!([]); let result = data_contract_validator .validate(&raw_data_contract) @@ -1838,7 +1842,7 @@ mod indices { let property = &mut raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"][0]; - property["anotherField"] = json!("something"); + property["anotherField"] = platform_value!("something"); let result = data_contract_validator .validate(&raw_data_contract) @@ -1861,7 +1865,7 @@ mod indices { } = setup_test(); raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"][0] - ["$ownerId"] = json!("wrong"); + ["$ownerId"] = platform_value!("wrong"); let result = data_contract_validator .validate(&raw_data_contract) @@ -1883,7 +1887,7 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"][0]["unique"] = json!(12); + raw_data_contract["documents"]["indexedDocument"]["indices"][0]["unique"] = platform_value!(12); let result = data_contract_validator .validate(&raw_data_contract) @@ -1908,13 +1912,13 @@ mod indices { for i in 0..10 { let property_name = format!("field{}", i); raw_data_contract["documents"]["indexedDocument"]["properties"] - .insert(property_name.clone(), json!({ "type" : "string"})) + .insert(property_name.clone(), platform_value!({ "type" : "string"})) .expect("properties should be present"); if let Some(JsonValue::Array(ref mut indices)) = raw_data_contract["documents"]["indexedDocument"].get_mut("indices") { - indices.push(json!({ + indices.push(platform_value!({ "name" : format!("{}_index", property_name), "properties" : [ { property_name : "asc"}] })) @@ -1946,14 +1950,14 @@ mod indices { raw_data_contract["documents"]["indexedDocument"]["properties"] .insert( property_name.clone(), - json!({ "type" : "string", "maxLength" : 63 }), + platform_value!({ "type" : "string", "maxLength" : 63 }), ) .expect("properties should be present"); if let Some(JsonValue::Array(ref mut indices)) = raw_data_contract["documents"]["indexedDocument"].get_mut("indices") { - indices.push(json!({ + indices.push(platform_value!({ "name" : format!("index_{}", i), "properties" : [ { property_name : "asc"}], "unique" : true @@ -1989,7 +1993,7 @@ mod indices { .. } = setup_test(); - let index_definition = json!({ + let index_definition = platform_value!({ "name" : "index_1", "properties" : [ { "$id" : "asc"}, @@ -2033,7 +2037,7 @@ mod indices { if let Some(JsonValue::Array(ref mut index_properties)) = raw_data_contract["documents"]["indexedDocument"]["indices"][0].get_mut("properties") { - index_properties.push(json!({ "missingProperty" : "asc"})) + index_properties.push(platform_value!({ "missingProperty" : "asc"})) } else { panic!("the index properties are not array") } @@ -2062,7 +2066,7 @@ mod indices { .. } = setup_test(); - let object_property = json!({ + let object_property = platform_value!({ "type" : "object", "properties" : { "something" : { @@ -2077,12 +2081,12 @@ mod indices { if let Some(JsonValue::Array(ref mut required)) = raw_data_contract["documents"]["indexedDocument"].get_mut("required") { - required.push(json!("objectProperty")) + required.push(platform_value!("objectProperty")) } if let Some(JsonValue::Array(ref mut properties)) = raw_data_contract["documents"]["indexedDocument"]["indices"][0].get_mut("properties") { - properties.push(json!({"objectProperty" : "asc" })) + properties.push(platform_value!({"objectProperty" : "asc" })) } let result = data_contract_validator @@ -2113,7 +2117,7 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedArray"] = json!({ + raw_data_contract["documents"]["indexedArray"] = platform_value!({ "type": "object", "indices": [ { @@ -2329,7 +2333,7 @@ mod indices { } = setup_test(); let indexed_document_definition = &mut raw_data_contract["documents"]["indexedDocument"]; - indexed_document_definition["properties"]["arrayProperty"] = json!({ + indexed_document_definition["properties"]["arrayProperty"] = platform_value!({ "type": "array", "prefixItems": [ { @@ -2343,11 +2347,11 @@ mod indices { "items": false, }); indexed_document_definition["required"] - .push(json!("arrayProperty")) + .push(platform_value!("arrayProperty")) .expect("array should exist"); let index_definition = &mut indexed_document_definition["indices"][0]; index_definition["properties"] - .push(json!({ "arrayProperty" : "asc"})) + .push(platform_value!({ "arrayProperty" : "asc"})) .expect("properties of index should exist"); let result = data_contract_validator @@ -2379,8 +2383,8 @@ mod indices { .. } = setup_test(); - if let Some(JsonValue::Array(arr)) = - raw_data_contract["documents"]["optionalUniqueIndexedDocument"].get_mut("required") + if let Some(Value::Array(arr)) = + raw_data_contract.get_optional_mut_value_at_path("documents.optionalUniqueIndexedDocument.required").expect("expected to get optional value at path") { arr.pop(); } @@ -2427,10 +2431,10 @@ mod indices { for property_name in valid_names { let mut cloned_data_contract = raw_data_contract.clone(); cloned_data_contract["documents"]["indexedDocument"]["properties"][property_name] = - json!({"type" : "string", "maxLength" : 63}); + platform_value!({"type" : "string", "maxLength" : 63}); cloned_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] - .push(json!({ property_name : "asc"})) + .push(platform_value!({ property_name : "asc"})) .unwrap(); cloned_data_contract["documents"]["indexedDocument"]["required"] @@ -2453,7 +2457,7 @@ mod indices { } = setup_test(); let invalid_names = ["a.", ".a"]; - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "a": { @@ -2480,7 +2484,7 @@ mod indices { for invalid_name in invalid_names { let mut cloned_data_contract = raw_data_contract.clone(); cloned_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] - .push(json!({ invalid_name : "asc"})) + .push(platform_value!({ invalid_name : "asc"})) .unwrap(); let result = data_contract_validator .validate(&cloned_data_contract) @@ -2507,7 +2511,7 @@ mod indices { .. } = setup_test(); - let index_definition = json!({ + let index_definition = platform_value!({ "name" : "index_1", "properties" : [ { "$id" : "desc"}, @@ -2545,7 +2549,7 @@ mod signature_level { } = setup_test(); raw_data_contract["documents"]["indexedDocument"]["signatureSecurityLevelRequirement"] = - json!("definitely not a number"); + platform_value!("definitely not a number"); let result = data_contract_validator .validate(&raw_data_contract) @@ -2568,7 +2572,7 @@ mod signature_level { } = setup_test(); raw_data_contract["documents"]["indexedDocument"]["signatureSecurityLevelRequirement"] = - json!(199); + platform_value!(199); let result = data_contract_validator .validate(&raw_data_contract) @@ -2594,7 +2598,7 @@ mod dependent_schemas { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "abc": { @@ -2625,7 +2629,7 @@ mod dependent_schemas { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "abc": { @@ -2656,7 +2660,7 @@ mod dependent_schemas { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "abc": { @@ -2690,7 +2694,7 @@ mod dependent_schemas { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "abc": { @@ -2723,7 +2727,7 @@ mod dependent_schemas { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"] = json!({ + raw_data_contract["documents"]["indexedDocument"] = platform_value!({ "type": "object", "properties": { "abc": { @@ -2757,7 +2761,7 @@ fn should_return_invalid_result_with_circular_ref_pointer() { .. } = setup_test(); - raw_data_contract["$defs"]["object"] = json!({ "$ref" : "#/$defs/object"}); + raw_data_contract["$defs"]["object"] = platform_value!({ "$ref" : "#/$defs/object"}); let result = data_contract_validator .validate(&raw_data_contract) @@ -2929,7 +2933,7 @@ mod indexed_array { } = setup_test(); raw_data_contract["documents"]["withByteArrays"]["properties"]["byteArrayField"] - ["maxItems"] = json!(8192); + ["maxItems"] = platform_value!(8192); let result = data_contract_validator .validate(&raw_data_contract) diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 4c5e035f971..8222a1d0557 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -19,13 +19,11 @@ use crate::{ get_schema_error, }, }, - util::json_value::JsonValueExt, version::{ProtocolVersionValidator, LATEST_VERSION}, }; use jsonschema::error::ValidationErrorKind; -use platform_value::Value; -use serde_json::{json, Value as JsonValue}; +use platform_value::{platform_value, Value}; use test_case::test_case; struct TestData { @@ -122,7 +120,7 @@ async fn property_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: JsonValue::String(missing_property) + property: Value::String(missing_property) } if missing_property == property )); } @@ -136,7 +134,7 @@ async fn protocol_version_should_be_integer() { .. } = setup_test(Action::Create); - raw_state_transition["protocolVersion"] = json!("1"); + raw_state_transition["protocolVersion"] = platform_value!("1"); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -161,7 +159,7 @@ async fn protocol_version_should_be_valid() { .. } = setup_test(Action::Create); - raw_state_transition["protocolVersion"] = json!("-1"); + raw_state_transition["protocolVersion"] = platform_value!("-1"); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -186,7 +184,7 @@ async fn type_should_be_equal_1() { .. } = setup_test(Action::Create); - raw_state_transition["type"] = json!(666); + raw_state_transition["type"] = platform_value!(666); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -214,7 +212,7 @@ async fn property_in_state_transition_should_be_byte_array(property_name: &str) } = setup_test(Action::Create); let array = ["string"; 32]; - raw_state_transition[property_name] = json!(array); + raw_state_transition[property_name] = platform_value!(array); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -248,7 +246,7 @@ async fn owner_id_should_be_no_less_than_32_bytes() { } = setup_test(Action::Create); let array = [0u8; 31]; - raw_state_transition["ownerId"] = json!(array); + raw_state_transition["ownerId"] = platform_value!(array); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -275,7 +273,7 @@ async fn owner_id_should_be_no_longer_than_32_bytes() { let mut array = Vec::new(); array.resize(33, 0u8); - raw_state_transition["ownerId"] = json!(array); + raw_state_transition["ownerId"] = platform_value!(array); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -300,7 +298,7 @@ async fn transitions_should_be_an_array() { .. } = setup_test(Action::Create); - raw_state_transition["transitions"] = json!("not an array"); + raw_state_transition["transitions"] = platform_value!("not an array"); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -325,7 +323,7 @@ async fn transitions_should_have_at_least_one_element() { .. } = setup_test(Action::Create); - raw_state_transition["transitions"] = json!([]); + raw_state_transition["transitions"] = platform_value!([]); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -352,9 +350,9 @@ async fn transitions_should_have_no_more_than_10_elements() { let mut elements = vec![]; for _ in 0..11 { - elements.push(json!({})) + elements.push(platform_value!({})) } - raw_state_transition["transitions"] = JsonValue::Array(elements); + raw_state_transition["transitions"] = Value::Array(elements); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -379,8 +377,8 @@ async fn transitions_should_have_an_object_as_elements() { .. } = setup_test(Action::Create); - let elements = vec![json!(1)]; - raw_state_transition["transitions"] = JsonValue::Array(elements); + let elements = vec![platform_value!(1)]; + raw_state_transition["transitions"] = Value::Array(elements); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -426,7 +424,7 @@ async fn property_in_document_transition_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: JsonValue::String(missing_property) + property: Value::String(missing_property) } if missing_property == property )); } @@ -472,7 +470,7 @@ async fn property_should_be_byte_array(property_name: &str) { } = setup_test(Action::Create); let array = ["string"; 32]; - raw_state_transition["transitions"][0][property_name] = json!(array); + raw_state_transition["transitions"][0][property_name] = platform_value!(array); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -505,7 +503,7 @@ async fn data_contract_id_should_be_byte_array() { .. } = setup_test(Action::Create); - raw_state_transition["transitions"][0]["$dataContractId"] = json!("something"); + raw_state_transition["transitions"][0]["$dataContractId"] = platform_value!("something"); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -532,7 +530,7 @@ async fn property_should_be_no_less_than_32_bytes(property_name: &str) { } = setup_test(Action::Create); let array = [0u8; 31]; - raw_state_transition["transitions"][0][property_name] = json!(array); + raw_state_transition["transitions"][0][property_name] = platform_value!(array); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -564,7 +562,7 @@ async fn id_should_be_no_longer_than_32_bytes(property_name: &str) { let mut array = Vec::new(); array.resize(33, 0u8); - raw_state_transition["transitions"][0][property_name] = json!(array); + raw_state_transition["transitions"][0][property_name] = platform_value!(array); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -621,7 +619,7 @@ async fn type_should_be_defined_in_data_contract() { .. } = setup_test(Action::Create); - raw_state_transition["transitions"][0]["$type"] = json!("wrong"); + raw_state_transition["transitions"][0]["$type"] = platform_value!("wrong"); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -645,7 +643,7 @@ async fn should_throw_invalid_document_transaction_action_error_if_action_is_not .. } = setup_test(Action::Create); - raw_state_transition["transitions"][0]["$action"] = json!(4); + raw_state_transition["transitions"][0]["$action"] = platform_value!(4); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -669,7 +667,7 @@ async fn id_should_be_valid_generated_id() { .. } = setup_test(Action::Create); - raw_state_transition["transitions"][0]["$id"] = json!(generate_random_identifier()); + raw_state_transition["transitions"][0]["$id"] = platform_value!(generate_random_identifier()); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -711,7 +709,7 @@ async fn property_in_replace_transition_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: JsonValue::String(missing_property) + property: Value::String(missing_property) } if missing_property == property )); } @@ -725,7 +723,7 @@ async fn revision_should_be_number() { .. } = setup_test(Action::Replace); - raw_state_transition["transitions"][0]["$revision"] = json!("1"); + raw_state_transition["transitions"][0]["$revision"] = platform_value!("1"); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -750,7 +748,7 @@ async fn revision_should_not_be_fractional() { .. } = setup_test(Action::Replace); - raw_state_transition["transitions"][0]["$revision"] = json!(1.2); + raw_state_transition["transitions"][0]["$revision"] = platform_value!(1.2); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -775,7 +773,7 @@ async fn revision_should_be_at_least_1() { .. } = setup_test(Action::Replace); - raw_state_transition["transitions"][0]["$revision"] = json!(0); + raw_state_transition["transitions"][0]["$revision"] = platform_value!(0); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -817,7 +815,7 @@ async fn id_should_be_present_in_delete_transition() { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: JsonValue::String(missing_property) + property: Value::String(missing_property) } if missing_property == "$id" )); } @@ -844,7 +842,7 @@ async fn signature_should_be_not_less_than_65_bytes() { } = setup_test(Action::Create); let array = [0u8; 64].to_vec(); - raw_state_transition["signature"] = json!(array); + raw_state_transition["signature"] = platform_value!(array); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -870,7 +868,7 @@ async fn signature_should_be_not_longer_than_96_bytes() { } = setup_test(Action::Create); let array = [0u8; 97].to_vec(); - raw_state_transition["signature"] = json!(array); + raw_state_transition["signature"] = platform_value!(array); let result = validate_documents_batch_transition_basic( &protocol_version_validator, @@ -895,7 +893,7 @@ async fn signature_public_key_should_be_an_integer() { .. } = setup_test(Action::Delete); - raw_state_transition["signaturePublicKeyId"] = json!(1.4); + raw_state_transition["signaturePublicKeyId"] = platform_value!(1.4); let result = validate_documents_batch_transition_basic( &protocol_version_validator, diff --git a/packages/rs-platform-value/src/index.rs b/packages/rs-platform-value/src/index.rs new file mode 100644 index 00000000000..ac2190ec266 --- /dev/null +++ b/packages/rs-platform-value/src/index.rs @@ -0,0 +1,271 @@ +use super::Value; +use core::fmt::{self, Display}; +use core::ops; +use crate::value_map::{ValueMap, ValueMapHelper}; + +/// A type that can be used to index into a `platform_value::Value`. +/// +/// The [`get`] and [`get_mut`] methods of `Value` accept any type that +/// implements `Index`, as does the [square-bracket indexing operator]. This +/// trait is implemented for strings which are used as the index into a JSON +/// map, and for `usize` which is used as the index into a JSON array. +/// +/// [`get`]: ../enum.Value.html#method.get +/// [`get_mut`]: ../enum.Value.html#method.get_mut +/// [square-bracket indexing operator]: ../enum.Value.html#impl-Index%3CI%3E +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `platform_value`. +/// +/// # Examples +/// +/// ``` +/// # use platform_value::platform_value; +/// # +/// let data = platform_value!({ "inner": [1, 2, 3] }); +/// +/// // Data is a JSON map so it can be indexed with a string. +/// let inner = &data["inner"]; +/// +/// // Inner is a JSON array so it can be indexed with an integer. +/// let first = &inner[0]; +/// +/// assert_eq!(first, 1); +/// ``` +pub trait Index: private::Sealed { + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>; + + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>; + + /// Panic if array index out of bounds. If key is not already in the object, + /// insert it with a value of null. Panic if Value is a type that cannot be + /// indexed into, except if Value is null then it can be treated as an empty + /// object. + #[doc(hidden)] + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value; +} + +impl Index for usize { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match v { + Value::Array(vec) => vec.get(*self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match v { + Value::Array(vec) => vec.get_mut(*self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + match v { + Value::Array(vec) => { + let len = vec.len(); + vec.get_mut(*self).unwrap_or_else(|| { + panic!( + "cannot access index {} of JSON array of length {}", + self, len + ) + }) + } + _ => panic!("cannot access index {} of JSON {}", self, Type(v)), + } + } +} + +impl Index for str { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + match v { + Value::Map(map) => map.get_key(self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + match v { + Value::Map(map) => map.get_key_mut(self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + if let Value::Null = v { + *v = Value::Map(ValueMap::new()); + } + match v { + Value::Map(map) => { + map.get_key_mut_or_insert(self, Value::Null) + }, + _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), + } + } +} + +impl Index for String { + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + self[..].index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + self[..].index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + self[..].index_or_insert(v) + } +} + +impl<'a, T> Index for &'a T + where + T: ?Sized + Index, +{ + fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { + (**self).index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { + (**self).index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value { + (**self).index_or_insert(v) + } +} + +// Prevent users from implementing the Index trait. +mod private { + pub trait Sealed {} + impl Sealed for usize {} + impl Sealed for str {} + impl Sealed for String {} + impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {} +} + +/// Used in panic messages. +struct Type<'a>(&'a Value); + +impl<'a> Display for Type<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self.0 { + Value::Null => formatter.write_str("null"), + Value::Bool(_) => formatter.write_str("boolean"), + Value::Float(_) => formatter.write_str("float"), + Value::Text(_) => formatter.write_str("string"), + Value::Array(_) => formatter.write_str("array"), + Value::Map(_) => formatter.write_str("map"), + Value::U128(_) => formatter.write_str("u128"), + Value::I128(_) => formatter.write_str("i128"), + Value::U64(_) => formatter.write_str("u64"), + Value::I64(_) => formatter.write_str("i64"), + Value::U32(_) => formatter.write_str("u32"), + Value::I32(_) => formatter.write_str("i32"), + Value::U16(_) => formatter.write_str("u16"), + Value::I16(_) => formatter.write_str("i16"), + Value::U8(_) => formatter.write_str("u8"), + Value::I8(_) => formatter.write_str("i8"), + Value::Bytes(_) => formatter.write_str("bytes"), + Value::Bytes32(_) => formatter.write_str("bytes32"), + Value::Identifier(_) => formatter.write_str("identifier"), + } + } +} + +// The usual semantics of Index is to panic on invalid indexing. +// +// That said, the usual semantics are for things like Vec and BTreeMap which +// have different use cases than Value. If you are working with a Vec, you know +// that you are working with a Vec and you can get the len of the Vec and make +// sure your indices are within bounds. The Value use cases are more +// loosey-goosey. You got some JSON from an endpoint and you want to pull values +// out of it. Outside of this Index impl, you already have the option of using +// value.as_array() and working with the Vec directly, or matching on +// Value::Array and getting the Vec directly. The Index impl means you can skip +// that and index directly into the thing using a concise syntax. You don't have +// to check the type, you don't have to check the len, it is all about what you +// expect the Value to look like. +// +// Basically the use cases that would be well served by panicking here are +// better served by using one of the other approaches: get and get_mut, +// as_array, or match. The value of this impl is that it adds a way of working +// with Value that is not well served by the existing approaches: concise and +// careless and sometimes that is exactly what you want. +impl ops::Index for Value + where + I: Index, +{ + type Output = Value; + + /// Index into a `serde_json::Value` using the syntax `value[0]` or + /// `value["k"]`. + /// + /// Returns `Value::Null` if the type of `self` does not match the type of + /// the index, for example if the index is a string and `self` is an array + /// or a number. Also returns `Value::Null` if the given key does not exist + /// in the map or the given index is not within the bounds of the array. + /// + /// For retrieving deeply nested values, you should have a look at the + /// `Value::pointer` method. + /// + /// # Examples + /// + /// ``` + /// # use platform_value::platform_value; + /// # + /// let data = platform_value!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data["x"]["y"], platform_value!(["z", "zz"])); + /// assert_eq!(data["x"]["y"][0], platform_value!("z")); + /// + /// assert_eq!(data["a"], platform_value!(null)); // returns null for undefined values + /// assert_eq!(data["a"]["b"], platform_value!(null)); // does not panic + /// ``` + fn index(&self, index: I) -> &Value { + static NULL: Value = Value::Null; + index.index_into(self).unwrap_or(&NULL) + } +} + +impl ops::IndexMut for Value + where + I: Index, +{ + /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or + /// `value["k"] = ...`. + /// + /// If the index is a number, the value must be an array of length bigger + /// than the index. Indexing into a value that is not an array or an array + /// that is too small will panic. + /// + /// If the index is a string, the value must be an object or null which is + /// treated like an empty object. If the key is not already present in the + /// object, it will be inserted with a value of null. Indexing into a value + /// that is neither an object nor null will panic. + /// + /// # Examples + /// + /// ``` + /// # use platform_value::platform_value; + /// # + /// let mut data = platform_value!({ "x": 0 }); + /// + /// // replace an existing key + /// data["x"] = platform_value!(1); + /// + /// // insert a new key + /// data["y"] = platform_value!([false, false, false]); + /// + /// // replace an array value + /// data["y"][0] = platform_value!(true); + /// + /// // inserted a deeply nested key + /// data["a"]["b"]["c"]["d"] = platform_value!(true); + /// + /// println!("{}", data); + /// ``` + fn index_mut(&mut self, index: I) -> &mut Value { + index.index_or_insert(self) + } +} diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 7611b9082c0..66ac89227c3 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -19,7 +19,12 @@ impl Value { Ok(Self::insert_in_map(map, key, value)) } - pub fn remove_value(&mut self, key: &str) -> Result { + pub fn insert(&mut self, key: String, value: Value) -> Result<(), Error> { + let map = self.as_map_mut_ref()?; + Ok(Self::insert_in_map_string_value(map, key, value)) + } + + pub fn remove(&mut self, key: &str) -> Result { let map = self.as_map_mut_ref()?; map.remove_key(key) } @@ -287,7 +292,7 @@ impl Value { key: &'a str, ) -> Result, Error> { Self::get_optional_from_map(document_type, key) - .map(|v| v.as_str()) + .map(|v| v.to_str()) .transpose() } @@ -296,7 +301,7 @@ impl Value { document_type: &'a [(Value, Value)], key: &'a str, ) -> Result<&'a str, Error> { - Self::get_from_map(document_type, key).map(|v| v.as_str())? + Self::get_from_map(document_type, key).map(|v| v.to_str())? } /// Retrieves the value of a key from a map if it's a hash256. @@ -406,4 +411,29 @@ impl Value { map.push((Value::Text(inserting_key.to_string()), inserting_value)) } } + + /// Inserts into a map + /// If the element already existed it will replace it + pub fn insert_in_map_string_value( + map: &mut ValueMap, + inserting_key: String, + inserting_value: Value, + ) { + let mut found_value = None; + for (key, value) in map.iter_mut() { + if !key.is_text() { + continue; + } + + if key.as_text().expect("confirmed as text") == inserting_key { + found_value = Some(value); + break; + } + } + if let Some(value) = found_value { + *value = inserting_value; + } else { + map.push((Value::Text(inserting_key), inserting_value)) + } + } } diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs new file mode 100644 index 00000000000..e9138ae3fce --- /dev/null +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -0,0 +1,80 @@ +use crate::{Error, Value}; +use crate::value_map::ValueMapHelper; + +impl Value { + pub fn get_value_at_path<'a>(&'a self, path: &'a str) -> Result<&'a Value, Error> { + let mut split = path.split('.'); + let mut current_value = self; + for path_component in split { + let map = current_value.to_map_ref()?; + current_value = map.get_key(path_component).ok_or_else(|| { + Error::StructureError(format!("unable to get property {path_component} in {path}")) + })?; + } + Ok(current_value) + } + + pub fn get_optional_value_at_path<'a>(&'a self, path: &'a str) -> Result, Error> { + let mut split = path.split('.'); + let mut current_value = self; + for path_component in split { + let map = current_value.to_map_ref()?; + let Some(new_value) = map.get_key(path_component) else { + return Ok(None); + }; + current_value = new_value; + } + Ok(Some(current_value)) + } + + pub fn get_mut_value_at_path<'a>(&'a mut self, path: &'a str) -> Result<&'a mut Value, Error> { + let mut split = path.split('.'); + let mut current_value = self; + for path_component in split { + let map = current_value.to_map_mut()?; + current_value = map.get_key_mut(path_component).ok_or_else(|| { + Error::StructureError(format!("unable to get property {path_component} in {path}")) + })?; + } + Ok(current_value) + } + + pub fn get_optional_mut_value_at_path<'a>(&'a mut self, path: &'a str) -> Result, Error> { + let mut split = path.split('.'); + let mut current_value = self; + for path_component in split { + let map = current_value.to_map_mut()?; + let Some(new_value) = map.get_key_mut(path_component) else { + return Ok(None); + }; + current_value = new_value; + } + Ok(Some(current_value)) + } + + pub fn set_value_at_full_path(&mut self, path: &str, value: Value) -> Result<(), Error> { + let mut split = path.split('.').peekable(); + let mut current_value = self; + let mut last_path_component = None; + while let Some(path_component) = split.next() { + if split.peek().is_none() { + last_path_component = Some(path_component); + } else { + let map = current_value.to_map_mut()?; + current_value = map.get_key_mut(path_component).ok_or_else(|| { + Error::StructureError(format!("unable to get property {path_component} in {path}")) + })?; + }; + } + let Some(last_path_component) = last_path_component else { + return Err(Error::StructureError(format!("path was empty"))); + }; + let map = current_value.as_map_mut_ref()?; + Ok(Self::insert_in_map(map, last_path_component, value)) + } + + pub fn set_value_at_path(&mut self, path: &str, key: &str, value: Value) -> Result<(), Error> { + let map = self.get_mut_value_at_path(path)?.as_map_mut_ref()?; + Ok(Self::insert_in_map(map, key, value)) + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index b0c499e9fee..22adf309f50 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -22,6 +22,9 @@ mod ser; pub mod string_encoding; pub mod system_bytes; pub mod value_map; +mod inner_value_at_path; +mod macros; +mod index; use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; @@ -550,25 +553,44 @@ impl Value { } } - /// If the `Value` is a `String`, returns a reference to the associated `String` data as `Ok`. + /// If the `Value` is a `String`, returns a the associated `&str` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` /// # use platform_value::{Error, Value}; /// # /// let value = Value::Text(String::from("hello")); - /// assert_eq!(value.as_str(), Ok("hello")); + /// assert_eq!(value.to_str(), Ok("hello")); /// /// let value = Value::Bool(true); - /// assert_eq!(value.as_str(), Err(Error::StructureError("value is not a string".to_string()))); + /// assert_eq!(value.to_str(), Err(Error::StructureError("value is not a string".to_string()))); /// ``` - pub fn as_str(&self) -> Result<&str, Error> { + pub fn to_str(&self) -> Result<&str, Error> { match self { Value::Text(s) => Ok(s), _other => Err(Error::StructureError("value is not a string".to_string())), } } + /// If the `Value` is a `String`, returns a reference to the associated `String` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Value}; + /// # + /// let value = Value::Text(String::from("hello")); + /// assert_eq!(value.as_str(), Some("hello")); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.as_str(), None); + /// ``` + pub fn as_str(&self) -> Option<&str> { + match self { + Value::Text(s) => Some(s), + _ => None, + } + } + /// Returns true if the `Value` is a `Bool`. Returns false otherwise. /// /// ``` @@ -875,6 +897,29 @@ impl Value { } } + /// If the `Value` is a Map, returns a mutable reference to the associated Map Data. + /// Returns Err otherwise. + /// + /// ``` + /// # use platform_value::Value; + /// # + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foo")), Value::Text(String::from("bar"))) + /// ] + /// ); + /// + /// value.to_map_mut().unwrap().clear(); + /// assert_eq!(value, Value::Map(vec![])); + /// assert_eq!(value.as_map().unwrap().len(), 0); + /// ``` + pub fn to_map_mut(&mut self) -> Result<&mut Vec<(Value, Value)>, Error> { + match *self { + Value::Map(ref mut map) => Ok(map), + _ => Err(Error::StructureError("value is not a map".to_string())), + } + } + /// If the `Value` is a `Map`, returns a the associated ValueMap which is a `Vec<(Value, Value)>` /// data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs new file mode 100644 index 00000000000..79a54ccf8f3 --- /dev/null +++ b/packages/rs-platform-value/src/macros.rs @@ -0,0 +1,298 @@ +/// Construct a `serde_platform_value::Value` from a JSON literal. +/// +/// ``` +/// # use platform_value::platform_value; +/// # +/// let value = platform_value!({ +/// "code": 200, +/// "success": true, +/// "payload": { +/// "features": [ +/// "serde", +/// "platform_value" +/// ] +/// } +/// }); +/// ``` +/// +/// Variables or expressions can be interpolated into the JSON literal. Any type +/// interpolated into an array element or object value must implement Serde's +/// `Serialize` trait, while any type interpolated into a object key must +/// implement `Into`. If the `Serialize` implementation of the +/// interpolated type decides to fail, or if the interpolated type contains a +/// map with non-string keys, the `platform_value!` macro will panic. +/// +/// ``` +/// # use platform_value::platform_value; +/// # +/// let code = 200; +/// let features = vec!["serde", "platform_value"]; +/// +/// let value = platform_value!({ +/// "code": code, +/// "success": code == 200, +/// "payload": { +/// features[0]: features[1] +/// } +/// }); +/// ``` +/// +/// Trailing commas are allowed inside both arrays and objects. +/// +/// ``` +/// # use platform_value::platform_value; +/// # +/// let value = platform_value!([ +/// "notice", +/// "the", +/// "trailing", +/// "comma -->", +/// ]); +/// ``` +#[macro_export(local_inner_macros)] +macro_rules! platform_value { + // Hide distracting implementation details from the generated rustdoc. + ($($platform_value:tt)+) => { + platform_value_internal!($($platform_value)+) + }; +} + +// Changes are fine as long as `platform_value_internal!` does not call any new helper +// macros and can still be invoked as `platform_value_internal!($($platform_value)+)`. +#[macro_export(local_inner_macros)] +#[doc(hidden)] +macro_rules! platform_value_internal { + ////////////////////////////////////////////////////////////////////////// + // TT muncher for parsing the inside of an array [...]. Produces a vec![...] + // of the elements. + // + // Must be invoked as: platform_value_internal!(@array [] $($tt)*) + ////////////////////////////////////////////////////////////////////////// + + // Done with trailing comma. + (@array [$($elems:expr,)*]) => { + platform_value_internal_vec![$($elems,)*] + }; + + // Done without trailing comma. + (@array [$($elems:expr),*]) => { + platform_value_internal_vec![$($elems),*] + }; + + // Next element is `null`. + (@array [$($elems:expr,)*] null $($rest:tt)*) => { + platform_value_internal!(@array [$($elems,)* platform_value_internal!(null)] $($rest)*) + }; + + // Next element is `true`. + (@array [$($elems:expr,)*] true $($rest:tt)*) => { + platform_value_internal!(@array [$($elems,)* platform_value_internal!(true)] $($rest)*) + }; + + // Next element is `false`. + (@array [$($elems:expr,)*] false $($rest:tt)*) => { + platform_value_internal!(@array [$($elems,)* platform_value_internal!(false)] $($rest)*) + }; + + // Next element is an array. + (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => { + platform_value_internal!(@array [$($elems,)* platform_value_internal!([$($array)*])] $($rest)*) + }; + + // Next element is a map. + (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => { + platform_value_internal!(@array [$($elems,)* platform_value_internal!({$($map)*})] $($rest)*) + }; + + // Next element is an expression followed by comma. + (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => { + platform_value_internal!(@array [$($elems,)* platform_value_internal!($next),] $($rest)*) + }; + + // Last element is an expression with no trailing comma. + (@array [$($elems:expr,)*] $last:expr) => { + platform_value_internal!(@array [$($elems,)* platform_value_internal!($last)]) + }; + + // Comma after the most recent element. + (@array [$($elems:expr),*] , $($rest:tt)*) => { + platform_value_internal!(@array [$($elems,)*] $($rest)*) + }; + + // Unexpected token after most recent element. + (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => { + platform_value_unexpected!($unexpected) + }; + + ////////////////////////////////////////////////////////////////////////// + // TT muncher for parsing the inside of an object {...}. Each entry is + // inserted into the given map variable. + // + // Must be invoked as: platform_value_internal!(@object $map () ($($tt)*) ($($tt)*)) + // + // We require two copies of the input tokens so that we can match on one + // copy and trigger errors on the other copy. + ////////////////////////////////////////////////////////////////////////// + + // Done. + (@object $object:ident () () ()) => {}; + + // Insert the current entry followed by trailing comma. + (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { + let _ = $object.insert(($($key)+).into(), $value); + platform_value_internal!(@object $object () ($($rest)*) ($($rest)*)); + }; + + // Current entry followed by unexpected token. + (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => { + platform_value_unexpected!($unexpected); + }; + + // Insert the last entry without trailing comma. + (@object $object:ident [$($key:tt)+] ($value:expr)) => { + let _ = $object.insert(($($key)+).into(), $value); + }; + + // Next value is `null`. + (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => { + platform_value_internal!(@object $object [$($key)+] (platform_value_internal!(null)) $($rest)*); + }; + + // Next value is `true`. + (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => { + platform_value_internal!(@object $object [$($key)+] (platform_value_internal!(true)) $($rest)*); + }; + + // Next value is `false`. + (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => { + platform_value_internal!(@object $object [$($key)+] (platform_value_internal!(false)) $($rest)*); + }; + + // Next value is an array. + (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => { + platform_value_internal!(@object $object [$($key)+] (platform_value_internal!([$($array)*])) $($rest)*); + }; + + // Next value is a map. + (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => { + platform_value_internal!(@object $object [$($key)+] (platform_value_internal!({$($map)*})) $($rest)*); + }; + + // Next value is an expression followed by comma. + (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => { + platform_value_internal!(@object $object [$($key)+] (platform_value_internal!($value)) , $($rest)*); + }; + + // Last value is an expression with no trailing comma. + (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => { + platform_value_internal!(@object $object [$($key)+] (platform_value_internal!($value))); + }; + + // Missing value for last entry. Trigger a reasonable error message. + (@object $object:ident ($($key:tt)+) (:) $copy:tt) => { + // "unexpected end of macro invocation" + platform_value_internal!(); + }; + + // Missing colon and value for last entry. Trigger a reasonable error + // message. + (@object $object:ident ($($key:tt)+) () $copy:tt) => { + // "unexpected end of macro invocation" + platform_value_internal!(); + }; + + // Misplaced colon. Trigger a reasonable error message. + (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => { + // Takes no arguments so "no rules expected the token `:`". + platform_value_unexpected!($colon); + }; + + // Found a comma inside a key. Trigger a reasonable error message. + (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => { + // Takes no arguments so "no rules expected the token `,`". + platform_value_unexpected!($comma); + }; + + // Key is fully parenthesized. This avoids clippy double_parens false + // positives because the parenthesization may be necessary here. + (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => { + platform_value_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*)); + }; + + // Refuse to absorb colon token into key expression. + (@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => { + platform_value_expect_expr_comma!($($unexpected)+); + }; + + // Munch a token into the current key. + (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => { + platform_value_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*)); + }; + + ////////////////////////////////////////////////////////////////////////// + // The main implementation. + // + // Must be invoked as: platform_value_internal!($($platform_value)+) + ////////////////////////////////////////////////////////////////////////// + + (null) => { + $crate::Value::Null + }; + + (true) => { + $crate::Value::Bool(true) + }; + + (false) => { + $crate::Value::Bool(false) + }; + + ([]) => { + $crate::Value::Array(platform_value_internal_vec![]) + }; + + ([ $($tt:tt)+ ]) => { + $crate::Value::Array(platform_value_internal!(@array [] $($tt)+)) + }; + + ({}) => { + $crate::Value::Map($crate::ValueMap::new()) + }; + + ({ $($tt:tt)+ }) => { + $crate::Value::Map({ + let mut object = $crate::ValueMap::new(); + platform_value_internal!(@object object () ($($tt)+) ($($tt)+)); + object + }) + }; + + // Any Serialize type: numbers, strings, struct literals, variables etc. + // Must be below every other rule. + ($other:expr) => { + $crate::to_value(&$other).unwrap() + }; +} + +// The platform_value_internal macro above cannot invoke vec directly because it uses +// local_inner_macros. A vec invocation there would resolve to $crate::vec. +// Instead invoke vec here outside of local_inner_macros. +#[macro_export] +#[doc(hidden)] +macro_rules! platform_value_internal_vec { + ($($content:tt)*) => { + vec![$($content)*] + }; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! platform_value_unexpected { + () => {}; +} + +#[macro_export] +#[doc(hidden)] +macro_rules! platform_value_expect_expr_comma { + ($e:expr , $($tt:tt)*) => {}; +} diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 6db087c5c21..e9df9d79233 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,5 +1,6 @@ use crate::{Error, Value}; use std::collections::BTreeMap; +use std::collections::hash_map::Entry; pub type ValueMap = Vec<(Value, Value)>; From 6e5b6b6ae3ef8fda0b696f355de5e7d917b967a9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 12 Mar 2023 04:06:37 +0700 Subject: [PATCH 104/228] moooor --- .../validation/data_contract_validator.rs | 8 +- .../validation/multi_validator.rs | 20 +++-- packages/rs-dpp/src/document/serialize.rs | 1 + ...lidate_documents_batch_transition_basic.rs | 4 +- .../identity_create_transition.rs | 1 - .../identity_topup_transition.rs | 74 ++----------------- .../identity_update_transition.rs | 19 ++--- ...a_contract_update_transition_basic_spec.rs | 2 +- ..._documents_batch_transitions_basic_spec.rs | 8 +- packages/rs-platform-value/src/inner_value.rs | 19 ++++- packages/rs-platform-value/src/macros.rs | 4 +- packages/wasm-dpp/src/identifier/mod.rs | 1 + 12 files changed, 56 insertions(+), 105 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs index 6650babacbe..27c97fc973b 100644 --- a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs @@ -53,7 +53,7 @@ pub struct DataContractValidator { } impl DataValidator for DataContractValidator { - type Item = JsonValue; + type Item = Value; fn validate( &self, @@ -78,7 +78,7 @@ impl DataContractValidator { trace!("validating against data contract meta validator"); result.merge(JsonSchemaValidator::validate_data_contract_schema( - raw_data_contract.into(), + &raw_data_contract.into(), )); if !result.is_valid() { return Ok(result); @@ -88,9 +88,7 @@ impl DataContractValidator { result.merge( self.protocol_version_validator.validate( raw_data_contract - .get_u64("protocolVersion") - .map_err(|_| anyhow!("protocolVersion isn't unsigned integer"))? - as u32, + .get_integer("protocolVersion").map_err(ProtocolError::ValueError)?, )?, ); if !result.is_valid() { diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 70668ae426b..bff5038e6e8 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -27,14 +27,18 @@ pub fn validate( let new_path = format!("{}/{}", path, key); values_queue.push((current_value, new_path)) } - for validator in validators { - validator(&path, key.to_str().map_err(ProtocolError::ValueError)?, value, current_value, &mut result); + if let Some(Value::Text(key)) = key.as_str() { + for validator in validators { + validator(&path, key, value, current_value, &mut result); + } + } else { + result.add_error(ProtocolError::DecodingError("keys of properties must be strings".to_string())); } } } Value::Array(arr) => { for (i, value) in arr.iter().enumerate() { - if value.is_object() { + if value.is_map() { let new_path = format!("{}/[{}]", path, i); values_queue.push((value, new_path)) } @@ -69,7 +73,7 @@ pub fn pattern_is_valid_regex_validator( IncompatibleRe2PatternError::new( String::new(), path.to_string(), - format!("{} is not a string", string), + format!("{} is not a string", path), ), )); } @@ -83,9 +87,10 @@ pub fn byte_array_has_no_items_as_parent_validator( value: &Value, result: &mut ValidationResult<()>, ) { + if key == "byteArray" && value.is_bool() - && (parent.get("items").is_some() || parent.get("prefixItems").is_some()) + && (parent.get("items").map_err(ProtocolError::ValueError)?.is_some() || parent.get("prefixItems").map_err(ProtocolError::ValueError)?.is_some()) { result.add_error(BasicError::JsonSchemaCompilationError(format!( "invalid path: '{}': byteArray cannot be used with 'items' or 'prefixItems", @@ -97,6 +102,7 @@ pub fn byte_array_has_no_items_as_parent_validator( #[cfg(test)] mod test { use serde_json::json; + use platform_value::platform_value; use super::*; @@ -200,7 +206,7 @@ mod test { fn invalid_result_for_array_of_object() { let mut schema = get_document_schema(); schema["properties"]["arrayOfObject"]["items"]["properties"]["simple"]["pattern"] = - json!("^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$"); + platform_value!("^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$"); let result = validate(&schema, &[pattern_is_valid_regex_validator]); let consensus_error = result.errors.get(0).expect("the error should be returned"); @@ -225,7 +231,7 @@ mod test { fn invalid_result_for_array_of_objects() { let mut schema = get_document_schema(); schema["properties"]["arrayOfObjects"]["items"][0]["properties"]["simple"]["pattern"] = - json!("^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$"); + platform_value!("^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$"); let result = validate(&schema, &[pattern_is_valid_regex_validator]); let consensus_error = result.errors.get(0).expect("the error should be returned"); diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index e53a2a27f01..ca9191d9543 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -22,6 +22,7 @@ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::convert::TryFrom; use std::io::{BufReader, Read}; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; //todo: delete in later PR #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index a3bf07f8572..38b8e0c0223 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -216,13 +216,13 @@ fn get_enriched_contracts_by_action( fn validate_raw_transitions<'a>( data_contract: &DataContract, - raw_document_transitions: Vec>, + raw_document_transitions: impl IntoIterator>, enriched_contracts_by_action: &HashMap, owner_id: &Identifier, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); - for raw_document_transition in raw_document_transitions.iter() { + for raw_document_transition in raw_document_transitions { let Some(document_type) = raw_document_transition.get_optional_str("$type").map_err(ProtocolError::ValueError) else { result.add_error(BasicError::MissingDocumentTransitionTypeError); return Ok(result); diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 6e90a7310f1..368ab8ea532 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -31,7 +31,6 @@ mod property_names { #[derive(Debug, Copy, Clone, Default)] pub struct SerializationOptions { pub skip_signature: bool, - pub skip_identifiers_conversion: bool, } #[derive(Debug, Clone)] diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 41d2dff1dba..288e2106ef3 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -13,7 +13,6 @@ use crate::state_transition::state_transition_execution_context::StateTransition use crate::state_transition::{ StateTransition, StateTransitionConvert, StateTransitionLike, StateTransitionType, }; -use crate::util::json_value::JsonValueExt; use crate::version::LATEST_VERSION; use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; use platform_value::string_encoding::Encoding; @@ -63,7 +62,7 @@ impl Serialize for IdentityTopUpTransition { S: Serializer, { let raw = self - .to_json_object(Default::default()) + .to_object(Default::default()) .map_err(|e| S::Error::custom(e.to_string()))?; raw.serialize(serializer) @@ -152,52 +151,6 @@ impl IdentityTopUpTransition { &self.identity_id } - /// Get raw state transition - pub fn to_json_object( - &self, - options: SerializationOptions, - ) -> Result { - let mut json_map = JsonValue::Object(Default::default()); - - if !options.skip_signature { - let sig = self.signature.iter().map(|num| JsonValue::from(*num)); - json_map.insert( - property_names::SIGNATURE.to_string(), - JsonValue::Array(sig.collect()), - )?; - } - - if !options.skip_identifiers_conversion { - let bytes = self - .identity_id - .buffer - .iter() - .map(|num| JsonValue::from(*num)); - json_map.insert( - property_names::IDENTITY_ID.to_string(), - JsonValue::Array(bytes.collect()), - )?; - } else { - json_map.insert( - property_names::IDENTITY_ID.to_string(), - JsonValue::String(self.identity_id.to_string(Encoding::Base58)), - )?; - } - - json_map.insert( - property_names::ASSET_LOCK_PROOF.to_string(), - self.asset_lock_proof.as_ref().try_into()?, - )?; - - // TODO ?? - json_map.insert( - property_names::PROTOCOL_VERSION.to_string(), - JsonValue::Number(self.get_protocol_version().into()), - )?; - - Ok(json_map) - } - pub fn set_protocol_version(&mut self, protocol_version: u32) { self.protocol_version = protocol_version; } @@ -219,11 +172,11 @@ impl StateTransitionConvert for IdentityTopUpTransition { vec![] } - fn to_object(&self, skip_signature: bool) -> Result { - let mut json_value: JsonValue = serde_json::to_value(self)?; + fn to_object(&self, skip_signature: bool) -> Result { + let mut json_value: Value = platform_value::to_value(self)?; if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { + if let Value::Object(ref mut o) = json_value { for path in Self::signature_property_paths() { o.remove(path); } @@ -234,24 +187,7 @@ impl StateTransitionConvert for IdentityTopUpTransition { } fn to_json(&self, skip_signature: bool) -> Result { - let mut json = serde_json::Value::Object(Default::default()); - - // TODO: super.toJSON() - - if skip_signature { - if let JsonValue::Object(ref mut o) = json { - for path in Self::signature_property_paths() { - o.remove(path); - } - } - } - - json.insert( - property_names::ASSET_LOCK_PROOF.to_string(), - self.asset_lock_proof.as_ref().try_into()?, - )?; - - Ok(json) + self.to_object(skip_signature).map(|value| value.into()) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 4c0c1940766..736e537d46d 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -96,17 +96,13 @@ impl IdentityUpdateTransition { .map_err(ProtocolError::ValueError)? .unwrap_or(LATEST_VERSION); let signature = raw_object - .get_optional_bytes(property_names::SIGNATURE) - .map_err(ProtocolError::ValueError)? - .unwrap_or_default(); + .get_bytes(property_names::SIGNATURE) + .map_err(ProtocolError::ValueError)?; let signature_public_key_id = raw_object - .get_u64(property_names::SIGNATURE_PUBLIC_KEY_ID) - .unwrap_or_default() as KeyID; - let identity_id = Identifier::from( - raw_object - .get_hash256(property_names::IDENTITY_ID) - .map_err(ProtocolError::ValueError)?, - ); + .get_integer(property_names::SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)?; + let identity_id = raw_object + .get_identifier(property_names::IDENTITY_ID) + .map_err(ProtocolError::ValueError)?; let revision = raw_object .get_integer(property_names::REVISION) @@ -114,8 +110,7 @@ impl IdentityUpdateTransition { let add_public_keys = get_list(&mut raw_object, property_names::ADD_PUBLIC_KEYS)?; let disable_public_keys = get_list(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; let public_keys_disabled_at = raw_object - .remove_into::(property_names::PUBLIC_KEYS_DISABLED_AT) - .ok(); + .remove_optional_integer(property_names::PUBLIC_KEYS_DISABLED_AT).map_err(ProtocolError::ValueError)?; Ok(IdentityUpdateTransition { protocol_version, diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 19912c05cb9..69693cc8cd2 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -88,7 +88,7 @@ async fn should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::String(missing_property) + property: Value::Text(missing_property) } if missing_property == property )); } diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 8222a1d0557..bdf68dccd35 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -120,7 +120,7 @@ async fn property_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::String(missing_property) + property: Value::Text(missing_property) } if missing_property == property )); } @@ -424,7 +424,7 @@ async fn property_in_document_transition_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::String(missing_property) + property: Value::Text(missing_property) } if missing_property == property )); } @@ -709,7 +709,7 @@ async fn property_in_replace_transition_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::String(missing_property) + property: Value::Text(missing_property) } if missing_property == property )); } @@ -815,7 +815,7 @@ async fn id_should_be_present_in_delete_transition() { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::String(missing_property) + property: Value::Text(missing_property) } if missing_property == "$id" )); } diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 66ac89227c3..608a01d71e4 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -2,14 +2,19 @@ use crate::value_map::{ValueMap, ValueMapHelper}; use crate::Value::Bool; use crate::{Error, Value}; use std::collections::BTreeMap; +use crate::identifier::Identifier; impl Value { + pub fn get<'a>(&'a self, key: &'a str) -> Result, Error> { + self.get_optional_value(key) + } + pub fn get_value<'a>(&'a self, key: &'a str) -> Result<&'a Value, Error> { let map = self.to_map()?; Self::get_from_map(map, key) } - pub fn get_optional_value<'a>(&'a self, key: &'a str) -> Result, Error> { + pub fn get_optional_value<'a>(&'a self, key: &'a str) -> Result, Error> { let map = self.to_map()?; Ok(Self::get_optional_from_map(map, key)) } @@ -93,7 +98,7 @@ impl Value { value.into_bytes() } - pub fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { + pub fn remove_optional_bytes(&mut self, key: &str) -> Result>, Error> { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) .map(|v| v.into_bytes()) @@ -182,6 +187,16 @@ impl Value { Self::inner_optional_hash256_value(map, key) } + pub fn get_identifier<'a>(&'a self, key: &'a str) -> Result { + let map = self.to_map()?; + Ok(Identifier::new(Self::inner_hash256_value(map, key)?)) + } + + pub fn get_optional_identifier<'a>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Ok(Self::inner_optional_hash256_value(map, key)?.map(|identifier| Identifier::new(identifier))) + } + pub fn get_hash256<'a>(&'a self, key: &'a str) -> Result<[u8; 32], Error> { let map = self.to_map()?; Self::inner_hash256_value(map, key) diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index 79a54ccf8f3..6d60579f38f 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -256,12 +256,12 @@ macro_rules! platform_value_internal { }; ({}) => { - $crate::Value::Map($crate::ValueMap::new()) + $crate::Value::Map($crate::value_map::ValueMap::new()) }; ({ $($tt:tt)+ }) => { $crate::Value::Map({ - let mut object = $crate::ValueMap::new(); + let mut object = $crate::value_map::ValueMap::new(); platform_value_internal!(@object object () ($($tt)+) ($($tt)+)); object }) diff --git a/packages/wasm-dpp/src/identifier/mod.rs b/packages/wasm-dpp/src/identifier/mod.rs index d7d3915bbeb..7ac160c9ca9 100644 --- a/packages/wasm-dpp/src/identifier/mod.rs +++ b/packages/wasm-dpp/src/identifier/mod.rs @@ -13,6 +13,7 @@ use crate::utils::Inner; use crate::utils::ToSerdeJSONExt; use crate::utils::WithJsError; use dpp::identifier; +use dpp::platform_value::string_encoding::Encoding; #[derive(Serialize, Deserialize, PartialEq, Eq)] enum IdentifierSource { From ce8f43767dc8152cb40950350d5ed03e72893ce1 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 12 Mar 2023 04:45:22 +0700 Subject: [PATCH 105/228] more work --- .../document_type/document_type.rs | 6 +- .../data_contract_create_transition/mod.rs | 22 ++-- .../data_contract_update_transition/mod.rs | 10 +- .../validation/data_contract_validator.rs | 5 +- .../validation/multi_validator.rs | 60 ++++++----- .../validate_data_contract_max_depth.rs | 50 +++++---- packages/rs-dpp/src/document/document.rs | 2 +- .../rs-dpp/src/document/document_validator.rs | 24 ++++- .../rs-dpp/src/document/extended_document.rs | 8 +- packages/rs-dpp/src/document/serialize.rs | 2 +- .../state_transition/asset_lock_proof/mod.rs | 2 +- .../identity_create_transition.rs | 1 + .../identity_update_transition.rs | 10 +- ...lidate_identity_update_transition_basic.rs | 32 +++--- .../validation/public_keys_validator.rs | 8 +- .../data_contract_validator_spec.rs | 100 +++++++++++++----- .../validation/public_keys_validator_spec.rs | 73 +++++++------ packages/rs-dpp/src/tests/utils/utils.rs | 15 +-- packages/rs-platform-value/src/index.rs | 18 ++-- packages/rs-platform-value/src/inner_value.rs | 14 ++- .../src/inner_value_at_path.rs | 18 +++- packages/rs-platform-value/src/lib.rs | 38 +++++-- packages/rs-platform-value/src/macros.rs | 4 +- packages/rs-platform-value/src/value_map.rs | 2 +- 24 files changed, 322 insertions(+), 202 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index e1344893100..97cdec8f2cf 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -183,12 +183,14 @@ impl DocumentType { // Do documents of this type keep history? (Overrides contract value) let documents_keep_history: bool = - Value::inner_optional_bool_value(document_type_value_map, "documentsKeepHistory").map_err(ProtocolError::ValueError)? + Value::inner_optional_bool_value(document_type_value_map, "documentsKeepHistory") + .map_err(ProtocolError::ValueError)? .unwrap_or(default_keeps_history); // Are documents of this type mutable? (Overrides contract value) let documents_mutable: bool = - Value::inner_optional_bool_value(document_type_value_map, "documentsMutable").map_err(ProtocolError::ValueError)? + Value::inner_optional_bool_value(document_type_value_map, "documentsMutable") + .map_err(ProtocolError::ValueError)? .unwrap_or(default_mutability); let index_values = Value::inner_optional_array_slice_value( diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 83564ebc56e..1de2d8eba4a 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -3,10 +3,10 @@ use std::convert::TryInto; use anyhow::anyhow; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::{ data_contract::DataContract, @@ -77,9 +77,11 @@ impl DataContractCreateTransition { data_contract: DataContract::from_raw_object( raw_data_contract_update_transition .remove(DATA_CONTRACT) - .map_err(|_| ProtocolError::DecodingError( - "data contract missing on state transition".to_string(), - ))?, + .map_err(|_| { + ProtocolError::DecodingError( + "data contract missing on state transition".to_string(), + ) + })?, )?, ..Default::default() }) @@ -250,12 +252,12 @@ mod test { fn get_test_data() -> TestData { let data_contract = get_data_contract_fixture(None); - let state_transition = DataContractCreateTransition::from_raw_object( - Value::from([(PROTOCOL_VERSION, version::LATEST_VERSION.into()), - (ENTROPY, Value::Bytes32(data_contract.entropy)), - (DATA_CONTRACT, data_contract.to_object().unwrap()), - ]) - ).expect("state transition should be created without errors"); + let state_transition = DataContractCreateTransition::from_raw_object(Value::from([ + (PROTOCOL_VERSION, version::LATEST_VERSION.into()), + (ENTROPY, Value::Bytes32(data_contract.entropy)), + (DATA_CONTRACT, data_contract.to_object().unwrap()), + ])) + .expect("state transition should be created without errors"); TestData { data_contract, diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 9c3fa736145..100e9e850f4 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -1,9 +1,9 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::{ data_contract::DataContract, @@ -68,9 +68,11 @@ impl DataContractUpdateTransition { data_contract: DataContract::from_raw_object( raw_data_contract_update_transition .remove(DATA_CONTRACT) - .map_err(|_| ProtocolError::DecodingError( - "data contract missing on state transition".to_string(), - ))?, + .map_err(|_| { + ProtocolError::DecodingError( + "data contract missing on state transition".to_string(), + ) + })?, )?, ..Default::default() }) diff --git a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs index 27c97fc973b..ab3b0d4f900 100644 --- a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs @@ -4,8 +4,8 @@ use anyhow::anyhow; use itertools::Itertools; use lazy_static::lazy_static; use log::trace; -use serde_json::Value as JsonValue; use platform_value::Value; +use serde_json::Value as JsonValue; use crate::consensus::basic::data_contract::{ DuplicateIndexError, DuplicateIndexNameError, InvalidCompoundIndexError, @@ -88,7 +88,8 @@ impl DataContractValidator { result.merge( self.protocol_version_validator.validate( raw_data_contract - .get_integer("protocolVersion").map_err(ProtocolError::ValueError)?, + .get_integer("protocolVersion") + .map_err(ProtocolError::ValueError)?, )?, ); if !result.is_valid() { diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index bff5038e6e8..69c0407d512 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -1,21 +1,17 @@ -use regex::Regex; use platform_value::Value; +use regex::Regex; use crate::consensus::basic::data_contract::IncompatibleRe2PatternError; -use crate::{consensus::{basic::BasicError, ConsensusError}, ProtocolError, validation::ValidationResult}; +use crate::{ + consensus::{basic::BasicError, ConsensusError}, + validation::ValidationResult, + ProtocolError, +}; -pub type SubValidator = fn( - path: &str, - key: &str, - parent: &Value, - value: &Value, - result: &mut ValidationResult<()>, -); +pub type SubValidator = + fn(path: &str, key: &str, parent: &Value, value: &Value, result: &mut ValidationResult<()>); -pub fn validate( - raw_data_contract: &Value, - validators: &[SubValidator], -) -> ValidationResult<()> { +pub fn validate(raw_data_contract: &Value, validators: &[SubValidator]) -> ValidationResult<()> { let mut result = ValidationResult::default(); let mut values_queue: Vec<(&Value, String)> = vec![(raw_data_contract, String::from(""))]; @@ -23,16 +19,18 @@ pub fn validate( match value { Value::Map(current_map) => { for (key, current_value) in current_map.iter() { - if current_value.is_object() || current_value.is_array() { + if current_value.is_map() || current_value.is_array() { let new_path = format!("{}/{}", path, key); values_queue.push((current_value, new_path)) } - if let Some(Value::Text(key)) = key.as_str() { + if let Some(key) = key.as_str() { for validator in validators { validator(&path, key, value, current_value, &mut result); } } else { - result.add_error(ProtocolError::DecodingError("keys of properties must be strings".to_string())); + result.add_error(ConsensusError::SerializedObjectParsingError( + "keys of properties must be strings".to_string(), + )); } } } @@ -87,10 +85,16 @@ pub fn byte_array_has_no_items_as_parent_validator( value: &Value, result: &mut ValidationResult<()>, ) { - if key == "byteArray" && value.is_bool() - && (parent.get("items").map_err(ProtocolError::ValueError)?.is_some() || parent.get("prefixItems").map_err(ProtocolError::ValueError)?.is_some()) + && (parent + .get("items") + .map_err(ProtocolError::ValueError)? + .is_some() + || parent + .get("prefixItems") + .map_err(ProtocolError::ValueError)? + .is_some()) { result.add_error(BasicError::JsonSchemaCompilationError(format!( "invalid path: '{}': byteArray cannot be used with 'items' or 'prefixItems", @@ -101,8 +105,8 @@ pub fn byte_array_has_no_items_as_parent_validator( #[cfg(test)] mod test { - use serde_json::json; use platform_value::platform_value; + use serde_json::json; use super::*; @@ -114,7 +118,7 @@ mod test { #[test] fn should_return_error_if_bytes_array_parent_contains_items_or_prefix_items() { - let schema : Value = json!( + let schema: Value = json!( { "type": "object", "properties": { @@ -129,7 +133,8 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ).into(); + ) + .into(); let mut result = validate(&schema, &[byte_array_has_no_items_as_parent_validator]); assert_eq!(2, result.errors().len()); let first_error = get_basic_error(result.errors.pop().unwrap()); @@ -147,7 +152,7 @@ mod test { #[test] fn should_return_valid_result() { - let schema : Value = json!( + let schema: Value = json!( { "type": "object", "properties": { @@ -160,14 +165,15 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ).into(); + ) + .into(); assert!(validate(&schema, &[pattern_is_valid_regex_validator]).is_valid()) } #[test] fn should_return_invalid_result() { - let schema : Value = json!({ + let schema: Value = json!({ "type": "object", "properties": { "foo": { "type": "integer" }, @@ -179,7 +185,8 @@ mod test { "required": ["foo"], "additionalProperties": false, - }).into(); + }) + .into(); let result = validate(&schema, &[pattern_is_valid_regex_validator]); let consensus_error = result.errors.get(0).expect("the error should be returned"); @@ -329,7 +336,8 @@ mod test { ] } } - }).into() + }) + .into() } fn get_basic_error(error: ConsensusError) -> BasicError { diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index 4d0fcfe7c48..ee81e50e677 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -4,9 +4,7 @@ use anyhow::bail; use platform_value::Value; use crate::consensus::basic::data_contract::InvalidJsonSchemaRefError; -use crate::{ - consensus::basic::BasicError, validation::ValidationResult, -}; +use crate::{consensus::basic::BasicError, validation::ValidationResult, ProtocolError}; const MAX_DEPTH: usize = 500; @@ -30,6 +28,7 @@ fn calc_max_depth(value: &Value) -> Result { let mut values_depth_queue: Vec<(&Value, usize)> = vec![(value, 0)]; let mut max_depth: usize = 0; let mut visited: BTreeSet<*const Value> = BTreeSet::new(); + let ref_value = Value::Text("$ref".to_string()); while let Some((value, depth)) = values_depth_queue.pop() { match value { @@ -40,7 +39,7 @@ fn calc_max_depth(value: &Value) -> Result { } for (property_name, v) in map { // handling the internal references - if property_name == "$ref" { + if property_name == ref_value { if let Some(uri) = v.as_str() { let resolved = resolve_uri(value, uri).map_err(|e| { BasicError::InvalidJsonSchemaRefError( @@ -89,13 +88,15 @@ fn calc_max_depth(value: &Value) -> Result { Ok(max_depth) } -fn resolve_uri<'a>(value: &'a Value, uri: &str) -> Result<&'a Value, anyhow::Error> { +fn resolve_uri<'a>(value: &'a Value, uri: &str) -> Result<&'a Value, ProtocolError> { if !uri.starts_with("#/") { bail!("only local references are allowed") } let string_path = uri.strip_prefix("#/").unwrap().replace('/', "."); - value.get_at_path(&string_path) + value + .get_value_at_path(&string_path) + .map_err(ProtocolError::ValueError) } #[cfg(test)] @@ -106,7 +107,7 @@ mod test { #[test] fn should_return_error_when_cycle_is_spotted() { - let schema : Value = json!( + let schema: Value = json!( { "$defs" : { "object": { @@ -130,7 +131,8 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ).into(); + ) + .into(); let result = calc_max_depth(&schema); let err = get_ref_error(result); @@ -142,7 +144,7 @@ mod test { #[test] fn should_calculate_valid_depth_with_included_ref() { - let schema : Value = json!( + let schema: Value = json!( { "$defs" : { "object": { @@ -165,14 +167,15 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ).into(); + ) + .into(); let result = calc_max_depth(&schema); assert!(matches!(result, Ok(5))); } #[test] fn should_return_error_with_non_existing_ref() { - let schema : Value = json!( + let schema: Value = json!( { "type": "object", "properties": { @@ -188,7 +191,8 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ).into(); + ) + .into(); let result = calc_max_depth(&schema); let err = get_ref_error(result); @@ -197,7 +201,7 @@ mod test { #[test] fn should_return_error_with_external_ref() { - let schema : Value = json!( + let schema: Value = json!( { "type": "object", "properties": { @@ -213,7 +217,8 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ).into(); + ) + .into(); let result = calc_max_depth(&schema); let err = get_ref_error(result); @@ -226,7 +231,7 @@ mod test { #[test] fn should_return_error_with_empty_ref() { - let schema : Value = json!( + let schema: Value = json!( { "type": "object", "properties": { @@ -242,7 +247,8 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ).into(); + ) + .into(); let result = calc_max_depth(&schema); let err = get_ref_error(result); @@ -254,7 +260,7 @@ mod test { #[test] fn should_calculate_valid_depth() { - let schema : Value = json!( + let schema: Value = json!( { "type": "object", "properties": { @@ -267,19 +273,20 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ).into(); + ) + .into(); assert!(matches!(calc_max_depth(&schema), Ok(3))); } #[test] fn should_calculate_valid_depth_for_empty_json() { - let schema : Value = json!({}).into(); + let schema: Value = json!({}).into(); assert!(matches!(calc_max_depth(&schema), Ok(1))); } #[test] fn should_calculate_valid_depth_for_schema_containing_array() { - let schema : Value = json!({ + let schema: Value = json!({ "type": "object", "properties": { "foo": { "type": "integer" }, @@ -290,7 +297,8 @@ mod test { }, "required": [ { "alpha": "value_alpha"}, { "bravo" : { "a" : "b"} }], - }).into(); + }) + .into(); assert!(matches!(calc_max_depth(&schema), Ok(4))); } diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 767dbc9e614..f876e2cfeeb 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -43,9 +43,9 @@ use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType}; use crate::data_contract::errors::DataContractError; diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 18e74f8a33d..a39f4d40061 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -229,7 +229,10 @@ mod test { } = get_test_data(); raw_document - .insert(String::from(property_name), Value::Text("string".to_string())) + .insert( + String::from(property_name), + Value::Text("string".to_string()), + ) .unwrap(); let result = document_validator @@ -266,7 +269,10 @@ mod test { let too_short_id = [0u8; 31]; raw_document - .insert(String::from(property_name), Value::Bytes(too_short_id.to_vec())) + .insert( + String::from(property_name), + Value::Bytes(too_short_id.to_vec()), + ) .unwrap(); let result = document_validator @@ -335,7 +341,10 @@ mod test { } = get_test_data(); raw_document - .insert(String::from("$protocolVersion"), Value::Text("1".to_string())) + .insert( + String::from("$protocolVersion"), + Value::Text("1".to_string()), + ) .unwrap(); let result = document_validator @@ -386,7 +395,10 @@ mod test { } = get_test_data(); raw_document - .insert("$type".to_string(), Value::Text("undefinedDocument".to_string())) + .insert( + "$type".to_string(), + Value::Text("undefinedDocument".to_string()), + ) .unwrap(); let result = document_validator @@ -460,7 +472,9 @@ mod test { data_contract, } = get_test_data(); - raw_document.insert(String::from("name"), Value::U64(1)).unwrap(); + raw_document + .insert(String::from("name"), Value::U64(1)) + .unwrap(); let result = document_validator .validate_extended(&raw_document, &data_contract) .expect("the validator should return the validation result"); diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 0f6c7bf8e3b..bed11813f9b 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -18,13 +18,13 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::converter::serde_json::BTreeValueJsonConverter; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; use std::collections::{BTreeMap, HashSet}; use std::convert::TryInto; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; pub mod property_names { pub const PROTOCOL_VERSION: &str = "$protocolVersion"; @@ -456,9 +456,9 @@ impl TryInto for &ExtendedDocument { #[cfg(test)] mod test { - use std::convert::TryInto; use anyhow::Result; use serde_json::{json, Value as JsonValue}; + use std::convert::TryInto; use crate::document::extended_document::{ExtendedDocument, IDENTIFIER_FIELDS}; @@ -527,8 +527,8 @@ mod test { ("$ownerId", Value::Identifier([0_u8; 32])), ("documents", documents), ]) - .try_into() - .unwrap() + .try_into() + .unwrap() } #[test] diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index ca9191d9543..32f924908cb 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -17,12 +17,12 @@ use byteorder::{BigEndian, ReadBytesExt}; use ciborium::Value as CborValue; use integer_encoding::VarIntWriter; use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::convert::TryFrom; use std::io::{BufReader, Read}; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; //todo: delete in later PR #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index 868e76f2501..50cd790c775 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -190,4 +190,4 @@ impl TryInto for &AssetLockProof { AssetLockProof::Chain(chain_proof) => platform_value::to_value(chain_proof), } } -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 368ab8ea532..ba1821bfba4 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -17,6 +17,7 @@ use crate::state_transition::{ }; use crate::util::json_value::JsonValueExt; use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; +use platform_value::btreemap_removal_inner_value_extensions::BTreeValueRemoveInnerValueFromMapHelper; use platform_value::string_encoding::Encoding; mod property_names { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 736e537d46d..cd57c3a8b8a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -99,10 +99,11 @@ impl IdentityUpdateTransition { .get_bytes(property_names::SIGNATURE) .map_err(ProtocolError::ValueError)?; let signature_public_key_id = raw_object - .get_integer(property_names::SIGNATURE_PUBLIC_KEY_ID).map_err(ProtocolError::ValueError)?; + .get_integer(property_names::SIGNATURE_PUBLIC_KEY_ID) + .map_err(ProtocolError::ValueError)?; let identity_id = raw_object - .get_identifier(property_names::IDENTITY_ID) - .map_err(ProtocolError::ValueError)?; + .get_identifier(property_names::IDENTITY_ID) + .map_err(ProtocolError::ValueError)?; let revision = raw_object .get_integer(property_names::REVISION) @@ -110,7 +111,8 @@ impl IdentityUpdateTransition { let add_public_keys = get_list(&mut raw_object, property_names::ADD_PUBLIC_KEYS)?; let disable_public_keys = get_list(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; let public_keys_disabled_at = raw_object - .remove_optional_integer(property_names::PUBLIC_KEYS_DISABLED_AT).map_err(ProtocolError::ValueError)?; + .remove_optional_integer(property_names::PUBLIC_KEYS_DISABLED_AT) + .map_err(ProtocolError::ValueError)?; Ok(IdentityUpdateTransition { protocol_version, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs index 79141650f74..17ee3791fb3 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs @@ -1,5 +1,6 @@ use anyhow::anyhow; use lazy_static::lazy_static; +use platform_value::Value; use serde_json::Value as JsonValue; use std::sync::Arc; @@ -58,44 +59,39 @@ where pub fn validate( &self, - raw_state_transition: &JsonValue, + raw_state_transition: &Value, ) -> Result { - let result = self.json_schema_validator.validate(raw_state_transition)?; + let result = self + .json_schema_validator + .validate(&raw_state_transition.into())?; if !result.is_valid() { return Ok(result); } let protocol_version = raw_state_transition - .get_u64(property_names::PROTOCOL_VERSION) - .map_err(|e| NonConsensusError::SerdeJsonError(e.to_string()))?; + .get_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)?; - let result = self - .protocol_version_validator - .validate(protocol_version as u32)?; + let result = self.protocol_version_validator.validate(protocol_version)?; if !result.is_valid() { return Ok(result); } - let maybe_raw_public_keys = raw_state_transition.get(property_names::ADD_PUBLIC_KEYS); + let maybe_raw_public_keys = raw_state_transition + .get_optional_value(property_names::ADD_PUBLIC_KEYS) + .and_then(|value| value.map(|value| value.to_array_slice()).transpose()) + .map_err(ProtocolError::ValueError)?; match maybe_raw_public_keys { Some(raw_public_keys) => { - let raw_public_keys_list = raw_public_keys.as_array().ok_or_else(|| { - NonConsensusError::SerdeJsonError(format!( - "'{}' property isn't an array", - property_names::ADD_PUBLIC_KEYS - )) - })?; - let result = self - .public_keys_validator - .validate_keys(raw_public_keys_list)?; + let result = self.public_keys_validator.validate_keys(raw_public_keys)?; if !result.is_valid() { return Ok(result); } let result = self .public_keys_signatures_validator - .validate_public_key_signatures(raw_state_transition, raw_public_keys_list)?; + .validate_public_key_signatures(raw_state_transition, raw_public_keys)?; if !result.is_valid() { return Ok(result); } diff --git a/packages/rs-dpp/src/identity/validation/public_keys_validator.rs b/packages/rs-dpp/src/identity/validation/public_keys_validator.rs index bd781455f00..b5d8f57cc77 100644 --- a/packages/rs-dpp/src/identity/validation/public_keys_validator.rs +++ b/packages/rs-dpp/src/identity/validation/public_keys_validator.rs @@ -2,7 +2,6 @@ use std::collections::HashMap; use dashcore::PublicKey; use lazy_static::lazy_static; -use serde_json::Value; use crate::errors::consensus::basic::identity::{ DuplicatedIdentityPublicKeyError, DuplicatedIdentityPublicKeyIdError, @@ -17,6 +16,7 @@ use crate::{ use crate::identity::security_level::ALLOWED_SECURITY_LEVELS; #[cfg(test)] use mockall::{automock, predicate::*}; +use platform_value::Value; lazy_static! { pub static ref PUBLIC_KEY_SCHEMA: serde_json::Value = @@ -60,7 +60,7 @@ impl TPublicKeysValidator for PublicKeysValidator { // Public keys already passed json schema validation at this point let mut public_keys = Vec::::with_capacity(raw_public_keys.len()); for raw_public_key in raw_public_keys { - let pk: IdentityPublicKey = serde_json::from_value(raw_public_key.clone())?; + let pk: IdentityPublicKey = platform_value::from_value(raw_public_key.clone())?; public_keys.push(pk); } @@ -161,7 +161,7 @@ impl PublicKeysValidator { schema: Value, bls_validator: T, ) -> Result { - let public_key_schema_validator = JsonSchemaValidator::new(schema)?; + let public_key_schema_validator = JsonSchemaValidator::new(schema.into())?; let public_keys_validator = Self { public_key_schema_validator, @@ -175,7 +175,7 @@ impl PublicKeysValidator { &self, public_key: &Value, ) -> Result, NonConsensusError> { - self.public_key_schema_validator.validate(public_key) + self.public_key_schema_validator.validate(public_key.into()) } } diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index 6cc70f0bb7a..65d2bcb04b6 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -2,9 +2,9 @@ use std::sync::Arc; use jsonschema::error::ValidationErrorKind; use log::trace; +use platform_value::{platform_value, Value}; use serde_json::{json, Value as JsonValue}; use test_case::test_case; -use platform_value::{platform_value, Value}; use crate::{ codes::ErrorWithCode, @@ -126,7 +126,9 @@ mod protocol { .. } = setup_test(); - raw_data_contract.set_value("protocolVersion", "1".into()).expect("expected to set value"); + raw_data_contract + .set_value("protocolVersion", "1".into()) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -145,7 +147,9 @@ mod protocol { .. } = setup_test(); - raw_data_contract.set_value("protocolVersion", Value::I8(-1)).expect("expected to set value"); + raw_data_contract + .set_value("protocolVersion", Value::I8(-1)) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -166,7 +170,9 @@ fn defs_should_be_object() { .. } = setup_test(); - raw_data_contract.set_value("$defs", Value::U32(1)).expect("expected to set value"); + raw_data_contract + .set_value("$defs", Value::U32(1)) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -179,8 +185,8 @@ fn defs_should_be_object() { } mod defs { - use platform_value::platform_value; use super::*; + use platform_value::platform_value; #[test] fn defs_should_not_be_empty() { @@ -189,7 +195,9 @@ mod defs { data_contract_validator, .. } = setup_test(); - raw_data_contract.set_value("$defs", Value::Map(vec![])).expect("expected to set value"); + raw_data_contract + .set_value("$defs", Value::Map(vec![])) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -208,7 +216,15 @@ mod defs { data_contract_validator, .. } = setup_test(); - raw_data_contract.set_value("$defs", Value::Map(vec![(Value::Text("$subSchema".to_string()), Value::Map(vec![]))])).expect("expected to set value"); + raw_data_contract + .set_value( + "$defs", + Value::Map(vec![( + Value::Text("$subSchema".to_string()), + Value::Map(vec![]), + )]), + ) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -254,7 +270,9 @@ mod defs { ]; for property_name in valid_names { - raw_data_contract.set_value_at_path("$defs", property_name, platform_value!({"type" : "string"})).expect("expected to set value"); + raw_data_contract + .set_value_at_path("$defs", property_name, platform_value!({"type" : "string"})) + .expect("expected to set value"); } let result = data_contract_validator @@ -282,7 +300,9 @@ mod defs { "ab", ]; for property_name in invalid_names { - raw_data_contract.set_value_at_path("$defs", property_name, platform_value!({"type" : "string"})).expect("expected to set value"); + raw_data_contract + .set_value_at_path("$defs", property_name, platform_value!({"type" : "string"})) + .expect("expected to set value"); } let result = data_contract_validator @@ -303,7 +323,13 @@ mod defs { } = setup_test(); for i in 1..101 { - raw_data_contract.set_value_at_path("$defs", format!("def_{}", i).as_str(), platform_value!({"type" : "string"}).into()).expect("expected to set value"); + raw_data_contract + .set_value_at_path( + "$defs", + format!("def_{}", i).as_str(), + platform_value!({"type" : "string"}).into(), + ) + .expect("expected to set value"); } let result = data_contract_validator @@ -327,7 +353,9 @@ mod schema { .. } = setup_test(); - raw_data_contract.set_value("$schema", Value::U64(1)).expect("expected to set value"); + raw_data_contract + .set_value("$schema", Value::U64(1)) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -346,7 +374,9 @@ mod schema { .. } = setup_test(); - raw_data_contract.set_value("$schema", Value::Text("wrong".to_string())).expect("expected to set value"); + raw_data_contract + .set_value("$schema", Value::Text("wrong".to_string())) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -369,7 +399,9 @@ fn owner_id_should_be_byte_array(property_name: &str) { } = setup_test(); let array = ["string"; 32]; - raw_data_contract.set_value(property_name, platform_value!(array).into()).expect("expected to set value"); + raw_data_contract + .set_value(property_name, platform_value!(array).into()) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -399,7 +431,9 @@ fn owner_id_should_be_no_less_32_bytes(property_name: &str) { } = setup_test(); let array = [0u8; 31]; - raw_data_contract.set_value(property_name, platform_value!(array).into()).expect("expected to set value"); + raw_data_contract + .set_value(property_name, platform_value!(array).into()) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -424,7 +458,9 @@ fn owner_id_should_be_no_longer_32_bytes(property_name: &str) { let mut too_long_id = Vec::new(); too_long_id.resize(33, 0u8); - raw_data_contract.set_value(property_name, platform_value!(too_long_id).into()).expect("expected to set value"); + raw_data_contract + .set_value(property_name, platform_value!(too_long_id).into()) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -449,7 +485,9 @@ mod documents { .. } = setup_test(); - raw_data_contract.set_value("documents", platform_value!(1).into()).expect("expected to set value"); + raw_data_contract + .set_value("documents", platform_value!(1).into()) + .expect("expected to set value"); let result = data_contract_validator .validate(&raw_data_contract) @@ -469,7 +507,9 @@ mod documents { .. } = setup_test(); - raw_data_contract.set_value("documents", platform_value!({}).into()).expect("expected to set value"); + raw_data_contract + .set_value("documents", platform_value!({}).into()) + .expect("expected to set value"); raw_data_contract["documents"] = platform_value!({}); let result = data_contract_validator @@ -731,8 +771,7 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["niceDocument"]["properties"]["something"] = - platform_value!({"type": "object", "properties": platform_value!({}), "additionalProperties" : false}); + raw_data_contract["documents"]["niceDocument"]["properties"]["something"] = platform_value!({"type": "object", "properties": platform_value!({}), "additionalProperties" : false}); let valid_names = [ "validName", @@ -770,7 +809,8 @@ mod documents { let invalid_names = ["*(*&^", "$test", ".", ".a"]; for property_name in invalid_names { - raw_data_contract["documents"]["niceDocument"]["properties"][property_name] = platform_value!({}) + raw_data_contract["documents"]["niceDocument"]["properties"][property_name] = + platform_value!({}) } let result = data_contract_validator @@ -862,7 +902,8 @@ mod documents { .. } = setup_test(); - raw_data_contract["documents"]["niceDocument"]["additionalProperties"] = platform_value!(true); + raw_data_contract["documents"]["niceDocument"]["additionalProperties"] = + platform_value!(true); let result = data_contract_validator .validate(&raw_data_contract) @@ -1668,7 +1709,8 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"] = platform_value!(["something else"]); + raw_data_contract["documents"]["indexedDocument"]["indices"] = + platform_value!(["something else"]); let result = data_contract_validator .validate(&raw_data_contract) .expect("validation result should be returned"); @@ -1741,7 +1783,8 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = platform_value!([]); + raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = + platform_value!([]); let result = data_contract_validator .validate(&raw_data_contract) @@ -1818,7 +1861,8 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = platform_value!([]); + raw_data_contract["documents"]["indexedDocument"]["indices"][0]["properties"] = + platform_value!([]); let result = data_contract_validator .validate(&raw_data_contract) @@ -1887,7 +1931,8 @@ mod indices { .. } = setup_test(); - raw_data_contract["documents"]["indexedDocument"]["indices"][0]["unique"] = platform_value!(12); + raw_data_contract["documents"]["indexedDocument"]["indices"][0]["unique"] = + platform_value!(12); let result = data_contract_validator .validate(&raw_data_contract) @@ -2383,8 +2428,9 @@ mod indices { .. } = setup_test(); - if let Some(Value::Array(arr)) = - raw_data_contract.get_optional_mut_value_at_path("documents.optionalUniqueIndexedDocument.required").expect("expected to get optional value at path") + if let Some(Value::Array(arr)) = raw_data_contract + .get_optional_mut_value_at_path("documents.optionalUniqueIndexedDocument.required") + .expect("expected to get optional value at path") { arr.pop(); } diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index 8f8e6975671..db26af41c27 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -1,12 +1,11 @@ -use serde_json::{json, Value}; - use crate::consensus::ConsensusError; use crate::identity::validation::PublicKeysValidator; use crate::identity::validation::TPublicKeysValidator; use crate::identity::{KeyID, KeyType, Purpose, SecurityLevel}; use crate::tests::fixtures::get_public_keys_validator; -use crate::tests::utils::serde_set_ref; +use crate::tests::utils::platform_value_set_ref; use crate::{assert_consensus_errors, NativeBlsModule}; +use platform_value::{platform_value, Value}; fn setup_test() -> (Vec, PublicKeysValidator) { ( @@ -30,7 +29,7 @@ pub mod id { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::serde_set_ref; + use crate::tests::utils::platform_value_set_ref; use crate::tests::utils::SerdeTestExtension; #[test] @@ -56,7 +55,11 @@ pub mod id { #[test] pub fn should_be_a_number() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "id", "string"); + raw_public_keys + .get_mut(1) + .unwrap() + .set_value("id", "string".into()) + .unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -69,7 +72,7 @@ pub mod id { #[test] pub fn should_be_an_integer() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "id", 1.1); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "id", 1.1); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -82,7 +85,7 @@ pub mod id { #[test] pub fn should_be_greater_or_equal_to_zero() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "id", -1); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "id", -1); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -98,7 +101,7 @@ pub mod key_type { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::{serde_remove_ref, serde_set_ref}; + use crate::tests::utils::{platform_value_set_ref, serde_remove_ref}; #[test] pub fn should_be_present() { @@ -117,7 +120,7 @@ pub mod key_type { #[test] pub fn should_be_a_number() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", "string"); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", "string"); let result = validator.validate_keys(&raw_public_keys).unwrap(); // TODO: in the original code, there was only one error @@ -136,7 +139,7 @@ pub mod data { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::{serde_remove_ref, serde_set_ref}; + use crate::tests::utils::{platform_value_set_ref, serde_remove_ref}; #[test] pub fn should_be_present() { @@ -161,7 +164,7 @@ pub mod data { #[test] pub fn should_be_a_byte_array() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref( + platform_value_set_ref( raw_public_keys.get_mut(1).unwrap(), "data", vec!["string"; 33], @@ -187,12 +190,12 @@ pub mod data { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::serde_set_ref; + use crate::tests::utils::platform_value_set_ref; #[test] pub fn should_be_no_less_than_33_bytes() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 32]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 32]); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -205,7 +208,7 @@ pub mod data { #[test] pub fn should_be_no_longer_than_33_bytes() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 34]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 34]); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -221,13 +224,13 @@ pub mod data { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::serde_set_ref; + use crate::tests::utils::platform_value_set_ref; #[test] pub fn should_be_no_less_than_48_bytes() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 47]); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 1); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 47]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 1); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -240,8 +243,8 @@ pub mod data { #[test] pub fn should_be_no_longer_than_48_bytes() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 49]); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 1); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 49]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 1); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -257,13 +260,13 @@ pub mod data { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::serde_set_ref; + use crate::tests::utils::platform_value_set_ref; #[test] pub fn should_be_no_less_than_20_bytes() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 19]); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 3); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 19]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 3); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -276,8 +279,8 @@ pub mod data { #[test] pub fn should_be_no_longer_than_20_bytes() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 21]); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 3); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 21]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 3); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -293,13 +296,13 @@ pub mod data { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::serde_set_ref; + use crate::tests::utils::platform_value_set_ref; #[test] pub fn should_be_no_less_than_20_bytes() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 19]); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 2); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 19]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 2); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -312,8 +315,8 @@ pub mod data { #[test] pub fn should_be_no_longer_than_20_bytes() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 21]); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 2); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 21]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "type", 2); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -330,7 +333,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_key_ids() { let (mut raw_public_keys, validator) = setup_test(); let key0 = raw_public_keys.get(0).unwrap().clone(); let key1 = raw_public_keys.get_mut(1).unwrap(); - serde_set_ref( + platform_value_set_ref( key1, "id", key0.as_object().unwrap().get("id").unwrap().clone(), @@ -365,7 +368,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { let (mut raw_public_keys, validator) = setup_test(); let key0 = raw_public_keys.get(0).unwrap().clone(); let key1 = raw_public_keys.get_mut(1).unwrap(); - serde_set_ref( + platform_value_set_ref( key1, "data", key0.as_object().unwrap().get("data").unwrap().clone(), @@ -398,7 +401,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { #[test] pub fn should_return_invalid_result_if_key_data_is_not_a_valid_der() { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 33]); + platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 33]); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!( @@ -425,12 +428,12 @@ pub fn should_return_invalid_result_if_key_data_is_not_a_valid_der() { pub fn should_return_invalid_result_if_key_has_an_invalid_combination_of_purpose_and_security_level( ) { let (mut raw_public_keys, validator) = setup_test(); - serde_set_ref( + platform_value_set_ref( raw_public_keys.get_mut(1).unwrap(), "purpose", Purpose::ENCRYPTION as u64, ); - serde_set_ref( + platform_value_set_ref( raw_public_keys.get_mut(1).unwrap(), "securityLevel", SecurityLevel::MASTER as u64, @@ -518,7 +521,7 @@ pub fn should_pass_valid_ecdsa_hash160_public_key() { #[test] pub fn should_return_invalid_result_if_bls12_381_public_key_is_invalid() { let (_, validator) = setup_test(); - let raw_public_keys_json = json!([{ + let raw_public_keys_json = platform_value!([{ "id": 0, "type": KeyType::BLS12_381, "purpose": 0, diff --git a/packages/rs-dpp/src/tests/utils/utils.rs b/packages/rs-dpp/src/tests/utils/utils.rs index 6acb5ab7d18..eeba75fe519 100644 --- a/packages/rs-dpp/src/tests/utils/utils.rs +++ b/packages/rs-dpp/src/tests/utils/utils.rs @@ -1,7 +1,8 @@ use anyhow::Result; use dashcore::{Block, BlockHeader}; use getrandom::getrandom; -use serde_json::Value; +use platform_value::Value; +use serde_json::Value as JsonValue; use crate::prelude::Identifier; @@ -48,16 +49,16 @@ where } /// Sets a key value pair in serde_json object, returns the modified object -pub fn serde_set_ref(object: &mut Value, key: T, value: S) +pub fn platform_value_set_ref(object: &mut Value, key: T, value: S) where - T: Into, - S: Into, - serde_json::Value: From, + T: Into, + S: Into, + Value: From, { let map = object - .as_object_mut() + .as_map_mut() .expect("Expected value to be an JSON object"); - map.insert(key.into(), serde_json::Value::from(value)); + map.push((key.into(), value.into())); } /// Removes a key value pair in serde_json object, returns the modified object diff --git a/packages/rs-platform-value/src/index.rs b/packages/rs-platform-value/src/index.rs index ac2190ec266..b048f42e050 100644 --- a/packages/rs-platform-value/src/index.rs +++ b/packages/rs-platform-value/src/index.rs @@ -1,7 +1,7 @@ use super::Value; +use crate::value_map::{ValueMap, ValueMapHelper}; use core::fmt::{self, Display}; use core::ops; -use crate::value_map::{ValueMap, ValueMapHelper}; /// A type that can be used to index into a `platform_value::Value`. /// @@ -96,9 +96,7 @@ impl Index for str { *v = Value::Map(ValueMap::new()); } match v { - Value::Map(map) => { - map.get_key_mut_or_insert(self, Value::Null) - }, + Value::Map(map) => map.get_key_mut_or_insert(self, Value::Null), _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), } } @@ -117,8 +115,8 @@ impl Index for String { } impl<'a, T> Index for &'a T - where - T: ?Sized + Index, +where + T: ?Sized + Index, { fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { (**self).index_into(v) @@ -189,8 +187,8 @@ impl<'a> Display for Type<'a> { // with Value that is not well served by the existing approaches: concise and // careless and sometimes that is exactly what you want. impl ops::Index for Value - where - I: Index, +where + I: Index, { type Output = Value; @@ -229,8 +227,8 @@ impl ops::Index for Value } impl ops::IndexMut for Value - where - I: Index, +where + I: Index, { /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or /// `value["k"] = ...`. diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 608a01d71e4..c2ddc59265b 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,8 +1,8 @@ +use crate::identifier::Identifier; use crate::value_map::{ValueMap, ValueMapHelper}; use crate::Value::Bool; use crate::{Error, Value}; use std::collections::BTreeMap; -use crate::identifier::Identifier; impl Value { pub fn get<'a>(&'a self, key: &'a str) -> Result, Error> { @@ -108,13 +108,13 @@ impl Value { pub fn remove_array(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; let value = map.remove_key(key)?; - value.to_array() + value.to_array_owned() } pub fn remove_optional_array(&mut self, key: &str) -> Result>, Error> { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) - .map(|v| v.to_array()) + .map(|v| v.to_array_owned()) .transpose() } @@ -192,9 +192,13 @@ impl Value { Ok(Identifier::new(Self::inner_hash256_value(map, key)?)) } - pub fn get_optional_identifier<'a>(&'a self, key: &'a str) -> Result, Error> { + pub fn get_optional_identifier<'a>( + &'a self, + key: &'a str, + ) -> Result, Error> { let map = self.to_map()?; - Ok(Self::inner_optional_hash256_value(map, key)?.map(|identifier| Identifier::new(identifier))) + Ok(Self::inner_optional_hash256_value(map, key)? + .map(|identifier| Identifier::new(identifier))) } pub fn get_hash256<'a>(&'a self, key: &'a str) -> Result<[u8; 32], Error> { diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index e9138ae3fce..a40565b496c 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -1,5 +1,5 @@ -use crate::{Error, Value}; use crate::value_map::ValueMapHelper; +use crate::{Error, Value}; impl Value { pub fn get_value_at_path<'a>(&'a self, path: &'a str) -> Result<&'a Value, Error> { @@ -14,7 +14,10 @@ impl Value { Ok(current_value) } - pub fn get_optional_value_at_path<'a>(&'a self, path: &'a str) -> Result, Error> { + pub fn get_optional_value_at_path<'a>( + &'a self, + path: &'a str, + ) -> Result, Error> { let mut split = path.split('.'); let mut current_value = self; for path_component in split { @@ -39,7 +42,10 @@ impl Value { Ok(current_value) } - pub fn get_optional_mut_value_at_path<'a>(&'a mut self, path: &'a str) -> Result, Error> { + pub fn get_optional_mut_value_at_path<'a>( + &'a mut self, + path: &'a str, + ) -> Result, Error> { let mut split = path.split('.'); let mut current_value = self; for path_component in split { @@ -62,7 +68,9 @@ impl Value { } else { let map = current_value.to_map_mut()?; current_value = map.get_key_mut(path_component).ok_or_else(|| { - Error::StructureError(format!("unable to get property {path_component} in {path}")) + Error::StructureError(format!( + "unable to get property {path_component} in {path}" + )) })?; }; } @@ -77,4 +85,4 @@ impl Value { let map = self.get_mut_value_at_path(path)?.as_map_mut_ref()?; Ok(Self::insert_in_map(map, key, value)) } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 22adf309f50..5c1af3b28e5 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -11,20 +11,20 @@ mod btreemap_mut_value_extensions; pub mod btreemap_path_extensions; pub mod btreemap_path_insertion_extensions; pub mod btreemap_removal_extensions; -mod btreemap_removal_inner_value_extensions; +pub mod btreemap_removal_inner_value_extensions; pub mod converter; pub mod display; mod error; pub mod identifier; +mod index; pub mod inner_value; +mod inner_value_at_path; mod integer; +mod macros; mod ser; pub mod string_encoding; pub mod system_bytes; pub mod value_map; -mod inner_value_at_path; -mod macros; -mod index; use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; @@ -757,6 +757,30 @@ impl Value { .ok_or(Error::StructureError("value is not an array".to_string())) } + /// If the `Value` is a `Array`, returns a the associated `&[Value]` slice as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Value, Integer, Error}; + /// # + /// let mut value = Value::Array( + /// vec![ + /// Value::U64(17), + /// Value::Float(18.), + /// ] + /// ); + /// assert_eq!(value.to_array_slice(), Ok(vec![Value::U64(17), Value::Float(18.)].as_slice())); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_array_slice(), Err(Error::StructureError("value is not an array".to_string()))); + /// ``` + pub fn to_array_slice(&self) -> Result<&[Value], Error> { + match self { + Value::Array(vec) => Ok(vec.as_slice()), + _other => Err(Error::StructureError("value is not an array".to_string())), + } + } + /// If the `Value` is a `Array`, returns a the associated `Vec` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. /// @@ -769,12 +793,12 @@ impl Value { /// Value::Float(18.), /// ] /// ); - /// assert_eq!(value.to_array(), Ok(vec![Value::U64(17), Value::Float(18.)])); + /// assert_eq!(value.to_array_owned(), Ok(vec![Value::U64(17), Value::Float(18.)])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.to_array(), Err(Error::StructureError("value is not an array".to_string()))); + /// assert_eq!(value.to_array_owned(), Err(Error::StructureError("value is not an array".to_string()))); /// ``` - pub fn to_array(&self) -> Result, Error> { + pub fn to_array_owned(&self) -> Result, Error> { match self { Value::Array(vec) => Ok(vec.clone()), _other => Err(Error::StructureError("value is not an array".to_string())), diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index 6d60579f38f..4ed24d50373 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -139,7 +139,7 @@ macro_rules! platform_value_internal { // Insert the current entry followed by trailing comma. (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => { - let _ = $object.insert(($($key)+).into(), $value); + let _ = $object.push((($($key)+).into(), $value)); platform_value_internal!(@object $object () ($($rest)*) ($($rest)*)); }; @@ -150,7 +150,7 @@ macro_rules! platform_value_internal { // Insert the last entry without trailing comma. (@object $object:ident [$($key:tt)+] ($value:expr)) => { - let _ = $object.insert(($($key)+).into(), $value); + let _ = $object.push((($($key)+).into(), $value)); }; // Next value is `null`. diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index e9df9d79233..089f64f758b 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,6 +1,6 @@ use crate::{Error, Value}; -use std::collections::BTreeMap; use std::collections::hash_map::Entry; +use std::collections::BTreeMap; pub type ValueMap = Vec<(Value, Value)>; From 0858b7530a0362027f2bf33f6c6e598b2253a748 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 12 Mar 2023 12:07:56 +0700 Subject: [PATCH 106/228] more work --- .../rs-dpp/src/data_contract/data_contract.rs | 2 +- packages/rs-dpp/src/document/document.rs | 4 -- .../rs-dpp/src/document/extended_document.rs | 17 ----- packages/rs-dpp/src/identity/identity.rs | 26 ++------ .../identity/validation/identity_validator.rs | 23 ++++--- .../validation/public_keys_validator.rs | 11 +++- ...ed_purpose_and_security_level_validator.rs | 16 +++-- ...te_documents_uniqueness_by_indices_spec.rs | 1 - .../src/tests/fixtures/identity_fixture.rs | 29 ++++---- .../validation/identity_validator_spec.rs | 21 ++++-- .../validation/public_keys_validator_spec.rs | 66 +++++++++---------- ...rpose_and_security_level_validator_spec.rs | 23 +++---- packages/rs-platform-value/src/lib.rs | 34 ++++++---- 13 files changed, 131 insertions(+), 142 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 631f4bcb57f..3b75d5967eb 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -12,12 +12,12 @@ use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::consensus::basic::document::InvalidDocumentTypeError; +use crate::data_contract::contract_config; use crate::data_contract::contract_config::{ ContractConfig, DEFAULT_CONTRACT_CAN_BE_DELETED, DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY, DEFAULT_CONTRACT_DOCUMENT_MUTABILITY, DEFAULT_CONTRACT_KEEPS_HISTORY, DEFAULT_CONTRACT_MUTABILITY, }; -use crate::data_contract::{contract_config, DriveContractExt}; use crate::data_contract::get_binary_properties_from_schema::get_binary_properties; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index f876e2cfeeb..fb32a9eec09 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -443,10 +443,6 @@ impl Document { Ok(json_object) } - pub fn from_raw_json_document(raw_document: JsonValue) -> Result { - Self::from_json_value::>(raw_document) - } - pub fn from_json_value(mut document_value: JsonValue) -> Result where for<'de> S: Deserialize<'de> + TryInto, diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index bed11813f9b..70d298c3b57 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -64,23 +64,6 @@ pub struct ExtendedDocument { } impl ExtendedDocument { - /// Creates a Document from the json form. Json format contains strings instead of - /// arrays of u8 (bytes) - pub fn from_json_document( - json_document: JsonValue, - data_contract: DataContract, - ) -> Result { - let document = Self::from_json_value::(json_document, data_contract)?; - // let mut properties = document.properties_as_mut(); - - // replace only the dynamic data - //todo: not sure if this is needed anymore - // let (identifier_paths, binary_paths) = document.get_identifiers_and_binary_paths()?; - // properties.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - // properties.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; - Ok(document) - } - fn properties_as_json_data(&self) -> Result { self.document .properties diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 0a51f3e1a0d..adfd6d0bf6e 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -2,8 +2,9 @@ use std::collections::BTreeMap; use ciborium::value::Value as CborValue; use integer_encoding::VarInt; +use platform_value::Value; use serde::{Deserialize, Serialize}; -use serde_json::{Value as JsonValue, Value}; +use serde_json::Value as JsonValue; use crate::identity::identity_public_key; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; @@ -229,22 +230,7 @@ impl Identity { } pub fn to_object(&self) -> Result { - let mut identity_json: JsonValue = serde_json::to_value(self)?; - - identity_json.replace_identifier_paths(IDENTIFIER_FIELDS_RAW_OBJECT, ReplaceWith::Bytes)?; - - let pk_values = self - .public_keys - .values() - .map(|pk| pk.to_raw_json_object()) - .collect::, SerdeParsingError>>()?; - - identity_json.insert( - property_names::PUBLIC_KEYS.to_string(), - JsonValue::Array(pk_values), - )?; - - Ok(identity_json) + platform_value::to_value(self).map_err(ProtocolError::ValueError) } pub fn from_buffer(b: impl AsRef<[u8]>) -> Result { @@ -314,10 +300,8 @@ impl Identity { } /// Creates an identity from a raw object - pub fn from_raw_object(mut raw_object: JsonValue) -> Result { - raw_object.replace_identifier_paths(IDENTIFIER_FIELDS_RAW_OBJECT, ReplaceWith::Base58)?; - - let identity: Identity = serde_json::from_value(raw_object)?; + pub fn from_raw_object(mut raw_object: Value) -> Result { + let identity: Identity = platform_value::from_value(raw_object)?; Ok(identity) } diff --git a/packages/rs-dpp/src/identity/validation/identity_validator.rs b/packages/rs-dpp/src/identity/validation/identity_validator.rs index 478e32b1153..e950a38c000 100644 --- a/packages/rs-dpp/src/identity/validation/identity_validator.rs +++ b/packages/rs-dpp/src/identity/validation/identity_validator.rs @@ -1,4 +1,5 @@ use lazy_static::lazy_static; +use platform_value::Value; use serde_json::Value as JsonValue; use std::sync::Arc; @@ -6,7 +7,8 @@ use crate::identity::validation::TPublicKeysValidator; use crate::util::protocol_data::{get_protocol_version, get_raw_public_keys}; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::version::ProtocolVersionValidator; -use crate::{DashPlatformProtocolInitError, NonConsensusError, SerdeParsingError}; +use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError}; +use crate::identity::state_transition::identity_update_transition::identity_update_transition::property_names::PROTOCOL_VERSION; lazy_static! { static ref IDENTITY_JSON_SCHEMA: JsonValue = @@ -38,26 +40,29 @@ impl IdentityValidator { pub fn validate_identity( &self, - identity_json: &serde_json::Value, + identity_object: &Value, ) -> Result, NonConsensusError> { - let mut validation_result = self.json_schema_validator.validate(identity_json)?; + let mut validation_result = self.json_schema_validator.validate( + &identity_object + .try_to_validating_json() + .map_err(ProtocolError::ValueError)?, + )?; if !validation_result.is_valid() { return Ok(validation_result); } - let identity_map = identity_json - .as_object() - .ok_or_else(|| SerdeParsingError::new("Expected identity to be a json object"))?; - - let protocol_version = get_protocol_version(identity_map)?; + let identity_map = identity_object + .to_map() + .map_err(ProtocolError::ValueError)?; + let protocol_version = identity_object.get_integer(PROTOCOL_VERSION)?; validation_result.merge(self.protocol_version_validator.validate(protocol_version)?); if !validation_result.is_valid() { return Ok(validation_result); } - let raw_public_keys = get_raw_public_keys(identity_map)?; + let raw_public_keys = identity_object.get_array?; validation_result.merge(self.public_keys_validator.validate_keys(raw_public_keys)?); Ok(validation_result) diff --git a/packages/rs-dpp/src/identity/validation/public_keys_validator.rs b/packages/rs-dpp/src/identity/validation/public_keys_validator.rs index b5d8f57cc77..f018df99a0b 100644 --- a/packages/rs-dpp/src/identity/validation/public_keys_validator.rs +++ b/packages/rs-dpp/src/identity/validation/public_keys_validator.rs @@ -19,11 +19,16 @@ use mockall::{automock, predicate::*}; use platform_value::Value; lazy_static! { - pub static ref PUBLIC_KEY_SCHEMA: serde_json::Value = - serde_json::from_str(include_str!("./../../schema/identity/publicKey.json")).unwrap(); - pub static ref PUBLIC_KEY_SCHEMA_FOR_TRANSITION: serde_json::Value = serde_json::from_str( + pub static ref PUBLIC_KEY_SCHEMA: platform_value::Value = + serde_json::from_str(include_str!("./../../schema/identity/publicKey.json")) + .unwrap() + .try_into() + .unwrap(); + pub static ref PUBLIC_KEY_SCHEMA_FOR_TRANSITION: platform_value::Value = serde_json::from_str( include_str!("./../../schema/identity/stateTransition/publicKey.json") ) + .unwrap() + .try_into() .unwrap(); } diff --git a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs index 1cdc7cb4f14..d4aeb96d91a 100644 --- a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs +++ b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs @@ -1,13 +1,12 @@ +use platform_value::Value; +use platform_value::Value::Null; use std::collections::HashMap; -use serde_json::Value; -use serde_json::Value::Null; - use crate::consensus::basic::identity::MissingMasterPublicKeyError; use crate::identity::validation::TPublicKeysValidator; use crate::identity::{IdentityPublicKey, Purpose, SecurityLevel}; use crate::validation::ValidationResult; -use crate::{DashPlatformProtocolInitError, NonConsensusError}; +use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError}; #[derive(Eq, Hash, PartialEq)] struct PurposeKey { @@ -28,13 +27,16 @@ impl TPublicKeysValidator for RequiredPurposeAndSecurityLevelValidator { let mut key_purposes_and_levels_count: HashMap = HashMap::new(); for raw_public_key in raw_public_keys.iter().filter(|pk| { - if let Some(disabled_at) = pk.get("disabledAt") { - disabled_at == &Null + if let Some(disabled_at) = pk + .get_optional_bool("disabledAt") + .map_err(ProtocolError::ValueError)? + { + disabled_at == false } else { true } }) { - let public_key: IdentityPublicKey = serde_json::from_value(raw_public_key.clone())?; + let public_key: IdentityPublicKey = platform_value::from_value(raw_public_key.clone())?; let combo = PurposeKey { purpose: public_key.purpose, security_level: public_key.security_level, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs index 86f66a019ae..914aeffa732 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_uniqueness_by_indices_spec.rs @@ -1,4 +1,3 @@ -use futures::StreamExt; use mockall::predicate; use platform_value::string_encoding::Encoding; use serde_json::json; diff --git a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs index 1c902cc4bf4..f01167b75d2 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs @@ -1,3 +1,4 @@ +use platform_value::platform_value; use platform_value::string_encoding::{decode, Encoding}; use serde_json::json; @@ -6,30 +7,30 @@ use crate::prelude::Identity; //3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT //[198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237] -pub fn identity_fixture_raw_object() -> serde_json::Value { - json!({ - "protocolVersion": 1, - "id": [198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237], +pub fn identity_fixture_raw_object() -> platform_value::Value { + platform_value!({ + "protocolVersion": 1u32, + "id": Identifier::from([198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237]), "publicKeys": [ { - "id": 0, - "type": 0, - "purpose": 0, - "securityLevel": 0, + "id": 0u32, + "type": 0u8, + "purpose": 0u8, + "securityLevel": 0u8, "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), "readOnly": false }, { - "id": 1, - "type": 0, - "purpose": 1, - "securityLevel": 3, + "id": 1u32, + "type": 0u8, + "purpose": 1u8, + "securityLevel": 3u8, "data": decode("A8AK95PYMVX5VQKzOhcVQRCUbc9pyg3RiL7jttEMDU+L", Encoding::Base64).unwrap(), "readOnly": false } ], - "balance": 10, - "revision": 0 + "balance": 10u64, + "revision": 0u64 }) } diff --git a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs index 6a9cc0276dc..dbfcfb8394b 100644 --- a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs @@ -1,7 +1,6 @@ +use platform_value::Value; use std::sync::Arc; -use serde_json::Value; - use crate::errors::consensus::ConsensusError; use crate::identity::validation::{IdentityValidator, PublicKeysValidator, PUBLIC_KEY_SCHEMA}; use crate::version::ProtocolVersionValidator; @@ -36,7 +35,9 @@ pub mod protocol_version { #[test] pub fn should_be_present() { let (mut identity, identity_validator) = setup_test(); - identity = serde_remove(identity, "protocolVersion"); + identity + .remove("protocolVersion") + .expect("expected to remove protocol version"); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -95,7 +96,7 @@ pub mod id { #[test] pub fn should_be_present() { let (mut identity, identity_validator) = setup_test(); - identity = serde_remove(identity, "id"); + identity.remove("id").expect("expected to remove id"); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -167,7 +168,9 @@ pub mod balance { #[test] pub fn should_be_present() { let (mut identity, identity_validator) = setup_test(); - identity = serde_remove(identity, "balance"); + identity + .remove("balance") + .expect("expected to remove balance"); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -231,7 +234,9 @@ pub mod public_keys { #[test] pub fn should_be_present() { let (mut identity, identity_validator) = setup_test(); - identity = serde_remove(identity, "publicKeys"); + identity + .remove("publicKeys") + .expect("expected to remove public keys"); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -342,7 +347,9 @@ pub mod revision { #[test] pub fn should_be_present() { let (mut identity, identity_validator) = setup_test(); - identity = serde_remove(identity, "revision"); + identity + .remove("protocolVersion") + .expect("expected to remove revision"); let result = identity_validator.validate_identity(&identity).unwrap(); diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index db26af41c27..f2a1ab47723 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -10,7 +10,7 @@ use platform_value::{platform_value, Value}; fn setup_test() -> (Vec, PublicKeysValidator) { ( crate::tests::fixtures::identity_fixture_raw_object() - .as_object() + .to_() .unwrap() .get("publicKeys") .unwrap() @@ -35,7 +35,11 @@ pub mod id { #[test] pub fn should_be_present() { let (mut raw_public_keys, validator) = setup_test(); - raw_public_keys.get_mut(1).unwrap().remove_key("id"); + raw_public_keys + .get_mut(1) + .unwrap() + .remove_integer("id") + .unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -336,7 +340,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_key_ids() { platform_value_set_ref( key1, "id", - key0.as_object().unwrap().get("id").unwrap().clone(), + key0.to_map().unwrap().get_integer("id").unwrap().clone(), ); let result = validator.validate_keys(&raw_public_keys).unwrap(); @@ -352,11 +356,9 @@ pub fn should_return_invalid_result_if_there_are_duplicate_key_ids() { let expected_ids = vec![raw_public_keys .get(1) .unwrap() - .as_object() - .unwrap() - .get("id") + .as_map() .unwrap() - .as_u64() + .get_integer("id") .unwrap() as KeyID]; assert_eq!(consensus_error.code(), 1030); @@ -371,7 +373,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { platform_value_set_ref( key1, "data", - key0.as_object().unwrap().get("data").unwrap().clone(), + key0.as_map().unwrap().get("data").unwrap().clone(), ); let result = validator.validate_keys(&raw_public_keys).unwrap(); @@ -387,7 +389,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { let expected_ids = vec![raw_public_keys .get(1) .unwrap() - .as_object() + .as_map() .unwrap() .get("id") .unwrap() @@ -416,7 +418,7 @@ pub fn should_return_invalid_result_if_key_data_is_not_a_valid_der() { assert_eq!(consensus_error.code(), 1040); assert_eq!( error.public_key_id(), - raw_public_keys[1].get("id").unwrap().as_u64().unwrap() as KeyID + raw_public_keys[1].get_integer("id").unwrap() as KeyID ); assert_eq!( error.validation_error().as_ref().unwrap().message(), @@ -451,19 +453,17 @@ pub fn should_return_invalid_result_if_key_has_an_invalid_combination_of_purpose assert_eq!(consensus_error.code(), 1047); assert_eq!( error.public_key_id(), - raw_public_keys[1].get("id").unwrap().as_u64().unwrap() as KeyID + raw_public_keys[1].get_integer("id").unwrap() as KeyID ); assert_eq!( - error.security_level() as u64, + error.security_level() as u8, raw_public_keys[1] - .get("securityLevel") - .unwrap() - .as_u64() + .get_integer::("securityLevel") .unwrap() ); assert_eq!( - error.purpose() as u64, - raw_public_keys[1].get("purpose").unwrap().as_u64().unwrap() + error.purpose() as u8, + raw_public_keys[1]..get_integer::("purpose").unwrap() ); } @@ -482,11 +482,11 @@ pub fn should_pass_valid_bls12_381_public_key() { // needs reevaluation once v19 is released. let (_, validator) = setup_test(); - let raw_public_keys_json = json!([{ - "id": 0, - "type": KeyType::BLS12_381 as u64, - "purpose": 0, - "securityLevel": 0, + let raw_public_keys_json = platform_value!([{ + "id": 0u32, + "type": KeyType::BLS12_381 as u8, + "purpose": 0u8, + "securityLevel": 0u8, "readOnly": true, "data": hex::decode("01fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694").unwrap(), }]); @@ -503,11 +503,11 @@ pub fn should_pass_valid_bls12_381_public_key() { #[test] pub fn should_pass_valid_ecdsa_hash160_public_key() { let (_, validator) = setup_test(); - let raw_public_keys_json = json!([{ - "id": 0, - "type": KeyType::ECDSA_HASH160 as u64, - "purpose": 0, - "securityLevel": 0, + let raw_public_keys_json = platform_value!([{ + "id": 0u32, + "type": KeyType::ECDSA_HASH160 as u8, + "purpose": 0u8, + "securityLevel": 0u8, "readOnly": true, "data": hex::decode("6086389d3fa4773aa950b8de18c5bd6d8f2b73bc").unwrap(), }]); @@ -522,10 +522,10 @@ pub fn should_pass_valid_ecdsa_hash160_public_key() { pub fn should_return_invalid_result_if_bls12_381_public_key_is_invalid() { let (_, validator) = setup_test(); let raw_public_keys_json = platform_value!([{ - "id": 0, - "type": KeyType::BLS12_381, - "purpose": 0, - "securityLevel": 0, + "id": 0u32, + "type": KeyType::BLS12_381 as u8, + "purpose": 0u8, + "securityLevel": 0u8, "readOnly": true, "data": hex::decode("11fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694").unwrap(), }]); @@ -547,9 +547,9 @@ pub fn should_return_invalid_result_if_bls12_381_public_key_is_invalid() { raw_public_keys .get(0) .unwrap() - .as_object() + .to_map() .unwrap() - .get("id") + .get_integer("id") .unwrap() .as_u64() .unwrap() as KeyID diff --git a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs index b734b134599..0e5da661b0d 100644 --- a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs @@ -2,6 +2,7 @@ use crate::identity::{ validation::{RequiredPurposeAndSecurityLevelValidator, TPublicKeysValidator}, KeyType, Purpose, SecurityLevel, }; +use platform_value::platform_value; use platform_value::string_encoding::{decode, Encoding}; use serde_json::json; @@ -9,20 +10,20 @@ use serde_json::json; fn should_return_invalid_result_if_state_transition_does_not_contain_master_key() { let validator = RequiredPurposeAndSecurityLevelValidator {}; let raw_public_keys = vec![ - json!({ - "id": 0, - "type" : KeyType::ECDSA_SECP256K1, - "purpose" : Purpose::AUTHENTICATION, - "securityLevel" : SecurityLevel::CRITICAL, + platform_value!({ + "id": 0u32, + "type" : KeyType::ECDSA_SECP256K1 as u8, + "purpose" : Purpose::AUTHENTICATION as u8, + "securityLevel" : SecurityLevel::CRITICAL as u8, "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), "readOnly" : false, }), // this key must be filtered out - json!({ - "id": 0, - "type" : KeyType::ECDSA_SECP256K1, - "purpose": Purpose::AUTHENTICATION, - "securityLevel" : SecurityLevel::CRITICAL, + platform_value!({ + "id": 0u32, + "type" : KeyType::ECDSA_SECP256K1 as u8, + "purpose": Purpose::AUTHENTICATION as u8, + "securityLevel" : SecurityLevel::CRITICAL as u8, "disabledAt" : 42, "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), "readOnly" : false, @@ -30,7 +31,7 @@ fn should_return_invalid_result_if_state_transition_does_not_contain_master_key( ]; let result = validator - .validate_keys(&raw_public_keys) + .validate_keys(raw_public_keys.as_slice()) .expect("validation result should be returned"); assert!(matches!( diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 5c1af3b28e5..d0631e986d0 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -1122,17 +1122,6 @@ implfrom! { Map(Vec<(Value, Value)>), } -impl From> for Value { - fn from(value: BTreeMap) -> Self { - Value::Map( - value - .into_iter() - .map(|(key, value)| (Value::Text(key), value)) - .collect(), - ) - } -} - impl From<[(Value, Value); N]> for Value { /// Converts a `[(Value, Value); N]` into a `Value`. /// @@ -1194,12 +1183,29 @@ impl From<[(&str, Value); N]> for Value { } } -impl From> for Value { - fn from(value: BTreeMap) -> Self { +impl From> for Value +where + T: Into, +{ + fn from(value: BTreeMap) -> Self { + Value::Map( + value + .into_iter() + .map(|(key, value)| (key.into(), value.clone())) + .collect(), + ) + } +} + +impl From> for Value +where + T: Into, +{ + fn from(value: BTreeMap) -> Self { Value::Map( value .into_iter() - .map(|(key, value)| (Value::Text(key), value.clone())) + .map(|(key, value)| (key.into(), value)) .collect(), ) } From 67f52a33b6cd5d455a7d3f6812cc7beff42eea96 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 12 Mar 2023 13:11:48 +0700 Subject: [PATCH 107/228] some cleanup --- packages/rs-dpp/src/data_contract/data_contract.rs | 3 +-- .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- .../rs-dpp/src/data_trigger/dpns_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/document.rs | 4 ++-- packages/rs-dpp/src/document/extended_document.rs | 10 +++++----- packages/rs-dpp/src/document/serialize.rs | 2 +- .../document_base_transition.rs | 2 +- .../document_create_transition.rs | 4 ++-- .../document_replace_transition.rs | 2 +- .../documents_batch_transition/mod.rs | 2 +- .../validate_documents_batch_transition_basic.rs | 2 +- .../basic/validate_partial_compound_indices.rs | 2 +- .../identity_create_transition.rs | 4 ++-- .../identity_public_key_transitions.rs | 2 +- .../btreemap_field_replacement.rs | 0 .../btreemap_mut_value_extensions.rs | 0 .../btreemap_path_extensions.rs | 0 .../btreemap_path_insertion_extensions.rs | 0 .../btreemap_removal_extensions.rs | 0 .../btreemap_removal_inner_value_extensions.rs | 0 .../mod.rs} | 14 ++++++++++++++ packages/rs-platform-value/src/lib.rs | 8 +------- 23 files changed, 37 insertions(+), 30 deletions(-) rename packages/rs-platform-value/src/{ => btreemap_extensions}/btreemap_field_replacement.rs (100%) rename packages/rs-platform-value/src/{ => btreemap_extensions}/btreemap_mut_value_extensions.rs (100%) rename packages/rs-platform-value/src/{ => btreemap_extensions}/btreemap_path_extensions.rs (100%) rename packages/rs-platform-value/src/{ => btreemap_extensions}/btreemap_path_insertion_extensions.rs (100%) rename packages/rs-platform-value/src/{ => btreemap_extensions}/btreemap_removal_extensions.rs (100%) rename packages/rs-platform-value/src/{ => btreemap_extensions}/btreemap_removal_inner_value_extensions.rs (100%) rename packages/rs-platform-value/src/{btreemap_extensions.rs => btreemap_extensions/mod.rs} (95%) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 3b75d5967eb..d18e556883f 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -4,8 +4,7 @@ use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; use itertools::{Either, Itertools}; -use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; use platform_value::identifier::Identifier; use platform_value::Value; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 1de2d8eba4a..07c0d891bb4 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use anyhow::anyhow; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 100e9e850f4..987b925c781 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -1,5 +1,5 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index a7b7f20c181..0cb18e54b13 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use anyhow::Context; use anyhow::{anyhow, bail}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use serde_json::json; use crate::document::Document; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index fb32a9eec09..8488463ffd2 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -42,8 +42,8 @@ use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 70d298c3b57..2f0a5b01e54 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -15,10 +15,10 @@ use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::document::Document; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; -use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; -use platform_value::btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapInsertionPathHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::converter::serde_json::BTreeValueJsonConverter; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; @@ -450,7 +450,7 @@ mod test { use crate::identifier::Identifier; use crate::tests::utils::*; use platform_value::btreemap_extensions::BTreeValueMapHelper; - use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; + use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::string_encoding::Encoding; use platform_value::Value; use pretty_assertions::assert_eq; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 32f924908cb..7d5bf9df177 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -17,7 +17,7 @@ use byteorder::{BigEndian, ReadBytesExt}; use ciborium::Value as CborValue; use integer_encoding::VarIntWriter; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index c692b629b7b..4eb5e77a66c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -4,7 +4,7 @@ use std::convert::{TryFrom, TryInto}; use anyhow::bail; use num_enum::IntoPrimitive; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; pub use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 2b302e7972f..600cd4a79f6 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,6 +1,6 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index c73b95be9b6..deb44acb343 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -1,5 +1,5 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index c860e593786..357eda4531a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -5,7 +5,7 @@ use anyhow::{anyhow, Context}; use ciborium::value::Value as CborValue; use integer_encoding::VarInt; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 38b8e0c0223..472d5b5340b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -34,7 +34,7 @@ use crate::{ use anyhow::anyhow; use lazy_static::lazy_static; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::Value; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index 4f630d98512..68c56455779 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -1,7 +1,7 @@ use std::borrow::Borrow; use std::collections::BTreeMap; -use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::Value; use crate::consensus::basic::document::InconsistentCompoundIndexDataError; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index ba1821bfba4..75cd442d6ad 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -1,7 +1,7 @@ use std::convert::{TryFrom, TryInto}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::Value; use serde::de::Error as DeError; use serde::ser::Error as SerError; @@ -17,7 +17,7 @@ use crate::state_transition::{ }; use crate::util::json_value::JsonValueExt; use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; -use platform_value::btreemap_removal_inner_value_extensions::BTreeValueRemoveInnerValueFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveInnerValueFromMapHelper; use platform_value::string_encoding::Encoding; mod property_names { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index ee063b8b4ba..7fd7b5aab64 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -4,7 +4,7 @@ use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-platform-value/src/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs similarity index 100% rename from packages/rs-platform-value/src/btreemap_field_replacement.rs rename to packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs diff --git a/packages/rs-platform-value/src/btreemap_mut_value_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_mut_value_extensions.rs similarity index 100% rename from packages/rs-platform-value/src/btreemap_mut_value_extensions.rs rename to packages/rs-platform-value/src/btreemap_extensions/btreemap_mut_value_extensions.rs diff --git a/packages/rs-platform-value/src/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs similarity index 100% rename from packages/rs-platform-value/src/btreemap_path_extensions.rs rename to packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs diff --git a/packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_insertion_extensions.rs similarity index 100% rename from packages/rs-platform-value/src/btreemap_path_insertion_extensions.rs rename to packages/rs-platform-value/src/btreemap_extensions/btreemap_path_insertion_extensions.rs diff --git a/packages/rs-platform-value/src/btreemap_removal_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs similarity index 100% rename from packages/rs-platform-value/src/btreemap_removal_extensions.rs rename to packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs diff --git a/packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_inner_value_extensions.rs similarity index 100% rename from packages/rs-platform-value/src/btreemap_removal_inner_value_extensions.rs rename to packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_inner_value_extensions.rs diff --git a/packages/rs-platform-value/src/btreemap_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/mod.rs similarity index 95% rename from packages/rs-platform-value/src/btreemap_extensions.rs rename to packages/rs-platform-value/src/btreemap_extensions/mod.rs index 83cf6936ddc..1257a4507cc 100644 --- a/packages/rs-platform-value/src/btreemap_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/mod.rs @@ -6,6 +6,20 @@ use std::{collections::BTreeMap, convert::TryInto}; use crate::{Error, Value, ValueMap}; +pub(crate) mod btreemap_field_replacement; +mod btreemap_mut_value_extensions; +mod btreemap_path_extensions; +mod btreemap_path_insertion_extensions; +mod btreemap_removal_extensions; +mod btreemap_removal_inner_value_extensions; + +pub use btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; +pub use btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +pub use btreemap_path_extensions::BTreeValueMapPathHelper; +pub use btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper; +pub use btreemap_removal_inner_value_extensions::BTreeValueRemoveInnerValueFromMapHelper; +pub use btreemap_mut_value_extensions::BTreeMutValueMapHelper; + pub trait BTreeValueMapHelper { fn get_optional_identifier(&self, key: &str) -> Result, Error>; fn get_identifier(&self, key: &str) -> Result<[u8; 32], Error>; diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index d0631e986d0..a980975e041 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -6,12 +6,6 @@ //! //! pub mod btreemap_extensions; -pub mod btreemap_field_replacement; -mod btreemap_mut_value_extensions; -pub mod btreemap_path_extensions; -pub mod btreemap_path_insertion_extensions; -pub mod btreemap_removal_extensions; -pub mod btreemap_removal_inner_value_extensions; pub mod converter; pub mod display; mod error; @@ -35,7 +29,7 @@ use std::collections::{BTreeMap, HashMap}; pub type Hash256 = [u8; 32]; use crate::ser::Serializer; -pub use btreemap_field_replacement::ReplacementType; +pub use btreemap_extensions::btreemap_field_replacement::ReplacementType; /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] From 46801a8f36b86ed7761cf41efd03098d7ea4c283 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 12 Mar 2023 20:09:02 +0700 Subject: [PATCH 108/228] more work on deserialization --- .../rs-dpp/src/data_contract/data_contract.rs | 2 +- .../document_type/document_factory.rs | 2 +- .../errors/data_contract_not_present_error.rs | 2 +- .../errors/identity_not_present_error.rs | 2 +- .../src/data_contract/serialization/cbor.rs | 2 +- packages/rs-dpp/src/document/document.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 4 +- .../document_replace_transition.rs | 2 +- ...incompatible_data_contract_schema_error.rs | 2 +- .../invalid_document_transition_id_error.rs | 2 +- .../document/invalid_document_type_error.rs | 2 +- .../signature/identity_not_found_error.rs | 2 +- packages/rs-dpp/src/identifier/mod.rs | 4 +- packages/rs-dpp/src/identity/factory.rs | 2 +- .../rs-dpp/src/identity/identity_facade.rs | 2 +- .../instant/instant_asset_lock_proof.rs | 2 +- packages/rs-dpp/src/tests/identifier_spec.rs | 2 +- packages/rs-platform-value/src/error.rs | 6 + packages/rs-platform-value/src/inner_value.rs | 2 +- packages/rs-platform-value/src/integer.rs | 144 ----- packages/rs-platform-value/src/lib.rs | 39 +- .../src/{ => types}/identifier.rs | 2 +- packages/rs-platform-value/src/types/mod.rs | 1 + .../src/value_serialization/de.rs | 568 ++++++++++++++++++ .../src/value_serialization/mod.rs | 111 ++++ .../src/{ => value_serialization}/ser.rs | 0 26 files changed, 726 insertions(+), 185 deletions(-) delete mode 100644 packages/rs-platform-value/src/integer.rs rename packages/rs-platform-value/src/{ => types}/identifier.rs (98%) create mode 100644 packages/rs-platform-value/src/types/mod.rs create mode 100644 packages/rs-platform-value/src/value_serialization/de.rs create mode 100644 packages/rs-platform-value/src/value_serialization/mod.rs rename packages/rs-platform-value/src/{ => value_serialization}/ser.rs (100%) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index d18e556883f..b29ceb63ebd 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -5,7 +5,7 @@ use anyhow::anyhow; use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; -use platform_value::identifier::Identifier; +use platform_value::Identifier; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs index 125422cbaed..618a6cf34ff 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs @@ -7,7 +7,7 @@ use crate::ProtocolError; use chrono::Utc; use platform_value::Value; -use platform_value::identifier::Identifier; +use platform_value::Identifier; use std::collections::BTreeMap; impl DocumentType { diff --git a/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs b/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs index 133d508a3cb..440cf3f79eb 100644 --- a/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs +++ b/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs @@ -1,4 +1,4 @@ -use platform_value::identifier::Identifier; +use platform_value::Identifier; use thiserror::Error; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs b/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs index 520407d445d..82d3fdf1f78 100644 --- a/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs +++ b/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs @@ -1,4 +1,4 @@ -use platform_value::identifier::Identifier; +use platform_value::Identifier; use thiserror::Error; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index b4bc3e69b67..4011f6f684f 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -1,5 +1,5 @@ use crate::data_contract::{property_names, DataContract}; -use crate::identifier::Identifier; +use crate::prelude::Identifier; use crate::util::cbor_value::CborCanonicalMap; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 8488463ffd2..986c3a9e6e6 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -52,7 +52,7 @@ use crate::data_contract::errors::DataContractError; use crate::document::errors::DocumentError; -use crate::identifier::Identifier; +use crate::prelude::Identifier; use crate::identity::TimestampMillis; use crate::prelude::Revision; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 2f0a5b01e54..766fe1d3059 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -1,5 +1,5 @@ use crate::data_contract::{DataContract, DriveContractExt}; -use crate::identifier::Identifier; +use crate::prelude::Identifier; use crate::metadata::Metadata; use crate::prelude::{Revision, TimestampMillis}; use crate::util::cbor_value::CborCanonicalMap; @@ -447,7 +447,7 @@ mod test { use crate::data_contract::DataContract; use crate::document::Document; - use crate::identifier::Identifier; + use crate::prelude::Identifier; use crate::tests::utils::*; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index deb44acb343..8e9ffbebca4 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -8,7 +8,7 @@ use std::convert::TryInto; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::document::Document; -use crate::identifier::Identifier; +use crate::prelude::Identifier; use crate::identity::TimestampMillis; use crate::prelude::{ExtendedDocument, Revision}; use crate::{data_contract::DataContract, errors::ProtocolError}; diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/incompatible_data_contract_schema_error.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/incompatible_data_contract_schema_error.rs index 41a12ba18ae..c7d425dabf4 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/data_contract/incompatible_data_contract_schema_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/incompatible_data_contract_schema_error.rs @@ -3,7 +3,7 @@ use thiserror::Error; use crate::consensus::ConsensusError; use crate::document::document_transition::document_base_transition::JsonValue; -use crate::identifier::Identifier; +use crate::prelude::Identifier; #[derive(Error, Debug, Clone, PartialEq, Eq)] #[error("Data Contract updated schema is not backward compatible with one defined in Data Contract wid id {data_contract_id}. Field: '{field_path}', Operation: '{operation}'" diff --git a/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_transition_id_error.rs b/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_transition_id_error.rs index e4a49c8236d..53b29f79cae 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_transition_id_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_transition_id_error.rs @@ -1,5 +1,5 @@ use crate::consensus::basic::BasicError; -use crate::identifier::Identifier; +use crate::prelude::Identifier; use thiserror::Error; #[derive(Error, Debug, Clone, PartialEq, Eq)] diff --git a/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_type_error.rs b/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_type_error.rs index 585d3e5a318..1f9811ea2fd 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_type_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_type_error.rs @@ -1,7 +1,7 @@ use thiserror::Error; use crate::data_contract::errors::DataContractError; -use crate::identifier::Identifier; +use crate::prelude::Identifier; #[derive(Error, Debug, Clone, PartialEq, Eq)] #[error("Data Contract {data_contract_id} doesn't define document with the type {document_type}")] diff --git a/packages/rs-dpp/src/errors/consensus/signature/identity_not_found_error.rs b/packages/rs-dpp/src/errors/consensus/signature/identity_not_found_error.rs index 18613962366..1acdcbab98b 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/identity_not_found_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/identity_not_found_error.rs @@ -2,7 +2,7 @@ use thiserror::Error; use crate::consensus::signature::SignatureError; use crate::consensus::ConsensusError; -use crate::identifier::Identifier; +use crate::prelude::Identifier; #[derive(Error, Debug, Clone, PartialEq, Eq)] #[error("Identity {identity_id} not found")] diff --git a/packages/rs-dpp/src/identifier/mod.rs b/packages/rs-dpp/src/identifier/mod.rs index f270a7cd0fb..ced6fa8aa88 100644 --- a/packages/rs-dpp/src/identifier/mod.rs +++ b/packages/rs-dpp/src/identifier/mod.rs @@ -1,2 +1,2 @@ -pub use platform_value::identifier::Identifier; -pub use platform_value::identifier::MEDIA_TYPE; +pub use platform_value::Identifier; +pub use platform_value::IDENTIFIER_MEDIA_TYPE as MEDIA_TYPE; diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index 07195ef8539..938f09788c0 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -1,5 +1,5 @@ use crate::decode_protocol_entity_factory::DecodeProtocolEntity; -use crate::identifier::Identifier; +use crate::prelude::Identifier; use crate::identity::identity_public_key::factory::KeyCount; use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; use crate::identity::state_transition::asset_lock_proof::{AssetLockProof, InstantAssetLockProof}; diff --git a/packages/rs-dpp/src/identity/identity_facade.rs b/packages/rs-dpp/src/identity/identity_facade.rs index 4dc9b92bf44..b9aee96a3dc 100644 --- a/packages/rs-dpp/src/identity/identity_facade.rs +++ b/packages/rs-dpp/src/identity/identity_facade.rs @@ -3,7 +3,7 @@ use serde_json::Value; use std::collections::BTreeMap; use std::sync::Arc; -use crate::identifier::Identifier; +use crate::prelude::Identifier; use crate::identity::factory::IdentityFactory; use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; use crate::identity::state_transition::asset_lock_proof::{AssetLockProof, InstantAssetLockProof}; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs index 506156cc1ff..7d6b2d4c69d 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs @@ -6,7 +6,7 @@ use serde::de::Error as DeError; use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use crate::identifier::Identifier; +use crate::prelude::Identifier; use crate::util::cbor_value::CborCanonicalMap; use crate::util::hash::hash; use crate::util::vec::vec_to_array; diff --git a/packages/rs-dpp/src/tests/identifier_spec.rs b/packages/rs-dpp/src/tests/identifier_spec.rs index d0efafa1dc8..3f80d6e7999 100644 --- a/packages/rs-dpp/src/tests/identifier_spec.rs +++ b/packages/rs-dpp/src/tests/identifier_spec.rs @@ -1,4 +1,4 @@ -use crate::identifier::Identifier; +use crate::prelude::Identifier; use platform_value::string_encoding::Encoding; #[test] diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index 089f25faf3f..a566ddf9f3a 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -34,3 +34,9 @@ impl serde::ser::Error for Error { todo!() } } + +impl serde::de::Error for Error { + fn custom(msg: T) -> Self where T: Display { + todo!() + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index c2ddc59265b..5fcc76ccbcb 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,4 +1,4 @@ -use crate::identifier::Identifier; +use crate::Identifier; use crate::value_map::{ValueMap, ValueMapHelper}; use crate::Value::Bool; use crate::{Error, Value}; diff --git a/packages/rs-platform-value/src/integer.rs b/packages/rs-platform-value/src/integer.rs deleted file mode 100644 index 22ae8a4c122..00000000000 --- a/packages/rs-platform-value/src/integer.rs +++ /dev/null @@ -1,144 +0,0 @@ -// from ciborium -// SPDX-License-Identifier: Apache-2.0 -use core::cmp::Ordering; - -macro_rules! implfrom { - ($( $(#[$($attr:meta)+])? $t:ident)+) => { - $( - $(#[$($attr)+])? - impl From<$t> for Integer { - #[inline] - fn from(value: $t) -> Self { - Self(value as _) - } - } - - impl TryFrom for $t { - type Error = core::num::TryFromIntError; - - #[inline] - fn try_from(value: Integer) -> Result { - $t::try_from(value.0) - } - } - )+ - }; -} - -/// An abstract integer value -/// -/// This opaque type represents an integer value which can be encoded in CBOR -/// without resulting to big integer encoding. Larger values may be encoded -/// using the big integer encoding as described in the CBOR RFC. See the -/// implementations for 128-bit integer conversions on `Value` for more -/// details. -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct Integer(i128); - -impl Integer { - /// Returns the canonical length this integer will have when serialized to bytes. - /// This is called `canonical` as it is only used for canonically comparing two - /// values. It shouldn't be used in any other context. - fn canonical_len(&self) -> usize { - let x = self.0; - - if let Ok(x) = u8::try_from(x) { - if x < 24 { - 1 - } else { - 2 - } - } else if let Ok(x) = i8::try_from(x) { - if x >= -24i8 { - 1 - } else { - 2 - } - } else if u16::try_from(x).is_ok() || i16::try_from(x).is_ok() { - 3 - } else if u32::try_from(x).is_ok() || i32::try_from(x).is_ok() { - 5 - } else if u64::try_from(x).is_ok() || i64::try_from(x).is_ok() { - 9 - } else { - // Ciborium serializes u128/i128 as BigPos if they don't fit in 64 bits. - // In this special case we have to calculate the length. - // The Tag itself will always be 1 byte. - x.to_be_bytes().len() + 1 - } - } - - /// Compare two integers as if we were to serialize them, but more efficiently. - pub fn canonical_cmp(&self, other: &Self) -> Ordering { - match self.canonical_len().cmp(&other.canonical_len()) { - Ordering::Equal => { - // Negative numbers are higher in byte-order than positive numbers. - match (self.0.is_negative(), other.0.is_negative()) { - (false, true) => Ordering::Less, - (true, false) => Ordering::Greater, - (true, true) => { - // For negative numbers the byte order puts numbers closer to 0 which - // are lexically higher, lower. So -1 < -2 when sorting by be_bytes(). - match self.0.cmp(&other.0) { - Ordering::Less => Ordering::Greater, - Ordering::Equal => Ordering::Equal, - Ordering::Greater => Ordering::Less, - } - } - (_, _) => self.0.cmp(&other.0), - } - } - x => x, - } - } -} - -implfrom! { - u8 u16 u32 u64 - i8 i16 i32 i64 - - #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] - usize - - #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] - isize -} - -impl TryFrom for Integer { - type Error = core::num::TryFromIntError; - - #[inline] - fn try_from(value: i128) -> Result { - u64::try_from(match value.is_negative() { - false => value, - true => value ^ !0, - })?; - - Ok(Integer(value)) - } -} - -impl TryFrom for Integer { - type Error = core::num::TryFromIntError; - - #[inline] - fn try_from(value: u128) -> Result { - Ok(Self(u64::try_from(value)?.into())) - } -} - -impl From for i128 { - #[inline] - fn from(value: Integer) -> Self { - value.0 - } -} - -impl TryFrom for u128 { - type Error = core::num::TryFromIntError; - - #[inline] - fn try_from(value: Integer) -> Result { - u128::try_from(value.0) - } -} diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index a980975e041..5c1e5e758b5 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -9,32 +9,32 @@ pub mod btreemap_extensions; pub mod converter; pub mod display; mod error; -pub mod identifier; mod index; pub mod inner_value; mod inner_value_at_path; -mod integer; mod macros; -mod ser; pub mod string_encoding; pub mod system_bytes; pub mod value_map; +mod types; +mod value_serialization; use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; -pub use integer::Integer; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; pub type Hash256 = [u8; 32]; -use crate::ser::Serializer; + pub use btreemap_extensions::btreemap_field_replacement::ReplacementType; +pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; + +pub use value_serialization::{to_value, from_value}; /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] -#[derive(Deserialize, Clone, Debug, PartialEq, PartialOrd)] -#[serde(untagged)] +#[derive(Clone, Debug, PartialEq, PartialOrd)] pub enum Value { /// A u128 integer U128(u128), @@ -72,6 +72,12 @@ pub enum Value { /// Bytes 32 Bytes32([u8; 32]), + /// An enumeration of u8 + EnumU8(Vec), + + /// An enumeration of strings + EnumString(String), + /// Identifier /// The identifier is very similar to bytes, however it is serialized to Base58 when converted /// to a JSON Value @@ -166,7 +172,7 @@ impl Value { /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` - /// # use platform_value::{Value, Integer, Error}; + /// # use platform_value::{Value, Error}; /// # /// let value = Value::U64(17); /// let r_value : Result = value.into_integer(); @@ -208,7 +214,7 @@ impl Value { /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` - /// # use platform_value::{Value, Integer, Error}; + /// # use platform_value::{Value, Error}; /// # /// let value = Value::U64(17); /// let r_value : Result = value.to_integer(); @@ -755,7 +761,7 @@ impl Value { /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` - /// # use platform_value::{Value, Integer, Error}; + /// # use platform_value::{Value, Error}; /// # /// let mut value = Value::Array( /// vec![ @@ -779,7 +785,7 @@ impl Value { /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` - /// # use platform_value::{Value, Integer, Error}; + /// # use platform_value::{Value, Error}; /// # /// let mut value = Value::Array( /// vec![ @@ -803,7 +809,7 @@ impl Value { /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` - /// # use platform_value::{Value, Integer, Error}; + /// # use platform_value::{Value, Error}; /// # /// let mut value = Value::Array( /// vec![ @@ -827,7 +833,7 @@ impl Value { /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` - /// # use platform_value::{Value, Integer, Error}; + /// # use platform_value::{Value, Error}; /// # /// let mut value = Value::Array( /// vec![ @@ -1213,10 +1219,3 @@ impl From for Value { Value::Text(v) } } - -pub fn to_value(value: T) -> Result -where - T: Serialize, -{ - value.serialize(Serializer) -} diff --git a/packages/rs-platform-value/src/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs similarity index 98% rename from packages/rs-platform-value/src/identifier.rs rename to packages/rs-platform-value/src/types/identifier.rs index 3df17301932..2681ca0c893 100644 --- a/packages/rs-platform-value/src/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -8,7 +8,7 @@ use serde_json::Value as JsonValue; use crate::string_encoding::Encoding; use crate::{string_encoding, Error}; -pub const MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; +pub const IDENTIFIER_MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy)] pub struct Identifier { diff --git a/packages/rs-platform-value/src/types/mod.rs b/packages/rs-platform-value/src/types/mod.rs new file mode 100644 index 00000000000..7db6becf372 --- /dev/null +++ b/packages/rs-platform-value/src/types/mod.rs @@ -0,0 +1 @@ +pub(crate) mod identifier; diff --git a/packages/rs-platform-value/src/value_serialization/de.rs b/packages/rs-platform-value/src/value_serialization/de.rs new file mode 100644 index 00000000000..d871b67d350 --- /dev/null +++ b/packages/rs-platform-value/src/value_serialization/de.rs @@ -0,0 +1,568 @@ +use std::iter::Peekable; +use serde::de::{self, Deserializer as _}; +use crate::{Error, Value}; + +impl<'a> From<&'a Value> for de::Unexpected<'a> { + #[inline] + fn from(value: &'a Value) -> Self { + match value { + Value::Bool(x) => Self::Bool(*x), + Value::Float(x) => Self::Float(*x), + Value::Bytes(x) => Self::Bytes(x), + Value::Text(x) => Self::Str(x), + Value::Array(..) => Self::Seq, + Value::Map(..) => Self::Map, + Value::Null => Self::Other("null"), + } + } +} + +macro_rules! mkvisit { + ($($f:ident($v:ty)),+ $(,)?) => { + $( + #[inline] + fn $f(self, v: $v) -> Result { + Ok(v.into()) + } + )+ + }; +} + +struct Visitor; + +impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = Value; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(formatter, "a valid platform value item") + } + + mkvisit! { + visit_bool(bool), + visit_f32(f32), + visit_f64(f64), + + visit_i8(i8), + visit_i16(i16), + visit_i32(i32), + visit_i64(i64), + visit_i128(i128), + + visit_u8(u8), + visit_u16(u16), + visit_u32(u32), + visit_u64(u64), + visit_u128(u128), + + visit_char(char), + visit_str(&str), + visit_borrowed_str(&'de str), + visit_string(String), + + visit_bytes(&[u8]), + visit_borrowed_bytes(&'de [u8]), + visit_byte_buf(Vec), + } + + #[inline] + fn visit_none(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn visit_some>( + self, + deserializer: D, + ) -> Result { + deserializer.deserialize_any(self) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn visit_newtype_struct>( + self, + deserializer: D, + ) -> Result { + deserializer.deserialize_any(self) + } + + #[inline] + fn visit_seq>(self, mut acc: A) -> Result { + let mut seq = Vec::new(); + + while let Some(elem) = acc.next_element()? { + seq.push(elem); + } + + Ok(Value::Array(seq)) + } + + #[inline] + fn visit_map>(self, mut acc: A) -> Result { + let mut map = Vec::<(Value, Value)>::new(); + + while let Some(kv) = acc.next_entry()? { + map.push(kv); + } + + Ok(Value::Map(map)) + } + + #[inline] + fn visit_enum>(self, acc: A) -> Result { + use serde::de::VariantAccess; + + struct Inner; + + impl<'de> serde::de::Visitor<'de> for Inner { + type Value = Value; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(formatter, "a valid CBOR item") + } + + #[inline] + fn visit_seq>(self, mut acc: A) -> Result { + let tag: u64 = acc + .next_element()? + .ok_or_else(|| de::Error::custom("expected tag"))?; + let val = acc + .next_element()? + .ok_or_else(|| de::Error::custom("expected val"))?; + Ok(Value::EnumU8(tag, Box::new(val))) + } + } + + let (name, data): (String, _) = acc.variant()?; + assert_eq!("@@TAGGED@@", name); + data.tuple_variant(2, Inner) + } +} + +impl<'de> de::Deserialize<'de> for Value { + #[inline] + fn deserialize>(deserializer: D) -> Result { + deserializer.deserialize_any(Visitor) + } +} + +struct Deserializer(T); +// +// impl<'a> Deserializer<&'a Value> { +// fn integer(&self, kind: &'static str) -> Result +// where +// N: TryFrom, +// N: TryFrom, +// { +// fn raw(value: &Value) -> Result { +// let mut buffer = 0u128.to_ne_bytes(); +// let length = buffer.len(); +// +// let bytes = match value { +// Value::Bytes(bytes) => { +// // Skip leading zeros... +// let mut bytes: &[u8] = bytes.as_ref(); +// while bytes.len() > buffer.len() && bytes[0] == 0 { +// bytes = &bytes[1..]; +// } +// +// if bytes.len() > buffer.len() { +// return Err(de::Error::custom("bigint too large")); +// } +// +// bytes +// } +// +// _ => return Err(de::Error::invalid_type(value.into(), &"bytes")), +// }; +// +// buffer[length - bytes.len()..].copy_from_slice(bytes); +// Ok(u128::from_be_bytes(buffer)) +// } +// +// let err = || de::Error::invalid_type(self.0.into(), &kind); +// +// Ok(match self { +// Value::Integer(x) => i128::from(*x).try_into().map_err(|_| err())?, +// Value::Tag(t, v) if *t == tag::BIGPOS => raw(v)?.try_into().map_err(|_| err())?, +// Value::Tag(t, v) if *t == tag::BIGNEG => i128::try_from(raw(v)?) +// .map(|x| x ^ !0) +// .map_err(|_| err()) +// .and_then(|x| x.try_into().map_err(|_| err()))?, +// _ => return Err(de::Error::invalid_type(self.0.into(), &"(big)int")), +// }) +// } +// } + +impl<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { + type Error = Error; + + #[inline] + fn deserialize_any>(self, visitor: V) -> Result { + match self.0 { + Value::Bytes(x) => visitor.visit_bytes(x), + Value::Text(x) => visitor.visit_str(x), + Value::Array(x) => visitor.visit_seq(Deserializer(x.iter())), + Value::Map(x) => visitor.visit_map(Deserializer(x.iter().peekable())), + Value::Bool(x) => visitor.visit_bool(*x), + Value::Null => visitor.visit_none(), + + Value::Float(x) => visitor.visit_f64(*x), + Value::U128(x) => visitor.visit_u128(*x), + Value::I128(x) => visitor.visit_i128(*x), + Value::U64(x) => visitor.visit_u64(*x), + Value::I64(x) => visitor.visit_i64(*x), + Value::U32(x) => visitor.visit_u32(*x), + Value::I32(x) => visitor.visit_i32(*x), + Value::U16(x) => visitor.visit_u16(*x), + Value::I16(x) => visitor.visit_i16(*x), + Value::U8(x) => visitor.visit_u8(*x), + Value::I8(x) => visitor.visit_i8(*x), + Value::Bytes32(x) => visitor.visit_bytes(x), + Value::EnumU8(x) => visitor.visit_enum(x), + Value::EnumString(x) => visitor.visit_enum(x), + Value::Identifier(x) => visitor.visit_bytes(x), + } + } + + #[inline] + fn deserialize_bool>(self, visitor: V) -> Result { + let mut value = self.0; + + match value { + Value::Bool(x) => visitor.visit_bool(*x), + _ => Err(de::Error::invalid_type(value.into(), &"bool")), + } + } + + #[inline] + fn deserialize_f32>(self, visitor: V) -> Result { + self.deserialize_f64(visitor) + } + + #[inline] + fn deserialize_f64>(self, visitor: V) -> Result { + let mut value = self.0; + + match value { + Value::Float(x) => visitor.visit_f64(*x), + _ => Err(de::Error::invalid_type(value.into(), &"f64")), + } + } + + fn deserialize_i8>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_i8(value.to_integer()?) + } + + fn deserialize_i16>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_i16(value.to_integer()?) + } + + fn deserialize_i32>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_i32(value.to_integer()?) + } + + fn deserialize_i64>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_i64(value.to_integer()?) + } + + fn deserialize_i128>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_i128(value.to_integer()?) + } + + fn deserialize_u8>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_u8(value.to_integer()?) + } + + fn deserialize_u16>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_u16(value.to_integer()?) + } + + fn deserialize_u32>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_u32(value.to_integer()?) + } + + fn deserialize_u64>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_u64(value.to_integer()?) + } + + fn deserialize_u128>(self, visitor: V) -> Result { + let mut value = self.0; + visitor.visit_u128(value.to_integer()?) + } + + fn deserialize_char>(self, visitor: V) -> Result { + let mut value = self.0; + + match value { + Value::Text(x) => match x.chars().count() { + 1 => visitor.visit_char(x.chars().next().unwrap()), + _ => Err(de::Error::invalid_type(value.into(), &"char")), + }, + + _ => Err(de::Error::invalid_type(value.into(), &"char")), + } + } + + fn deserialize_str>(self, visitor: V) -> Result { + let mut value = self.0; + + match value { + Value::Text(x) => visitor.visit_str(x), + _ => Err(de::Error::invalid_type(value.into(), &"str")), + } + } + + fn deserialize_string>(self, visitor: V) -> Result { + self.deserialize_str(visitor) + } + + fn deserialize_bytes>(self, visitor: V) -> Result { + let mut value = self.0; + + match value { + Value::Bytes(x) => visitor.visit_bytes(x), + _ => Err(de::Error::invalid_type(value.into(), &"bytes")), + } + } + + fn deserialize_byte_buf>( + self, + visitor: V, + ) -> Result { + self.deserialize_bytes(visitor) + } + + fn deserialize_seq>(self, visitor: V) -> Result { + let mut value = self.0; + + match value { + Value::Array(x) => visitor.visit_seq(Deserializer(x.iter())), + _ => Err(de::Error::invalid_type(value.into(), &"array")), + } + } + + fn deserialize_map>(self, visitor: V) -> Result { + let mut value = self.0; + + match value { + Value::Map(x) => visitor.visit_map(Deserializer(x.iter().peekable())), + _ => Err(de::Error::invalid_type(value.into(), &"map")), + } + } + + fn deserialize_struct>( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result { + self.deserialize_map(visitor) + } + + fn deserialize_tuple>( + self, + _len: usize, + visitor: V, + ) -> Result { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct>( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result { + self.deserialize_seq(visitor) + } + + fn deserialize_identifier>( + self, + visitor: V, + ) -> Result { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any>( + self, + visitor: V, + ) -> Result { + self.deserialize_any(visitor) + } + + #[inline] + fn deserialize_option>(self, visitor: V) -> Result { + match self.0 { + Value::Null => visitor.visit_none(), + x => visitor.visit_some(Self(x)), + } + } + + #[inline] + fn deserialize_unit>(self, visitor: V) -> Result { + match self.0 { + Value::Null => visitor.visit_unit(), + _ => Err(de::Error::invalid_type(self.0.into(), &"null")), + } + } + + #[inline] + fn deserialize_unit_struct>( + self, + _name: &'static str, + visitor: V, + ) -> Result { + self.deserialize_unit(visitor) + } + + #[inline] + fn deserialize_newtype_struct>( + self, + _name: &'static str, + visitor: V, + ) -> Result { + visitor.visit_newtype_struct(self) + } + + #[inline] + fn deserialize_enum>( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result { + match self.0 { + Value::Map(x) if x.len() == 1 => visitor.visit_enum(Deserializer(&x[0])), + x @ Value::Text(..) => visitor.visit_enum(Deserializer(x)), + _ => Err(de::Error::invalid_type(self.0.into(), &"map")), + } + } +} + +impl<'a, 'de, T: Iterator> de::SeqAccess<'de> for Deserializer { + type Error = Error; + + #[inline] + fn next_element_seed>( + &mut self, + seed: U, + ) -> Result, Self::Error> { + match self.0.next() { + None => Ok(None), + Some(v) => seed.deserialize(Deserializer(v)).map(Some), + } + } +} + +impl<'a, 'de, T: Iterator> de::MapAccess<'de> +for Deserializer> +{ + type Error = Error; + + #[inline] + fn next_key_seed>( + &mut self, + seed: K, + ) -> Result, Self::Error> { + match self.0.peek() { + None => Ok(None), + Some(x) => Ok(Some(seed.deserialize(Deserializer(&x.0))?)), + } + } + + #[inline] + fn next_value_seed>( + &mut self, + seed: V, + ) -> Result { + seed.deserialize(Deserializer(&self.0.next().unwrap().1)) + } +} + +impl<'a, 'de> de::EnumAccess<'de> for Deserializer<&'a (Value, Value)> { + type Error = Error; + type Variant = Deserializer<&'a Value>; + + #[inline] + fn variant_seed>( + self, + seed: V, + ) -> Result<(V::Value, Self::Variant), Self::Error> { + let k = seed.deserialize(Deserializer(&self.0 .0))?; + Ok((k, Deserializer(&self.0 .1))) + } +} + +impl<'a, 'de> de::EnumAccess<'de> for Deserializer<&'a Value> { + type Error = Error; + type Variant = Deserializer<&'a Value>; + + #[inline] + fn variant_seed>( + self, + seed: V, + ) -> Result<(V::Value, Self::Variant), Self::Error> { + let k = seed.deserialize(self)?; + Ok((k, Deserializer(&Value::Null))) + } +} + +impl<'a, 'de> de::VariantAccess<'de> for Deserializer<&'a Value> { + type Error = Error; + + #[inline] + fn unit_variant(self) -> Result<(), Self::Error> { + match self.0 { + Value::Null => Ok(()), + _ => Err(de::Error::invalid_type(self.0.into(), &"unit")), + } + } + + #[inline] + fn newtype_variant_seed>( + self, + seed: U, + ) -> Result { + seed.deserialize(self) + } + + #[inline] + fn tuple_variant>( + self, + _len: usize, + visitor: V, + ) -> Result { + self.deserialize_seq(visitor) + } + + #[inline] + fn struct_variant>( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result { + self.deserialize_map(visitor) + } +} + +impl Value { + /// Deserializes the `Value` into an object + #[inline] + pub fn deserialized<'de, T: de::Deserialize<'de>>(&self) -> Result { + T::deserialize(Deserializer(self)) + } +} diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs new file mode 100644 index 00000000000..5273d01b15f --- /dev/null +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -0,0 +1,111 @@ +use serde::de::DeserializeOwned; +use serde::Serialize; +use crate::{Error, Value}; +use crate::value_serialization::ser::Serializer; + +pub mod ser; +pub mod de; + + +/// Convert a `T` into `platform_value::Value` which is an enum that can represent +/// data. +/// +/// # Example +/// +/// ``` +/// use serde::Serialize; +/// use platform_value::platform_value; +/// +/// use std::error::Error; +/// +/// #[derive(Serialize)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn compare_platform_values() -> Result<(), Box> { +/// let u = User { +/// fingerprint: "0xF9BA143B95FF6D82".to_owned(), +/// location: "Menlo Park, CA".to_owned(), +/// }; +/// +/// // The type of `expected` is `serde_json::Value` +/// let expected = platform_value!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA", +/// }); +/// +/// let v = platform_value::to_value(u).unwrap(); +/// assert_eq!(v, expected); +/// +/// Ok(()) +/// } +/// # +/// # compare_platform_values().unwrap(); +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if `T`'s implementation of `Serialize` decides to +/// fail, or if `T` contains a map with non-string keys. +/// +/// ``` +/// use std::collections::BTreeMap; +/// +/// fn main() { +/// // The keys in this map are vectors, not strings. +/// let mut map = BTreeMap::new(); +/// map.insert(vec![32, 64], "x86"); +/// +/// println!("{}", platform_value::to_value(map).unwrap_err()); +/// } +/// ``` +pub fn to_value(value: T) -> Result + where + T: Serialize, +{ + value.serialize(Serializer) +} + +/// Interpret a `serde_json::Value` as an instance of type `T`. +/// +/// # Example +/// +/// ``` +/// use serde::Deserialize; +/// use platform_value::platform_value; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `serde_json::Value` +/// let j = platform_value!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA" +/// }); +/// +/// let u: User = platform_value::from_value(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the Value does not match the +/// structure expected by `T`, for example if `T` is a struct type but the Value +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_value(value: Value) -> Result + where + T: DeserializeOwned, +{ + T::deserialize(value) +} diff --git a/packages/rs-platform-value/src/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs similarity index 100% rename from packages/rs-platform-value/src/ser.rs rename to packages/rs-platform-value/src/value_serialization/ser.rs From 1b3b42dacc994ef2268c64a6a82dfcc7aa689ac7 Mon Sep 17 00:00:00 2001 From: Evgeny Fomin Date: Mon, 13 Mar 2023 03:26:25 +0100 Subject: [PATCH 109/228] even more work on deserialization --- .../src/converter/ciborium.rs | 6 +- .../src/converter/serde_json.rs | 6 + packages/rs-platform-value/src/display.rs | 2 + packages/rs-platform-value/src/error.rs | 6 +- packages/rs-platform-value/src/index.rs | 7 +- .../src/inner_value_at_path.rs | 8 +- packages/rs-platform-value/src/lib.rs | 2 +- .../src/value_serialization/de.rs | 364 +++++++----------- .../src/value_serialization/mod.rs | 57 ++- .../src/value_serialization/ser.rs | 2 + 10 files changed, 216 insertions(+), 244 deletions(-) diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 231aab16ec3..5506e094944 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -36,7 +36,7 @@ impl TryFrom for Value { CborValue::Text(string) => Self::Text(string), CborValue::Bool(value) => Self::Bool(value), CborValue::Null => Self::Null, - CborValue::Tag(int, value) => { + CborValue::Tag(_, _) => { return Err(Error::Unsupported( "conversion from cbor tags are currently not supported".to_string(), )) @@ -115,6 +115,8 @@ impl TryInto for Value { .collect::, Error>>()?, ), Value::Identifier(bytes) => CborValue::Bytes(bytes.to_vec()), + Value::EnumU8(_) => todo!(), + Value::EnumString(_) => todo!(), }) } } @@ -122,6 +124,6 @@ impl TryInto for Value { impl TryInto> for Box { type Error = Error; fn try_into(self) -> Result, Self::Error> { - self.try_into() + (*self).try_into().map(Box::new) } } diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index cccabbddef7..d9ba27f47f0 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -78,6 +78,8 @@ impl Value { .map(|byte| JsonValue::Number(byte.into())) .collect(), ), + Value::EnumU8(_) => todo!(), + Value::EnumString(_) => todo!(), }) } @@ -152,6 +154,8 @@ impl Value { .map(|byte| JsonValue::Number((*byte).into())) .collect(), ), + Value::EnumU8(_) => todo!(), + Value::EnumString(_) => todo!(), }) } } @@ -290,6 +294,8 @@ impl TryInto for Value { Value::Identifier(bytes) => { JsonValue::String(bs58::encode(bytes.as_slice()).into_string()) } + Value::EnumU8(_) => todo!(), + Value::EnumString(_) => todo!(), }) } } diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index bf1dd273692..105e7741338 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -51,6 +51,8 @@ impl Value { "identifier {}", bs58::encode(identifier.as_slice()).into_string() ), + Value::EnumU8(_) => todo!(), + Value::EnumString(_) => todo!(), } } } diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index a566ddf9f3a..bf0d6557988 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -1,5 +1,5 @@ -use std::error; use std::fmt::Display; + use thiserror::Error; #[derive(Error, Clone, Eq, PartialEq, Debug)] @@ -31,12 +31,14 @@ impl serde::ser::Error for Error { where T: Display, { + println!("{msg}"); todo!() } } impl serde::de::Error for Error { fn custom(msg: T) -> Self where T: Display { + println!("{msg}"); todo!() } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/index.rs b/packages/rs-platform-value/src/index.rs index b048f42e050..e1090a57f8c 100644 --- a/packages/rs-platform-value/src/index.rs +++ b/packages/rs-platform-value/src/index.rs @@ -1,8 +1,9 @@ -use super::Value; -use crate::value_map::{ValueMap, ValueMapHelper}; use core::fmt::{self, Display}; use core::ops; +use super::Value; +use crate::value_map::{ValueMap, ValueMapHelper}; + /// A type that can be used to index into a `platform_value::Value`. /// /// The [`get`] and [`get_mut`] methods of `Value` accept any type that @@ -163,6 +164,8 @@ impl<'a> Display for Type<'a> { Value::Bytes(_) => formatter.write_str("bytes"), Value::Bytes32(_) => formatter.write_str("bytes32"), Value::Identifier(_) => formatter.write_str("identifier"), + Value::EnumU8(_) => formatter.write_str("enum u8"), + Value::EnumString(_) => formatter.write_str("enum string"), } } } diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index a40565b496c..8de046b3694 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -3,7 +3,7 @@ use crate::{Error, Value}; impl Value { pub fn get_value_at_path<'a>(&'a self, path: &'a str) -> Result<&'a Value, Error> { - let mut split = path.split('.'); + let split = path.split('.'); let mut current_value = self; for path_component in split { let map = current_value.to_map_ref()?; @@ -18,7 +18,7 @@ impl Value { &'a self, path: &'a str, ) -> Result, Error> { - let mut split = path.split('.'); + let split = path.split('.'); let mut current_value = self; for path_component in split { let map = current_value.to_map_ref()?; @@ -31,7 +31,7 @@ impl Value { } pub fn get_mut_value_at_path<'a>(&'a mut self, path: &'a str) -> Result<&'a mut Value, Error> { - let mut split = path.split('.'); + let split = path.split('.'); let mut current_value = self; for path_component in split { let map = current_value.to_map_mut()?; @@ -46,7 +46,7 @@ impl Value { &'a mut self, path: &'a str, ) -> Result, Error> { - let mut split = path.split('.'); + let split = path.split('.'); let mut current_value = self; for path_component in split { let map = current_value.to_map_mut()?; diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 5c1e5e758b5..12601769c43 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -1132,7 +1132,7 @@ impl From<[(Value, Value); N]> for Value { /// let map2: Value = [(1, 2), (3, 4)].into(); /// assert_eq!(map1, map2); /// ``` - fn from(mut arr: [(Value, Value); N]) -> Self { + fn from(arr: [(Value, Value); N]) -> Self { if N == 0 { return Value::Map(vec![]); } diff --git a/packages/rs-platform-value/src/value_serialization/de.rs b/packages/rs-platform-value/src/value_serialization/de.rs index d871b67d350..311d249c70f 100644 --- a/packages/rs-platform-value/src/value_serialization/de.rs +++ b/packages/rs-platform-value/src/value_serialization/de.rs @@ -1,9 +1,11 @@ +use core::{fmt, slice}; use std::iter::Peekable; + use serde::de::{self, Deserializer as _}; + use crate::{Error, Value}; impl<'a> From<&'a Value> for de::Unexpected<'a> { - #[inline] fn from(value: &'a Value) -> Self { match value { Value::Bool(x) => Self::Bool(*x), @@ -13,6 +15,20 @@ impl<'a> From<&'a Value> for de::Unexpected<'a> { Value::Array(..) => Self::Seq, Value::Map(..) => Self::Map, Value::Null => Self::Other("null"), + Value::U128(_x) => todo!(), // TODO: it seems serde is not happy about u128 + Value::I128(_x) => todo!(), // TODO: ... and for i128 either + Value::U64(x) => Self::Unsigned(*x), + Value::I64(x) => Self::Signed(*x), + Value::U32(x) => Self::Unsigned(*x as u64), + Value::I32(x) => Self::Signed(*x as i64), + Value::U16(x) => Self::Unsigned(*x as u64), + Value::I16(x) => Self::Signed(*x as i64), + Value::U8(x) => Self::Unsigned(*x as u64), + Value::I8(x) => Self::Signed(*x as i64), + Value::Bytes32(_) => Self::Seq, + Value::EnumU8(_x) => todo!(), + Value::EnumString(_x) => todo!(), + Value::Identifier(_x) => todo!(), } } } @@ -20,8 +36,7 @@ impl<'a> From<&'a Value> for de::Unexpected<'a> { macro_rules! mkvisit { ($($f:ident($v:ty)),+ $(,)?) => { $( - #[inline] - fn $f(self, v: $v) -> Result { + fn $f(self, v: $v) -> Result { Ok(v.into()) } )+ @@ -30,10 +45,10 @@ macro_rules! mkvisit { struct Visitor; -impl<'de> serde::de::Visitor<'de> for Visitor { +impl<'de> de::Visitor<'de> for Visitor { type Value = Value; - fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { write!(formatter, "a valid platform value item") } @@ -64,12 +79,10 @@ impl<'de> serde::de::Visitor<'de> for Visitor { visit_byte_buf(Vec), } - #[inline] fn visit_none(self) -> Result { Ok(Value::Null) } - #[inline] fn visit_some>( self, deserializer: D, @@ -77,12 +90,10 @@ impl<'de> serde::de::Visitor<'de> for Visitor { deserializer.deserialize_any(self) } - #[inline] fn visit_unit(self) -> Result { Ok(Value::Null) } - #[inline] fn visit_newtype_struct>( self, deserializer: D, @@ -90,7 +101,6 @@ impl<'de> serde::de::Visitor<'de> for Visitor { deserializer.deserialize_any(self) } - #[inline] fn visit_seq>(self, mut acc: A) -> Result { let mut seq = Vec::new(); @@ -101,7 +111,6 @@ impl<'de> serde::de::Visitor<'de> for Visitor { Ok(Value::Array(seq)) } - #[inline] fn visit_map>(self, mut acc: A) -> Result { let mut map = Vec::<(Value, Value)>::new(); @@ -112,217 +121,165 @@ impl<'de> serde::de::Visitor<'de> for Visitor { Ok(Value::Map(map)) } - #[inline] - fn visit_enum>(self, acc: A) -> Result { - use serde::de::VariantAccess; + fn visit_enum>(self, _acc: A) -> Result { + // use serde::de::VariantAccess; - struct Inner; + // struct Inner; - impl<'de> serde::de::Visitor<'de> for Inner { - type Value = Value; + // impl<'de> serde::de::Visitor<'de> for Inner { + // type Value = Value; - fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(formatter, "a valid CBOR item") - } + // fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + // write!(formatter, "a valid CBOR item") + // } - #[inline] - fn visit_seq>(self, mut acc: A) -> Result { - let tag: u64 = acc - .next_element()? - .ok_or_else(|| de::Error::custom("expected tag"))?; - let val = acc - .next_element()? - .ok_or_else(|| de::Error::custom("expected val"))?; - Ok(Value::EnumU8(tag, Box::new(val))) - } - } + // // fn visit_seq>(self, mut acc: A) -> Result { + // let tag: u64 = acc + // .next_element()? + // .ok_or_else(|| de::Error::custom("expected tag"))?; + // let val = acc + // .next_element()? + // .ok_or_else(|| de::Error::custom("expected val"))?; + // Ok(Value::EnumU8(tag, Box::new(val))) + // } + // } - let (name, data): (String, _) = acc.variant()?; - assert_eq!("@@TAGGED@@", name); - data.tuple_variant(2, Inner) + // let (name, data): (String, _) = acc.variant()?; + // assert_eq!("@@TAGGED@@", name); + // data.tuple_variant(2, Inner) + + todo!() } } impl<'de> de::Deserialize<'de> for Value { - #[inline] fn deserialize>(deserializer: D) -> Result { deserializer.deserialize_any(Visitor) } } -struct Deserializer(T); -// -// impl<'a> Deserializer<&'a Value> { -// fn integer(&self, kind: &'static str) -> Result -// where -// N: TryFrom, -// N: TryFrom, -// { -// fn raw(value: &Value) -> Result { -// let mut buffer = 0u128.to_ne_bytes(); -// let length = buffer.len(); -// -// let bytes = match value { -// Value::Bytes(bytes) => { -// // Skip leading zeros... -// let mut bytes: &[u8] = bytes.as_ref(); -// while bytes.len() > buffer.len() && bytes[0] == 0 { -// bytes = &bytes[1..]; -// } -// -// if bytes.len() > buffer.len() { -// return Err(de::Error::custom("bigint too large")); -// } -// -// bytes -// } -// -// _ => return Err(de::Error::invalid_type(value.into(), &"bytes")), -// }; -// -// buffer[length - bytes.len()..].copy_from_slice(bytes); -// Ok(u128::from_be_bytes(buffer)) -// } -// -// let err = || de::Error::invalid_type(self.0.into(), &kind); -// -// Ok(match self { -// Value::Integer(x) => i128::from(*x).try_into().map_err(|_| err())?, -// Value::Tag(t, v) if *t == tag::BIGPOS => raw(v)?.try_into().map_err(|_| err())?, -// Value::Tag(t, v) if *t == tag::BIGNEG => i128::try_from(raw(v)?) -// .map(|x| x ^ !0) -// .map_err(|_| err()) -// .and_then(|x| x.try_into().map_err(|_| err()))?, -// _ => return Err(de::Error::invalid_type(self.0.into(), &"(big)int")), -// }) -// } -// } - -impl<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { +pub(crate) struct Deserializer(pub(crate) Value); + +impl<'de> de::Deserializer<'de> for Deserializer { type Error = Error; - #[inline] fn deserialize_any>(self, visitor: V) -> Result { match self.0 { - Value::Bytes(x) => visitor.visit_bytes(x), - Value::Text(x) => visitor.visit_str(x), - Value::Array(x) => visitor.visit_seq(Deserializer(x.iter())), - Value::Map(x) => visitor.visit_map(Deserializer(x.iter().peekable())), - Value::Bool(x) => visitor.visit_bool(*x), + Value::Bytes(x) => visitor.visit_bytes(&x), + Value::Text(x) => visitor.visit_str(&x), + Value::Array(x) => visitor.visit_seq(ArrayDeserializer(x.iter())), + Value::Map(x) => visitor.visit_map(ValueMapDeserializer(x.iter().peekable())), + Value::Bool(x) => visitor.visit_bool(x), Value::Null => visitor.visit_none(), - - Value::Float(x) => visitor.visit_f64(*x), - Value::U128(x) => visitor.visit_u128(*x), - Value::I128(x) => visitor.visit_i128(*x), - Value::U64(x) => visitor.visit_u64(*x), - Value::I64(x) => visitor.visit_i64(*x), - Value::U32(x) => visitor.visit_u32(*x), - Value::I32(x) => visitor.visit_i32(*x), - Value::U16(x) => visitor.visit_u16(*x), - Value::I16(x) => visitor.visit_i16(*x), - Value::U8(x) => visitor.visit_u8(*x), - Value::I8(x) => visitor.visit_i8(*x), - Value::Bytes32(x) => visitor.visit_bytes(x), - Value::EnumU8(x) => visitor.visit_enum(x), - Value::EnumString(x) => visitor.visit_enum(x), - Value::Identifier(x) => visitor.visit_bytes(x), + Value::Float(x) => visitor.visit_f64(x), + Value::U128(x) => visitor.visit_u128(x), + Value::I128(x) => visitor.visit_i128(x), + Value::U64(x) => visitor.visit_u64(x), + Value::I64(x) => visitor.visit_i64(x), + Value::U32(x) => visitor.visit_u32(x), + Value::I32(x) => visitor.visit_i32(x), + Value::U16(x) => visitor.visit_u16(x), + Value::I16(x) => visitor.visit_i16(x), + Value::U8(x) => visitor.visit_u8(x), + Value::I8(x) => visitor.visit_i8(x), + Value::Bytes32(x) => visitor.visit_bytes(&x), + Value::EnumU8(_x) => todo!(), + Value::EnumString(_x) => todo!(), + Value::Identifier(x) => visitor.visit_bytes(&x), } } - #[inline] fn deserialize_bool>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; match value { - Value::Bool(x) => visitor.visit_bool(*x), - _ => Err(de::Error::invalid_type(value.into(), &"bool")), + Value::Bool(x) => visitor.visit_bool(x), + _ => Err(de::Error::invalid_type((&value).into(), &"bool")), } } - #[inline] fn deserialize_f32>(self, visitor: V) -> Result { self.deserialize_f64(visitor) } - #[inline] fn deserialize_f64>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; match value { - Value::Float(x) => visitor.visit_f64(*x), - _ => Err(de::Error::invalid_type(value.into(), &"f64")), + Value::Float(x) => visitor.visit_f64(x), + _ => Err(de::Error::invalid_type((&value).into(), &"f64")), } } fn deserialize_i8>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_i8(value.to_integer()?) } fn deserialize_i16>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_i16(value.to_integer()?) } fn deserialize_i32>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_i32(value.to_integer()?) } fn deserialize_i64>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_i64(value.to_integer()?) } fn deserialize_i128>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_i128(value.to_integer()?) } fn deserialize_u8>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_u8(value.to_integer()?) } fn deserialize_u16>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_u16(value.to_integer()?) } fn deserialize_u32>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_u32(value.to_integer()?) } fn deserialize_u64>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_u64(value.to_integer()?) } fn deserialize_u128>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; visitor.visit_u128(value.to_integer()?) } fn deserialize_char>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; match value { - Value::Text(x) => match x.chars().count() { + Value::Text(ref x) => match x.chars().count() { 1 => visitor.visit_char(x.chars().next().unwrap()), - _ => Err(de::Error::invalid_type(value.into(), &"char")), + _ => Err(de::Error::invalid_type((&value).into(), &"char")), }, - _ => Err(de::Error::invalid_type(value.into(), &"char")), + _ => Err(de::Error::invalid_type((&value).into(), &"char")), } } fn deserialize_str>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; match value { - Value::Text(x) => visitor.visit_str(x), - _ => Err(de::Error::invalid_type(value.into(), &"str")), + Value::Text(x) => visitor.visit_str(&x), + _ => Err(de::Error::invalid_type((&value).into(), &"str")), } } @@ -331,11 +288,11 @@ impl<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { } fn deserialize_bytes>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; match value { - Value::Bytes(x) => visitor.visit_bytes(x), - _ => Err(de::Error::invalid_type(value.into(), &"bytes")), + Value::Bytes(x) => visitor.visit_bytes(&x), + _ => Err(de::Error::invalid_type((&value).into(), &"bytes")), } } @@ -347,20 +304,20 @@ impl<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { } fn deserialize_seq>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; match value { - Value::Array(x) => visitor.visit_seq(Deserializer(x.iter())), - _ => Err(de::Error::invalid_type(value.into(), &"array")), + Value::Array(x) => visitor.visit_seq(ArrayDeserializer(x.iter())), + _ => Err(de::Error::invalid_type((&value).into(), &"array")), } } fn deserialize_map>(self, visitor: V) -> Result { - let mut value = self.0; + let value = self.0; match value { - Value::Map(x) => visitor.visit_map(Deserializer(x.iter().peekable())), - _ => Err(de::Error::invalid_type(value.into(), &"map")), + Value::Map(x) => visitor.visit_map(ValueMapDeserializer(x.iter().peekable())), + _ => Err(de::Error::invalid_type((&value).into(), &"map")), } } @@ -404,7 +361,6 @@ impl<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { self.deserialize_any(visitor) } - #[inline] fn deserialize_option>(self, visitor: V) -> Result { match self.0 { Value::Null => visitor.visit_none(), @@ -412,15 +368,13 @@ impl<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { } } - #[inline] fn deserialize_unit>(self, visitor: V) -> Result { match self.0 { Value::Null => visitor.visit_unit(), - _ => Err(de::Error::invalid_type(self.0.into(), &"null")), + _ => Err(de::Error::invalid_type((&self.0).into(), &"null")), } } - #[inline] fn deserialize_unit_struct>( self, _name: &'static str, @@ -429,7 +383,6 @@ impl<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { self.deserialize_unit(visitor) } - #[inline] fn deserialize_newtype_struct>( self, _name: &'static str, @@ -438,101 +391,78 @@ impl<'a, 'de> de::Deserializer<'de> for Deserializer<&'a Value> { visitor.visit_newtype_struct(self) } - #[inline] fn deserialize_enum>( self, - name: &'static str, - variants: &'static [&'static str], - visitor: V, + _name: &'static str, + _variants: &'static [&'static str], + _visitor: V, ) -> Result { - match self.0 { - Value::Map(x) if x.len() == 1 => visitor.visit_enum(Deserializer(&x[0])), - x @ Value::Text(..) => visitor.visit_enum(Deserializer(x)), - _ => Err(de::Error::invalid_type(self.0.into(), &"map")), - } + // match self.0 { + // Value::Map(x) if x.len() == 1 => visitor.visit_enum(Deserializer(&x[0])), + // x @ Value::Text(..) => visitor.visit_enum(Deserializer(x)), + // _ => Err(de::Error::invalid_type(self.0.into(), &"map")), + // } + todo!() } } -impl<'a, 'de, T: Iterator> de::SeqAccess<'de> for Deserializer { +struct ArrayDeserializer<'a>(slice::Iter<'a, Value>); + +impl<'a, 'de> de::SeqAccess<'de> for ArrayDeserializer<'a> { type Error = Error; - #[inline] fn next_element_seed>( &mut self, seed: U, ) -> Result, Self::Error> { - match self.0.next() { - None => Ok(None), - Some(v) => seed.deserialize(Deserializer(v)).map(Some), - } - } -} - -impl<'a, 'de, T: Iterator> de::MapAccess<'de> -for Deserializer> -{ - type Error = Error; - - #[inline] - fn next_key_seed>( - &mut self, - seed: K, - ) -> Result, Self::Error> { - match self.0.peek() { - None => Ok(None), - Some(x) => Ok(Some(seed.deserialize(Deserializer(&x.0))?)), - } - } - - #[inline] - fn next_value_seed>( - &mut self, - seed: V, - ) -> Result { - seed.deserialize(Deserializer(&self.0.next().unwrap().1)) + self.0 + .next() + .map(|x| seed.deserialize(Deserializer(x.clone()))) + .transpose() // TODO } } -impl<'a, 'de> de::EnumAccess<'de> for Deserializer<&'a (Value, Value)> { - type Error = Error; - type Variant = Deserializer<&'a Value>; +struct ValueMapDeserializer<'a>(Peekable>); - #[inline] - fn variant_seed>( - self, - seed: V, - ) -> Result<(V::Value, Self::Variant), Self::Error> { - let k = seed.deserialize(Deserializer(&self.0 .0))?; - Ok((k, Deserializer(&self.0 .1))) - } -} - -impl<'a, 'de> de::EnumAccess<'de> for Deserializer<&'a Value> { +impl<'a, 'de> de::MapAccess<'de> for ValueMapDeserializer<'a> { type Error = Error; - type Variant = Deserializer<&'a Value>; - #[inline] - fn variant_seed>( - self, - seed: V, - ) -> Result<(V::Value, Self::Variant), Self::Error> { - let k = seed.deserialize(self)?; - Ok((k, Deserializer(&Value::Null))) + fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> + where + K: de::DeserializeSeed<'de>, + { + // Serde expect `key` call to go first, thus it should not move iterator + // as `value` call should follow + self.0 + .peek() + .map(|x| seed.deserialize(Deserializer(x.0.clone()))) // TODO + .transpose() + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: de::DeserializeSeed<'de>, + { + let map_value = self + .0 + .next() + .expect("`next_key_seed` must be called first") + .1 + .clone(); // TODO + seed.deserialize(Deserializer(map_value)) } } -impl<'a, 'de> de::VariantAccess<'de> for Deserializer<&'a Value> { +impl<'a, 'de> de::VariantAccess<'de> for Deserializer { type Error = Error; - #[inline] fn unit_variant(self) -> Result<(), Self::Error> { match self.0 { Value::Null => Ok(()), - _ => Err(de::Error::invalid_type(self.0.into(), &"unit")), + v => Err(de::Error::invalid_type((&v).into(), &"unit")), } } - #[inline] fn newtype_variant_seed>( self, seed: U, @@ -540,7 +470,6 @@ impl<'a, 'de> de::VariantAccess<'de> for Deserializer<&'a Value> { seed.deserialize(self) } - #[inline] fn tuple_variant>( self, _len: usize, @@ -549,7 +478,6 @@ impl<'a, 'de> de::VariantAccess<'de> for Deserializer<&'a Value> { self.deserialize_seq(visitor) } - #[inline] fn struct_variant>( self, _fields: &'static [&'static str], @@ -558,11 +486,3 @@ impl<'a, 'de> de::VariantAccess<'de> for Deserializer<&'a Value> { self.deserialize_map(visitor) } } - -impl Value { - /// Deserializes the `Value` into an object - #[inline] - pub fn deserialized<'de, T: de::Deserialize<'de>>(&self) -> Result { - T::deserialize(Deserializer(self)) - } -} diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index 5273d01b15f..4db08f556a3 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -1,11 +1,10 @@ -use serde::de::DeserializeOwned; -use serde::Serialize; -use crate::{Error, Value}; use crate::value_serialization::ser::Serializer; +use crate::{Error, Value}; +use serde::{Deserialize, de::DeserializeOwned}; +use serde::Serialize; -pub mod ser; pub mod de; - +pub mod ser; /// Convert a `T` into `platform_value::Value` which is an enum that can represent /// data. @@ -62,8 +61,8 @@ pub mod de; /// } /// ``` pub fn to_value(value: T) -> Result - where - T: Serialize, +where + T: Serialize, { value.serialize(Serializer) } @@ -103,9 +102,45 @@ pub fn to_value(value: T) -> Result /// is wrong with the data, for example required struct fields are missing from /// the JSON map or some number is too big to fit in the expected primitive /// type. -pub fn from_value(value: Value) -> Result - where - T: DeserializeOwned, +pub fn from_value<'de, T>(value: Value) -> Result +where + T: Deserialize<'de>, { - T::deserialize(value) + T::deserialize(de::Deserializer(value)) +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use serde::{Deserialize, Serialize}; + + use super::*; + + #[test] + fn yeet() { + #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] + struct Yeet { + arr: Vec, + map: HashMap, + number: i32, + static_string: &'static str, + } + + let mut hm = HashMap::new(); + hm.insert("wow".to_owned(), 'a'); + hm.insert("lol".to_owned(), 'd'); + + let yeet = Yeet { + arr: vec!["kek".to_owned(), "top".to_owned()], + map: hm, + number: 420, + static_string: "pizza", + }; + + let platform_value = to_value(yeet.clone()).expect("please"); + let yeet_back: Yeet = from_value(platform_value).expect("please once again"); + + assert_eq!(yeet, yeet_back); + } } diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index 1169be215dc..f7ba14f7402 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -48,6 +48,8 @@ impl Serialize for Value { Value::Identifier(bytes) => serializer.serialize_bytes(bytes), Value::Float(f64) => serializer.serialize_f64(*f64), Value::Text(string) => serializer.serialize_str(string), + Value::EnumU8(_x) => todo!(), + Value::EnumString(_x) => todo!(), } } } From 14111ee627b121a571d942b9cc3bca0aee01fddf Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 13 Mar 2023 12:05:50 +0700 Subject: [PATCH 110/228] more work --- .../src/data_contract/data_contract_facade.rs | 10 +- .../data_contract/data_contract_factory.rs | 7 +- .../errors/invalid_data_contract_error.rs | 11 +- .../validation/data_contract_validator.rs | 4 +- .../validation/multi_validator.rs | 35 ++++-- .../validate_data_contract_max_depth.rs | 2 +- packages/rs-dpp/src/document/document.rs | 2 +- .../rs-dpp/src/document/document_factory.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 47 ++++++- .../fetch_and_validate_data_contract.rs | 2 - .../document_replace_transition.rs | 4 +- .../basic/find_duplicates_by_indices.rs | 2 +- ...lidate_documents_batch_transition_basic.rs | 4 +- packages/rs-dpp/src/errors/errors.rs | 4 +- .../rs-dpp/src/errors/non_consensus_error.rs | 4 + packages/rs-dpp/src/identity/factory.rs | 4 +- .../rs-dpp/src/identity/identity_facade.rs | 9 +- .../apply_identity_topup_transition.rs | 8 +- ...entity_topup_transition_basic_validator.rs | 16 ++- .../identity_update_transition.rs | 22 ++-- .../validation/public_keys_validator.rs | 25 ++-- .../abstract_state_transition.rs | 37 ++---- .../validate_state_transition_fee.rs | 4 +- ...validate_state_transition_key_signature.rs | 4 +- .../src/tests/fixtures/identity_fixture.rs | 2 +- .../identity_topup_transition_fixture.rs | 2 +- ..._top_up_transition_basic_validator_spec.rs | 38 ++++-- ...e_identity_update_transition_basic_spec.rs | 15 +-- .../validation/identity_validator_spec.rs | 72 ++++++----- ...rpose_and_security_level_validator_spec.rs | 22 ++-- .../src/btreemap_extensions/mod.rs | 4 +- packages/rs-platform-value/src/error.rs | 5 +- packages/rs-platform-value/src/inner_value.rs | 66 +++++++++- .../src/inner_value_at_path.rs | 23 ++++ packages/rs-platform-value/src/lib.rs | 4 +- .../rs-platform-value/src/system_bytes.rs | 115 +++++++++++++++++- .../rs-platform-value/src/types/identifier.rs | 30 ++++- .../src/value_serialization/mod.rs | 2 +- .../src/document/extended_document.rs | 8 +- 39 files changed, 484 insertions(+), 193 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index cae7b77d7d9..50c397428f8 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -83,16 +83,8 @@ impl DataContractFacade { /// Validate Data Contract pub async fn validate( &self, - data_contract: JsonValue, + data_contract: Value, ) -> Result, ProtocolError> { - // TODO: figure out what to do with a case where it's not a raw data contract - // let rawDataContract; - // if (dataContract instanceof DataContract) { - // rawDataContract = dataContract.toObject(); - // } else { - // rawDataContract = dataContract; - // } - self.data_contract_validator.validate(&data_contract) } } diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index e8a038c91b9..385d91286ee 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -113,15 +113,12 @@ impl DataContractFactory { raw_data_contract: Value, skip_validation: bool, ) -> Result { - let json_value = raw_data_contract - .try_to_validating_json() - .map_err(ProtocolError::ValueError)?; if !skip_validation { - let result = self.validate_data_contract.validate(&json_value)?; + let result = self.validate_data_contract.validate(&raw_data_contract)?; if !result.is_valid() { return Err(ProtocolError::InvalidDataContractError( - InvalidDataContractError::new(result.errors, json_value), + InvalidDataContractError::new(result.errors, raw_data_contract), )); } } diff --git a/packages/rs-dpp/src/data_contract/errors/invalid_data_contract_error.rs b/packages/rs-dpp/src/data_contract/errors/invalid_data_contract_error.rs index 6482309ac96..1e7f5b3dbee 100644 --- a/packages/rs-dpp/src/data_contract/errors/invalid_data_contract_error.rs +++ b/packages/rs-dpp/src/data_contract/errors/invalid_data_contract_error.rs @@ -1,18 +1,17 @@ use crate::consensus::ConsensusError; -use thiserror::Error; - -use crate::document::document_transition::document_base_transition::JsonValue; use crate::ProtocolError; +use platform_value::Value; +use thiserror::Error; #[derive(Error, Debug)] #[error("Invalid Data Contract: {errors:?}")] pub struct InvalidDataContractError { pub errors: Vec, - raw_data_contract: JsonValue, + raw_data_contract: Value, } impl InvalidDataContractError { - pub fn new(errors: Vec, raw_data_contract: JsonValue) -> Self { + pub fn new(errors: Vec, raw_data_contract: Value) -> Self { Self { errors, raw_data_contract, @@ -22,7 +21,7 @@ impl InvalidDataContractError { pub fn errors(&self) -> &[ConsensusError] { &self.errors } - pub fn raw_data_contract(&self) -> JsonValue { + pub fn raw_data_contract(&self) -> Value { self.raw_data_contract.clone() } } diff --git a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs index ab3b0d4f900..09c20ba2580 100644 --- a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs @@ -78,7 +78,9 @@ impl DataContractValidator { trace!("validating against data contract meta validator"); result.merge(JsonSchemaValidator::validate_data_contract_schema( - &raw_data_contract.into(), + &raw_data_contract + .try_to_validating_json() + .map_err(ProtocolError::ValueError)?, )); if !result.is_valid() { return Ok(result); diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 69c0407d512..13127114cfc 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -5,7 +5,7 @@ use crate::consensus::basic::data_contract::IncompatibleRe2PatternError; use crate::{ consensus::{basic::BasicError, ConsensusError}, validation::ValidationResult, - ProtocolError, + NonConsensusError, ProtocolError, }; pub type SubValidator = @@ -78,6 +78,19 @@ pub fn pattern_is_valid_regex_validator( } } +fn unwrap_error_to_result<'a, 'b>( + v: Result, NonConsensusError>, + result: &'b mut ValidationResult<()>, +) -> Option<&'a Value> { + match v { + Ok(v) => v, + Err(e) => { + result.add_error(e.into()); + None + } + } +} + pub fn byte_array_has_no_items_as_parent_validator( path: &str, key: &str, @@ -87,14 +100,18 @@ pub fn byte_array_has_no_items_as_parent_validator( ) { if key == "byteArray" && value.is_bool() - && (parent - .get("items") - .map_err(ProtocolError::ValueError)? - .is_some() - || parent - .get("prefixItems") - .map_err(ProtocolError::ValueError)? - .is_some()) + && (unwrap_error_to_result( + parent.get("items").map_err(NonConsensusError::ValueError), + result, + ) + .is_some() + || unwrap_error_to_result( + parent + .get("prefixItems") + .map_err(NonConsensusError::ValueError), + result, + ) + .is_some()) { result.add_error(BasicError::JsonSchemaCompilationError(format!( "invalid path: '{}': byteArray cannot be used with 'items' or 'prefixItems", diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index ee81e50e677..8bafa2e41b1 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -39,7 +39,7 @@ fn calc_max_depth(value: &Value) -> Result { } for (property_name, v) in map { // handling the internal references - if property_name == ref_value { + if property_name == &ref_value { if let Some(uri) = v.as_str() { let resolved = resolve_uri(value, uri).map_err(|e| { BasicError::InvalidJsonSchemaRefError( diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 986c3a9e6e6..effe897b9c4 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -52,8 +52,8 @@ use crate::data_contract::errors::DataContractError; use crate::document::errors::DocumentError; -use crate::prelude::Identifier; use crate::identity::TimestampMillis; +use crate::prelude::Identifier; use crate::prelude::Revision; use crate::util::hash::hash; diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 318f7b369b9..fb4276b3190 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -283,7 +283,7 @@ where .validate_data_contract_for_extended_document(&raw_document, options) .await?; - ExtendedDocument::from_platform_value(raw_document, data_contract) + ExtendedDocument::from_untrusted_platform_value(raw_document, data_contract) } async fn validate_data_contract_for_extended_document( diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 766fe1d3059..32f706e3a8d 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -1,6 +1,6 @@ use crate::data_contract::{DataContract, DriveContractExt}; -use crate::prelude::Identifier; use crate::metadata::Metadata; +use crate::prelude::Identifier; use crate::prelude::{Revision, TimestampMillis}; use crate::util::cbor_value::CborCanonicalMap; use crate::util::deserializer; @@ -15,9 +15,9 @@ use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::document::Document; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; -use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_extensions::BTreeValueMapInsertionPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapPathHelper; +use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::converter::serde_json::BTreeValueJsonConverter; use platform_value::{ReplacementType, Value}; @@ -119,11 +119,11 @@ impl ExtendedDocument { self.document.updated_at.as_ref() } - pub fn from_json_string(string: &str) -> Result { + pub fn from_json_string(string: &str, contract: DataContract) -> Result { let json_value: JsonValue = serde_json::from_str(string).map_err(|_| { ProtocolError::StringDecodeError("error decoding from json string".to_string()) })?; - Self::from_json_document(json_value, DataContract::new()) + Self::from_untrusted_platform_value(json_value.into(), contract) } pub fn from_raw_document( @@ -133,7 +133,42 @@ impl ExtendedDocument { Self::from_json_value::>(raw_document, data_contract) } - pub fn from_platform_value( + /// Create an extended document from a platform value object where fields are already in the + /// proper format for the contract + pub fn from_trusted_platform_value( + document_value: Value, + data_contract: DataContract, + ) -> Result { + let mut properties = document_value + .into_btree_map() + .map_err(ProtocolError::ValueError)?; + let document_type_name = properties + .remove_string(property_names::DOCUMENT_TYPE) + .map_err(ProtocolError::ValueError)?; + + let mut extended_document = Self { + data_contract, + document_type_name, + ..Default::default() + }; + + // if the protocol version is not set, use the current protocol version + extended_document.protocol_version = properties + .remove_optional_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)? + .unwrap_or(PROTOCOL_VERSION); + extended_document.data_contract_id = Identifier::new( + properties + .remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? + .unwrap_or(extended_document.data_contract.id.buffer), + ); + extended_document.document = Document::from_map(properties, None, None)?; + Ok(extended_document) + } + + /// Create an extended document from a platform value object where fields might not be in the + /// proper format for the contract + pub fn from_untrusted_platform_value( document_value: Value, data_contract: DataContract, ) -> Result { diff --git a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs index 1ad12647e9d..aa3da5147aa 100644 --- a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs +++ b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs @@ -1,7 +1,6 @@ use std::{convert::TryInto, sync::Arc}; use platform_value::Value; -use serde_json::Value as JsonValue; use crate::consensus::basic::invalid_identifier_error::InvalidIdentifierError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; @@ -11,7 +10,6 @@ use crate::{ prelude::Identifier, state_repository::StateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, - util::json_value::JsonValueExt, validation::ValidationResult, ProtocolError, }; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 8e9ffbebca4..4fb8e658355 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -1,5 +1,5 @@ -use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; +use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -8,8 +8,8 @@ use std::convert::TryInto; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::document::Document; -use crate::prelude::Identifier; use crate::identity::TimestampMillis; +use crate::prelude::Identifier; use crate::prelude::{ExtendedDocument, Revision}; use crate::{data_contract::DataContract, errors::ProtocolError}; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index e4c562dc9e3..6a14b568fa0 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -35,7 +35,7 @@ pub fn find_duplicates_by_indices<'a>( let mut groups: BTreeMap<&'a str, Group> = BTreeMap::new(); for dt in raw_extended_documents.into_iter() { - let document_type_name = dt.get_string("$type")?; + let document_type_name = dt.get_str("$type")?; let document_type = data_contract.document_type_for_name(document_type_name)?; match groups.entry(document_type_name) { Entry::Occupied(mut o) => { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 472d5b5340b..9b9e2988467 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -223,7 +223,7 @@ fn validate_raw_transitions<'a>( let mut result = ValidationResult::default(); for raw_document_transition in raw_document_transitions { - let Some(document_type) = raw_document_transition.get_optional_str("$type").map_err(ProtocolError::ValueError) else { + let Some(document_type) = raw_document_transition.get_optional_str("$type").map_err(ProtocolError::ValueError)? else { result.add_error(BasicError::MissingDocumentTransitionTypeError); return Ok(result); }; @@ -270,7 +270,7 @@ fn validate_raw_transitions<'a>( if action == Action::Create { let document_id = - Identifier::from_bytes(&raw_document_transition.get_bytes("$id")?)?; + Identifier::from_bytes(&raw_document_transition.get_identifier("$id")?)?; let entropy = raw_document_transition.get_bytes("$entropy")?; // validate the id generation let generated_document_id = diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index f7316a58b18..eddf3a2ba1f 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -13,7 +13,7 @@ use crate::state_transition::errors::{ PublicKeySecurityLevelNotMetError, StateTransitionIsNotSignedError, WrongPublicKeyPurposeError, }; use crate::{CompatibleProtocolVersionIsNotDefinedError, NonConsensusError, SerdeParsingError}; -use platform_value::Error as ValueError; +use platform_value::{Error as ValueError, Value}; #[derive(Error, Debug)] pub enum ProtocolError { @@ -124,7 +124,7 @@ pub enum ProtocolError { #[error("Invalid Identity: {errors:?}")] InvalidIdentityError { errors: Vec, - raw_identity: JsonValue, + raw_identity: Value, }, #[error("Public key generation error {0}")] diff --git a/packages/rs-dpp/src/errors/non_consensus_error.rs b/packages/rs-dpp/src/errors/non_consensus_error.rs index c39b280ea67..62ebd7941bf 100644 --- a/packages/rs-dpp/src/errors/non_consensus_error.rs +++ b/packages/rs-dpp/src/errors/non_consensus_error.rs @@ -1,3 +1,4 @@ +use platform_value::Error as ValueError; use thiserror::Error; use crate::{ @@ -6,6 +7,9 @@ use crate::{ #[derive(Debug, Error)] pub enum NonConsensusError { + /// Value error + #[error("value error: {0}")] + ValueError(#[from] ValueError), #[error("Unexpected serde parsing error: {0:#}")] SerdeParsingError(SerdeParsingError), #[error(transparent)] diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index 938f09788c0..3ec1cd8a24f 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -1,5 +1,4 @@ use crate::decode_protocol_entity_factory::DecodeProtocolEntity; -use crate::prelude::Identifier; use crate::identity::identity_public_key::factory::KeyCount; use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; use crate::identity::state_transition::asset_lock_proof::{AssetLockProof, InstantAssetLockProof}; @@ -9,6 +8,7 @@ use crate::identity::state_transition::identity_topup_transition::IdentityTopUpT use crate::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; use crate::identity::validation::{IdentityValidator, PublicKeysValidator}; use crate::identity::{Identity, IdentityPublicKey, KeyID, TimestampMillis}; +use crate::prelude::Identifier; use crate::{BlsModule, ProtocolError}; @@ -120,7 +120,7 @@ where pub fn create_from_object( &self, - raw_identity: JsonValue, + raw_identity: Value, skip_validation: bool, ) -> Result { if !skip_validation { diff --git a/packages/rs-dpp/src/identity/identity_facade.rs b/packages/rs-dpp/src/identity/identity_facade.rs index b9aee96a3dc..528cb61e5e6 100644 --- a/packages/rs-dpp/src/identity/identity_facade.rs +++ b/packages/rs-dpp/src/identity/identity_facade.rs @@ -1,9 +1,9 @@ use dashcore::{InstantLock, Transaction}; -use serde_json::Value; +use platform_value::Value; +use serde_json::Value as JsonValue; use std::collections::BTreeMap; use std::sync::Arc; -use crate::prelude::Identifier; use crate::identity::factory::IdentityFactory; use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; use crate::identity::state_transition::asset_lock_proof::{AssetLockProof, InstantAssetLockProof}; @@ -13,6 +13,7 @@ use crate::identity::state_transition::identity_topup_transition::IdentityTopUpT use crate::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; use crate::identity::validation::{IdentityValidator, PublicKeysValidator}; use crate::identity::{Identity, IdentityPublicKey, KeyID, TimestampMillis}; +use crate::prelude::Identifier; use crate::validation::ValidationResult; use crate::version::ProtocolVersionValidator; @@ -71,9 +72,9 @@ where pub fn validate( &self, - identity_json: &serde_json::Value, + identity_object: &Value, ) -> Result, NonConsensusError> { - self.identity_validator.validate_identity(identity_json) + self.identity_validator.validate_identity(identity_object) } pub fn create_instant_lock_proof( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/apply_identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/apply_identity_topup_transition.rs index 4c864a83f21..ab47b72256f 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/apply_identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/apply_identity_topup_transition.rs @@ -95,14 +95,14 @@ mod test { }, state_repository::MockStateRepositoryLike, state_transition::StateTransitionLike, - tests::fixtures::identity_topup_transition_fixture_json, + tests::fixtures::identity_topup_transition_fixture, }; use super::ApplyIdentityTopUpTransition; #[tokio::test] async fn should_topup_amount_to_identity_balance() { - let raw_transition = identity_topup_transition_fixture_json(None); + let raw_transition = identity_topup_transition_fixture(None); let state_transition = IdentityTopUpTransition::new(raw_transition).unwrap(); let IdentityTopUpTransition { identity_id, .. } = state_transition.clone(); @@ -151,7 +151,7 @@ mod test { #[tokio::test] async fn should_ignore_balance_debt_for_system_credits() { - let raw_transition = identity_topup_transition_fixture_json(None); + let raw_transition = identity_topup_transition_fixture(None); let state_transition = IdentityTopUpTransition::new(raw_transition).unwrap(); let IdentityTopUpTransition { identity_id, .. } = state_transition.clone(); @@ -200,7 +200,7 @@ mod test { #[tokio::test] async fn should_add_topup_amount_to_identity_balance_on_dry_run() { - let raw_transition = identity_topup_transition_fixture_json(None); + let raw_transition = identity_topup_transition_fixture(None); let state_transition = IdentityTopUpTransition::new(raw_transition).unwrap(); let IdentityTopUpTransition { identity_id, .. } = state_transition.clone(); diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs index 43c87499839..6939dd03b72 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs @@ -1,7 +1,9 @@ +use std::convert::TryInto; use std::sync::Arc; use lazy_static::lazy_static; -use serde_json::Value; +use platform_value::Value; +use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProofValidator; use crate::state_repository::StateRepositoryLike; @@ -9,10 +11,10 @@ use crate::state_transition::state_transition_execution_context::StateTransition use crate::util::protocol_data::get_protocol_version; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::version::ProtocolVersionValidator; -use crate::{DashPlatformProtocolInitError, NonConsensusError, SerdeParsingError}; +use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError}; lazy_static! { - static ref INDENTITY_CREATE_TRANSITION_SCHEMA: Value = serde_json::from_str(include_str!( + static ref INDENTITY_CREATE_TRANSITION_SCHEMA: JsonValue = serde_json::from_str(include_str!( "../../../../../schema/identity/stateTransition/identityTopUp.json" )) .unwrap(); @@ -48,9 +50,11 @@ impl IdentityTopUpTransitionBasicValidator { identity_topup_transition_json: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result, NonConsensusError> { - let mut result = self - .json_schema_validator - .validate(identity_topup_transition_json)?; + let mut result = self.json_schema_validator.validate( + &identity_topup_transition_json + .try_into_validating_json() + .map_err(ProtocolError::ValueError)?, + )?; let identity_transition_map = identity_topup_transition_json.as_object().ok_or_else(|| { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index cd57c3a8b8a..080f8f2a62f 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -218,23 +218,25 @@ impl StateTransitionConvert for IdentityUpdateTransition { vec![property_names::SIGNATURE] } - fn to_object(&self, skip_signature: bool) -> Result { + fn to_object(&self, skip_signature: bool) -> Result { // The [state_transition_helpers::to_object] doesn't convert the `add_public_keys` property. // The property must be serialized manually - let mut add_public_keys: Vec = vec![]; + let mut add_public_keys: Vec = vec![]; for key in self.add_public_keys.iter() { - add_public_keys.push(key.to_raw_json_object(skip_signature)?); + add_public_keys.push(key.to_raw_object(skip_signature)?); } - let mut raw_object: JsonValue = state_transition_helpers::to_object( - self, - Self::signature_property_paths(), - Self::identifiers_property_paths(), - skip_signature, - )?; + let skip_signature_paths = if skip_signature { + Self::signature_property_paths() + } else { + vec![] + }; + + let mut raw_object: Value = + state_transition_helpers::to_object(self, skip_signature_paths)?; raw_object.insert( property_names::ADD_PUBLIC_KEYS.to_owned(), - JsonValue::Array(add_public_keys), + Value::Array(add_public_keys), )?; Ok(raw_object) diff --git a/packages/rs-dpp/src/identity/validation/public_keys_validator.rs b/packages/rs-dpp/src/identity/validation/public_keys_validator.rs index f018df99a0b..b29431e4f19 100644 --- a/packages/rs-dpp/src/identity/validation/public_keys_validator.rs +++ b/packages/rs-dpp/src/identity/validation/public_keys_validator.rs @@ -10,25 +10,22 @@ use crate::errors::consensus::basic::identity::{ use crate::identity::{IdentityPublicKey, KeyID, KeyType}; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::{ - BlsModule, DashPlatformProtocolInitError, NonConsensusError, PublicKeyValidationError, + BlsModule, DashPlatformProtocolInitError, NonConsensusError, ProtocolError, + PublicKeyValidationError, }; use crate::identity::security_level::ALLOWED_SECURITY_LEVELS; #[cfg(test)] use mockall::{automock, predicate::*}; use platform_value::Value; +use serde_json::Value as JsonValue; lazy_static! { - pub static ref PUBLIC_KEY_SCHEMA: platform_value::Value = - serde_json::from_str(include_str!("./../../schema/identity/publicKey.json")) - .unwrap() - .try_into() - .unwrap(); - pub static ref PUBLIC_KEY_SCHEMA_FOR_TRANSITION: platform_value::Value = serde_json::from_str( + pub static ref PUBLIC_KEY_SCHEMA: JsonValue = + serde_json::from_str(include_str!("./../../schema/identity/publicKey.json")).unwrap(); + pub static ref PUBLIC_KEY_SCHEMA_FOR_TRANSITION: JsonValue = serde_json::from_str( include_str!("./../../schema/identity/stateTransition/publicKey.json") ) - .unwrap() - .try_into() .unwrap(); } @@ -163,10 +160,10 @@ impl PublicKeysValidator { } pub fn new_with_schema( - schema: Value, + schema: JsonValue, bls_validator: T, ) -> Result { - let public_key_schema_validator = JsonSchemaValidator::new(schema.into())?; + let public_key_schema_validator = JsonSchemaValidator::new(schema)?; let public_keys_validator = Self { public_key_schema_validator, @@ -180,7 +177,11 @@ impl PublicKeysValidator { &self, public_key: &Value, ) -> Result, NonConsensusError> { - self.public_key_schema_validator.validate(public_key.into()) + self.public_key_schema_validator.validate( + &public_key + .try_to_validating_json() + .map_err(NonConsensusError::ValueError)?, + ) } } diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index c94efc87ac8..2f0183fc664 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -2,6 +2,7 @@ use std::fmt::Debug; use dashcore::signer; +use platform_value::Value; use serde::Serialize; use serde_json::Value as JsonValue; @@ -182,15 +183,10 @@ pub trait StateTransitionConvert: Serialize { fn identifiers_property_paths() -> Vec<&'static str>; fn binary_property_paths() -> Vec<&'static str>; - /// Returns the [`serde_json::Value`] instance that preserves the `Vec` representation + /// Returns the [`platform_value::Value`] instance that preserves the `Vec` representation /// for Identifiers and binary data - fn to_object(&self, skip_signature: bool) -> Result { - state_transition_helpers::to_object( - self, - Self::signature_property_paths(), - Self::identifiers_property_paths(), - skip_signature, - ) + fn to_object(&self, skip_signature: bool) -> Result { + state_transition_helpers::to_object(self, skip_signature) } /// Returns the [`serde_json::Value`] instance that encodes: @@ -243,23 +239,14 @@ pub mod state_transition_helpers { Ok(json_value) } - pub fn to_object<'a>( + pub fn to_object<'a, I: IntoIterator>( serializable: impl Serialize, - signature_property_paths: impl IntoIterator, - identifier_property_paths: impl IntoIterator, - skip_signature: bool, - ) -> Result { - let mut json_value: JsonValue = serde_json::to_value(serializable)?; - - json_value.replace_identifier_paths(identifier_property_paths, ReplaceWith::Bytes)?; - - if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { - for path in signature_property_paths { - o.remove(path); - } - } - } - Ok(json_value) + skip_signature_paths: I, + ) -> Result { + let mut value: Value = platform_value::to_value(serializable)?; + skip_signature_paths + .into_iter() + .try_for_each(|path| value.remove_value_at_path(path))?; + Ok(value) } } diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs index 837e4f67786..dee849c6c1a 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs @@ -166,7 +166,7 @@ mod test { use crate::identity::state_transition::identity_topup_transition::IdentityTopUpTransition; use crate::state_transition::StateTransitionLike; - use crate::tests::fixtures::identity_topup_transition_fixture_json; + use crate::tests::fixtures::identity_topup_transition_fixture; use crate::ProtocolError; use crate::{ consensus::fee::FeeError, @@ -367,7 +367,7 @@ mod test { .returning(move |_, _| Ok(Some(identity.clone()))); let mut identity_topup_transition = - IdentityTopUpTransition::new(identity_topup_transition_fixture_json(None)).unwrap(); + IdentityTopUpTransition::new(identity_topup_transition_fixture(None)).unwrap(); identity_topup_transition.set_execution_context(execution_context_with_cost(45000000, 5)); let validator = StateTransitionFeeValidator::new(Arc::new(state_repository_mock)); diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs index b157e24ea0f..be94595b0d0 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs @@ -153,7 +153,7 @@ mod test { state_transition::{StateTransition, StateTransitionLike}, tests::{ fixtures::{ - identity_create_transition_fixture_json, identity_topup_transition_fixture_json, + identity_create_transition_fixture_json, identity_topup_transition_fixture, }, utils::get_signature_error_from_result, }, @@ -299,7 +299,7 @@ mod test { let private_key = PrivateKey::new(secret_key, Network::Testnet); let state_transition: StateTransition = - IdentityTopUpTransition::new(identity_topup_transition_fixture_json(Some(private_key))) + IdentityTopUpTransition::new(identity_topup_transition_fixture(Some(private_key))) .unwrap() .into(); diff --git a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs index f01167b75d2..0451e10e6c7 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs @@ -2,7 +2,7 @@ use platform_value::platform_value; use platform_value::string_encoding::{decode, Encoding}; use serde_json::json; -use crate::prelude::Identity; +use crate::prelude::{Identifier, Identity}; //3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT //[198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237] diff --git a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs index a8fd1ee7697..58e89760b94 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs @@ -10,7 +10,7 @@ use crate::version; //3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT //[198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237] -pub fn identity_topup_transition_fixture_json(one_time_private_key: Option) -> Value { +pub fn identity_topup_transition_fixture(one_time_private_key: Option) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); Value::from([ diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs index 32992952262..be134b0f4c2 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use jsonschema::error::ValidationErrorKind; -use serde_json::Value; +use platform_value::Value; use crate::assert_consensus_errors; use crate::errors::consensus::ConsensusError; @@ -41,7 +41,7 @@ pub fn setup_test( let protocol_version_validator = ProtocolVersionValidator::default(); ( - crate::tests::fixtures::identity_topup_transition_fixture_json(None), + crate::tests::fixtures::identity_topup_transition_fixture(None), IdentityTopUpTransitionBasicValidator::new( protocol_version_validator, asset_lock_proof_validator, @@ -60,7 +60,7 @@ mod validate_identity_topup_transition_basic { pub async fn should_be_present() { let state_repository = MockStateRepositoryLike::new(); let (mut raw_state_transition, validator) = setup_test(state_repository); - raw_state_transition.remove_key("protocolVersion"); + raw_state_transition.remove("protocolVersion").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -84,7 +84,9 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_an_integer() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.set_key_value("protocolVersion", "1"); + raw_state_transition + .set_into_value("protocolVersion", "1") + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -102,7 +104,9 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_valid() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.set_key_value("protocolVersion", -1); + raw_state_transition + .set_into_value("protocolVersion", -1) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -130,7 +134,7 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.remove_key("type"); + raw_state_transition.remove("type").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) .await @@ -154,7 +158,7 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_equal_to_3() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.set_key_value("type", 666); + raw_state_transition.set_into_value("type", 666).unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -183,7 +187,7 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.remove_key("assetLockProof"); + raw_state_transition.remove("assetLockProof").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -208,7 +212,9 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_an_object() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.set_key_value("assetLockProof", 1); + raw_state_transition + .set_into_value("assetLockProof", 1u64) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -252,7 +258,7 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.remove_key("signature"); + raw_state_transition.remove("signature").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -277,7 +283,9 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_a_byte_array() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.set_key_value("signature", vec!["string"; 65]); + raw_state_transition + .set_into_value("signature", vec!["string"; 65]) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -295,7 +303,9 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_not_shorter_than_65_bytes() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.set_key_value("signature", vec![0; 64]); + raw_state_transition + .set_into_value("signature", vec![0; 64]) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -313,7 +323,9 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_not_longer_than_65_bytes() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - raw_state_transition.set_key_value("signature", vec![0; 66]); + raw_state_transition + .set_into_value("signature", vec![0; 66]) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs index 758c410f306..15d121049b6 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs @@ -26,6 +26,7 @@ use crate::{ NativeBlsModule, NonConsensusError, }; use jsonschema::error::ValidationErrorKind; +use platform_value::{platform_value, Value}; use serde_json::{json, Value as JsonValue}; use std::{convert::TryInto, sync::Arc}; use test_case::test_case; @@ -37,8 +38,8 @@ struct TestData { ec_private_key: [u8; 32], identity_public_key: IdentityPublicKey, state_transition: IdentityUpdateTransition, - raw_state_transition: JsonValue, - raw_public_key_to_add: JsonValue, + raw_state_transition: Value, + raw_public_key_to_add: Value, public_keys_signatures_validator: PublicKeysSignaturesValidator, } @@ -82,12 +83,12 @@ fn setup_test() -> TestData { .expect("transition should be singed"); let raw_state_transition = state_transition.to_object(false).unwrap(); - let raw_public_key_to_add = json!({ - "id": 0, - "type": KeyType::ECDSA_SECP256K1, + let raw_public_key_to_add = platform_value!({ + "id": 0u32, + "type": KeyType::ECDSA_SECP256K1 as u8, "data": base64::decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di").unwrap(), - "purpose": Purpose::AUTHENTICATION, - "securityLevel": SecurityLevel::MASTER, + "purpose": Purpose::AUTHENTICATION as u8, + "securityLevel": SecurityLevel::MASTER as u8, "readOnly": false, }); diff --git a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs index dbfcfb8394b..5729dd838a6 100644 --- a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs @@ -30,7 +30,7 @@ pub mod protocol_version { use crate::assert_consensus_errors; use crate::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::{serde_remove, serde_set}; + use crate::tests::utils::{platform_value_set_ref, serde_set}; #[test] pub fn should_be_present() { @@ -58,7 +58,7 @@ pub mod protocol_version { #[test] pub fn should_be_an_integer() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "protocolVersion", "1"); + identity.set_into_value("protocolVersion", "1").unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -72,7 +72,7 @@ pub mod protocol_version { #[test] pub fn should_be_valid() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "protocolVersion", -1); + identity.set_into_value("protocolVersion", -1i32).unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -91,7 +91,7 @@ pub mod id { use crate::assert_consensus_errors; use crate::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::{serde_remove, serde_set}; + use crate::tests::utils::serde_set; #[test] pub fn should_be_present() { @@ -117,7 +117,9 @@ pub mod id { #[test] pub fn should_be_a_byte_array() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "id", vec![Value::from("string"); 32]); + identity + .set_into_value("id", vec![Value::from("string"); 32]) + .unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 32); @@ -131,7 +133,9 @@ pub mod id { #[test] pub fn should_not_be_less_than_32_bytes() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "id", vec![Value::from(15); 31]); + identity + .set_into_value("id", vec![Value::from(15); 31]) + .unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -145,7 +149,9 @@ pub mod id { #[test] pub fn should_not_be_more_than_32_bytes() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "id", vec![Value::from(15); 33]); + identity + .set_into_value("id", vec![Value::from(15); 33]) + .unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -163,7 +169,7 @@ pub mod balance { use crate::assert_consensus_errors; use crate::errors::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::{serde_remove, serde_set}; + use crate::tests::utils::serde_set; #[test] pub fn should_be_present() { @@ -191,7 +197,7 @@ pub mod balance { #[test] pub fn should_be_an_integer() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "balance", 1.2); + identity.set_into_value("balance", 1.2).unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -205,7 +211,7 @@ pub mod balance { #[test] pub fn should_be_greater_or_equal_0() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "balance", -1); + identity.set_into_value("balance", -1i64).unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -215,7 +221,7 @@ pub mod balance { assert_eq!(error.keyword().unwrap(), "minimum"); assert_eq!(error.instance_path().to_string(), "/balance"); - identity = serde_set(identity, "balance", 0); + identity.set_into_value("balance", 0u64).unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); assert!(result.is_valid()); @@ -223,13 +229,12 @@ pub mod balance { } pub mod public_keys { - use jsonschema::error::ValidationErrorKind; - use serde_json::Value; - use crate::assert_consensus_errors; use crate::errors::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::{serde_remove, serde_set}; + use crate::tests::utils::serde_set; + use jsonschema::error::ValidationErrorKind; + use platform_value::Value; #[test] pub fn should_be_present() { @@ -257,7 +262,7 @@ pub mod public_keys { #[test] pub fn should_be_an_array() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "publicKeys", 1); + identity.set_into_value("publicKeys", 1u64).unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -271,7 +276,9 @@ pub mod public_keys { #[test] pub fn should_not_be_empty() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "publicKeys", Value::Array(vec![])); + identity + .set_into_value("publicKeys", Value::Array(vec![])) + .unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -287,19 +294,18 @@ pub mod public_keys { let (mut identity, identity_validator) = setup_test(); let public_key = identity - .get("publicKeys") - .unwrap() - .as_array() + .get_array_slice("publicKeys") .unwrap() .get(0) .unwrap() .clone(); - identity = serde_set( - identity, - "publicKeys", - Value::Array(vec![public_key.clone(), public_key]), - ); + identity + .set_into_value( + "publicKeys", + Value::Array(vec![public_key.clone(), public_key]), + ) + .unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -315,15 +321,15 @@ pub mod public_keys { let (mut identity, identity_validator) = setup_test(); let public_key = identity - .get("publicKeys") - .unwrap() - .as_array() + .get_array_slice("publicKeys") .unwrap() .get(0) .unwrap() .clone(); - identity = serde_set(identity, "publicKeys", Value::Array(vec![public_key; 101])); + identity + .set_into_value("publicKeys", Value::Array(vec![public_key; 101])) + .unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); @@ -341,7 +347,7 @@ pub mod revision { use crate::assert_consensus_errors; use crate::errors::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::{serde_remove, serde_set}; + use crate::tests::utils::serde_set; // revision tests #[test] @@ -371,7 +377,7 @@ pub mod revision { pub fn should_be_an_integer() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "revision", 1.2); + identity.set_into_value("revision", 1.2).unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -388,7 +394,7 @@ pub mod revision { pub fn should_should_be_greater_or_equal_0() { let (mut identity, identity_validator) = setup_test(); - identity = serde_set(identity, "revision", -1); + identity.set_into_value("revision", -1i32).unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -400,7 +406,7 @@ pub mod revision { assert_eq!(error.keyword().unwrap(), "minimum"); assert_eq!(error.instance_path().to_string(), "/revision"); - identity = serde_set(identity, "revision", 0); + identity.set_into_value("revision", 0).unwrap(); let result = identity_validator.validate_identity(&identity).unwrap(); diff --git a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs index 0e5da661b0d..f411932ad97 100644 --- a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs @@ -45,21 +45,21 @@ fn should_return_invalid_result_if_state_transition_does_not_contain_master_key( fn should_return_valid_result() { let validator = RequiredPurposeAndSecurityLevelValidator {}; let raw_public_keys = vec![ - json!({ - "id": 0, - "type" : KeyType::ECDSA_SECP256K1, - "purpose" : Purpose::AUTHENTICATION, - "securityLevel" : SecurityLevel::MASTER, + platform_value!({ + "id": 0u32, + "type" : KeyType::ECDSA_SECP256K1 as u8, + "purpose" : Purpose::AUTHENTICATION as u8, + "securityLevel" : SecurityLevel::MASTER as u8, "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), "readOnly" : false, }), // this key must be filtered out - json!({ - "id": 0, - "type" : KeyType::ECDSA_SECP256K1, - "purpose": Purpose::AUTHENTICATION, - "securityLevel" : SecurityLevel::CRITICAL, - "disabledAt" : 42, + platform_value!({ + "id": 0u32, + "type" : KeyType::ECDSA_SECP256K1 as u8, + "purpose": Purpose::AUTHENTICATION as u8, + "securityLevel" : SecurityLevel::CRITICAL as u8, + "disabledAt" : 42u64, "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), "readOnly" : false, }), diff --git a/packages/rs-platform-value/src/btreemap_extensions/mod.rs b/packages/rs-platform-value/src/btreemap_extensions/mod.rs index 1257a4507cc..00a0441318d 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/mod.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/mod.rs @@ -13,12 +13,12 @@ mod btreemap_path_insertion_extensions; mod btreemap_removal_extensions; mod btreemap_removal_inner_value_extensions; -pub use btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; pub use btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +pub use btreemap_mut_value_extensions::BTreeMutValueMapHelper; pub use btreemap_path_extensions::BTreeValueMapPathHelper; pub use btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper; +pub use btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; pub use btreemap_removal_inner_value_extensions::BTreeValueRemoveInnerValueFromMapHelper; -pub use btreemap_mut_value_extensions::BTreeMutValueMapHelper; pub trait BTreeValueMapHelper { fn get_optional_identifier(&self, key: &str) -> Result, Error>; diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index bf0d6557988..eec07f95373 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -37,7 +37,10 @@ impl serde::ser::Error for Error { } impl serde::de::Error for Error { - fn custom(msg: T) -> Self where T: Display { + fn custom(msg: T) -> Self + where + T: Display, + { println!("{msg}"); todo!() } diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 5fcc76ccbcb..c217840adad 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,5 +1,5 @@ -use crate::Identifier; use crate::value_map::{ValueMap, ValueMapHelper}; +use crate::Identifier; use crate::Value::Bool; use crate::{Error, Value}; use std::collections::BTreeMap; @@ -19,6 +19,14 @@ impl Value { Ok(Self::get_optional_from_map(map, key)) } + pub fn set_into_value(&mut self, key: &str, value: T) -> Result<(), Error> + where + T: Into, + { + let map = self.as_map_mut_ref()?; + Ok(Self::insert_in_map(map, key, value.into())) + } + pub fn set_value(&mut self, key: &str, value: Value) -> Result<(), Error> { let map = self.as_map_mut_ref()?; Ok(Self::insert_in_map(map, key, value)) @@ -172,6 +180,29 @@ impl Value { Self::inner_bool_value(map, key) } + pub fn get_optional_array(&self, key: &str) -> Result>, Error> { + let map = self.to_map()?; + Self::inner_optional_array(map, key) + } + + pub fn get_array<'a>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Self::inner_array(map, key) + } + + pub fn get_optional_array_slice<'a>( + &'a self, + key: &'a str, + ) -> Result, Error> { + let map = self.to_map()?; + Self::inner_optional_array_slice(map, key) + } + + pub fn get_array_slice<'a>(&'a self, key: &'a str) -> Result<&[Value], Error> { + let map = self.to_map()?; + Self::inner_array_slice(map, key) + } + pub fn get_optional_bytes<'a>(&'a self, key: &'a str) -> Result>, Error> { let map = self.to_map()?; Self::inner_optional_bytes_value(map, key) @@ -236,6 +267,39 @@ impl Value { } } + /// Retrieves the value of a key from a map if it's an array of strings. + pub fn inner_optional_array( + document_type: &[(Value, Value)], + key: &str, + ) -> Result>, Error> { + Self::get_optional_from_map(document_type, key) + .map(|value| value.to_array_owned()) + .transpose() + } + + /// Retrieves the value of a key from a map if it's an array of strings. + pub fn inner_array(document_type: &[(Value, Value)], key: &str) -> Result, Error> { + Self::get_from_map(document_type, key).map(|value| value.to_array_owned())? + } + + /// Retrieves the value of a key from a map if it's an array of strings. + pub fn inner_optional_array_slice<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result, Error> { + Self::get_optional_from_map(document_type, key) + .map(|value| value.to_array_slice()) + .transpose() + } + + /// Retrieves the value of a key from a map if it's an array of strings. + pub fn inner_array_slice<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result<&'a [Value], Error> { + Self::get_from_map(document_type, key).map(|value| value.to_array_slice())? + } + /// Gets the inner btree map from a map pub fn inner_optional_btree_map<'a>( document_type: &'a [(Value, Value)], diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index 8de046b3694..1441bb0d8d6 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -2,6 +2,29 @@ use crate::value_map::ValueMapHelper; use crate::{Error, Value}; impl Value { + pub fn remove_value_at_path(&mut self, path: &str) -> Result { + let mut split = path.split('.').peekable(); + let mut current_value = self; + let mut last_path_component = None; + while let Some(path_component) = split.next() { + if split.peek().is_none() { + last_path_component = Some(path_component); + } else { + let map = current_value.to_map_mut()?; + current_value = map.get_key_mut(path_component).ok_or_else(|| { + Error::StructureError(format!( + "unable to get property {path_component} in {path}" + )) + })?; + }; + } + let Some(last_path_component) = last_path_component else { + return Err(Error::StructureError(format!("path was empty"))); + }; + let map = current_value.as_map_mut_ref()?; + map.remove_key(last_path_component) + } + pub fn get_value_at_path<'a>(&'a self, path: &'a str) -> Result<&'a Value, Error> { let split = path.split('.'); let mut current_value = self; diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 12601769c43..ed57fc30f41 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -15,8 +15,8 @@ mod inner_value_at_path; mod macros; pub mod string_encoding; pub mod system_bytes; -pub mod value_map; mod types; +pub mod value_map; mod value_serialization; use crate::value_map::{ValueMap, ValueMapHelper}; @@ -30,7 +30,7 @@ pub type Hash256 = [u8; 32]; pub use btreemap_extensions::btreemap_field_replacement::ReplacementType; pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; -pub use value_serialization::{to_value, from_value}; +pub use value_serialization::{from_value, to_value}; /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index 4d0ea964816..80caa90ea15 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -1,4 +1,4 @@ -use crate::{Error, Value}; +use crate::{Error, Identifier, Value}; impl Value { /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the @@ -297,4 +297,117 @@ impl Value { _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), } } + + /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the + /// associated `Identifier` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Identifier, Value}; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]); + /// assert_eq!(value.into_identifier(), Ok(Identifier::new([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]))); /// + /// + /// let value = Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string()); + /// assert_eq!(value.into_identifier(), Ok(Identifier::new([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.into_identifier(), Err(Error::StructureError("value was a string, could be decoded from base 58, but was not 32 bytes long".to_string()))); + /// + /// let value = Value::Text("a811Ii".to_string()); + /// assert_eq!(value.into_identifier(), Err(Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); + /// assert_eq!(value.into_identifier(), Ok(Identifier::new([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); + /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.into_identifier(), Ok(Identifier::new([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5]))); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.into_identifier(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn into_identifier(self) -> Result { + match self { + Value::Text(text) => { + bs58::decode(text).into_vec() + .map_err(|_| Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))? + .try_into() + .map_err(|_| Error::StructureError("value was a string, could be decoded from base 58, but was not 32 bytes long".to_string())) + } + Value::Array(array) => { + Ok(array + .into_iter() + .map(|byte| match byte { + Value::U8(value_as_u8) => { + Ok(value_as_u8) + } + _ => Err(Error::StructureError("not an array of bytes".to_string())), + }) + .collect::, Error>>()? + .try_into() + .map_err(|_| Error::StructureError("value was an array of bytes, but was not 32 bytes long".to_string()))?) + } + Value::Bytes(vec) => { + vec.try_into() + .map_err(|_| Error::StructureError("value was bytes, but was not 32 bytes long".to_string())) + }, + Value::Bytes32(bytes) => Ok(Identifier::new(bytes)), + Value::Identifier(identifier) => Ok(Identifier::new(identifier)), + _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), + } + } + + /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the + /// associated `Identifier` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Identifier, Value}; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]); + /// assert_eq!(value.to_identifier(), Ok(Identifier::new([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]))); /// + /// + /// let value = Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string()); + /// assert_eq!(value.to_identifier(), Ok(Identifier::new([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.to_identifier(), Err(Error::StructureError("value was a string, could be decoded from base 58, but was not 32 bytes long".to_string()))); + /// + /// let value = Value::Text("a811Ii".to_string()); + /// assert_eq!(value.to_identifier(), Err(Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); + /// assert_eq!(value.to_identifier(), Ok(Identifier::new([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); + /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.to_identifier(), Ok(Identifier::new([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5]))); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_identifier(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn to_identifier(&self) -> Result { + match self { + Value::Text(text) => { + bs58::decode(text).into_vec() + .map_err(|_| Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))? + .try_into() + .map_err(|_| Error::StructureError("value was a string, could be decoded from base 58, but was not 32 bytes long".to_string())) + }, + Value::Array(array) => { + Ok(array + .iter() + .map(|byte| byte.to_integer()) + .collect::, Error>>()? + .try_into() + .map_err(|_| Error::StructureError("value was an array of bytes, but was not 32 bytes long".to_string()))?) + }, + Value::Bytes32(bytes) => Ok(Identifier::new(*bytes)), + Value::Bytes(vec) => { + vec.clone().try_into() + .map_err(|_| Error::StructureError("value was bytes, but was not 32 bytes long".to_string())) + }, + Value::Identifier(identifier) => Ok(Identifier::new(*identifier)), + _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), + } + } } diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 2681ca0c893..bd03368d84c 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; use crate::string_encoding::Encoding; -use crate::{string_encoding, Error}; +use crate::{string_encoding, Error, Value}; pub const IDENTIFIER_MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; @@ -168,3 +168,31 @@ impl PartialEq for [u8; 32] { self == &other.buffer } } + +impl TryFrom for Identifier { + type Error = Error; + + fn try_from(value: Value) -> Result { + value.into_identifier() + } +} + +impl TryFrom<&Value> for Identifier { + type Error = Error; + + fn try_from(value: &Value) -> Result { + value.to_identifier() + } +} + +impl From for Value { + fn from(value: Identifier) -> Self { + Value::Identifier(value.buffer) + } +} + +impl From<&Identifier> for Value { + fn from(value: &Identifier) -> Self { + Value::Identifier(value.buffer) + } +} diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index 4db08f556a3..29a5a340431 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -1,7 +1,7 @@ use crate::value_serialization::ser::Serializer; use crate::{Error, Value}; -use serde::{Deserialize, de::DeserializeOwned}; use serde::Serialize; +use serde::{de::DeserializeOwned, Deserialize}; pub mod de; pub mod ser; diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 89741e26edb..e6da180b428 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -56,9 +56,11 @@ impl ExtendedDocumentWasm { // .with_js_error()?; // // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array - let document = - ExtendedDocument::from_platform_value(raw_document, js_data_contract.to_owned().into()) - .with_js_error()?; + let document = ExtendedDocument::from_untrusted_platform_value( + raw_document, + js_data_contract.to_owned().into(), + ) + .with_js_error()?; Ok(document.into()) } From 7c509e0b4ca5245176f9e04eea046fe024b2519c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 13 Mar 2023 16:11:26 +0700 Subject: [PATCH 111/228] more work --- .../document_type/document_type.rs | 2 +- .../data_contract_create_transition/mod.rs | 19 +++---- .../data_contract_update_transition/mod.rs | 19 +++---- .../rs-dpp/src/document/extended_document.rs | 15 ++++-- .../abstract_state_transition.rs | 2 +- ...stract_state_transition_identity_signed.rs | 19 ++++--- .../identity_update_transition_spec.rs | 51 ++++++++++--------- ...e_identity_update_transition_basic_spec.rs | 46 +++++++++-------- packages/rs-platform-value/src/inner_value.rs | 4 ++ 9 files changed, 93 insertions(+), 84 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index 97cdec8f2cf..9be0712f56e 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -9,7 +9,7 @@ use crate::data_contract::document_type::{property_names, ArrayFieldType}; use crate::data_contract::errors::{DataContractError, StructureError}; use crate::ProtocolError; -use platform_value::btreemap_extensions::BTreeValueMapHelper; +use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; use platform_value::Value; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 07c0d891bb4..c41d78ffa50 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -217,20 +217,15 @@ impl StateTransitionConvert for DataContractCreateTransition { Ok(json_value) } - fn to_object(&self, skip_signature: bool) -> Result { - let mut json_object: JsonValue = serde_json::to_value(self)?; + fn to_object(&self, skip_signature: bool) -> Result { + let mut object: Value = platform_value::to_value(self)?; if skip_signature { - if let JsonValue::Object(ref mut o) = json_object { - for path in Self::signature_property_paths() { - o.remove(path); - } - } + Self::signature_property_paths() + .into_iter() + .try_for_each(|path| object.remove_value_at_path(path))?; } - json_object.insert( - String::from(DATA_CONTRACT), - self.data_contract.to_json_object(false)?, - )?; - Ok(json_object) + object.insert(String::from(DATA_CONTRACT), self.data_contract.to_object()?)?; + Ok(object) } } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 987b925c781..57d4c33af78 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -196,20 +196,15 @@ impl StateTransitionConvert for DataContractUpdateTransition { Ok(json_value) } - fn to_object(&self, skip_signature: bool) -> Result { - let mut json_object: JsonValue = serde_json::to_value(self)?; + fn to_object(&self, skip_signature: bool) -> Result { + let mut object: Value = platform_value::to_value(self)?; if skip_signature { - if let JsonValue::Object(ref mut o) = json_object { - for path in Self::signature_property_paths() { - o.remove(path); - } - } + Self::signature_property_paths() + .into_iter() + .try_for_each(|path| object.remove_value_at_path(path))?; } - json_object.insert( - String::from(DATA_CONTRACT), - self.data_contract.to_json_object(false)?, - )?; - Ok(json_object) + object.insert(String::from(DATA_CONTRACT), self.data_contract.to_object()?)?; + Ok(object) } } diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 32f706e3a8d..cfbb13585b2 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -483,7 +483,9 @@ mod test { use crate::data_contract::DataContract; use crate::document::Document; use crate::prelude::Identifier; + use crate::system_data_contracts::load_system_data_contract; use crate::tests::utils::*; + use data_contracts::SystemDataContract; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::string_encoding::Encoding; @@ -552,8 +554,9 @@ mod test { #[test] fn test_document_deserialize() -> Result<()> { init(); + let dpns_contract = load_system_data_contract(SystemDataContract::DPNS)?; let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - let doc = ExtendedDocument::from_json_string(&document_json)?; + let doc = ExtendedDocument::from_json_string(&document_json, dpns_contract)?; assert_eq!(doc.document_type_name, "domain"); assert_eq!(doc.protocol_version, 0); assert_eq!( @@ -615,8 +618,9 @@ mod test { #[test] fn test_to_object() { init(); + let dpns_contract = load_system_data_contract(SystemDataContract::DPNS)?; let document_json = get_data_from_file("src/tests/payloads/document_dpns.json").unwrap(); - let document = ExtendedDocument::from_json_string(&document_json).unwrap(); + let document = ExtendedDocument::from_json_string(&document_json, dpns_contract).unwrap(); let document_object = document.to_json_object_for_validation().unwrap(); for property in IDENTIFIER_FIELDS { @@ -633,10 +637,13 @@ mod test { fn test_json_serialize() -> Result<()> { init(); + let dpns_contract = load_system_data_contract(SystemDataContract::DPNS)?; let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - let document = ExtendedDocument::from_json_string(&document_json)?; + let document = ExtendedDocument::from_json_string(&document_json, dpns_contract)?; - serde_json::to_string(&document)?; + let string = serde_json::to_string(&document)?; + //added this, not sure if we want this check + assert_eq!(document_json, string); Ok(()) } diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 2f0183fc664..2bfbaec1e04 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -204,7 +204,7 @@ pub trait StateTransitionConvert: Serialize { // Returns the cibor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { let mut json_value = self.to_object(skip_signature)?; - let protocol_version = json_value.remove_u32(PROPERTY_PROTOCOL_VERSION)?; + let protocol_version = json_value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; serializer::value_to_cbor(json_value, Some(protocol_version)) } diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index f7e8f9f6190..9f5a2753d50 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -346,9 +346,14 @@ mod test { let st = get_mock_state_transition(); let st_object = st.to_object(false).unwrap(); - assert_eq!(st_object["protocolVersion"].as_i64().unwrap(), 1); - assert_eq!(st_object["transitionType"].as_u64().unwrap(), 1); - assert_eq!(st_object["signaturePublicKeyId"].as_u64().unwrap(), 1); + assert_eq!(st_object["protocolVersion"].to_integer::().unwrap(), 1); + assert_eq!(st_object["transitionType"].to_integer::().unwrap(), 1); + assert_eq!( + st_object["signaturePublicKeyId"] + .to_integer::() + .unwrap(), + 1 + ); assert!(st_object["signature"].as_array().unwrap().is_empty()); } @@ -357,10 +362,10 @@ mod test { let st = get_mock_state_transition(); let st_object = st.to_object(true).unwrap(); - assert_eq!(st_object["protocolVersion"].as_i64().unwrap(), 1); - assert_eq!(st_object["transitionType"].as_u64().unwrap(), 1); - assert!(st_object.get("signaturePublicKeyId").is_none()); - assert!(st_object.get("signature").is_none()); + assert_eq!(st_object["protocolVersion"].to_integer::().unwrap(), 1); + assert_eq!(st_object["transitionType"].to_integer::().unwrap(), 1); + assert!(st_object.has("signaturePublicKeyId").unwrap()); + assert!(st_object.has("signature").unwrap()); } #[test] diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index e8b54b27a16..797193082c5 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -1,5 +1,6 @@ use chrono::Utc; use platform_value::string_encoding::Encoding; +use platform_value::{platform_value, Value}; use serde_json::{json, Value as JsonValue}; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; @@ -18,7 +19,7 @@ use crate::{ struct TestData { transition: IdentityUpdateTransition, - raw_transition: JsonValue, + raw_transition: Value, } fn setup_test() -> TestData { @@ -134,25 +135,25 @@ fn to_object() { .to_object(false) .expect("conversion to object shouldn't fail"); - let expected_raw_state_transition = json!({ - "protocolVersion" : 1, - "type" : 5, + let expected_raw_state_transition = platform_value!({ + "protocolVersion" : 1u32, + "type" : 5u8, "signature" : [], - "signaturePublicKeyId": 0, - "identityId" : transition.identity_id.to_buffer(), - "revision": 0, - "disablePublicKeys" : [0], - "publicKeysDisabledAt" : 1234567, + "signaturePublicKeyId": 0u32, + "identityId" : transition.identity_id, + "revision": 0u8, + "disablePublicKeys" : [0u32], + "publicKeysDisabledAt" : 1234567u64, "addPublicKeys" : [ { - "id" : 3, - "purpose" : 0, - "type": 0, - "securityLevel" : 0, + "id" : 3u32, + "purpose" : 0u8, + "type": 0u8, + "securityLevel" : 0u8, "data" :base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap(), "readOnly" : false, - "signature" : vec![0;65] + "signature" : vec![0u8;65] } ] }); @@ -167,21 +168,21 @@ fn to_object_with_signature_skipped() { .to_object(true) .expect("conversion to object shouldn't fail"); - let expected_raw_state_transition = json!({ - "protocolVersion" : 1, - "type" : 5, - "signaturePublicKeyId": 0, + let expected_raw_state_transition = platform_value!({ + "protocolVersion" : 1u32, + "type" : 5u8, + "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id.to_buffer(), - "revision": 0, - "disablePublicKeys" : [0], - "publicKeysDisabledAt" : 1234567, + "revision": 0u8, + "disablePublicKeys" : [0u32], + "publicKeysDisabledAt" : 1234567u64, "addPublicKeys" : [ { - "id" : 3, - "purpose" : 0, - "type": 0, - "securityLevel" : 0, + "id" : 3u32, + "purpose" : 0u8, + "type": 0u8, + "securityLevel" : 0u8, "data" :base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap(), "readOnly" : false, } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs index 15d121049b6..ce88e1f7aed 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs @@ -154,7 +154,7 @@ fn property_should_be_byte_array(property_name: &str) { } = setup_test(); let array = ["string"; 32]; - raw_state_transition[property_name] = json!(array); + raw_state_transition[property_name] = platform_value!(array); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -192,7 +192,7 @@ fn property_should_be_integer(property_name: &str) { .. } = setup_test(); - raw_state_transition[property_name] = json!("1"); + raw_state_transition[property_name] = platform_value!("1"); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -225,7 +225,7 @@ fn signature_should_be_not_less_than_n_bytes(property_name: &str, n_bytes: usize } = setup_test(); let array = vec![0u8; n_bytes - 1]; - raw_state_transition[property_name] = json!(array); + raw_state_transition[property_name] = platform_value!(array); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -258,7 +258,7 @@ fn signature_should_be_not_longer_than_n_bytes(property_name: &str, n_bytes: usi } = setup_test(); let array = vec![0u8; n_bytes + 1]; - raw_state_transition[property_name] = json!(array); + raw_state_transition[property_name] = platform_value!(array); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -289,7 +289,7 @@ fn protocol_version_should_be_valid() { .. } = setup_test(); - raw_state_transition[property_names::PROTOCOL_VERSION] = json!(-1); + raw_state_transition[property_names::PROTOCOL_VERSION] = platform_value!(-1); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -315,7 +315,7 @@ fn raw_state_transition_type_should_be_valid() { .. } = setup_test(); - raw_state_transition[property_names::TYPE] = json!(666); + raw_state_transition[property_names::TYPE] = platform_value!(666); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -346,7 +346,7 @@ fn revision_should_be_greater_or_equal_0() { .. } = setup_test(); - raw_state_transition[property_names::REVISION] = json!(-1); + raw_state_transition[property_names::REVISION] = platform_value!(-1); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -384,7 +384,8 @@ fn add_public_keys_should_return_valid_result() { let _ = raw_state_transition.remove(property_names::DISABLE_PUBLIC_KEYS); let _ = raw_state_transition.remove(property_names::PUBLIC_KEYS_DISABLED_AT); - raw_state_transition[property_names::ADD_PUBLIC_KEYS] = json!(vec![raw_public_key_to_add]); + raw_state_transition[property_names::ADD_PUBLIC_KEYS] = + platform_value!(vec![raw_public_key_to_add]); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -416,7 +417,7 @@ fn add_public_keys_should_not_be_empty() { let _ = raw_state_transition.remove(property_names::DISABLE_PUBLIC_KEYS); let _ = raw_state_transition.remove(property_names::PUBLIC_KEYS_DISABLED_AT); - raw_state_transition[property_names::ADD_PUBLIC_KEYS] = json!([]); + raw_state_transition[property_names::ADD_PUBLIC_KEYS] = platform_value!([]); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -456,7 +457,7 @@ fn add_public_keys_should_not_have_more_than_10_items() { let _ = raw_state_transition.remove(property_names::PUBLIC_KEYS_DISABLED_AT); let public_keys_to_add: Vec = (0..11).map(|_| raw_public_key_to_add.clone()).collect(); - raw_state_transition[property_names::ADD_PUBLIC_KEYS] = json!(public_keys_to_add); + raw_state_transition[property_names::ADD_PUBLIC_KEYS] = platform_value!(public_keys_to_add); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -496,7 +497,7 @@ fn add_public_keys_should_be_unique() { let _ = raw_state_transition.remove(property_names::PUBLIC_KEYS_DISABLED_AT); let public_keys_to_add: Vec = (0..2).map(|_| raw_public_key_to_add.clone()).collect(); - raw_state_transition[property_names::ADD_PUBLIC_KEYS] = json!(public_keys_to_add); + raw_state_transition[property_names::ADD_PUBLIC_KEYS] = platform_value!(public_keys_to_add); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -538,7 +539,8 @@ fn add_public_keys_should_be_valid() { let _ = raw_state_transition.remove(property_names::DISABLE_PUBLIC_KEYS); let _ = raw_state_transition.remove(property_names::PUBLIC_KEYS_DISABLED_AT); - raw_state_transition[property_names::ADD_PUBLIC_KEYS] = json!([raw_public_key_to_add]); + raw_state_transition[property_names::ADD_PUBLIC_KEYS] = + platform_value!([raw_public_key_to_add]); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -610,8 +612,8 @@ fn disable_public_keys_should_be_valid() { .returning(|_| Ok(Default::default())); let _ = raw_state_transition.remove(property_names::ADD_PUBLIC_KEYS); - raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = json!(vec![0]); - raw_state_transition[property_names::PUBLIC_KEYS_DISABLED_AT] = json!(0); + raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = platform_value!(vec![0]); + raw_state_transition[property_names::PUBLIC_KEYS_DISABLED_AT] = platform_value!(0); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -641,8 +643,8 @@ fn disable_public_keys_should_contain_number_greater_or_equal_0() { .returning(|_| Ok(Default::default())); let _ = raw_state_transition.remove(property_names::ADD_PUBLIC_KEYS); - raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = json!(vec![-1, 0]); - raw_state_transition[property_names::PUBLIC_KEYS_DISABLED_AT] = json!(0); + raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = platform_value!(vec![-1, 0]); + raw_state_transition[property_names::PUBLIC_KEYS_DISABLED_AT] = platform_value!(0); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -678,8 +680,8 @@ fn disable_public_keys_should_contain_integers() { .returning(|_| Ok(Default::default())); let _ = raw_state_transition.remove(property_names::ADD_PUBLIC_KEYS); - raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = json!(vec![1.1]); - raw_state_transition[property_names::PUBLIC_KEYS_DISABLED_AT] = json!(0); + raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = platform_value!(vec![1.1]); + raw_state_transition[property_names::PUBLIC_KEYS_DISABLED_AT] = platform_value!(0); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -716,7 +718,7 @@ fn disable_public_keys_should_not_have_more_than_10_items() { let _ = raw_state_transition.remove(property_names::ADD_PUBLIC_KEYS); let key_ids_to_disable: Vec = (0..11).collect(); - raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = json!(key_ids_to_disable); + raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = platform_value!(key_ids_to_disable); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -753,7 +755,7 @@ fn disable_public_keys_should_be_unique() { let _ = raw_state_transition.remove(property_names::ADD_PUBLIC_KEYS); let key_ids_to_disable: Vec = vec![0, 0]; - raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = json!(key_ids_to_disable); + raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = platform_value!(key_ids_to_disable); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( @@ -827,8 +829,8 @@ fn public_keys_disabled_at_should_be_greater_or_equal_0() { .returning(|_| Ok(Default::default())); let _ = raw_state_transition.remove(property_names::ADD_PUBLIC_KEYS); - raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = json!(vec![0]); - raw_state_transition[property_names::PUBLIC_KEYS_DISABLED_AT] = json!(-1); + raw_state_transition[property_names::DISABLE_PUBLIC_KEYS] = platform_value!(vec![0]); + raw_state_transition[property_names::PUBLIC_KEYS_DISABLED_AT] = platform_value!(-1); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = ValidateIdentityUpdateTransitionBasic::new( diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index c217840adad..7224fb5f953 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -5,6 +5,10 @@ use crate::{Error, Value}; use std::collections::BTreeMap; impl Value { + pub fn has(&self, key: &str) -> Result { + self.get_optional_value(key).map(|v| v.is_some()) + } + pub fn get<'a>(&'a self, key: &'a str) -> Result, Error> { self.get_optional_value(key) } From d32b6b688085e438c2c1d47a298c948a50349286 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 13 Mar 2023 21:46:19 +0700 Subject: [PATCH 112/228] more work --- .../rs-dpp/src/data_contract/data_contract.rs | 2 +- .../data_contract/data_contract_factory.rs | 6 +- .../rs-dpp/src/data_contract/extra/common.rs | 4 +- .../data_contract_create_transition/mod.rs | 10 +- ...e_data_contract_create_transition_basic.rs | 19 +- .../data_contract_update_transition/mod.rs | 7 +- .../validation/data_contract_validator.rs | 4 +- .../validation/multi_validator.rs | 2 +- packages/rs-dpp/src/document/document.rs | 1 - .../rs-dpp/src/document/document_facade.rs | 1 - .../rs-dpp/src/document/document_factory.rs | 1 - .../rs-dpp/src/document/extended_document.rs | 6 +- .../fetch_and_validate_data_contract.rs | 1 - packages/rs-dpp/src/document/serialize.rs | 4 +- ...lidate_documents_batch_transition_basic.rs | 2 - .../decode/protocol_version_parsing_error.rs | 5 +- packages/rs-dpp/src/identity/identity.rs | 5 +- .../rs-dpp/src/identity/identity_facade.rs | 1 - .../state_transition/asset_lock_proof/mod.rs | 16 +- .../identity_create_transition.rs | 24 +- .../mod.rs | 24 +- .../identity_update_transition.rs | 9 +- .../identity/validation/identity_validator.rs | 17 +- ...ed_purpose_and_security_level_validator.rs | 2 +- .../abstract_state_transition.rs | 13 +- packages/rs-dpp/src/state_transition/mod.rs | 5 +- .../validation/validator_transaction_basic.rs | 16 +- .../data_contract_validator_spec.rs | 51 ++- ..._documents_batch_transitions_basic_spec.rs | 11 +- ..._create_transition_basic_validator_spec.rs | 21 +- .../validation/identity_validator_spec.rs | 7 +- .../validation/public_keys_validator_spec.rs | 65 ++-- packages/rs-dpp/src/util/serializer.rs | 7 +- .../src/contracts/reward_shares.rs | 4 +- .../src/drive/batch/drive_op_batch/mod.rs | 36 +- .../rs-drive/src/drive/document/delete.rs | 8 +- .../rs-drive/src/drive/document/update.rs | 14 +- packages/rs-drive/src/query/mod.rs | 56 +-- packages/rs-drive/src/query/test_index.rs | 12 +- .../rs-drive/tests/deterministic_root_hash.rs | 8 +- packages/rs-drive/tests/query_tests.rs | 328 ++++++++++-------- .../rs-drive/tests/query_tests_history.rs | 132 +++---- .../src/inner_array_value.rs | 7 + packages/rs-platform-value/src/inner_value.rs | 53 ++- .../src/inner_value_at_path.rs | 11 + packages/rs-platform-value/src/lib.rs | 18 + 46 files changed, 576 insertions(+), 480 deletions(-) create mode 100644 packages/rs-platform-value/src/inner_array_value.rs diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index b29ceb63ebd..46f1ce09dc6 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -70,7 +70,7 @@ impl Convertible for DataContract { o.remove("protocolVersion"); }; - serializer::value_to_cbor(json_object, Some(protocol_version)) + serializer::serializable_value_to_cbor(&json_object, Some(protocol_version)) } } diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 385d91286ee..7bbeb41d3cf 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -1,4 +1,4 @@ -use serde_json::{json, Map, Value as JsonValue}; +use serde_json::{Map, Value as JsonValue}; use std::collections::BTreeMap; use std::convert::TryInto; use std::sync::Arc; @@ -8,7 +8,7 @@ use platform_value::Value; use crate::data_contract::errors::InvalidDataContractError; use crate::data_contract::property_names; -use crate::util::serializer::value_to_cbor; +use crate::util::serializer::serializable_value_to_cbor; use crate::{ data_contract::{self, generate_data_contract_id}, decode_protocol_entity_factory::DecodeProtocolEntity, @@ -102,7 +102,7 @@ impl DataContractFactory { root_map.insert(property_names::DOCUMENTS.to_string(), documents); - let cbor = value_to_cbor(JsonValue::Object(root_map), Some(1))?; + let cbor = serializable_value_to_cbor(&JsonValue::Object(root_map), Some(1))?; DataContract::from_cbor(cbor) } diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index cfda86df36b..8c7a598ffc6 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -1,6 +1,6 @@ use crate::data_contract::errors::StructureError; use crate::util::cbor_value::cbor_value_into_json_value; -use crate::util::serializer::value_to_cbor; +use crate::util::serializer::serializable_value_to_cbor; use crate::ProtocolError; use ciborium::Value; use std::collections::BTreeMap; @@ -276,7 +276,7 @@ pub fn json_document_to_cbor( protocol_version: Option, ) -> Result, ProtocolError> { let json = json_document_to_value(path)?; - value_to_cbor(json, protocol_version) + serializable_value_to_cbor(&json, protocol_version) } /// Make sure the protocol version is correct. diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index c41d78ffa50..b5f0892e6bb 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -1,7 +1,5 @@ use std::collections::BTreeMap; -use std::convert::TryInto; -use anyhow::anyhow; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; @@ -222,7 +220,12 @@ impl StateTransitionConvert for DataContractCreateTransition { if skip_signature { Self::signature_property_paths() .into_iter() - .try_for_each(|path| object.remove_value_at_path(path))?; + .try_for_each(|path| { + object + .remove_value_at_path(path) + .map_err(ProtocolError::ValueError) + .map(|_| ()) + })?; } object.insert(String::from(DATA_CONTRACT), self.data_contract.to_object()?)?; Ok(object) @@ -232,7 +235,6 @@ impl StateTransitionConvert for DataContractCreateTransition { #[cfg(test)] mod test { use integer_encoding::VarInt; - use serde_json::json; use crate::tests::fixtures::get_data_contract_fixture; use crate::version; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs index 3b9942153e4..5be18d1c356 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs @@ -1,9 +1,9 @@ -use std::convert::TryFrom; use std::sync::Arc; use anyhow::anyhow; use lazy_static::lazy_static; -use serde_json::Value; +use platform_value::Value; +use serde_json::Value as JsonValue; use crate::consensus::basic::data_contract::InvalidDataContractIdError; use crate::consensus::basic::decode::ProtocolVersionParsingError; @@ -15,7 +15,6 @@ use crate::{ validation::data_contract_validator::DataContractValidator, }, state_transition::state_transition_execution_context::StateTransitionExecutionContext, - util::json_value::JsonValueExt, validation::{ DataValidator, DataValidatorWithContext, JsonSchemaValidator, SimpleValidationResult, }, @@ -24,7 +23,7 @@ use crate::{ }; lazy_static! { - static ref DATA_CONTRACT_CREATE_SCHEMA: Value = serde_json::from_str(include_str!( + static ref DATA_CONTRACT_CREATE_SCHEMA: JsonValue = serde_json::from_str(include_str!( "../../../../../schema/data_contract/stateTransition/dataContractCreate.json" )) .unwrap(); @@ -70,20 +69,24 @@ impl DataValidatorWithContext for DataContractCreateTransitionBasicValidator { } fn validate_data_contract_create_transition_basic( - json_schema_validator: &impl DataValidator, + json_schema_validator: &impl DataValidator, protocol_validator: &impl DataValidator, data_contract_validator: &impl DataValidator, raw_state_transition: &Value, _execution_context: &StateTransitionExecutionContext, ) -> Result { - let result = json_schema_validator.validate(raw_state_transition)?; + let result = json_schema_validator.validate( + &raw_state_transition + .try_into_validating_json() + .map_err(ProtocolError::ValueError)?, + )?; if !result.is_valid() { return Ok(result); } let protocol_version = match raw_state_transition - .get_u64(property_names::PROTOCOL_VERSION) - .and_then(|x| u32::try_from(x).map_err(Into::into)) + .get_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError) { Ok(v) => v, Err(parsing_error) => { diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 57d4c33af78..de3abc8dc69 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -201,7 +201,11 @@ impl StateTransitionConvert for DataContractUpdateTransition { if skip_signature { Self::signature_property_paths() .into_iter() - .try_for_each(|path| object.remove_value_at_path(path))?; + .try_for_each(|path| { + object + .remove_value_at_path(path) + .map_err(ProtocolError::ValueError) + })?; } object.insert(String::from(DATA_CONTRACT), self.data_contract.to_object()?)?; Ok(object) @@ -211,7 +215,6 @@ impl StateTransitionConvert for DataContractUpdateTransition { #[cfg(test)] mod test { use integer_encoding::VarInt; - use serde_json::json; use std::convert::TryInto; use crate::tests::fixtures::get_data_contract_fixture; diff --git a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs index 09c20ba2580..62a69a5566c 100644 --- a/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/data_contract_validator.rs @@ -1,11 +1,9 @@ -use std::{collections::HashMap, sync::Arc}; - -use anyhow::anyhow; use itertools::Itertools; use lazy_static::lazy_static; use log::trace; use platform_value::Value; use serde_json::Value as JsonValue; +use std::{collections::HashMap, sync::Arc}; use crate::consensus::basic::data_contract::{ DuplicateIndexError, DuplicateIndexNameError, InvalidCompoundIndexError, diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 13127114cfc..ba7d81d833c 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -85,7 +85,7 @@ fn unwrap_error_to_result<'a, 'b>( match v { Ok(v) => v, Err(e) => { - result.add_error(e.into()); + result.add_error::(e.into()); None } } diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index effe897b9c4..c33884c5595 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -41,7 +41,6 @@ use ciborium::Value as CborValue; use serde_json::{json, Value as JsonValue}; use crate::data_contract::{DataContract, DriveContractExt}; -use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; diff --git a/packages/rs-dpp/src/document/document_facade.rs b/packages/rs-dpp/src/document/document_facade.rs index d480d898e42..d1c8f93dc72 100644 --- a/packages/rs-dpp/src/document/document_facade.rs +++ b/packages/rs-dpp/src/document/document_facade.rs @@ -2,7 +2,6 @@ use anyhow::anyhow; use platform_value::Value; use std::sync::Arc; -use crate::document::document_transition::document_base_transition::JsonValue; use crate::document::ExtendedDocument; use crate::{ data_contract::DataContract, prelude::Identifier, state_repository::StateRepositoryLike, diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index fb4276b3190..60d01602f05 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -8,7 +8,6 @@ use platform_value::Value; use rand::rngs::StdRng; use rand::SeedableRng; use serde::{Deserialize, Serialize}; -use serde_json::Value as JsonValue; use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::document::extended_document::{property_names, ExtendedDocument}; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index cfbb13585b2..b901ba6872a 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -618,7 +618,7 @@ mod test { #[test] fn test_to_object() { init(); - let dpns_contract = load_system_data_contract(SystemDataContract::DPNS)?; + let dpns_contract = load_system_data_contract(SystemDataContract::DPNS).unwrap(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json").unwrap(); let document = ExtendedDocument::from_json_string(&document_json, dpns_contract).unwrap(); let document_object = document.to_json_object_for_validation().unwrap(); @@ -652,7 +652,9 @@ mod test { init(); let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; - ExtendedDocument::from_json_string(&document_json)?; + let dpns_contract = load_system_data_contract(SystemDataContract::DPNS).unwrap(); + ExtendedDocument::from_json_string(&document_json, dpns_contract) + .expect("expected extended document"); Ok(()) } diff --git a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs index aa3da5147aa..e7242ae0b89 100644 --- a/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs +++ b/packages/rs-dpp/src/document/fetch_and_validate_data_contract.rs @@ -2,7 +2,6 @@ use std::{convert::TryInto, sync::Arc}; use platform_value::Value; -use crate::consensus::basic::invalid_identifier_error::InvalidIdentifierError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; use crate::{ consensus::{basic::BasicError, ConsensusError}, diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 7d5bf9df177..8a645054b9a 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -16,7 +16,6 @@ use crate::ProtocolError; use byteorder::{BigEndian, ReadBytesExt}; use ciborium::Value as CborValue; use integer_encoding::VarIntWriter; -use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; @@ -344,7 +343,8 @@ impl Document { "unable to decode document for document call", )) })?; - let document_map: BTreeMap = Value::convert_from_cbor_map(document_cbor_map); + let document_map: BTreeMap = + Value::convert_from_cbor_map(document_cbor_map).map_err(ProtocolError::ValueError)?; Self::from_map(document_map, document_id, owner_id) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 9b9e2988467..8f862bea4bc 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -1,5 +1,4 @@ use std::collections::BTreeMap; -use std::iter::Map; use std::{ collections::{hash_map::Entry, HashMap}, convert::{TryFrom, TryInto}, @@ -10,7 +9,6 @@ use crate::consensus::basic::document::{ InvalidDocumentTransitionActionError, InvalidDocumentTransitionIdError, InvalidDocumentTypeError, }; -use crate::consensus::basic::invalid_identifier_error::InvalidIdentifierError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; use crate::document::state_transition::documents_batch_transition::property_names; use crate::document::validation::basic::find_duplicates_by_id::find_duplicates_by_id; diff --git a/packages/rs-dpp/src/errors/consensus/basic/decode/protocol_version_parsing_error.rs b/packages/rs-dpp/src/errors/consensus/basic/decode/protocol_version_parsing_error.rs index 0a5e22b9a67..fc0e8bd644d 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/decode/protocol_version_parsing_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/decode/protocol_version_parsing_error.rs @@ -1,15 +1,16 @@ use thiserror::Error; use crate::consensus::ConsensusError; +use crate::ProtocolError; #[derive(Error, Debug)] #[error("Can't read protocol version from serialized object: {parsing_error}")] pub struct ProtocolVersionParsingError { - pub parsing_error: anyhow::Error, + pub parsing_error: ProtocolError, } impl ProtocolVersionParsingError { - pub fn new(parsing_error: anyhow::Error) -> Self { + pub fn new(parsing_error: ProtocolError) -> Self { Self { parsing_error } } } diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index adfd6d0bf6e..77d7b8f8948 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -13,10 +13,7 @@ use crate::util::cbor_value::{CborBTreeMapHelper, CborCanonicalMap}; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::util::json_value::{JsonValueExt, ReplaceWith}; -use crate::{ - errors::ProtocolError, identifier::Identifier, metadata::Metadata, util::hash, - SerdeParsingError, -}; +use crate::{errors::ProtocolError, identifier::Identifier, metadata::Metadata, util::hash}; use super::{IdentityPublicKey, KeyID}; diff --git a/packages/rs-dpp/src/identity/identity_facade.rs b/packages/rs-dpp/src/identity/identity_facade.rs index 528cb61e5e6..8b0c7bd3a1a 100644 --- a/packages/rs-dpp/src/identity/identity_facade.rs +++ b/packages/rs-dpp/src/identity/identity_facade.rs @@ -1,6 +1,5 @@ use dashcore::{InstantLock, Transaction}; use platform_value::Value; -use serde_json::Value as JsonValue; use std::collections::BTreeMap; use std::sync::Arc; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index 50cd790c775..e562c1e9120 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -175,8 +175,12 @@ impl TryInto for AssetLockProof { fn try_into(self) -> Result { match self { - AssetLockProof::Instant(instant_proof) => platform_value::to_value(instant_proof), - AssetLockProof::Chain(chain_proof) => platform_value::to_value(chain_proof), + AssetLockProof::Instant(instant_proof) => { + platform_value::to_value(instant_proof).map_err(ProtocolError::ValueError) + } + AssetLockProof::Chain(chain_proof) => { + platform_value::to_value(chain_proof).map_err(ProtocolError::ValueError) + } } } } @@ -186,8 +190,12 @@ impl TryInto for &AssetLockProof { fn try_into(self) -> Result { match self { - AssetLockProof::Instant(instant_proof) => platform_value::to_value(instant_proof), - AssetLockProof::Chain(chain_proof) => platform_value::to_value(chain_proof), + AssetLockProof::Instant(instant_proof) => { + platform_value::to_value(instant_proof).map_err(ProtocolError::ValueError) + } + AssetLockProof::Chain(chain_proof) => { + platform_value::to_value(chain_proof).map_err(ProtocolError::ValueError) + } } } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 75cd442d6ad..be5235ad176 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -85,7 +85,7 @@ impl<'de> Deserialize<'de> for IdentityCreateTransition { where D: Deserializer<'de>, { - let value = serde_json::Value::deserialize(deserializer)?; + let value = platform_value::Value::deserialize(deserializer)?; Self::new(value).map_err(|e| D::Error::custom(e.to_string())) } @@ -260,28 +260,26 @@ impl StateTransitionConvert for IdentityCreateTransition { vec![] } - fn to_object(&self, skip_signature: bool) -> Result { - let mut json_value: JsonValue = serde_json::to_value(self)?; + fn to_object(&self, skip_signature: bool) -> Result { + let mut value: Value = platform_value::to_value(self)?; if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { - for path in Self::signature_property_paths() { - o.remove(path); - } - } + value + .remove_values_at_paths(Self::signature_property_paths()) + .map_err(ProtocolError::ValueError)? } - let mut public_keys: Vec = vec![]; + let mut public_keys: Vec = vec![]; for key in self.public_keys.iter() { - public_keys.push(key.to_raw_json_object(skip_signature)?); + public_keys.push(key.to_raw_object(skip_signature)?); } - json_value.insert( + value.insert( property_names::PUBLIC_KEYS.to_owned(), - JsonValue::Array(public_keys), + Value::Array(public_keys), )?; - Ok(json_value) + Ok(value) } fn to_json(&self, skip_signature: bool) -> Result { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index aa2fd4796a0..b26d3a97afa 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -1,5 +1,6 @@ use anyhow::anyhow; use platform_value::string_encoding::{self, Encoding}; +use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use serde_repr::{Deserialize_repr, Serialize_repr}; @@ -76,8 +77,8 @@ impl std::default::Default for IdentityCreditWithdrawalTransition { } impl IdentityCreditWithdrawalTransition { - pub fn from_value(value: JsonValue) -> Result { - let transition: IdentityCreditWithdrawalTransition = serde_json::from_value(value)?; + pub fn from_value(value: Value) -> Result { + let transition: IdentityCreditWithdrawalTransition = platform_value::from_value(value)?; Ok(transition) } @@ -85,27 +86,12 @@ impl IdentityCreditWithdrawalTransition { pub fn from_json(mut value: JsonValue) -> Result { value.replace_binary_paths(Self::binary_property_paths(), ReplaceWith::Bytes)?; - Self::from_value(value) + Self::from_value(value.into()) } pub fn from_raw_object( - mut raw_object: JsonValue, + mut raw_object: Value, ) -> Result { - let output_script_option = raw_object.get(PROPERTY_OUTPUT_SCRIPT); - - let output_script_string = output_script_option - .ok_or_else(|| anyhow!("uanble to get outputScript")) - .and_then(|value| serde_json::from_value(value.clone()).map_err(|e| anyhow!(e))) - .map(|bytes: Vec| string_encoding::encode(&bytes, Encoding::Base64))?; - - raw_object.insert( - PROPERTY_OUTPUT_SCRIPT.to_owned(), - JsonValue::String(output_script_string), - )?; - - raw_object - .replace_identifier_paths(Self::identifiers_property_paths(), ReplaceWith::Base58)?; - Self::from_value(raw_object) } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 080f8f2a62f..8ad9559d66a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -368,15 +368,12 @@ mod test { assert!(matches!( result[property_names::IDENTITY_ID], - JsonValue::Array(_) - )); - assert!(matches!( - result[property_names::SIGNATURE], - JsonValue::Array(_) + Value::Array(_) )); + assert!(matches!(result[property_names::SIGNATURE], Value::Array(_))); assert!(matches!( result[property_names::ADD_PUBLIC_KEYS][0]["data"], - JsonValue::Array(_) + Value::Array(_) )); } } diff --git a/packages/rs-dpp/src/identity/validation/identity_validator.rs b/packages/rs-dpp/src/identity/validation/identity_validator.rs index e950a38c000..f9acb163e62 100644 --- a/packages/rs-dpp/src/identity/validation/identity_validator.rs +++ b/packages/rs-dpp/src/identity/validation/identity_validator.rs @@ -8,6 +8,7 @@ use crate::util::protocol_data::{get_protocol_version, get_raw_public_keys}; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::version::ProtocolVersionValidator; use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError}; +use crate::consensus::ConsensusError; use crate::identity::state_transition::identity_update_transition::identity_update_transition::property_names::PROTOCOL_VERSION; lazy_static! { @@ -45,16 +46,13 @@ impl IdentityValidator { let mut validation_result = self.json_schema_validator.validate( &identity_object .try_to_validating_json() - .map_err(ProtocolError::ValueError)?, + .map_err(NonConsensusError::ValueError)?, )?; if !validation_result.is_valid() { return Ok(validation_result); } - let identity_map = identity_object - .to_map() - .map_err(ProtocolError::ValueError)?; let protocol_version = identity_object.get_integer(PROTOCOL_VERSION)?; validation_result.merge(self.protocol_version_validator.validate(protocol_version)?); @@ -62,7 +60,7 @@ impl IdentityValidator { return Ok(validation_result); } - let raw_public_keys = identity_object.get_array?; + let raw_public_keys = identity_object.get_array_slice("publicKeys")?; validation_result.merge(self.public_keys_validator.validate_keys(raw_public_keys)?); Ok(validation_result) @@ -78,12 +76,3 @@ impl IdentityValidator { // as u32) // } // -// fn get_raw_public_keys( -// identity_map: &Map, -// ) -> Result<&Vec, SerdeParsingError> { -// identity_map -// .get("publicKeys") -// .ok_or_else(|| SerdeParsingError::new("Expected identity.publicKeys to exist"))? -// .as_array() -// .ok_or_else(|| SerdeParsingError::new("Expected identity.publicKeys to be an array")) -// } diff --git a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs index d4aeb96d91a..d7ab2278661 100644 --- a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs +++ b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs @@ -29,7 +29,7 @@ impl TPublicKeysValidator for RequiredPurposeAndSecurityLevelValidator { for raw_public_key in raw_public_keys.iter().filter(|pk| { if let Some(disabled_at) = pk .get_optional_bool("disabledAt") - .map_err(ProtocolError::ValueError)? + .map_err(NonConsensusError::ValueError)? { disabled_at == false } else { diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 2bfbaec1e04..a599eac3b70 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -186,7 +186,12 @@ pub trait StateTransitionConvert: Serialize { /// Returns the [`platform_value::Value`] instance that preserves the `Vec` representation /// for Identifiers and binary data fn to_object(&self, skip_signature: bool) -> Result { - state_transition_helpers::to_object(self, skip_signature) + let skip_signature_paths = if skip_signature { + Self::signature_property_paths() + } else { + vec![] + }; + state_transition_helpers::to_object(self, skip_signature_paths) } /// Returns the [`serde_json::Value`] instance that encodes: @@ -203,10 +208,10 @@ pub trait StateTransitionConvert: Serialize { // Returns the cibor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { - let mut json_value = self.to_object(skip_signature)?; - let protocol_version = json_value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; + let mut value = self.to_object(skip_signature)?; + let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; - serializer::value_to_cbor(json_value, Some(protocol_version)) + serializer::serializable_value_to_cbor(&value, Some(protocol_version)) } // Returns the hash of cibor-encoded bytes representation of the object diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 2bfecce8310..7b4e835d2e4 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -110,7 +110,10 @@ impl StateTransitionConvert for StateTransition { call_method!(self, to_json, skip_signature) } - fn to_object(&self, skip_signature: bool) -> Result { + fn to_object( + &self, + skip_signature: bool, + ) -> Result { call_method!(self, to_object, skip_signature) } diff --git a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs b/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs index 865d90651e2..d548cda4756 100644 --- a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs +++ b/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs @@ -3,6 +3,7 @@ use std::convert::TryFrom; use async_trait::async_trait; #[cfg(test)] use mockall::{automock, predicate::*}; +use platform_value::Value; use serde_json::Value as JsonValue; use crate::consensus::basic::state_transition::{ @@ -20,18 +21,18 @@ use crate::{ async fn validate_state_transition_basic( state_repository: &impl StateRepositoryLike, validate_functions_by_type: &impl ValidatorByStateTransitionType, - raw_state_transition: JsonValue, + raw_state_transition: Value, ) -> Result { let mut result = SimpleValidationResult::default(); - let raw_transition_type = match raw_state_transition.get_u64("type") { + let raw_transition_type = match raw_state_transition.get_integer("type") { Err(_) => { result.add_error(BasicError::MissingStateTransitionTypeError); return Ok(result); } Ok(transaction_type) => transaction_type, - } as u8; + }; let state_transition_type = match StateTransitionType::try_from(raw_transition_type) { Err(_) => { @@ -70,13 +71,14 @@ async fn validate_state_transition_basic( pub trait ValidatorByStateTransitionType: Sync { async fn validate( &self, - raw_state_transition: &JsonValue, + raw_state_transition: &Value, state_transition_type: StateTransitionType, ) -> Result; } #[cfg(test)] mod test { + use platform_value::{platform_value, Value}; use serde_json::{json, Value as JsonValue}; use std::sync::Arc; @@ -101,7 +103,7 @@ mod test { struct TestData { data_contract: DataContract, state_transition: DataContractCreateTransition, - raw_state_transition: JsonValue, + raw_state_transition: Value, bls: NativeBlsModule, } @@ -182,7 +184,7 @@ mod test { let state_repository_mock = MockStateRepositoryLike::new(); let validate_by_type_mock = MockValidatorByStateTransitionType::new(); - raw_state_transition["type"] = json!(123); + raw_state_transition["type"] = platform_value!(123u32); let result = validate_state_transition_basic( &state_repository_mock, @@ -215,7 +217,7 @@ mod test { let state_repository_mock = MockStateRepositoryLike::new(); let validate_by_type_mock = MockValidatorByStateTransitionType::new(); - raw_state_transition["type"] = json!(123); + raw_state_transition["type"] = platform_value!(123u32); let result = validate_state_transition_basic( &state_repository_mock, diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index 65d2bcb04b6..4efde6fe5fd 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -1638,8 +1638,9 @@ mod indices { raw_data_contract["documents"]["indexedDocument"]["indices"][0].clone(); index_definition["name"] = platform_value!("otherIndexName"); - if let Some(JsonValue::Array(ref mut arr)) = - raw_data_contract["documents"]["indexedDocument"].get_mut("indices") + if let Some(Value::Array(ref mut arr)) = raw_data_contract["documents"]["indexedDocument"] + .get_mut("indices") + .unwrap() { arr.push(index_definition) } else { @@ -1674,8 +1675,9 @@ mod indices { let index_definition = raw_data_contract["documents"]["indexedDocument"]["indices"][0].clone(); - if let Some(JsonValue::Array(ref mut arr)) = - raw_data_contract["documents"]["indexedDocument"].get_mut("indices") + if let Some(Value::Array(ref mut arr)) = raw_data_contract["documents"]["indexedDocument"] + .get_mut("indices") + .unwrap() { arr.push(index_definition) } else { @@ -1807,9 +1809,10 @@ mod indices { } = setup_test(); for i in 0..10 { - if let Some(JsonValue::Array(ref mut properties)) = raw_data_contract["documents"] + if let Some(Value::Array(ref mut properties)) = raw_data_contract["documents"] ["indexedDocument"]["indices"][0] .get_mut("properties") + .unwrap() { let field_name = format!("field{}", i); properties.push(platform_value!({ @@ -1960,8 +1963,10 @@ mod indices { .insert(property_name.clone(), platform_value!({ "type" : "string"})) .expect("properties should be present"); - if let Some(JsonValue::Array(ref mut indices)) = - raw_data_contract["documents"]["indexedDocument"].get_mut("indices") + if let Some(Value::Array(ref mut indices)) = raw_data_contract["documents"] + ["indexedDocument"] + .get_mut("indices") + .unwrap() { indices.push(platform_value!({ "name" : format!("{}_index", property_name), @@ -1999,8 +2004,10 @@ mod indices { ) .expect("properties should be present"); - if let Some(JsonValue::Array(ref mut indices)) = - raw_data_contract["documents"]["indexedDocument"].get_mut("indices") + if let Some(Value::Array(ref mut indices)) = raw_data_contract["documents"] + ["indexedDocument"] + .get_mut("indices") + .unwrap() { indices.push(platform_value!({ "name" : format!("index_{}", i), @@ -2046,8 +2053,10 @@ mod indices { ] }); - if let Some(JsonValue::Array(ref mut indices)) = - raw_data_contract["documents"]["indexedDocument"].get_mut("indices") + if let Some(Value::Array(ref mut indices)) = raw_data_contract["documents"] + ["indexedDocument"] + .get_mut("indices") + .unwrap() { indices.push(index_definition) } @@ -2079,8 +2088,10 @@ mod indices { .. } = setup_test(); - if let Some(JsonValue::Array(ref mut index_properties)) = - raw_data_contract["documents"]["indexedDocument"]["indices"][0].get_mut("properties") + if let Some(Value::Array(ref mut index_properties)) = raw_data_contract["documents"] + ["indexedDocument"]["indices"][0] + .get_mut("properties") + .unwrap() { index_properties.push(platform_value!({ "missingProperty" : "asc"})) } else { @@ -2123,13 +2134,17 @@ mod indices { raw_data_contract["documents"]["indexedDocument"]["properties"]["objectProperty"] = object_property; - if let Some(JsonValue::Array(ref mut required)) = - raw_data_contract["documents"]["indexedDocument"].get_mut("required") + if let Some(Value::Array(ref mut required)) = raw_data_contract["documents"] + ["indexedDocument"] + .get_mut("required") + .unwrap() { required.push(platform_value!("objectProperty")) } - if let Some(JsonValue::Array(ref mut properties)) = - raw_data_contract["documents"]["indexedDocument"]["indices"][0].get_mut("properties") + if let Some(Value::Array(ref mut properties)) = raw_data_contract["documents"] + ["indexedDocument"]["indices"][0] + .get_mut("properties") + .unwrap() { properties.push(platform_value!({"objectProperty" : "asc" })) } @@ -2564,7 +2579,7 @@ mod indices { ] }); - if let Some(JsonValue::Array(ref mut indices)) = + if let Some(Value::Array(ref mut indices)) = raw_data_contract["documents"]["indexedDocument"].get_mut("indices") { indices.push(index_definition) diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index bdf68dccd35..09bcfa9e07b 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -22,6 +22,7 @@ use crate::{ version::{ProtocolVersionValidator, LATEST_VERSION}, }; +use crate::document::document_transition::document_base_transition::JsonValue; use jsonschema::error::ValidationErrorKind; use platform_value::{platform_value, Value}; use test_case::test_case; @@ -120,7 +121,7 @@ async fn property_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::Text(missing_property) + property: JsonValue::String(missing_property) } if missing_property == property )); } @@ -424,8 +425,8 @@ async fn property_in_document_transition_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::Text(missing_property) - } if missing_property == property + property: JsonValue::String(missing_property) + } if missing_property.into::() == property )); } @@ -709,7 +710,7 @@ async fn property_in_replace_transition_should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::Text(missing_property) + property: JsonValue::String(missing_property) } if missing_property == property )); } @@ -815,7 +816,7 @@ async fn id_should_be_present_in_delete_transition() { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::Text(missing_property) + property: JsonValue::String(missing_property) } if missing_property == "$id" )); } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index e48d3c8cdb7..506b2181451 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -1,7 +1,6 @@ +use platform_value::Value; use std::sync::Arc; -use serde_json::Value; - use crate::bls::NativeBlsModule; use crate::identity::state_transition::asset_lock_proof::{ AssetLockProofValidator, AssetLockTransactionValidator, ChainAssetLockProofStructureValidator, @@ -110,7 +109,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), state_repository, ); - raw_state_transition.remove_key("protocolVersion"); + raw_state_transition.remove("protocolVersion").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -138,7 +137,9 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_key_value("protocolVersion", "1"); + raw_state_transition + .set_into_value("protocolVersion", "1") + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -160,7 +161,9 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_key_value("protocolVersion", -1); + raw_state_transition + .set_into_value("protocolVersion", -1) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -231,7 +234,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_key_value("type", 666); + raw_state_transition.set_into_value("type", 666).unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -372,7 +375,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.remove_key("publicKeys"); + raw_state_transition.remove("publicKeys").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -401,7 +404,9 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_key_value("publicKeys", Vec::::new()); + raw_state_transition + .set_into_value("publicKeys", Vec::::new()) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) diff --git a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs index 5729dd838a6..11e9d4bbbd9 100644 --- a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs @@ -86,12 +86,12 @@ pub mod protocol_version { pub mod id { use jsonschema::error::ValidationErrorKind; - use serde_json::Value; + use platform_value::Value; + use serde_json::Value as JsonValue; use crate::assert_consensus_errors; use crate::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::serde_set; #[test] pub fn should_be_present() { @@ -169,7 +169,6 @@ pub mod balance { use crate::assert_consensus_errors; use crate::errors::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::serde_set; #[test] pub fn should_be_present() { @@ -232,7 +231,6 @@ pub mod public_keys { use crate::assert_consensus_errors; use crate::errors::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::serde_set; use jsonschema::error::ValidationErrorKind; use platform_value::Value; @@ -347,7 +345,6 @@ pub mod revision { use crate::assert_consensus_errors; use crate::errors::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::serde_set; // revision tests #[test] diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index f2a1ab47723..435b5989e35 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -10,14 +10,8 @@ use platform_value::{platform_value, Value}; fn setup_test() -> (Vec, PublicKeysValidator) { ( crate::tests::fixtures::identity_fixture_raw_object() - .to_() - .unwrap() - .get("publicKeys") - .unwrap() - .clone() - .as_array_mut() - .unwrap() - .clone(), + .get_array("publicKeys") + .unwrap(), get_public_keys_validator(), ) } @@ -28,6 +22,7 @@ pub mod id { use crate::assert_consensus_errors; use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; + use crate::identity::KeyID; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; use crate::tests::utils::platform_value_set_ref; use crate::tests::utils::SerdeTestExtension; @@ -38,7 +33,7 @@ pub mod id { raw_public_keys .get_mut(1) .unwrap() - .remove_integer("id") + .remove_integer::("id") .unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); @@ -168,11 +163,11 @@ pub mod data { #[test] pub fn should_be_a_byte_array() { let (mut raw_public_keys, validator) = setup_test(); - platform_value_set_ref( - raw_public_keys.get_mut(1).unwrap(), - "data", - vec!["string"; 33], - ); + raw_public_keys + .get_mut(1) + .unwrap() + .set_into_value("data", vec!["string"; 33]) + .unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); @@ -337,11 +332,8 @@ pub fn should_return_invalid_result_if_there_are_duplicate_key_ids() { let (mut raw_public_keys, validator) = setup_test(); let key0 = raw_public_keys.get(0).unwrap().clone(); let key1 = raw_public_keys.get_mut(1).unwrap(); - platform_value_set_ref( - key1, - "id", - key0.to_map().unwrap().get_integer("id").unwrap().clone(), - ); + key1.set_value("id", key0.get_value("id").unwrap().clone()) + .unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); @@ -356,9 +348,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_key_ids() { let expected_ids = vec![raw_public_keys .get(1) .unwrap() - .as_map() - .unwrap() - .get_integer("id") + .get_integer::("id") .unwrap() as KeyID]; assert_eq!(consensus_error.code(), 1030); @@ -370,11 +360,8 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { let (mut raw_public_keys, validator) = setup_test(); let key0 = raw_public_keys.get(0).unwrap().clone(); let key1 = raw_public_keys.get_mut(1).unwrap(); - platform_value_set_ref( - key1, - "data", - key0.as_map().unwrap().get("data").unwrap().clone(), - ); + key1.set_value("data", key0.get_value("data").unwrap()) + .expect("expected to set data"); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!( @@ -389,12 +376,8 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { let expected_ids = vec![raw_public_keys .get(1) .unwrap() - .as_map() - .unwrap() - .get("id") - .unwrap() - .as_u64() - .unwrap() as KeyID]; + .get_integer::("id") + .unwrap()]; assert_eq!(consensus_error.code(), 1029); assert_eq!(error.duplicated_public_keys_ids(), &expected_ids); @@ -403,7 +386,11 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { #[test] pub fn should_return_invalid_result_if_key_data_is_not_a_valid_der() { let (mut raw_public_keys, validator) = setup_test(); - platform_value_set_ref(raw_public_keys.get_mut(1).unwrap(), "data", vec![0; 33]); + raw_public_keys + .get_mut(1) + .unwrap() + .set_into_value("data", vec![0; 33]) + .expect("expected to set data"); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!( @@ -418,7 +405,7 @@ pub fn should_return_invalid_result_if_key_data_is_not_a_valid_der() { assert_eq!(consensus_error.code(), 1040); assert_eq!( error.public_key_id(), - raw_public_keys[1].get_integer("id").unwrap() as KeyID + raw_public_keys[1].get_integer::("id").unwrap() ); assert_eq!( error.validation_error().as_ref().unwrap().message(), @@ -463,7 +450,7 @@ pub fn should_return_invalid_result_if_key_has_an_invalid_combination_of_purpose ); assert_eq!( error.purpose() as u8, - raw_public_keys[1]..get_integer::("purpose").unwrap() + raw_public_keys[1].get_integer::("purpose").unwrap() ); } @@ -547,12 +534,8 @@ pub fn should_return_invalid_result_if_bls12_381_public_key_is_invalid() { raw_public_keys .get(0) .unwrap() - .to_map() - .unwrap() - .get_integer("id") + .get_integer::("id") .unwrap() - .as_u64() - .unwrap() as KeyID ); // TODO //assert_eq!(error.validation_error(), TypeError); diff --git a/packages/rs-dpp/src/util/serializer.rs b/packages/rs-dpp/src/util/serializer.rs index a933710207e..1f9cd4dddd0 100644 --- a/packages/rs-dpp/src/util/serializer.rs +++ b/packages/rs-dpp/src/util/serializer.rs @@ -1,4 +1,5 @@ use integer_encoding::VarIntWriter; +use serde::ser; use crate::errors::ProtocolError; @@ -6,8 +7,8 @@ use crate::errors::ProtocolError; pub const MAX_ENCODED_KBYTE_LENGTH: usize = 16; -pub fn value_to_cbor( - value: serde_json::Value, +pub fn serializable_value_to_cbor( + value: &T, protocol_version: Option, ) -> Result, ProtocolError> { let mut buffer: Vec = Vec::new(); @@ -18,7 +19,7 @@ pub fn value_to_cbor( } let size_with_protocol = buffer.len(); - ciborium::ser::into_writer(&value, &mut buffer) + ciborium::ser::into_writer(value, &mut buffer) .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; if (buffer.len() - size_with_protocol) >= MAX_ENCODED_KBYTE_LENGTH * 1024 { diff --git a/packages/rs-drive-abci/src/contracts/reward_shares.rs b/packages/rs-drive-abci/src/contracts/reward_shares.rs index 0048c49d4f9..9a9ee1325d1 100644 --- a/packages/rs-drive-abci/src/contracts/reward_shares.rs +++ b/packages/rs-drive-abci/src/contracts/reward_shares.rs @@ -72,8 +72,8 @@ impl Platform { ], }); - let query_cbor = - serializer::value_to_cbor(query_json, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) + .expect("expected to serialize to cbor"); let QueryDocumentsOutcome { items, .. } = self.drive.query_documents_cbor_with_document_type_lookup( diff --git a/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs index aafa293012f..71656e0bf6e 100644 --- a/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs @@ -311,8 +311,8 @@ mod tests { ["$ownerId", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( @@ -532,8 +532,8 @@ mod tests { ["$ownerId", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( @@ -660,8 +660,8 @@ mod tests { ["$ownerId", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( @@ -853,8 +853,8 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( @@ -876,8 +876,8 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( @@ -899,8 +899,8 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( @@ -1093,8 +1093,8 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( @@ -1116,8 +1116,8 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( @@ -1139,8 +1139,8 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (docs, _, _) = drive .query_documents_cbor_from_contract( diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 57f62490886..19384bbc81e 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -1691,8 +1691,8 @@ mod tests { ], }); - let query_cbor = - serializer::value_to_cbor(query_json, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) + .expect("expected to serialize to cbor"); drive .grove @@ -1732,8 +1732,8 @@ mod tests { ], }); - let query_cbor = - serializer::value_to_cbor(query_json, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) + .expect("expected to serialize to cbor"); let (results, _, _) = drive .query_documents_cbor_from_contract( diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 860befccd42..772b728061e 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -1141,8 +1141,9 @@ mod tests { }, }); - let contract = serializer::value_to_cbor(contract, Some(defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let contract = + serializer::serializable_value_to_cbor(&contract, Some(defaults::PROTOCOL_VERSION)) + .expect("expected to serialize to cbor"); drive .apply_contract_cbor( @@ -1171,7 +1172,7 @@ mod tests { }); let serialized_document = - serializer::value_to_cbor(document, Some(defaults::PROTOCOL_VERSION)) + serializer::serializable_value_to_cbor(&document, Some(defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); drive @@ -1204,7 +1205,7 @@ mod tests { }); let serialized_document = - serializer::value_to_cbor(document, Some(defaults::PROTOCOL_VERSION)) + serializer::serializable_value_to_cbor(&document, Some(defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); drive @@ -2084,8 +2085,9 @@ mod tests { transaction: TransactionArg, ) -> FeeResult { let value = serde_json::to_value(person).expect("serialized person"); - let document_cbor = serializer::value_to_cbor(value, Some(defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor = + serializer::serializable_value_to_cbor(&value, Some(defaults::PROTOCOL_VERSION)) + .expect("expected to serialize to cbor"); let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 047c8f6711c..a6fe3f1cc5f 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -1535,8 +1535,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect_err("all ranges must be on same field"); } @@ -1557,8 +1557,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type).expect_err( "fields of queries must of defined supported types (where, limit, orderBy...)", ); @@ -1581,8 +1581,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect_err("the query should not be created"); } @@ -1604,8 +1604,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect("the query should be created"); } @@ -1626,8 +1626,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect("query should be fine for a 255 byte long string"); } @@ -1652,8 +1652,8 @@ mod tests { ], }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, document_type) .expect("fields of queries length must be under 256 bytes long"); query @@ -1734,8 +1734,8 @@ mod tests { ], }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, document_type) .expect("The query itself should be valid for a null type"); query @@ -1761,8 +1761,8 @@ mod tests { ], }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, document_type) .expect("query should be valid for empty array"); @@ -1793,8 +1793,8 @@ mod tests { ], }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, document_type) .expect("query is valid for too many elements"); @@ -1821,8 +1821,8 @@ mod tests { ], }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); // The is actually valid, however executing it is not // This is in order to optimize query execution @@ -1850,8 +1850,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect_err("starts with can not start with an empty string"); } @@ -1871,8 +1871,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect_err("starts with can not start with an empty string"); } @@ -1892,8 +1892,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect_err("starts with can not start with an empty string"); } @@ -1913,8 +1913,8 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect_err("starts with can not start with an empty string"); } diff --git a/packages/rs-drive/src/query/test_index.rs b/packages/rs-drive/src/query/test_index.rs index 4efa6314f21..23744f084e7 100644 --- a/packages/rs-drive/src/query/test_index.rs +++ b/packages/rs-drive/src/query/test_index.rs @@ -80,8 +80,8 @@ mod tests { ["b", "==", "2"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect("query should be valid"); let index = query.find_best_index().expect("expected to find index"); @@ -92,8 +92,8 @@ mod tests { ["a", "==", "1"], ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect("query should be valid"); let index = query.find_best_index().expect("expected to find index"); @@ -110,8 +110,8 @@ mod tests { ["c", "==", "1"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, &document_type) .expect("query should be valid"); let error = query diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index 5154acdcc95..1421e9683e1 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -143,9 +143,11 @@ pub fn add_domains_to_contract( let domains = Domain::random_domains_in_parent(count, seed, "dash"); for domain in domains { let value = serde_json::to_value(domain).expect("serialized domain"); - let document_cbor = - serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor = serializer::serializable_value_to_cbor( + &value, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 1bfa70318cc..8c7ccabca4e 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -232,9 +232,11 @@ pub fn setup_family_tests(count: u32, with_batching: bool, seed: u64) -> (Drive, let people = Person::random_people(count, seed); for person in people { let value = serde_json::to_value(person).expect("serialized person"); - let document_cbor = - serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor = serializer::serializable_value_to_cbor( + &value, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); @@ -311,9 +313,11 @@ pub fn setup_family_tests_with_nulls( let people = PersonWithOptionalValues::random_people(count, seed); for person in people { let value = serde_json::to_value(person).expect("serialized person"); - let document_cbor = - serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor = serializer::serializable_value_to_cbor( + &value, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -389,9 +393,11 @@ pub fn setup_family_tests_only_first_name_index( let people = Person::random_people(count, seed); for person in people { let value = serde_json::to_value(person).expect("serialized person"); - let document_cbor = - serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor = serializer::serializable_value_to_cbor( + &value, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); @@ -501,9 +507,11 @@ pub fn add_domains_to_contract( let domains = Domain::random_domains_in_parent(count, seed, "dash"); for domain in domains { let value = serde_json::to_value(domain).expect("serialized domain"); - let document_cbor = - serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor = serializer::serializable_value_to_cbor( + &value, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -598,9 +606,11 @@ pub fn setup_dpns_test_with_data(path: &str) -> (Drive, Contract) { let domain_json: serde_json::Value = serde_json::from_str(&domain_json).expect("should parse json"); - let domain_cbor = - serializer::value_to_cbor(domain_json, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let domain_cbor = serializer::serializable_value_to_cbor( + &domain_json, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let domain = Document::from_cbor(&domain_cbor, None, None) .expect("expected to deserialize the document"); @@ -651,9 +661,11 @@ fn test_query_many() { let people = Person::random_people(10, 73409); for person in people { let value = serde_json::to_value(person).expect("serialized person"); - let document_cbor = - serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor = serializer::serializable_value_to_cbor( + &value, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -713,8 +725,8 @@ fn test_reference_proof_single_index() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -755,8 +767,8 @@ fn test_non_existence_reference_proof_single_index() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -817,8 +829,8 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -859,8 +871,8 @@ fn test_family_basic_queries() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -899,8 +911,8 @@ fn test_family_basic_queries() { ], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -955,8 +967,8 @@ fn test_family_basic_queries() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -998,8 +1010,8 @@ fn test_family_basic_queries() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1049,8 +1061,8 @@ fn test_family_basic_queries() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1089,8 +1101,8 @@ fn test_family_basic_queries() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1132,8 +1144,8 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1184,8 +1196,8 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1231,8 +1243,8 @@ fn test_family_basic_queries() { ["firstName", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1279,8 +1291,8 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1335,8 +1347,8 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1379,8 +1391,8 @@ fn test_family_basic_queries() { ["firstName", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1435,8 +1447,8 @@ fn test_family_basic_queries() { ["age", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1490,8 +1502,8 @@ fn test_family_basic_queries() { ["age", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1580,8 +1592,8 @@ fn test_family_basic_queries() { age: rng.gen_range(0..85), }; let serialized_person = serde_json::to_value(&fixed_person).expect("serialized person"); - let person_cbor = serializer::value_to_cbor( - serialized_person, + let person_cbor = serializer::serializable_value_to_cbor( + &serialized_person, Some(drive::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to serialize to cbor"); @@ -1630,8 +1642,8 @@ fn test_family_basic_queries() { age: rng.gen_range(0..85), }; let serialized_person = serde_json::to_value(&next_person).expect("serialized person"); - let person_cbor = serializer::value_to_cbor( - serialized_person, + let person_cbor = serializer::serializable_value_to_cbor( + &serialized_person, Some(drive::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to serialize to cbor"); @@ -1671,8 +1683,8 @@ fn test_family_basic_queries() { ], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1714,8 +1726,8 @@ fn test_family_basic_queries() { "orderBy": [["$id", "asc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1755,8 +1767,8 @@ fn test_family_basic_queries() { "orderBy": [["$id", "desc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1792,8 +1804,8 @@ fn test_family_basic_queries() { // let query_value = json!({}); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1819,8 +1831,8 @@ fn test_family_basic_queries() { "orderBy": [["$id", "desc"]] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1861,8 +1873,8 @@ fn test_family_basic_queries() { "orderBy": [["$ownerId", "desc"]] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1891,8 +1903,8 @@ fn test_family_basic_queries() { "orderBy": [["$ownerId", "asc"]] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1933,8 +1945,8 @@ fn test_family_basic_queries() { ], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (results, _, _) = drive .query_raw_documents_from_contract_cbor_using_cbor_encoded_query_with_cost( @@ -1957,8 +1969,8 @@ fn test_family_basic_queries() { "orderBy": [["$id", "asc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1987,8 +1999,8 @@ fn test_family_basic_queries() { "orderBy": [["$id", "asc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -2017,8 +2029,8 @@ fn test_family_basic_queries() { "orderBy": [["$id", "asc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -2100,8 +2112,8 @@ fn test_family_starts_at_queries() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -2155,8 +2167,8 @@ fn test_family_starts_at_queries() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -2204,8 +2216,8 @@ fn test_family_starts_at_queries() { ["firstName", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -2259,8 +2271,8 @@ fn test_family_starts_at_queries() { ["firstName", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -2312,7 +2324,7 @@ fn test_family_sql_query() { .expect("contract should have a person document type"); // Empty where clause - let query_cbor = serializer::value_to_cbor( + let query_cbor = serializer::serializable_value_to_cbor( json!({ "where": [], "limit": 100, @@ -2332,7 +2344,7 @@ fn test_family_sql_query() { assert_eq!(query1, query2); // Equality clause - let query_cbor = serializer::value_to_cbor( + let query_cbor = serializer::serializable_value_to_cbor( json!({ "where": [ ["firstName", "==", "Chris"] @@ -2350,7 +2362,7 @@ fn test_family_sql_query() { assert_eq!(query1, query2); // Less than - let query_cbor = serializer::value_to_cbor( + let query_cbor = serializer::serializable_value_to_cbor( json!({ "where": [ ["firstName", "<", "Chris"] @@ -2373,7 +2385,7 @@ fn test_family_sql_query() { assert_eq!(query1, query2); // Starts with - let query_cbor = serializer::value_to_cbor( + let query_cbor = serializer::serializable_value_to_cbor( json!({ "where": [ ["firstName", "StartsWith", "C"] @@ -2396,7 +2408,7 @@ fn test_family_sql_query() { assert_eq!(query1, query2); // Range combination - let query_cbor = serializer::value_to_cbor( + let query_cbor = serializer::serializable_value_to_cbor( json!({ "where": [ ["firstName", ">", "Chris"], @@ -2420,7 +2432,7 @@ fn test_family_sql_query() { // In clause let names = vec![String::from("a"), String::from("b")]; - let query_cbor = serializer::value_to_cbor( + let query_cbor = serializer::serializable_value_to_cbor( json!({ "where": [ ["firstName", "in", names] @@ -2486,8 +2498,8 @@ fn test_family_with_nulls_query() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -2596,8 +2608,8 @@ fn test_query_with_cached_contract() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let QueryDocumentsOutcome { items, .. } = drive .query_documents_cbor_with_document_type_lookup( @@ -2663,8 +2675,8 @@ fn test_dpns_query() { ["normalizedLabel", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -2710,8 +2722,8 @@ fn test_dpns_query() { ["normalizedLabel", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -2785,8 +2797,8 @@ fn test_dpns_query() { ["normalizedLabel", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -2839,8 +2851,8 @@ fn test_dpns_query() { ["normalizedLabel", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -2910,8 +2922,8 @@ fn test_dpns_query() { ["records.dashUniqueIdentityId", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -2962,8 +2974,8 @@ fn test_dpns_query() { ["records.dashUniqueIdentityId", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -3006,8 +3018,8 @@ fn test_dpns_query() { ["records.dashUniqueIdentityId", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -3040,8 +3052,8 @@ fn test_dpns_insertion_no_aliases() { "orderBy": [["records.dashUniqueIdentityId", "desc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() @@ -3093,8 +3105,8 @@ fn test_dpns_insertion_with_aliases() { "orderBy": [["records.dashUniqueIdentityId", "desc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() @@ -3183,8 +3195,8 @@ fn test_dpns_query_start_at() { ["normalizedLabel", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -3271,8 +3283,8 @@ fn test_dpns_query_start_after() { ["normalizedLabel", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -3359,8 +3371,8 @@ fn test_dpns_query_start_at_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -3447,8 +3459,8 @@ fn test_dpns_query_start_after_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -3516,9 +3528,11 @@ fn test_dpns_query_start_at_with_null_id() { }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); - let document_cbor0 = - serializer::value_to_cbor(value0, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor0 = serializer::serializable_value_to_cbor( + &value0, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document0 = Document::from_cbor(document_cbor0.as_slice(), None, None) .expect("document should be properly deserialized"); @@ -3561,9 +3575,11 @@ fn test_dpns_query_start_at_with_null_id() { }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); - let document_cbor1 = - serializer::value_to_cbor(value1, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor1 = serializer::serializable_value_to_cbor( + &value1, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document1 = Document::from_cbor(document_cbor1.as_slice(), None, None) .expect("document should be properly deserialized"); @@ -3638,8 +3654,8 @@ fn test_dpns_query_start_at_with_null_id() { ["normalizedLabel", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -3716,9 +3732,11 @@ fn test_dpns_query_start_after_with_null_id() { }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); - let document_cbor0 = - serializer::value_to_cbor(value0, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor0 = serializer::serializable_value_to_cbor( + &value0, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document0 = Document::from_cbor(document_cbor0.as_slice(), None, None) .expect("document should be properly deserialized"); @@ -3761,9 +3779,11 @@ fn test_dpns_query_start_after_with_null_id() { }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); - let document_cbor1 = - serializer::value_to_cbor(value1, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor1 = serializer::serializable_value_to_cbor( + &value1, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document1 = Document::from_cbor(document_cbor1.as_slice(), None, None) .expect("document should be properly deserialized"); @@ -3839,8 +3859,8 @@ fn test_dpns_query_start_after_with_null_id() { ["normalizedLabel", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -3919,9 +3939,11 @@ fn test_dpns_query_start_after_with_null_id_desc() { }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); - let document_cbor0 = - serializer::value_to_cbor(value0, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor0 = serializer::serializable_value_to_cbor( + &value0, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document0 = Document::from_cbor(document_cbor0.as_slice(), None, None) .expect("document should be properly deserialized"); @@ -3964,9 +3986,11 @@ fn test_dpns_query_start_after_with_null_id_desc() { }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); - let document_cbor1 = - serializer::value_to_cbor(value1, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor1 = serializer::serializable_value_to_cbor( + &value1, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document1 = Document::from_cbor(document_cbor1.as_slice(), None, None) .expect("document should be properly deserialized"); @@ -4052,8 +4076,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -4101,8 +4125,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -4150,8 +4174,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types() .get("domain") @@ -4297,8 +4321,8 @@ fn test_query_a_b_c_d_e_contract() { ] }); - let query_cbor = - serializer::value_to_cbor(query_json, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) + .expect("expected to serialize to cbor"); drive .query_documents_cbor_from_contract( diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index e30b602561f..f81ce4c84cb 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -226,9 +226,11 @@ pub fn setup( } } let value = serde_json::to_value(person).expect("serialized person"); - let document_cbor = - serializer::value_to_cbor(value, Some(drive::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let document_cbor = serializer::serializable_value_to_cbor( + &value, + Some(drive::drive::defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); let document = Document::from_cbor(document_cbor.as_slice(), None, None) .expect("document should be properly deserialized"); let document_type = contract @@ -322,8 +324,8 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -359,8 +361,8 @@ fn test_query_historical() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -388,8 +390,8 @@ fn test_query_historical() { ], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -432,8 +434,8 @@ fn test_query_historical() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -463,8 +465,8 @@ fn test_query_historical() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -502,8 +504,8 @@ fn test_query_historical() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -530,8 +532,8 @@ fn test_query_historical() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -561,8 +563,8 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -607,8 +609,8 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -649,8 +651,8 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -725,8 +727,8 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -775,8 +777,8 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -819,8 +821,8 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -857,8 +859,8 @@ fn test_query_historical() { ["firstName", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -928,8 +930,8 @@ fn test_query_historical() { ["age", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -978,8 +980,8 @@ fn test_query_historical() { ["age", "desc"] ] }); - let where_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() .get("person") @@ -1063,8 +1065,8 @@ fn test_query_historical() { age: rng.gen_range(0..85), }; let serialized_person = serde_json::to_value(&fixed_person).expect("serialized person"); - let person_cbor = serializer::value_to_cbor( - serialized_person, + let person_cbor = serializer::serializable_value_to_cbor( + &serialized_person, Some(drive::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to serialize to cbor"); @@ -1114,8 +1116,8 @@ fn test_query_historical() { age: rng.gen_range(0..85), }; let serialized_person = serde_json::to_value(&next_person).expect("serialized person"); - let person_cbor = serializer::value_to_cbor( - serialized_person, + let person_cbor = serializer::serializable_value_to_cbor( + &serialized_person, Some(drive::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to serialize to cbor"); @@ -1155,8 +1157,8 @@ fn test_query_historical() { ], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1181,8 +1183,8 @@ fn test_query_historical() { ] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1208,8 +1210,8 @@ fn test_query_historical() { "blockTime": 300 }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1237,8 +1239,8 @@ fn test_query_historical() { "orderBy": [["$id", "asc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1278,8 +1280,8 @@ fn test_query_historical() { "orderBy": [["$id", "desc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1315,8 +1317,8 @@ fn test_query_historical() { // let query_value = json!({}); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1342,8 +1344,8 @@ fn test_query_historical() { "orderBy": [["$id", "desc"]] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1394,8 +1396,8 @@ fn test_query_historical() { "blockTime": 300 }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1448,8 +1450,8 @@ fn test_query_historical() { "orderBy": [["$ownerId", "desc"]] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1478,8 +1480,8 @@ fn test_query_historical() { "orderBy": [["$ownerId", "asc"]] }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1520,8 +1522,8 @@ fn test_query_historical() { ], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let (results, _, _) = drive .query_raw_documents_from_contract_cbor_using_cbor_encoded_query_with_cost( @@ -1545,8 +1547,8 @@ fn test_query_historical() { "orderBy": [["$id", "asc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() @@ -1575,8 +1577,8 @@ fn test_query_historical() { "orderBy": [["$id", "asc"]], }); - let query_cbor = - serializer::value_to_cbor(query_value, None).expect("expected to serialize to cbor"); + let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); let person_document_type = contract .document_types() diff --git a/packages/rs-platform-value/src/inner_array_value.rs b/packages/rs-platform-value/src/inner_array_value.rs new file mode 100644 index 00000000000..0481ccdf947 --- /dev/null +++ b/packages/rs-platform-value/src/inner_array_value.rs @@ -0,0 +1,7 @@ +use crate::{Error, Value}; + +impl Value { + pub fn push(&mut self, value: Value) -> Result<(), Error> { + self.to_array_mut().map(|array| array.push(value)) + } +} diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 7224fb5f953..d32cb1c63bc 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -13,16 +13,33 @@ impl Value { self.get_optional_value(key) } + pub fn get_mut<'a>(&'a mut self, key: &'a str) -> Result, Error> { + self.get_optional_value_mut(key) + } + pub fn get_value<'a>(&'a self, key: &'a str) -> Result<&'a Value, Error> { let map = self.to_map()?; Self::get_from_map(map, key) } + pub fn get_value_mut<'a>(&'a mut self, key: &'a str) -> Result<&'a mut Value, Error> { + let map = self.to_map_mut()?; + Self::get_mut_from_map(map, key) + } + pub fn get_optional_value<'a>(&'a self, key: &'a str) -> Result, Error> { let map = self.to_map()?; Ok(Self::get_optional_from_map(map, key)) } + pub fn get_optional_value_mut<'a>( + &'a mut self, + key: &'a str, + ) -> Result, Error> { + let map = self.to_map_mut()?; + Ok(Self::get_optional_mut_from_map(map, key)) + } + pub fn set_into_value(&mut self, key: &str, value: T) -> Result<(), Error> where T: Into, @@ -94,10 +111,7 @@ impl Value { value.into_hash256() } - pub fn remove_optional_hash256_bytes( - &mut self, - key: &str, - ) -> Result, Error> { + pub fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) .map(|v| v.into_hash256()) @@ -120,13 +134,13 @@ impl Value { pub fn remove_array(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; let value = map.remove_key(key)?; - value.to_array_owned() + value.into_array() } pub fn remove_optional_array(&mut self, key: &str) -> Result>, Error> { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) - .map(|v| v.to_array_owned()) + .map(|v| v.into_array()) .transpose() } @@ -457,6 +471,16 @@ impl Value { ))) } + pub fn get_mut_from_map<'a>( + map: &'a mut [(Value, Value)], + search_key: &'a str, + ) -> Result<&'a mut Value, Error> { + Self::get_optional_mut_from_map(map, search_key).ok_or(Error::StructureError(format!( + "{} not found in map", + search_key + ))) + } + /// Gets a value from a map pub fn get_optional_from_map<'a>( map: &'a [(Value, Value)], @@ -474,6 +498,23 @@ impl Value { None } + /// Gets a value from a map + pub fn get_optional_mut_from_map<'a>( + map: &'a mut [(Value, Value)], + search_key: &'a str, + ) -> Option<&'a mut Value> { + for (key, value) in map.iter_mut() { + if !key.is_text() { + continue; + } + + if key.as_text().expect("confirmed as text") == search_key { + return Some(value); + } + } + None + } + /// Inserts into a map /// If the element already existed it will replace it pub fn insert_in_map<'a>( diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index 1441bb0d8d6..92e073965cf 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -1,5 +1,6 @@ use crate::value_map::ValueMapHelper; use crate::{Error, Value}; +use std::collections::BTreeMap; impl Value { pub fn remove_value_at_path(&mut self, path: &str) -> Result { @@ -25,6 +26,16 @@ impl Value { map.remove_key(last_path_component) } + pub fn remove_values_at_paths<'a>( + &'a mut self, + paths: Vec<&'a str>, + ) -> Result, Error> { + paths + .into_iter() + .map(|path| Ok((path, self.remove_value_at_path(path)?))) + .collect() + } + pub fn get_value_at_path<'a>(&'a self, path: &'a str) -> Result<&'a Value, Error> { let split = path.split('.'); let mut current_value = self; diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index ed57fc30f41..8990e63098d 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -10,6 +10,7 @@ pub mod converter; pub mod display; mod error; mod index; +mod inner_array_value; pub mod inner_value; mod inner_value_at_path; mod macros; @@ -1219,3 +1220,20 @@ impl From for Value { Value::Text(v) } } + +impl From> for Value { + fn from(value: Vec<&str>) -> Self { + Value::Array(value.into_iter().map(|string| string.into()).collect()) + } +} + +impl From<&[&str]> for Value { + fn from(value: &[&str]) -> Self { + Value::Array( + value + .into_iter() + .map(|string| string.clone().into()) + .collect(), + ) + } +} From 55be6e04b0a34e07b4794a14a88402ebc87e0128 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 14 Mar 2023 17:34:48 +0700 Subject: [PATCH 113/228] more work --- .../rs-dpp/src/data_contract/data_contract.rs | 6 +- .../document_type/document_field.rs | 4 +- .../document_type/document_type.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- ...e_data_contract_update_transition_basic.rs | 51 ++++-------- .../validation/multi_validator.rs | 10 +-- .../validate_data_contract_max_depth.rs | 2 +- .../src/data_trigger/dpns_triggers/mod.rs | 2 +- packages/rs-dpp/src/document/document.rs | 4 +- .../rs-dpp/src/document/document_factory.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 4 +- .../document_base_transition.rs | 2 +- .../document_create_transition.rs | 6 +- .../document_replace_transition.rs | 4 +- .../document_transition/mod.rs | 2 +- .../documents_batch_transition/mod.rs | 4 +- ...lidate_documents_batch_transition_basic.rs | 2 +- .../validate_partial_compound_indices.rs | 2 +- .../asset_lock_proof_validator.rs | 9 ++- .../chain/chain_asset_lock_proof.rs | 22 +----- ...in_asset_lock_proof_structure_validator.rs | 16 ++-- ...nt_asset_lock_proof_structure_validator.rs | 47 +++-------- .../state_transition/asset_lock_proof/mod.rs | 6 +- .../identity_create_transition.rs | 2 +- ...ntity_create_transition_basic_validator.rs | 24 +++--- .../validate_public_keys.rs | 7 +- ...a_contract_update_transition_basic_spec.rs | 23 +++--- ..._documents_batch_transitions_basic_spec.rs | 2 +- .../tests/fixtures/get_documents_fixture.rs | 2 +- .../asset_lock/instant/mod.rs | 3 +- ..._create_transition_basic_validator_spec.rs | 9 ++- packages/rs-drive-abci/src/state/genesis.rs | 2 +- .../btreemap_mut_value_extensions.rs | 2 +- .../src/btreemap_extensions/mod.rs | 2 +- .../src/converter/serde_json.rs | 4 +- packages/rs-platform-value/src/inner_value.rs | 78 ++++++++++++++++++- packages/rs-platform-value/src/value_map.rs | 44 +++++------ .../src/document/extended_document.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 2 +- .../document_create_transition.rs | 2 +- .../document_replace_transition.rs | 2 +- packages/wasm-dpp/src/utils.rs | 2 +- 42 files changed, 218 insertions(+), 207 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 46f1ce09dc6..731b528db7a 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -112,7 +112,7 @@ impl DataContract { pub fn from_raw_object(raw_object: Value) -> Result { let mut data_contract_map = raw_object - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; let mutability = get_contract_configuration_properties(&data_contract_map) @@ -178,7 +178,7 @@ impl DataContract { json_value.replace_binary_paths(BINARY_FIELDS, ReplaceWith::Bytes)?; let value: Value = json_value.clone().into(); - let data_contract_map = value.into_btree_map().map_err(ProtocolError::ValueError)?; + let data_contract_map = value.into_btree_string_map().map_err(ProtocolError::ValueError)?; let mut data_contract: DataContract = serde_json::from_value(json_value)?; data_contract.generate_binary_properties(); @@ -569,7 +569,7 @@ pub fn get_definitions( .map(|definition_value| { definition_value .as_map() - .map(Value::map_ref_into_btree_map) + .map(Value::map_ref_into_btree_string_map) .transpose() }) .transpose()? diff --git a/packages/rs-dpp/src/data_contract/document_type/document_field.rs b/packages/rs-dpp/src/data_contract/document_type/document_field.rs index 385d462c8d1..e76628f302e 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_field.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_field.rs @@ -472,7 +472,7 @@ impl DocumentFieldType { DocumentFieldType::Object(inner_fields) => { if let Value::Map(map) = value { let mut value_map = - Value::map_into_btree_map(map).map_err(ProtocolError::ValueError)?; + Value::map_into_btree_string_map(map).map_err(ProtocolError::ValueError)?; let mut r_vec = vec![]; inner_fields.iter().try_for_each(|(key, field)| { if let Some(value) = value_map.remove(key) { @@ -608,7 +608,7 @@ impl DocumentFieldType { let Some(value_map) = value.as_map() else { return Err(get_field_type_matching_error()) }; - let value_map = Value::map_ref_into_btree_map(value_map)?; + let value_map = Value::map_ref_into_btree_string_map(value_map)?; let mut r_vec = vec![]; inner_fields.iter().try_for_each(|(key, field)| { if let Some(value) = value_map.get(key) { diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index 9be0712f56e..193c40a8e3c 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -364,7 +364,7 @@ fn insert_values( None => property_key, Some(prefix) => [prefix, property_key].join(".").to_owned(), }; - let mut inner_properties = property_value.to_btree_ref_map()?; + let mut inner_properties = property_value.to_btree_ref_string_map()?; let type_value = inner_properties .remove_optional_string(property_names::TYPE) .map_err(ProtocolError::ValueError)?; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index de3abc8dc69..7cb7f5dfdad 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -204,7 +204,7 @@ impl StateTransitionConvert for DataContractUpdateTransition { .try_for_each(|path| { object .remove_value_at_path(path) - .map_err(ProtocolError::ValueError) + .map_err(ProtocolError::ValueError).map(|_| ()) })?; } object.insert(String::from(DATA_CONTRACT), self.data_contract.to_object()?)?; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 57def77c640..0daa97032f7 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -26,6 +26,8 @@ use json_patch::PatchOperation; use lazy_static::lazy_static; use serde_json::{json, Value as JsonValue}; use std::sync::Arc; +use platform_value::Value; +use crate::tests::utils::SerdeTestExtension; use super::schema_compatibility_validator::validate_schema_compatibility; use super::schema_compatibility_validator::DiffVAlidatorError; @@ -68,25 +70,24 @@ where pub async fn validate( &self, - raw_state_transition: &JsonValue, + raw_state_transition: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result { let mut validation_result = SimpleValidationResult::default(); - let result = self.json_schema_validator.validate(raw_state_transition)?; + let result = self.json_schema_validator.validate(&raw_state_transition.try_into_validating_json().map_err(ProtocolError::ValueError)?)?; if !result.is_valid() { return Ok(result); } let protocol_version = match raw_state_transition - .get_u64(property_names::PROTOCOL_VERSION) - .and_then(|x| u32::try_from(x).map_err(Into::into)) + .get_integer(property_names::PROTOCOL_VERSION) { Ok(v) => v, Err(parsing_error) => { return Ok(SimpleValidationResult::new(Some(vec![ ConsensusError::ProtocolVersionParsingError(ProtocolVersionParsingError::new( - parsing_error, + parsing_error.into(), )), ]))) } @@ -98,13 +99,13 @@ where } // Validate Data Contract - let raw_data_contract = raw_state_transition.get_value(property_names::DATA_CONTRACT)?; - let result = self.data_contract_validator.validate(raw_data_contract)?; + let data_contract_object = raw_state_transition.get_value(property_names::DATA_CONTRACT)?; + let result = self.data_contract_validator.validate(data_contract_object)?; if !result.is_valid() { return Ok(result); } - let raw_data_contract_id = raw_data_contract.get_bytes(contract_property_names::ID)?; + let raw_data_contract_id = data_contract_object.get_bytes(contract_property_names::ID)?; let data_contract_id = Identifier::from_bytes(&raw_data_contract_id)?; if execution_context.is_dry_run() { @@ -128,46 +129,26 @@ where } }; - let new_version = raw_data_contract.get_u64(contract_property_names::VERSION)? as u32; + let new_version = data_contract_object.get_integer(contract_property_names::VERSION)?; let old_version = existing_data_contract.version; if (new_version - old_version) != 1 { validation_result.add_error(BasicError::InvalidDataContractVersionError( InvalidDataContractVersionError::new(old_version + 1, new_version), )) } - let raw_existing_data_contract = existing_data_contract.to_json_object(false)?; + let mut existing_data_contract_object = existing_data_contract.to_object()?; - let mut old_base_data_contract = raw_existing_data_contract; - old_base_data_contract - .remove(contract_property_names::DEFINITIONS) - .ok(); - old_base_data_contract.remove(contract_property_names::DOCUMENTS)?; - old_base_data_contract.remove(contract_property_names::VERSION)?; - - replace_bytes_with_hex_string( - &[ - contract_property_names::ID, - contract_property_names::OWNER_ID, - ], - &mut old_base_data_contract, - )?; + existing_data_contract_object + .remove_many(&vec![contract_property_names::DEFINITIONS, contract_property_names::DOCUMENTS, contract_property_names::VERSION]).map_err(ProtocolError::ValueError)?; - let mut new_base_data_contract = raw_data_contract.clone(); + let mut new_base_data_contract = data_contract_object.clone(); new_base_data_contract .remove(contract_property_names::DEFINITIONS) .ok(); new_base_data_contract.remove(contract_property_names::DOCUMENTS)?; new_base_data_contract.remove(contract_property_names::VERSION)?; - replace_bytes_with_hex_string( - &[ - contract_property_names::ID, - contract_property_names::OWNER_ID, - ], - &mut new_base_data_contract, - )?; - let base_data_contract_diff = json_patch::diff(&old_base_data_contract, &new_base_data_contract); @@ -186,7 +167,7 @@ where // Schema should be backward compatible let old_schema = &existing_data_contract.documents; - let new_schema = raw_data_contract.get_value("documents")?; + let new_schema = data_contract_object.get_value("documents")?; for (document_type, document_schema) in old_schema.iter() { let new_document_schema = new_schema.get(document_type).unwrap_or(&EMPTY_JSON); @@ -217,7 +198,7 @@ where } // check indices are not changed - let new_documents = raw_data_contract + let new_documents = data_contract_object .get_value("documents")? .as_object() .ok_or_else(|| anyhow!("the 'documents' property is not an array"))?; diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index ba7d81d833c..1cbb569c075 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -2,11 +2,7 @@ use platform_value::Value; use regex::Regex; use crate::consensus::basic::data_contract::IncompatibleRe2PatternError; -use crate::{ - consensus::{basic::BasicError, ConsensusError}, - validation::ValidationResult, - NonConsensusError, ProtocolError, -}; +use crate::{consensus::{basic::BasicError, ConsensusError}, validation::ValidationResult, NonConsensusError, ProtocolError, SerdeParsingError}; pub type SubValidator = fn(path: &str, key: &str, parent: &Value, value: &Value, result: &mut ValidationResult<()>); @@ -28,9 +24,7 @@ pub fn validate(raw_data_contract: &Value, validators: &[SubValidator]) -> Valid validator(&path, key, value, current_value, &mut result); } } else { - result.add_error(ConsensusError::SerializedObjectParsingError( - "keys of properties must be strings".to_string(), - )); + result.add_error(NonConsensusError::SerdeParsingError(SerdeParsingError::new("keys of properties must be strings"))); } } } diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index 8bafa2e41b1..cb348bf2096 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -90,7 +90,7 @@ fn calc_max_depth(value: &Value) -> Result { fn resolve_uri<'a>(value: &'a Value, uri: &str) -> Result<&'a Value, ProtocolError> { if !uri.starts_with("#/") { - bail!("only local references are allowed") + return Err(ProtocolError::Generic("only local references are allowed".to_string())); } let string_path = uri.strip_prefix("#/").unwrap().replace('/', "."); diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 0cb18e54b13..98093d008fa 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -69,7 +69,7 @@ where let records = data .get(PROPERTY_RECORDS) .ok_or_else(|| anyhow!("property '{}' doesn't exist", PROPERTY_RECORDS))? - .to_btree_ref_map() + .to_btree_ref_string_map() .map_err(ProtocolError::ValueError)?; let rule_allow_subdomains = data diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index c33884c5595..b18b032e24d 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -471,14 +471,14 @@ impl Document { let platform_value: Value = document_value.into(); document.properties = platform_value - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; Ok(document) } pub fn from_platform_value(document_value: Value) -> Result { let mut properties = document_value - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; let mut document = Self { ..Default::default() diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 60d01602f05..5ee8ca5bf37 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -152,7 +152,7 @@ where let document = Document { id: document_id.to_buffer(), owner_id: owner_id.to_buffer(), - properties: data.into_btree_map().map_err(ProtocolError::ValueError)?, + properties: data.into_btree_string_map().map_err(ProtocolError::ValueError)?, revision, created_at, updated_at, diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index b901ba6872a..00c568587f0 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -140,7 +140,7 @@ impl ExtendedDocument { data_contract: DataContract, ) -> Result { let mut properties = document_value - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; let document_type_name = properties .remove_string(property_names::DOCUMENT_TYPE) @@ -173,7 +173,7 @@ impl ExtendedDocument { data_contract: DataContract, ) -> Result { let mut properties = document_value - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; let document_type_name = properties .remove_string(property_names::DOCUMENT_TYPE) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index 4eb5e77a66c..11beb54e512 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -148,7 +148,7 @@ impl DocumentTransitionObjectLike for DocumentBaseTransition { data_contract: DataContract, ) -> Result { let map = raw_transition - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; Self::from_value_map(map, data_contract) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 600cd4a79f6..992a0b30e94 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -115,7 +115,7 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { data_contract: DataContract, ) -> Result { let value: Value = json_value.into(); - let mut map = value.into_btree_map().map_err(ProtocolError::ValueError)?; + let mut map = value.into_btree_string_map().map_err(ProtocolError::ValueError)?; let document_type = map.get_str("$type")?; @@ -145,7 +145,7 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { data_contract: DataContract, ) -> Result { let map = raw_transition - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; Self::from_value_map(map, data_contract) } @@ -342,7 +342,7 @@ mod test { let object_transition = document .to_object() .expect("no errors") - .into_btree_map() + .into_btree_string_map() .unwrap(); assert_eq!(object_transition.get_identifier_bytes("$id").unwrap(), id); assert_eq!( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 4fb8e658355..b70a3a24728 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -112,7 +112,7 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { data_contract: DataContract, ) -> Result { let value: Value = json_value.into(); - let mut map = value.into_btree_map().map_err(ProtocolError::ValueError)?; + let mut map = value.into_btree_string_map().map_err(ProtocolError::ValueError)?; let document_type = map.get_str("$type")?; @@ -137,7 +137,7 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { data_contract: DataContract, ) -> Result { let map = raw_transition - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; Self::from_value_map(map, data_contract) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index 2d40d68566f..885909bf8e0 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -128,7 +128,7 @@ impl DocumentTransitionObjectLike for DocumentTransition { Self: Sized, { let map = raw_transition - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; Self::from_value_map(map, data_contract) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 357eda4531a..277812f3642 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -157,7 +157,7 @@ impl DocumentsBatchTransition { data_contracts: Vec, ) -> Result { let map = raw_object - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; Self::from_value_map(map, data_contracts) } @@ -195,7 +195,7 @@ impl DocumentsBatchTransition { for raw_transition in raw_transitions { let mut raw_transition_map = raw_transition - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; let data_contract_id = raw_transition_map.get_hash256_bytes(property_names::DATA_CONTRACT_ID)?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 8f862bea4bc..90ff60cda9f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -90,7 +90,7 @@ pub async fn validate_documents_batch_transition_basic( } let state_transition_map = raw_state_transition - .to_btree_ref_map() + .to_btree_ref_string_map() .map_err(ProtocolError::ValueError)?; let owner_id = Identifier::from( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs index 68c56455779..abae49bf100 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_partial_compound_indices.rs @@ -30,7 +30,7 @@ pub fn validate_partial_compound_indices<'a>( result.merge(validate_indices( &indices, document_type, - &transition.to_btree_ref_map()?, + &transition.to_btree_ref_string_map()?, )); } diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_proof_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_proof_validator.rs index 2202d31693c..e7f655f5f76 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_proof_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_proof_validator.rs @@ -1,3 +1,4 @@ +use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::{ AssetLockProof, AssetLockProofType, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator, PublicKeyHash, @@ -25,21 +26,21 @@ impl AssetLockProofValidator { pub async fn validate_structure( &self, - raw_asset_lock_proof: &serde_json::Value, + asset_lock_proof_object: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result, NonConsensusError> { - let asset_lock_type = AssetLockProof::type_from_raw_value(raw_asset_lock_proof); + let asset_lock_type = AssetLockProof::type_from_raw_value(asset_lock_proof_object); if let Some(proof_type) = asset_lock_type { match proof_type { AssetLockProofType::Instant => { self.instant_asset_lock_structure_validator - .validate(raw_asset_lock_proof, execution_context) + .validate(asset_lock_proof_object, execution_context) .await } AssetLockProofType::Chain => { self.chain_asset_lock_structure_validator - .validate(raw_asset_lock_proof, execution_context) + .validate(asset_lock_proof_object, execution_context) .await } } diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index a2c659af88b..853890731f7 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -10,9 +10,9 @@ use crate::{ pub struct ChainAssetLockProof { #[serde(rename = "type")] asset_lock_type: u8, - core_chain_locked_height: u32, + pub core_chain_locked_height: u32, #[serde(with = "BigArray")] - out_point: [u8; 36], + pub out_point: [u8; 36], } impl ChainAssetLockProof { @@ -30,24 +30,6 @@ impl ChainAssetLockProof { 1 } - /// Get Asset Lock proof core height - pub fn core_chain_locked_height(&self) -> u32 { - self.core_chain_locked_height - } - - pub fn set_core_chain_locked_height(&mut self, value: u32) { - self.core_chain_locked_height = value; - } - - /// Get out_point - pub fn out_point(&self) -> &[u8; 36] { - &self.out_point - } - - pub fn set_out_point(&mut self, out_point: [u8; 36]) { - self.out_point = out_point; - } - /// Create identifier pub fn create_identifier(&self) -> Result { let array = vec_to_array(hash(self.out_point).as_ref())?; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs index 9f816d1006a..f3f222e771a 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs @@ -7,7 +7,8 @@ use dashcore::hashes::Hash; use dashcore::OutPoint; use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; -use serde_json::Value; +use serde_json::Value as JsonValue; +use platform_value::Value; use crate::consensus::basic::identity::{ IdentityAssetLockTransactionIsNotFoundError, InvalidAssetLockProofCoreChainHeightError, @@ -23,7 +24,7 @@ use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::{DashPlatformProtocolInitError, NonConsensusError}; lazy_static! { - static ref CHAIN_ASSET_LOCK_PROOF_SCHEMA: Value = serde_json::from_str(include_str!( + static ref CHAIN_ASSET_LOCK_PROOF_SCHEMA: JsonValue = serde_json::from_str(include_str!( "../../../../schema/identity/stateTransition/assetLockProof/chainAssetLockProof.json" )) .unwrap(); @@ -71,21 +72,21 @@ where pub async fn validate( &self, - raw_asset_lock_proof: &Value, + asset_lock_proof_object: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result, NonConsensusError> { let mut result = ValidationResult::default(); - result.merge(self.json_schema_validator.validate(raw_asset_lock_proof)?); + result.merge(self.json_schema_validator.validate(&asset_lock_proof_object.try_to_validating_json()?)?); if !result.is_valid() { return Ok(result); } - let proof: ChainAssetLockProof = serde_json::from_value(raw_asset_lock_proof.clone()) + let proof: ChainAssetLockProof = platform_value::from_value(asset_lock_proof_object.clone()) .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; - let proof_core_chain_locked_height = proof.core_chain_locked_height(); + let proof_core_chain_locked_height = proof.core_chain_locked_height; let current_core_chain_locked_height = self .state_repository @@ -103,8 +104,7 @@ where return Ok(result); } - let out_point_buffer = proof.out_point(); - let out_point = OutPoint::consensus_decode(out_point_buffer.as_slice()) + let out_point = OutPoint::consensus_decode(proof.out_point.as_slice()) .map_err(|e| NonConsensusError::SerdeParsingError(e.to_string().into()))?; let output_index = out_point.vout; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs index 45277840e41..6d8852bdabe 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs @@ -3,7 +3,8 @@ use std::sync::Arc; use dashcore::consensus; use dashcore::InstantLock; use lazy_static::lazy_static; -use serde_json::Value; +use serde_json::Value as JsonValue; +use platform_value::Value; use crate::consensus::basic::identity::{ IdentityAssetLockProofLockedTransactionMismatchError, InvalidInstantAssetLockProofError, @@ -14,10 +15,10 @@ use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::util::json_value::JsonValueExt; use crate::validation::{JsonSchemaValidator, ValidationResult}; -use crate::{DashPlatformProtocolInitError, NonConsensusError, SerdeParsingError}; +use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError}; lazy_static! { - static ref INSTANT_ASSET_LOCK_PROOF_SCHEMA: Value = serde_json::from_str(include_str!( + static ref INSTANT_ASSET_LOCK_PROOF_SCHEMA: JsonValue = serde_json::from_str(include_str!( "../../../../schema/identity/stateTransition/assetLockProof/instantAssetLockProof.json" )) .unwrap(); @@ -54,35 +55,18 @@ where pub async fn validate( &self, - raw_asset_lock_proof: &Value, + asset_lock_proof_object: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result, NonConsensusError> { let mut result = ValidationResult::default(); - result.merge(self.json_schema_validator.validate(raw_asset_lock_proof)?); + result.merge(self.json_schema_validator.validate(&asset_lock_proof_object.try_to_validating_json()?)?); if !result.is_valid() { return Ok(result); } - let raw_is_lock: Vec = raw_asset_lock_proof - .as_object() - .ok_or_else(|| SerdeParsingError::new("Expected raw asset lock proof to be an object"))? - .get("instantLock") - .ok_or_else(|| { - SerdeParsingError::new("Expected raw asset lock to have property 'instantLock'") - })? - .as_array() - .ok_or_else(|| SerdeParsingError::new("Expected 'instantLock' to be an array"))? - .iter() - .map(|val| { - val.as_u64() - .ok_or_else(|| SerdeParsingError::new("Expected 'instantLock' to be an array")) - }) - .collect::, SerdeParsingError>>()? - .into_iter() - .map(|n| n as u8) - .collect(); + let raw_is_lock = asset_lock_proof_object.get_bytes("instantLock")?; let instant_lock = match consensus::deserialize::(&raw_is_lock) { Ok(instant_lock) => instant_lock, @@ -104,25 +88,16 @@ where return Ok(result); } - let tx_json_uint_array = raw_asset_lock_proof - .get_bytes("transaction") - .map_err(|err| SerdeParsingError::new(err.to_string()))?; + let tx_json_uint_array = asset_lock_proof_object + .get_bytes("transaction")?; - let output_index = raw_asset_lock_proof - .as_object() - .ok_or_else(|| SerdeParsingError::new("Expected asset lock to be an object"))? - .get("outputIndex") - .ok_or_else(|| { - SerdeParsingError::new("Expect asset lock to have a 'transaction field'") - })? - .as_u64() - .ok_or_else(|| SerdeParsingError::new("Expect outputIndex to be a number"))?; + let output_index = asset_lock_proof_object.get_integer("outputIndex")?; let validate_asset_lock_transaction_result = self .asset_lock_transaction_validator .validate( &tx_json_uint_array, - output_index as usize, + output_index, execution_context, ) .await?; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index e562c1e9120..33b2eaf6697 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -3,7 +3,7 @@ use std::convert::{TryFrom, TryInto}; use dashcore::Transaction; use serde::de::Error as DeError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde_json::{Error, Value as JsonValue}; +use serde_json::{Value as JsonValue}; pub use asset_lock_proof_validator::*; pub use asset_lock_public_key_hash_fetcher::*; @@ -133,8 +133,8 @@ impl AssetLockProof { } } - pub fn to_raw_object(&self) -> Result { - serde_json::to_value(self) + pub fn to_raw_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index be5235ad176..e111eca428f 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -97,7 +97,7 @@ impl IdentityCreateTransition { let mut state_transition = Self::default(); let mut transition_map = raw_state_transition - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError)?; if let Some(keys_value_array) = transition_map .remove_optional_inner_value_array::>(property_names::PUBLIC_KEYS) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs index e505dfe1f2a..2699530a9f0 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs @@ -1,7 +1,8 @@ use std::sync::Arc; use lazy_static::lazy_static; -use serde_json::Value; +use serde_json::Value as JsonValue; +use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::AssetLockProofValidator; use crate::identity::state_transition::validate_public_key_signatures::TPublicKeysSignaturesValidator; @@ -11,10 +12,11 @@ use crate::state_transition::state_transition_execution_context::StateTransition use crate::util::protocol_data::{get_protocol_version, get_raw_public_keys}; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::version::ProtocolVersionValidator; -use crate::{BlsModule, DashPlatformProtocolInitError, NonConsensusError, SerdeParsingError}; +use crate::{BlsModule, DashPlatformProtocolInitError, NonConsensusError, ProtocolError}; +use crate::identity::state_transition::identity_update_transition::identity_update_transition::property_names; lazy_static! { - static ref INDENTITY_CREATE_TRANSITION_SCHEMA: Value = serde_json::from_str(include_str!( + static ref INDENTITY_CREATE_TRANSITION_SCHEMA: JsonValue = serde_json::from_str(include_str!( "../../../../../schema/identity/stateTransition/identityCreate.json" )) .unwrap(); @@ -67,14 +69,10 @@ impl< pub async fn validate( &self, - raw_transition: &Value, + transition_object: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result, NonConsensusError> { - let mut result = self.json_schema_validator.validate(raw_transition)?; - - let identity_transition_map = raw_transition - .as_object() - .ok_or_else(|| SerdeParsingError::new("Expected identity to be a json object"))?; + let mut result = self.json_schema_validator.validate(&transition_object.into())?; if !result.is_valid() { return Ok(result); @@ -82,13 +80,13 @@ impl< result.merge( self.protocol_version_validator - .validate(get_protocol_version(identity_transition_map)?)?, + .validate(transition_object.get_integer(property_names::PROTOCOL_VERSION).map_err(ProtocolError::ValueError)?)?, ); if !result.is_valid() { return Ok(result); } - let public_keys = get_raw_public_keys(identity_transition_map)?; + let public_keys = transition_object.get_array_slice("publicKeys").map_err(ProtocolError::ValueError)?; result.merge(self.public_keys_validator.validate_keys(public_keys)?); if !result.is_valid() { return Ok(result); @@ -96,7 +94,7 @@ impl< result.merge( self.public_keys_signatures_validator - .validate_public_key_signatures(raw_transition, public_keys)?, + .validate_public_key_signatures(transition_object, public_keys)?, ); if !result.is_valid() { return Ok(result); @@ -114,7 +112,7 @@ impl< result.merge( self.asset_lock_proof_validator .validate_structure( - identity_transition_map + transition_object .get(ASSET_LOCK_PROOF_PROPERTY_NAME) .ok_or_else(|| { NonConsensusError::SerdeJsonError(String::from( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_public_keys.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_public_keys.rs index 296729bdc6d..57944ee0831 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_public_keys.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_public_keys.rs @@ -1,6 +1,7 @@ use anyhow::anyhow; use lazy_static::lazy_static; use serde_json::Value as JsonValue; +use platform_value::Value; use crate::{ identity::validation::{duplicated_key_ids, duplicated_keys, TPublicKeysValidator}, @@ -20,7 +21,7 @@ pub struct IdentityUpdatePublicKeysValidator {} impl TPublicKeysValidator for IdentityUpdatePublicKeysValidator { fn validate_keys( &self, - raw_public_keys: &[JsonValue], + raw_public_keys: &[Value], ) -> Result { validate_public_keys(raw_public_keys) .map_err(|e| crate::NonConsensusError::SerdeJsonError(e.to_string())) @@ -28,7 +29,7 @@ impl TPublicKeysValidator for IdentityUpdatePublicKeysValidator { } pub fn validate_public_keys( - raw_public_keys: &[JsonValue], + raw_public_keys: &[Value], ) -> Result { let mut validation_result = SimpleValidationResult::default(); @@ -47,7 +48,7 @@ pub fn validate_public_keys( let public_keys: Vec = raw_public_keys .iter() .cloned() - .map(serde_json::from_value) + .map(platform_value::from_value) .collect::>()?; // Check that there's not duplicates key ids in the state transition diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 69693cc8cd2..2d4a0c361a0 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -22,7 +22,8 @@ use crate::{ }; use jsonschema::error::ValidationErrorKind; -use serde_json::{json, Value}; +use serde_json::{json, Value as JsonValue}; +use platform_value::{platform_value, Value}; struct TestData { version_validator: ProtocolVersionValidator, @@ -88,7 +89,7 @@ async fn should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::Text(missing_property) + property: Value::String(missing_property) } if missing_property == property )); } @@ -109,7 +110,7 @@ async fn should_be_integer(property: &str) { ) .expect("validator should be created"); - raw_state_transition[property] = json!("1"); + raw_state_transition[property] = platform_value!("1"); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -138,7 +139,7 @@ async fn protocol_version_should_be_valid() { ) .expect("validator should be created"); - raw_state_transition[property_names::PROTOCOL_VERSION] = json!(-1); + raw_state_transition[property_names::PROTOCOL_VERSION] = platform_value!(-1); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -165,7 +166,7 @@ async fn type_should_be_equal_4() { ) .expect("validator should be created"); - raw_state_transition[property_names::TRANSITION_TYPE] = json!(666); + raw_state_transition[property_names::TRANSITION_TYPE] = platform_value!(666); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -196,7 +197,7 @@ async fn property_should_be_byte_array(property_name: &str) { .expect("validator should be created"); let array = ["string"; 32]; - raw_state_transition[property_name] = json!(array); + raw_state_transition[property_name] = platform_value!(array); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -232,7 +233,7 @@ async fn should_be_not_less_than_n_bytes(property_name: &str, n_bytes: usize) { .expect("validator should be created"); let array = vec![0u8; n_bytes - 1]; - raw_state_transition[property_name] = json!(array); + raw_state_transition[property_name] = platform_value!(array); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -263,7 +264,7 @@ async fn should_be_not_longer_than_n_bytes(property_name: &str, n_bytes: usize) .expect("validator should be created"); let array = vec![0u8; n_bytes + 1]; - raw_state_transition[property_name] = json!(array); + raw_state_transition[property_name] = platform_value!(array); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -292,7 +293,7 @@ async fn signature_public_key_id_should_be_valid() { ) .expect("validator should be created"); - raw_state_transition[property_names::SIGNATURE_PUBLIC_KEY_ID] = json!(-1); + raw_state_transition[property_names::SIGNATURE_PUBLIC_KEY_ID] = platform_value!(-1); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -321,7 +322,7 @@ async fn should_allow_making_backward_compatible_changes() { .expect("validator should be created"); raw_state_transition[property_names::DATA_CONTRACT]["documents"]["indexedDocument"] - ["properties"]["newProp"] = json!({ + ["properties"]["newProp"] = platform_value!({ "type" : "integer", "minimum" : 0, @@ -350,7 +351,7 @@ async fn should_have_existing_documents_schema_backward_compatible() { .expect("validator should be created"); raw_state_transition[property_names::DATA_CONTRACT]["documents"]["niceDocument"]["required"] - .push(json!("name")) + .push(platform_value!("name")) .unwrap(); let result = validator diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 09bcfa9e07b..4bc8922acb5 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -426,7 +426,7 @@ async fn property_in_document_transition_should_be_present(property: &str) { schema_error.kind(), ValidationErrorKind::Required { property: JsonValue::String(missing_property) - } if missing_property.into::() == property + } if missing_property.into() == property )); } diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 098845888a7..82f6bd31bd1 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -141,7 +141,7 @@ pub fn get_withdrawal_document_fixture( let document_type = data_contract.document_type_for_name(document_types::WITHDRAWAL)?; let value: Value = data.into(); - let properties = value.into_btree_map().map_err(ProtocolError::ValueError)?; + let properties = value.into_btree_string_map().map_err(ProtocolError::ValueError)?; let id = Identifier::random(&mut rng); document_type.create_document_with_valid_properties(id, owner_id, properties) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs index 04408b40162..b498dc80ada 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs @@ -9,6 +9,7 @@ mod validate_instant_asset_lock_proof_structure_factory { use dashcore::{PrivateKey, Transaction}; use jsonschema::error::ValidationErrorKind; use serde_json::Value as JsonValue; + use platform_value::Value; use crate::assert_consensus_errors; use crate::consensus::ConsensusError; @@ -28,7 +29,7 @@ mod validate_instant_asset_lock_proof_structure_factory { struct TestData { pub validate_instant_asset_lock_proof_structure: InstantAssetLockProofStructureValidator, - pub raw_proof: JsonValue, + pub raw_proof: Value, pub transaction: Transaction, pub public_key_hash: Vec, pub state_repository_mock: Arc, diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index 506b2181451..3d17a584c37 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -206,7 +206,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.remove_key("type"); + raw_state_transition.remove("type").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) .await @@ -278,7 +278,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.remove_key("assetLockProof"); + raw_state_transition.remove("assetLockProof").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -307,7 +307,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_key_value("assetLockProof", 1); + raw_state_transition.set_into_value("assetLockProof", 1).unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -329,8 +329,9 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); + raw_state_transition.inser let st_map = raw_state_transition - .get_mut("assetLockProof") + .get_string_mut_ref_map("assetLockProof") .unwrap() .as_object_mut() .unwrap(); diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 35f516e8310..d0635e90f51 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -256,7 +256,7 @@ impl Platform { .into(); let document_stub_properties = document_stub_properties_value - .into_btree_map() + .into_btree_string_map() .map_err(|e| Error::Protocol(ProtocolError::ValueError(e)))?; let document_cbor = document.to_buffer()?; diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_mut_value_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_mut_value_extensions.rs index e4b5c1cd022..1bae247dc29 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_mut_value_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_mut_value_extensions.rs @@ -39,7 +39,7 @@ where .as_array_mut() .map(|vec| { vec.iter_mut() - .map(|v| v.to_ref_map_mut::()) + .map(|v| v.to_ref_string_map_mut::()) .collect::>() }) .ok_or_else(|| Error::StructureError(format!("{key} must be a an array"))) diff --git a/packages/rs-platform-value/src/btreemap_extensions/mod.rs b/packages/rs-platform-value/src/btreemap_extensions/mod.rs index 00a0441318d..fee49f10c2f 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/mod.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/mod.rs @@ -252,7 +252,7 @@ where .as_array() .map(|vec| { vec.iter() - .map(|v| v.to_ref_map::()) + .map(|v| v.to_ref_string_map::()) .collect::>() }) .ok_or_else(|| Error::StructureError(format!("{key} must be a an array"))) diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index d9ba27f47f0..09859568f9e 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -84,7 +84,7 @@ impl Value { } pub fn try_into_validating_btree_map_json(self) -> Result, Error> { - self.into_btree_map()? + self.into_btree_string_map()? .into_iter() .map(|(key, value)| Ok((key, value.try_into_validating_json()?))) .collect() @@ -345,7 +345,7 @@ impl BTreeValueJsonConverter for BTreeMap { fn from_json_value(value: JsonValue) -> Result { let platform_value: Value = value.into(); - platform_value.into_btree_map() + platform_value.into_btree_string_map() } } diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index d32cb1c63bc..e67bb95971c 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -63,6 +63,11 @@ impl Value { map.remove_key(key) } + pub fn remove_many(&mut self, keys: &Vec<&str>) -> Result<(), Error> { + let map = self.as_map_mut_ref()?; + keys.into_iter().try_for_each(|key| map.remove_key(key).map(|_| ())) + } + pub fn remove_optional_value(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; Ok(map.remove_optional_key(key)) @@ -208,6 +213,36 @@ impl Value { Self::inner_array(map, key) } + pub fn get_optional_string_ref_map<'a, I: FromIterator<(String, &'a Value)>>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Self::inner_optional_string_ref_map(map, key) + } + + pub fn get_string_ref_map<'a, I: FromIterator<(String, &'a Value)>>(&'a self, key: &'a str) -> Result { + let map = self.to_map()?; + Self::inner_string_ref_map(map, key) + } + + pub fn get_optional_string_mut_ref_map<'a, I: FromIterator<(String, &'a mut Value)>>(&'a mut self, key: &'a str) -> Result, Error> { + let map = self.to_map_mut()?; + Self::inner_optional_string_mut_ref_map(map, key) + } + + pub fn get_string_mut_ref_map<'a, I: FromIterator<(String, &'a mut Value)>>(&'a mut self, key: &'a str) -> Result { + let map = self.to_map_mut()?; + Self::inner_string_mut_ref_map(map, key) + } + + // pub fn get_array_into<'a, T: TryFrom>(&'a self, key: &'a str) -> Result, Error> { + // let map = self.to_map()?; + // Self::inner_array(map, key).and_then(|vec | vec.into_iter().map(|value| value.try_into()).collect::, Error>>()) + // } + // + // pub fn get_optional_array_into<'a, T: TryFrom>(&'a self, key: &'a str) -> Result>, Error> { + // let map = self.to_map()?; + // Self::inner_optional_array(map, key)?.map(|vec | vec.into_iter().map(|value| value.try_into()).collect::, Error>>()).transpose() + // } + pub fn get_optional_array_slice<'a>( &'a self, key: &'a str, @@ -318,6 +353,47 @@ impl Value { Self::get_from_map(document_type, key).map(|value| value.to_array_slice())? } + /// Gets the inner map from a map and converts it to a string map + pub fn inner_string_ref_map<'a, I: FromIterator<(String, &'a Value)>>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result { + Self::get_from_map(document_type, key).map(|value| value.to_ref_string_map())? + } + + /// Gets the inner map from a map and converts it to a string map + pub fn inner_optional_string_ref_map<'a, I: FromIterator<(String, &'a Value)>>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result, Error> { + let Some(key_value) = Self::get_optional_from_map(document_type, key) else { + return Ok(None); + }; + if let Value::Map(map_value) = key_value { + return Ok(Some(Value::map_ref_into_string_map(map_value)?)); + } + Ok(None) + } + + /// Gets the inner map from a map and converts it to a string map + pub fn inner_string_mut_ref_map<'a, I: FromIterator<(String, &'a mut Value)>>( + document_type: &'a mut [(Value, Value)], + key: &'a str, + ) -> Result { + Self::get_mut_from_map(document_type, key).map(|value| value.to_ref_string_map_mut())? + } + + /// Gets the inner map from a map and converts it to a string map + pub fn inner_optional_string_mut_ref_map<'a, I: FromIterator<(String, &'a mut Value)>>( + document_type: &'a mut [(Value, Value)], + key: &'a str, + ) -> Result, Error> { + let Some(key_value) = Self::get_optional_mut_from_map(document_type, key) else { + return Ok(None); + }; + Ok(Some(key_value.to_ref_string_map_mut()?)) + } + /// Gets the inner btree map from a map pub fn inner_optional_btree_map<'a>( document_type: &'a [(Value, Value)], @@ -327,7 +403,7 @@ impl Value { return Ok(None); }; if let Value::Map(map_value) = key_value { - return Ok(Some(Value::map_ref_into_btree_map(map_value)?)); + return Ok(Some(Value::map_ref_into_btree_string_map(map_value)?)); } Ok(None) } diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 089f64f758b..6236eb70891 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -104,13 +104,13 @@ impl Value { /// (Value::Text(String::from("key")), Value::Float(18.)), /// ] /// ); - /// assert_eq!(value.into_btree_map(), Ok(BTreeMap::from([(String::from("key"), Value::Float(18.))]))); + /// assert_eq!(value.into_btree_string_map(), Ok(BTreeMap::from([(String::from("key"), Value::Float(18.))]))); /// /// let value = Value::Bool(true); - /// assert_eq!(value.into_btree_map(), Err(Error::StructureError("value is not a map".to_string()))) + /// assert_eq!(value.into_btree_string_map(), Err(Error::StructureError("value is not a map".to_string()))) /// ``` - pub fn into_btree_map(self) -> Result, Error> { - Self::map_into_btree_map(self.into_map()?) + pub fn into_btree_string_map(self) -> Result, Error> { + Self::map_into_btree_string_map(self.into_map()?) } /// If the `Value` is a `Map`, returns a the associated `BTreeMap` data as `Ok`. @@ -125,13 +125,13 @@ impl Value { /// (Value::Text(String::from("key")), Value::Float(18.)), /// ] /// ); - /// assert_eq!(value.to_btree_ref_map(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))]))); + /// assert_eq!(value.to_btree_ref_string_map(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))]))); /// /// let value = Value::Bool(true); - /// assert_eq!(value.to_btree_ref_map(), Err(Error::StructureError("value is not a map".to_string()))) + /// assert_eq!(value.to_btree_ref_string_map(), Err(Error::StructureError("value is not a map".to_string()))) /// ``` - pub fn to_btree_ref_map(&self) -> Result, Error> { - Self::map_ref_into_btree_map(self.to_map_ref()?) + pub fn to_btree_ref_string_map(&self) -> Result, Error> { + Self::map_ref_into_btree_string_map(self.to_map_ref()?) } /// If the `Value` is a `Map`, returns a the associated `BTreeMap` data as `Ok`. @@ -146,15 +146,15 @@ impl Value { /// (Value::Text(String::from("key")), Value::Float(18.)), /// ] /// ); - /// assert_eq!(value.to_ref_map::>(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))]))); + /// assert_eq!(value.to_ref_string_map::>(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))]))); /// - /// assert_eq!(value.to_ref_map::>(), Ok(vec![(String::from("key"), &Value::Float(18.))])); + /// assert_eq!(value.to_ref_string_map::>(), Ok(vec![(String::from("key"), &Value::Float(18.))])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.to_ref_map::>(), Err(Error::StructureError("value is not a map".to_string()))) + /// assert_eq!(value.to_ref_string_map::>(), Err(Error::StructureError("value is not a map".to_string()))) /// ``` - pub fn to_ref_map<'a, I: FromIterator<(String, &'a Value)>>(&'a self) -> Result { - Self::map_ref_into_map(self.to_map_ref()?) + pub fn to_ref_string_map<'a, I: FromIterator<(String, &'a Value)>>(&'a self) -> Result { + Self::map_ref_into_string_map(self.to_map_ref()?) } /// If the `Value` is a `Map`, returns a the associated `BTreeMap` data as `Ok`. @@ -169,23 +169,23 @@ impl Value { /// (Value::Text(String::from("key")), Value::Float(18.)), /// ] /// ); - /// assert_eq!(value.to_ref_map_mut::>(), Ok(BTreeMap::from([(String::from("key"), &mut Value::Float(18.))]))); + /// assert_eq!(value.to_ref_string_map_mut::>(), Ok(BTreeMap::from([(String::from("key"), &mut Value::Float(18.))]))); /// - /// assert_eq!(value.to_ref_map_mut::>(), Ok(vec![(String::from("key"), &mut Value::Float(18.))])); + /// assert_eq!(value.to_ref_string_map_mut::>(), Ok(vec![(String::from("key"), &mut Value::Float(18.))])); /// /// let mut value = Value::Bool(true); - /// assert_eq!(value.to_ref_map_mut::>(), Err(Error::StructureError("value is not a map".to_string()))) + /// assert_eq!(value.to_ref_string_map_mut::>(), Err(Error::StructureError("value is not a map".to_string()))) /// ``` - pub fn to_ref_map_mut<'a, I: FromIterator<(String, &'a mut Value)>>( + pub fn to_ref_string_map_mut<'a, I: FromIterator<(String, &'a mut Value)>>( &'a mut self, ) -> Result { - Self::map_mut_ref_into_map(self.as_map_mut_ref()?) + Self::map_mut_ref_into_string_map(self.as_map_mut_ref()?) } /// Takes a ValueMap which is a `Vec<(Value, Value)>` /// Returns a BTreeMap as long as each Key is a String /// Returns `Err(Error::Structure("reason"))` otherwise. - pub fn map_into_btree_map(map: ValueMap) -> Result, Error> { + pub fn map_into_btree_string_map(map: ValueMap) -> Result, Error> { map.into_iter() .map(|(key, value)| { let key = key @@ -199,7 +199,7 @@ impl Value { /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>` /// Returns a BTreeMap as long as each Key is a String /// Returns `Err(Error::Structure("reason"))` otherwise. - pub fn map_ref_into_btree_map(map: &ValueMap) -> Result, Error> { + pub fn map_ref_into_btree_string_map(map: &ValueMap) -> Result, Error> { map.iter() .map(|(key, value)| { let key = key @@ -213,7 +213,7 @@ impl Value { /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>` /// Returns a BTreeMap as long as each Key is a String /// Returns `Err(Error::Structure("reason"))` otherwise. - pub fn map_ref_into_map<'a, I: FromIterator<(String, &'a Value)>>( + pub fn map_ref_into_string_map<'a, I: FromIterator<(String, &'a Value)>>( map: &'a ValueMap, ) -> Result { map.iter() @@ -229,7 +229,7 @@ impl Value { /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>` /// Returns a BTreeMap as long as each Key is a String /// Returns `Err(Error::Structure("reason"))` otherwise. - pub fn map_mut_ref_into_map<'a, I: FromIterator<(String, &'a mut Value)>>( + pub fn map_mut_ref_into_string_map<'a, I: FromIterator<(String, &'a mut Value)>>( map: &'a mut ValueMap, ) -> Result { map.iter_mut() diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index e6da180b428..09d200d6da0 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -145,7 +145,7 @@ impl ExtendedDocumentWasm { pub fn set_data(&mut self, d: JsValue) -> Result<(), JsValue> { let properties_as_value = d.with_serde_to_platform_value()?; self.0.document.properties = properties_as_value - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError) .with_js_error()?; Ok(()) diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index b01e8d5fc42..7f1469726b7 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -138,7 +138,7 @@ impl DocumentWasm { pub fn set_data(&mut self, d: JsValue) -> Result<(), JsValue> { let properties_as_value = d.with_serde_to_platform_value()?; self.0.properties = properties_as_value - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError) .with_js_error()?; Ok(()) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 2b58c81a079..07a14c7b779 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -166,7 +166,7 @@ impl DocumentCreateTransitionWasm { .map_err(ProtocolError::ValueError) .with_js_error()?; let map = value - .to_btree_ref_map() + .to_btree_ref_string_map() .map_err(ProtocolError::ValueError) .with_js_error()?; let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 75a2a59bf37..9435aa42e70 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -226,7 +226,7 @@ impl DocumentReplaceTransitionWasm { .map_err(ProtocolError::ValueError) .with_js_error()?; let map = value - .to_btree_ref_map() + .to_btree_ref_string_map() .map_err(ProtocolError::ValueError) .with_js_error()?; let js_value = json_value.serialize(&serde_wasm_bindgen::Serializer::json_compatible())?; diff --git a/packages/wasm-dpp/src/utils.rs b/packages/wasm-dpp/src/utils.rs index 612c76ecbd8..e6328b0c94b 100644 --- a/packages/wasm-dpp/src/utils.rs +++ b/packages/wasm-dpp/src/utils.rs @@ -44,7 +44,7 @@ impl ToSerdeJSONExt for JsValue { /// as `JsValue` must be stringified first fn with_serde_to_platform_value_map(&self) -> Result, JsValue> { self.with_serde_to_platform_value()? - .into_btree_map() + .into_btree_string_map() .map_err(ProtocolError::ValueError) .with_js_error() } From f95be9339b62f72b43cc66cba853b51c3139bc50 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Mar 2023 11:55:06 +0700 Subject: [PATCH 114/228] more work --- .../rs-dpp/src/data_contract/data_contract.rs | 4 +- .../data_contract_update_transition/mod.rs | 3 +- ...e_data_contract_update_transition_basic.rs | 45 +++++++----- .../validation/multi_validator.rs | 10 ++- .../validate_data_contract_max_depth.rs | 4 +- .../rs-dpp/src/document/document_factory.rs | 4 +- .../document_create_transition.rs | 4 +- .../document_replace_transition.rs | 4 +- .../documents_batch_transition/mod.rs | 17 ++--- packages/rs-dpp/src/errors/errors.rs | 2 + packages/rs-dpp/src/identity/core_script.rs | 6 ++ .../src/identity/identity_public_key/mod.rs | 17 +++++ .../asset_lock_proof_validator.rs | 2 +- ...in_asset_lock_proof_structure_validator.rs | 12 ++-- ...nt_asset_lock_proof_structure_validator.rs | 16 ++--- .../state_transition/asset_lock_proof/mod.rs | 2 +- .../identity_create_transition.rs | 2 - ...ntity_create_transition_basic_validator.rs | 19 +++-- ...tity_credit_withdrawal_transition_basic.rs | 55 +++++++-------- .../validate_public_keys.rs | 2 +- .../abstract_state_transition.rs | 9 ++- ...a_contract_update_transition_basic_spec.rs | 2 +- .../tests/fixtures/get_documents_fixture.rs | 4 +- ...ty_credit_withdrawal_transition_fixture.rs | 23 ++++--- .../asset_lock/instant/mod.rs | 2 +- ..._create_transition_basic_validator_spec.rs | 28 ++++---- ...credit_withdrawal_transition_basic_spec.rs | 3 +- ...e_identity_update_transition_basic_spec.rs | 8 +-- .../validate_public_keys.rs | 9 +-- packages/rs-dpp/src/util/deserializer.rs | 15 ++-- packages/rs-platform-value/src/inner_value.rs | 69 +++++++++++++++++-- packages/rs-platform-value/src/lib.rs | 24 +++++++ packages/rs-platform-value/src/value_map.rs | 8 ++- 33 files changed, 283 insertions(+), 151 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 731b528db7a..911149c5427 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -178,7 +178,9 @@ impl DataContract { json_value.replace_binary_paths(BINARY_FIELDS, ReplaceWith::Bytes)?; let value: Value = json_value.clone().into(); - let data_contract_map = value.into_btree_string_map().map_err(ProtocolError::ValueError)?; + let data_contract_map = value + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?; let mut data_contract: DataContract = serde_json::from_value(json_value)?; data_contract.generate_binary_properties(); diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 7cb7f5dfdad..7e23e3c5802 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -204,7 +204,8 @@ impl StateTransitionConvert for DataContractUpdateTransition { .try_for_each(|path| { object .remove_value_at_path(path) - .map_err(ProtocolError::ValueError).map(|_| ()) + .map_err(ProtocolError::ValueError) + .map(|_| ()) })?; } object.insert(String::from(DATA_CONTRACT), self.data_contract.to_object()?)?; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 0daa97032f7..f5b510ba406 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -7,6 +7,7 @@ use crate::consensus::basic::decode::ProtocolVersionParsingError; use crate::consensus::basic::invalid_data_contract_version_error::InvalidDataContractVersionError; use crate::consensus::ConsensusError; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use crate::tests::utils::SerdeTestExtension; use crate::{ consensus::basic::BasicError, data_contract::{ @@ -24,10 +25,9 @@ use anyhow::anyhow; use anyhow::Context; use json_patch::PatchOperation; use lazy_static::lazy_static; +use platform_value::Value; use serde_json::{json, Value as JsonValue}; use std::sync::Arc; -use platform_value::Value; -use crate::tests::utils::SerdeTestExtension; use super::schema_compatibility_validator::validate_schema_compatibility; use super::schema_compatibility_validator::DiffVAlidatorError; @@ -75,23 +75,26 @@ where ) -> Result { let mut validation_result = SimpleValidationResult::default(); - let result = self.json_schema_validator.validate(&raw_state_transition.try_into_validating_json().map_err(ProtocolError::ValueError)?)?; + let result = self.json_schema_validator.validate( + &raw_state_transition + .try_into_validating_json() + .map_err(ProtocolError::ValueError)?, + )?; if !result.is_valid() { return Ok(result); } - let protocol_version = match raw_state_transition - .get_integer(property_names::PROTOCOL_VERSION) - { - Ok(v) => v, - Err(parsing_error) => { - return Ok(SimpleValidationResult::new(Some(vec![ - ConsensusError::ProtocolVersionParsingError(ProtocolVersionParsingError::new( - parsing_error.into(), - )), - ]))) - } - }; + let protocol_version = + match raw_state_transition.get_integer(property_names::PROTOCOL_VERSION) { + Ok(v) => v, + Err(parsing_error) => { + return Ok(SimpleValidationResult::new(Some(vec![ + ConsensusError::ProtocolVersionParsingError( + ProtocolVersionParsingError::new(parsing_error.into()), + ), + ]))) + } + }; let result = self.protocol_version_validator.validate(protocol_version)?; if !result.is_valid() { @@ -100,7 +103,9 @@ where // Validate Data Contract let data_contract_object = raw_state_transition.get_value(property_names::DATA_CONTRACT)?; - let result = self.data_contract_validator.validate(data_contract_object)?; + let result = self + .data_contract_validator + .validate(data_contract_object)?; if !result.is_valid() { return Ok(result); } @@ -138,9 +143,13 @@ where } let mut existing_data_contract_object = existing_data_contract.to_object()?; - existing_data_contract_object - .remove_many(&vec![contract_property_names::DEFINITIONS, contract_property_names::DOCUMENTS, contract_property_names::VERSION]).map_err(ProtocolError::ValueError)?; + .remove_many(&vec![ + contract_property_names::DEFINITIONS, + contract_property_names::DOCUMENTS, + contract_property_names::VERSION, + ]) + .map_err(ProtocolError::ValueError)?; let mut new_base_data_contract = data_contract_object.clone(); new_base_data_contract diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 1cbb569c075..db08a5d10db 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -2,7 +2,11 @@ use platform_value::Value; use regex::Regex; use crate::consensus::basic::data_contract::IncompatibleRe2PatternError; -use crate::{consensus::{basic::BasicError, ConsensusError}, validation::ValidationResult, NonConsensusError, ProtocolError, SerdeParsingError}; +use crate::{ + consensus::{basic::BasicError, ConsensusError}, + validation::ValidationResult, + NonConsensusError, ProtocolError, SerdeParsingError, +}; pub type SubValidator = fn(path: &str, key: &str, parent: &Value, value: &Value, result: &mut ValidationResult<()>); @@ -24,7 +28,9 @@ pub fn validate(raw_data_contract: &Value, validators: &[SubValidator]) -> Valid validator(&path, key, value, current_value, &mut result); } } else { - result.add_error(NonConsensusError::SerdeParsingError(SerdeParsingError::new("keys of properties must be strings"))); + result.add_error(NonConsensusError::SerdeParsingError( + SerdeParsingError::new("keys of properties must be strings"), + )); } } } diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index cb348bf2096..3b6be104a86 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -90,7 +90,9 @@ fn calc_max_depth(value: &Value) -> Result { fn resolve_uri<'a>(value: &'a Value, uri: &str) -> Result<&'a Value, ProtocolError> { if !uri.starts_with("#/") { - return Err(ProtocolError::Generic("only local references are allowed".to_string())); + return Err(ProtocolError::Generic( + "only local references are allowed".to_string(), + )); } let string_path = uri.strip_prefix("#/").unwrap().replace('/', "."); diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 5ee8ca5bf37..cef41d68562 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -152,7 +152,9 @@ where let document = Document { id: document_id.to_buffer(), owner_id: owner_id.to_buffer(), - properties: data.into_btree_string_map().map_err(ProtocolError::ValueError)?, + properties: data + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?, revision, created_at, updated_at, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 992a0b30e94..e13b33d8849 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -115,7 +115,9 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { data_contract: DataContract, ) -> Result { let value: Value = json_value.into(); - let mut map = value.into_btree_string_map().map_err(ProtocolError::ValueError)?; + let mut map = value + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?; let document_type = map.get_str("$type")?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index b70a3a24728..e6ad667522d 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -112,7 +112,9 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { data_contract: DataContract, ) -> Result { let value: Value = json_value.into(); - let mut map = value.into_btree_string_map().map_err(ProtocolError::ValueError)?; + let mut map = value + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?; let document_type = map.get_str("$type")?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 277812f3642..f1e56f66182 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -376,27 +376,22 @@ impl StateTransitionConvert for DocumentsBatchTransition { } fn to_object(&self, skip_signature: bool) -> Result { - let mut json_object: Value = platform_value::to_value(self)?; - json_object.replace_at_paths( - Self::identifiers_property_paths(), - ReplacementType::Identifier, - )?; - + let mut object: Value = platform_value::to_value(self)?; if skip_signature { for path in Self::signature_property_paths() { - let _ = json_object.remove(path); + let _ = object.remove(path); } } let mut transitions = vec![]; for transition in self.transitions.iter() { - transitions.push(transition.to_object()?.try_into_validating_json().unwrap()) + transitions.push(transition.to_object()?) } - json_object.insert( + object.insert( String::from(property_names::TRANSITIONS), - JsonValue::Array(transitions), + Value::Array(transitions), )?; - Ok(json_object) + Ok(object) } fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index eddf3a2ba1f..14692f83f1b 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -34,6 +34,8 @@ pub enum ProtocolError { DecodingError(String), #[error("File not found Error - {0}")] FileNotFound(String), + #[error("unknown protocol version error {0}")] + UnknownProtocolVersionError(String), #[error("Not included or invalid protocol version")] NoProtocolVersionError, #[error("Parsing error: {0}")] diff --git a/packages/rs-dpp/src/identity/core_script.rs b/packages/rs-dpp/src/identity/core_script.rs index 892dedc8863..893ec8144cb 100644 --- a/packages/rs-dpp/src/identity/core_script.rs +++ b/packages/rs-dpp/src/identity/core_script.rs @@ -25,6 +25,12 @@ impl CoreScript { } } +impl From> for CoreScript { + fn from(value: Vec) -> Self { + CoreScript::from_bytes(value) + } +} + impl Deref for CoreScript { type Target = DashcoreScript; diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index a0215e6ed2b..44613a91706 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -11,6 +11,7 @@ use std::convert::TryInto; use anyhow::anyhow; use ciborium::value::Value as CborValue; use dashcore::PublicKey as ECDSAPublicKey; +use platform_value::Value; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; @@ -202,6 +203,22 @@ impl Into for &IdentityPublicKey { } } +impl TryInto for &IdentityPublicKey { + type Error = ProtocolError; + + fn try_into(self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } +} + +impl TryInto for IdentityPublicKey { + type Error = ProtocolError; + + fn try_into(self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } +} + pub fn de_base64_to_vec<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { let data: String = Deserialize::deserialize(d)?; base64::decode(data) diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_proof_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_proof_validator.rs index e7f655f5f76..fba2af98315 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_proof_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_proof_validator.rs @@ -1,4 +1,3 @@ -use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::{ AssetLockProof, AssetLockProofType, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator, PublicKeyHash, @@ -7,6 +6,7 @@ use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::validation::ValidationResult; use crate::NonConsensusError; +use platform_value::Value; pub struct AssetLockProofValidator { instant_asset_lock_structure_validator: InstantAssetLockProofStructureValidator, diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs index f3f222e771a..2c7d0bc7d85 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs @@ -6,9 +6,9 @@ use dashcore::hashes::hex::ToHex; use dashcore::hashes::Hash; use dashcore::OutPoint; use lazy_static::lazy_static; +use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use platform_value::Value; use crate::consensus::basic::identity::{ IdentityAssetLockTransactionIsNotFoundError, InvalidAssetLockProofCoreChainHeightError, @@ -77,14 +77,18 @@ where ) -> Result, NonConsensusError> { let mut result = ValidationResult::default(); - result.merge(self.json_schema_validator.validate(&asset_lock_proof_object.try_to_validating_json()?)?); + result.merge( + self.json_schema_validator + .validate(&asset_lock_proof_object.try_to_validating_json()?)?, + ); if !result.is_valid() { return Ok(result); } - let proof: ChainAssetLockProof = platform_value::from_value(asset_lock_proof_object.clone()) - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; + let proof: ChainAssetLockProof = + platform_value::from_value(asset_lock_proof_object.clone()) + .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; let proof_core_chain_locked_height = proof.core_chain_locked_height; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs index 6d8852bdabe..1ef974c19bd 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs @@ -3,8 +3,8 @@ use std::sync::Arc; use dashcore::consensus; use dashcore::InstantLock; use lazy_static::lazy_static; -use serde_json::Value as JsonValue; use platform_value::Value; +use serde_json::Value as JsonValue; use crate::consensus::basic::identity::{ IdentityAssetLockProofLockedTransactionMismatchError, InvalidInstantAssetLockProofError, @@ -60,7 +60,10 @@ where ) -> Result, NonConsensusError> { let mut result = ValidationResult::default(); - result.merge(self.json_schema_validator.validate(&asset_lock_proof_object.try_to_validating_json()?)?); + result.merge( + self.json_schema_validator + .validate(&asset_lock_proof_object.try_to_validating_json()?)?, + ); if !result.is_valid() { return Ok(result); @@ -88,18 +91,13 @@ where return Ok(result); } - let tx_json_uint_array = asset_lock_proof_object - .get_bytes("transaction")?; + let tx_json_uint_array = asset_lock_proof_object.get_bytes("transaction")?; let output_index = asset_lock_proof_object.get_integer("outputIndex")?; let validate_asset_lock_transaction_result = self .asset_lock_transaction_validator - .validate( - &tx_json_uint_array, - output_index, - execution_context, - ) + .validate(&tx_json_uint_array, output_index, execution_context) .await?; let validation_result_data = if validate_asset_lock_transaction_result.is_valid() { diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index 33b2eaf6697..e528ae2bdf6 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -3,7 +3,7 @@ use std::convert::{TryFrom, TryInto}; use dashcore::Transaction; use serde::de::Error as DeError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde_json::{Value as JsonValue}; +use serde_json::Value as JsonValue; pub use asset_lock_proof_validator::*; pub use asset_lock_public_key_hash_fetcher::*; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index e111eca428f..288fb65ee59 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -285,8 +285,6 @@ impl StateTransitionConvert for IdentityCreateTransition { fn to_json(&self, skip_signature: bool) -> Result { let mut json = serde_json::Value::Object(Default::default()); - // TODO: super.toJSON() - json.insert( property_names::TRANSITION_TYPE.to_string(), serde_json::Value::from(Self::get_type() as u8), diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs index 2699530a9f0..4426e112de7 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs @@ -1,10 +1,11 @@ use std::sync::Arc; use lazy_static::lazy_static; -use serde_json::Value as JsonValue; use platform_value::Value; +use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProofValidator; +use crate::identity::state_transition::identity_update_transition::identity_update_transition::property_names; use crate::identity::state_transition::validate_public_key_signatures::TPublicKeysSignaturesValidator; use crate::identity::validation::TPublicKeysValidator; use crate::state_repository::StateRepositoryLike; @@ -13,7 +14,6 @@ use crate::util::protocol_data::{get_protocol_version, get_raw_public_keys}; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::version::ProtocolVersionValidator; use crate::{BlsModule, DashPlatformProtocolInitError, NonConsensusError, ProtocolError}; -use crate::identity::state_transition::identity_update_transition::identity_update_transition::property_names; lazy_static! { static ref INDENTITY_CREATE_TRANSITION_SCHEMA: JsonValue = serde_json::from_str(include_str!( @@ -72,21 +72,28 @@ impl< transition_object: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result, NonConsensusError> { - let mut result = self.json_schema_validator.validate(&transition_object.into())?; + let mut result = self + .json_schema_validator + .validate(&transition_object.into())?; if !result.is_valid() { return Ok(result); } result.merge( - self.protocol_version_validator - .validate(transition_object.get_integer(property_names::PROTOCOL_VERSION).map_err(ProtocolError::ValueError)?)?, + self.protocol_version_validator.validate( + transition_object + .get_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)?, + )?, ); if !result.is_valid() { return Ok(result); } - let public_keys = transition_object.get_array_slice("publicKeys").map_err(ProtocolError::ValueError)?; + let public_keys = transition_object + .get_array_slice("publicKeys") + .map_err(ProtocolError::ValueError)?; result.merge(self.public_keys_validator.validate_keys(public_keys)?); if !result.is_valid() { return Ok(result); diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs index 34ccf4c9525..ebae1d172fb 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs @@ -1,7 +1,8 @@ use std::sync::Arc; use lazy_static::lazy_static; -use serde_json::Value; +use platform_value::Value; +use serde_json::Value as JsonValue; use crate::{ consensus::basic::identity::{ @@ -17,11 +18,11 @@ use crate::{ }, validation::{JsonSchemaValidator, ValidationResult}, version::ProtocolVersionValidator, - DashPlatformProtocolInitError, NonConsensusError, SerdeParsingError, + DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError, }; lazy_static! { - static ref INDENTITY_CREDIT_WITHDRAWAL_TRANSITION_SCHEMA: Value = + static ref INDENTITY_CREDIT_WITHDRAWAL_TRANSITION_SCHEMA: JsonValue = serde_json::from_str(include_str!( "../../../../../schema/identity/stateTransition/identityCreditWithdrawal.json" )) @@ -50,26 +51,24 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { pub async fn validate( &self, - transition_json: &Value, + transition_object: &Value, ) -> Result, NonConsensusError> { - let mut result = self.json_schema_validator.validate(transition_json)?; - - let identity_credit_withdrawal_transition_map = - transition_json.as_object().ok_or_else(|| { - SerdeParsingError::new( - "Expected identity credit withdrawal transition to be a json object", - ) - })?; + let mut result = self.json_schema_validator.validate( + &transition_object + .try_into_validating_json() + .map_err(ProtocolError::ValueError)?, + )?; if !result.is_valid() { return Ok(result); } result.merge( - self.protocol_version_validator - .validate(get_protocol_version( - identity_credit_withdrawal_transition_map, - )?)?, + self.protocol_version_validator.validate( + transition_object + .get_integer("protocolVersion") + .map_err(ProtocolError::ValueError)?, + )?, ); if !result.is_valid() { @@ -77,7 +76,9 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { } // validate pooling is always equals to 0 - let pooling = transition_json.get_u8(withdrawals_contract::property_names::POOLING)?; + let pooling = transition_object + .get_integer(withdrawals_contract::property_names::POOLING) + .map_err(ProtocolError::ValueError)?; if pooling > 0 { result.add_error( @@ -88,8 +89,9 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { } // validate core_fee is in fibonacci sequence - let core_fee_per_byte = - transition_json.get_u32(withdrawals_contract::property_names::CORE_FEE_PER_BYTE)?; + let core_fee_per_byte = transition_object + .get_integer(withdrawals_contract::property_names::CORE_FEE_PER_BYTE) + .map_err(ProtocolError::ValueError)?; if !is_fibonacci_number(core_fee_per_byte) { result.add_error(InvalidIdentityCreditWithdrawalTransitionCoreFeeError::new( @@ -100,18 +102,9 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { } // validate output_script types - let output_script_value = transition_json - .get(withdrawals_contract::property_names::OUTPUT_SCRIPT) - .ok_or_else(|| { - SerdeParsingError::new(format!( - "Expected credit withdrawal transition to have {} property", - withdrawals_contract::property_names::OUTPUT_SCRIPT - )) - })?; - - let output_script_bytes: Vec = serde_json::from_value(output_script_value.clone())?; - - let output_script = CoreScript::from_bytes(output_script_bytes); + let output_script: CoreScript = transition_object + .get_bytes_into(withdrawals_contract::property_names::OUTPUT_SCRIPT) + .map_err(ProtocolError::ValueError)?; if !output_script.is_p2pkh() && !output_script.is_p2sh() { result.add_error( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_public_keys.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_public_keys.rs index 57944ee0831..45daeb790fe 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_public_keys.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_public_keys.rs @@ -1,7 +1,7 @@ use anyhow::anyhow; use lazy_static::lazy_static; -use serde_json::Value as JsonValue; use platform_value::Value; +use serde_json::Value as JsonValue; use crate::{ identity::validation::{duplicated_key_ids, duplicated_keys, TPublicKeysValidator}, diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index a599eac3b70..98229121390 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -249,9 +249,12 @@ pub mod state_transition_helpers { skip_signature_paths: I, ) -> Result { let mut value: Value = platform_value::to_value(serializable)?; - skip_signature_paths - .into_iter() - .try_for_each(|path| value.remove_value_at_path(path))?; + skip_signature_paths.into_iter().try_for_each(|path| { + value + .remove_value_at_path(path) + .map_err(ProtocolError::ValueError) + .map(|_| ()) + })?; Ok(value) } } diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 2d4a0c361a0..73503f42a45 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -22,8 +22,8 @@ use crate::{ }; use jsonschema::error::ValidationErrorKind; -use serde_json::{json, Value as JsonValue}; use platform_value::{platform_value, Value}; +use serde_json::{json, Value as JsonValue}; struct TestData { version_validator: ProtocolVersionValidator, diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 82f6bd31bd1..245a4a61c64 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -141,7 +141,9 @@ pub fn get_withdrawal_document_fixture( let document_type = data_contract.document_type_for_name(document_types::WITHDRAWAL)?; let value: Value = data.into(); - let properties = value.into_btree_string_map().map_err(ProtocolError::ValueError)?; + let properties = value + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?; let id = Identifier::random(&mut rng); document_type.create_document_with_valid_properties(id, owner_id, properties) diff --git a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs index 6ce9abe37ab..7037164ad5e 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs @@ -1,6 +1,7 @@ use dashcore::{hashes::hex::FromHex, PubkeyHash, Script}; use platform_value::string_encoding::{encode, Encoding}; -use serde_json::{json, Value}; +use platform_value::{platform_value, Value}; +use serde_json::{json, Value as JsonValue}; use crate::{ identity::state_transition::identity_credit_withdrawal_transition::Pooling, @@ -8,21 +9,21 @@ use crate::{ }; pub fn identity_credit_withdrawal_transition_fixture_raw_object() -> Value { - json!({ - "protocolVersion": version::LATEST_VERSION, - "type": StateTransitionType::IdentityCreditWithdrawal, - "identityId": vec![1_u8; 32], - "amount": 1042, - "coreFeePerByte": 3, - "pooling": Pooling::Never, + platform_value!({ + "protocolVersion": version::LATEST_VERSION as u32, + "type": StateTransitionType::IdentityCreditWithdrawal as u8, + "identityId": Identifier::from([1_u8; 32]), + "amount": 1042u64, + "coreFeePerByte": 3u32, + "pooling": Pooling::Never as u8, "outputScript": Script::new_p2pkh(&PubkeyHash::from_hex("0000000000000000000000000000000000000000").unwrap()).to_bytes(), "signature": vec![0_u8; 65], - "signaturePublicKeyId": 0, - "revision": 1, + "signaturePublicKeyId": 0u32, + "revision": 1u32, }) } -pub fn identity_credit_withdrawal_transition_fixture_json() -> Value { +pub fn identity_credit_withdrawal_transition_fixture_json() -> JsonValue { json!({ "protocolVersion": version::LATEST_VERSION, "type": StateTransitionType::IdentityCreditWithdrawal, diff --git a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs index b498dc80ada..e8c7cad3b67 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs @@ -8,8 +8,8 @@ mod validate_instant_asset_lock_proof_structure_factory { use dashcore::Txid; use dashcore::{PrivateKey, Transaction}; use jsonschema::error::ValidationErrorKind; - use serde_json::Value as JsonValue; use platform_value::Value; + use serde_json::Value as JsonValue; use crate::assert_consensus_errors; use crate::consensus::ConsensusError; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index 3d17a584c37..2182b8d401b 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -307,7 +307,9 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_into_value("assetLockProof", 1).unwrap(); + raw_state_transition + .set_into_value("assetLockProof", 1) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -329,13 +331,13 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.inser - let st_map = raw_state_transition - .get_string_mut_ref_map("assetLockProof") - .unwrap() - .as_object_mut() + raw_state_transition + .set_value_at_path( + "assetLockProof", + "transaction", + "totally not a valid type".into(), + ) .unwrap(); - st_map.insert("transaction".into(), "totally not a valid type".into()); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -430,9 +432,8 @@ mod validate_identity_create_transition_basic_factory { MockStateRepositoryLike::new(), ); - let public_keys = raw_state_transition - .get_value_mut("publicKeys") - .as_array_mut() + let mut public_keys = raw_state_transition + .get_array_mut_ref("publicKeys") .unwrap(); let key = public_keys.first().unwrap().clone(); @@ -461,12 +462,11 @@ mod validate_identity_create_transition_basic_factory { MockStateRepositoryLike::new(), ); - let public_keys = raw_state_transition - .get_value_mut("publicKeys") - .as_array_mut() + let mut public_keys = raw_state_transition + .get_array_mut_ref("publicKeys") .unwrap(); let key = public_keys.first().unwrap().clone(); - public_keys.push(key.clone()); + public_keys.push(key); let result = validator .validate(&raw_state_transition, &Default::default()) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs index 253ad859f84..22f0ea2d1f6 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs @@ -1,6 +1,7 @@ use std::sync::Arc; -use serde_json::Value; +use platform_value::Value; +use serde_json::Value as JsonValue; use crate::{identity::state_transition::identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, tests::fixtures::identity_credit_withdrawal_transition_fixture_raw_object, version::ProtocolVersionValidator}; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs index ce88e1f7aed..9bdce486fe4 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs @@ -49,7 +49,7 @@ pub struct SignaturesValidatorMock {} impl TPublicKeysSignaturesValidator for SignaturesValidatorMock { fn validate_public_key_signatures<'a>( &self, - _raw_state_transition: &JsonValue, + _raw_state_transition: &Value, _raw_public_keys: impl IntoIterator, ) -> Result { Ok(SimpleValidationResult::default()) @@ -455,8 +455,7 @@ fn add_public_keys_should_not_have_more_than_10_items() { let _ = raw_state_transition.remove(property_names::DISABLE_PUBLIC_KEYS); let _ = raw_state_transition.remove(property_names::PUBLIC_KEYS_DISABLED_AT); - let public_keys_to_add: Vec = - (0..11).map(|_| raw_public_key_to_add.clone()).collect(); + let public_keys_to_add: Vec = (0..11).map(|_| raw_public_key_to_add.clone()).collect(); raw_state_transition[property_names::ADD_PUBLIC_KEYS] = platform_value!(public_keys_to_add); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = @@ -495,8 +494,7 @@ fn add_public_keys_should_be_unique() { let _ = raw_state_transition.remove(property_names::DISABLE_PUBLIC_KEYS); let _ = raw_state_transition.remove(property_names::PUBLIC_KEYS_DISABLED_AT); - let public_keys_to_add: Vec = - (0..2).map(|_| raw_public_key_to_add.clone()).collect(); + let public_keys_to_add: Vec = (0..2).map(|_| raw_public_key_to_add.clone()).collect(); raw_state_transition[property_names::ADD_PUBLIC_KEYS] = platform_value!(public_keys_to_add); let validator: ValidateIdentityUpdateTransitionBasic<_, SignaturesValidatorMock> = diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs index e47c7e670de..6c52c703eae 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs @@ -6,16 +6,17 @@ use crate::{ tests::{fixtures::identity_fixture, utils::get_state_error_from_result}, StateError, }; +use platform_value::Value; use serde_json::Value as JsonValue; struct TestData { - raw_public_keys: Vec, + raw_public_keys: Vec, identity: Identity, } fn setup_test() -> TestData { let identity = identity_fixture(); - let raw_public_keys: Vec = identity + let raw_public_keys: Vec = identity .public_keys .values() .map(|pk| pk.to_raw_json_object()) @@ -36,8 +37,8 @@ fn should_return_invalid_result_if_there_are_duplicate_key_ids() { } = setup_test(); raw_public_keys[1]["id"] = raw_public_keys[0]["id"].clone(); - let result = - validate_public_keys(&raw_public_keys).expect("the validation result should be returned"); + let result = validate_public_keys(raw_public_keys.as_slice()) + .expect("the validation result should be returned"); let state_error = get_state_error_from_result(&result, 0); diff --git a/packages/rs-dpp/src/util/deserializer.rs b/packages/rs-dpp/src/util/deserializer.rs index 6061e5fe05f..4a058b64c92 100644 --- a/packages/rs-dpp/src/util/deserializer.rs +++ b/packages/rs-dpp/src/util/deserializer.rs @@ -26,10 +26,9 @@ pub type ProtocolVersion = u32; pub fn get_protocol_version(version_bytes: &[u8]) -> Result { u32::decode_var(version_bytes) .ok_or_else(|| { - ConsensusError::ProtocolVersionParsingError(ProtocolVersionParsingError::new(anyhow!( - "length could not be decoded as a varint" - ))) - .into() + ProtocolError::UnknownProtocolVersionError( + "protocol version could not be decoded as a varint".to_string(), + ) }) .map(|(protocol_version, _size)| protocol_version) } @@ -48,11 +47,9 @@ pub fn split_protocol_version( message_bytes: &[u8], ) -> Result { let (protocol_version, protocol_version_size) = - u32::decode_var(message_bytes).ok_or(ProtocolError::AbstractConsensusError(Box::new( - ConsensusError::ProtocolVersionParsingError(ProtocolVersionParsingError::new(anyhow!( - "length could not be decoded as a varint" - ))), - )))?; + u32::decode_var(message_bytes).ok_or(ProtocolError::UnknownProtocolVersionError( + "protocol version could not be decoded as a varint".to_string(), + ))?; let (_, main_message_bytes) = message_bytes.split_at(protocol_version_size); if !check_protocol_version(protocol_version) { diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index e67bb95971c..845d207c42a 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -65,7 +65,8 @@ impl Value { pub fn remove_many(&mut self, keys: &Vec<&str>) -> Result<(), Error> { let map = self.as_map_mut_ref()?; - keys.into_iter().try_for_each(|key| map.remove_key(key).map(|_| ())) + keys.into_iter() + .try_for_each(|key| map.remove_key(key).map(|_| ())) } pub fn remove_optional_value(&mut self, key: &str) -> Result, Error> { @@ -210,25 +211,37 @@ impl Value { pub fn get_array<'a>(&'a self, key: &'a str) -> Result, Error> { let map = self.to_map()?; - Self::inner_array(map, key) + Self::inner_array_owned(map, key) } - pub fn get_optional_string_ref_map<'a, I: FromIterator<(String, &'a Value)>>(&'a self, key: &'a str) -> Result, Error> { + pub fn get_optional_string_ref_map<'a, I: FromIterator<(String, &'a Value)>>( + &'a self, + key: &'a str, + ) -> Result, Error> { let map = self.to_map()?; Self::inner_optional_string_ref_map(map, key) } - pub fn get_string_ref_map<'a, I: FromIterator<(String, &'a Value)>>(&'a self, key: &'a str) -> Result { + pub fn get_string_ref_map<'a, I: FromIterator<(String, &'a Value)>>( + &'a self, + key: &'a str, + ) -> Result { let map = self.to_map()?; Self::inner_string_ref_map(map, key) } - pub fn get_optional_string_mut_ref_map<'a, I: FromIterator<(String, &'a mut Value)>>(&'a mut self, key: &'a str) -> Result, Error> { + pub fn get_optional_string_mut_ref_map<'a, I: FromIterator<(String, &'a mut Value)>>( + &'a mut self, + key: &'a str, + ) -> Result, Error> { let map = self.to_map_mut()?; Self::inner_optional_string_mut_ref_map(map, key) } - pub fn get_string_mut_ref_map<'a, I: FromIterator<(String, &'a mut Value)>>(&'a mut self, key: &'a str) -> Result { + pub fn get_string_mut_ref_map<'a, I: FromIterator<(String, &'a mut Value)>>( + &'a mut self, + key: &'a str, + ) -> Result { let map = self.to_map_mut()?; Self::inner_string_mut_ref_map(map, key) } @@ -251,6 +264,16 @@ impl Value { Self::inner_optional_array_slice(map, key) } + pub fn get_array_ref<'a>(&'a self, key: &'a str) -> Result<&'a Vec, Error> { + let map = self.to_map()?; + Self::inner_array_ref(map, key) + } + + pub fn get_array_mut_ref<'a>(&'a mut self, key: &'a str) -> Result<&'a mut Vec, Error> { + let map = self.to_map_mut()?; + Self::inner_array_mut_ref(map, key) + } + pub fn get_array_slice<'a>(&'a self, key: &'a str) -> Result<&[Value], Error> { let map = self.to_map()?; Self::inner_array_slice(map, key) @@ -266,6 +289,19 @@ impl Value { Self::inner_bytes_value(map, key) } + pub fn get_bytes_into>>(&self, key: &str) -> Result { + let map = self.to_map()?; + Ok(Self::inner_bytes_value(map, key)?.into()) + } + + pub fn get_bytes_try_into, Error = Error>>( + &self, + key: &str, + ) -> Result { + let map = self.to_map()?; + Self::inner_bytes_value(map, key)?.try_into() + } + pub fn get_optional_hash256<'a>(&'a self, key: &'a str) -> Result, Error> { let map = self.to_map()?; Self::inner_optional_hash256_value(map, key) @@ -331,7 +367,26 @@ impl Value { } /// Retrieves the value of a key from a map if it's an array of strings. - pub fn inner_array(document_type: &[(Value, Value)], key: &str) -> Result, Error> { + pub fn inner_array_mut_ref<'a>( + document_type: &'a mut [(Value, Value)], + key: &'a str, + ) -> Result<&'a mut Vec, Error> { + Self::get_mut_from_map(document_type, key).map(|value| value.to_array_mut())? + } + + /// Retrieves the value of a key from a map if it's an array of strings. + pub fn inner_array_ref<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result<&'a Vec, Error> { + Self::get_from_map(document_type, key).map(|value| value.to_array_ref())? + } + + /// Retrieves the value of a key from a map if it's an array of strings. + pub fn inner_array_owned( + document_type: &[(Value, Value)], + key: &str, + ) -> Result, Error> { Self::get_from_map(document_type, key).map(|value| value.to_array_owned())? } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 8990e63098d..4924b0f0d0e 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -782,6 +782,30 @@ impl Value { } } + /// If the `Value` is a `Array`, returns a the associated `Vec<&Value>` array as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Value, Error}; + /// # + /// let mut value = Value::Array( + /// vec![ + /// Value::U64(17), + /// Value::Float(18.), + /// ] + /// ); + /// assert_eq!(value.to_array_ref(), Ok(&vec![Value::U64(17), Value::Float(18.)])); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_array_ref(), Err(Error::StructureError("value is not an array".to_string()))); + /// ``` + pub fn to_array_ref(&self) -> Result<&Vec, Error> { + match self { + Value::Array(vec) => Ok(vec), + _other => Err(Error::StructureError("value is not an array".to_string())), + } + } + /// If the `Value` is a `Array`, returns a the associated `Vec` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. /// diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 6236eb70891..fbb269b6820 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -153,7 +153,9 @@ impl Value { /// let value = Value::Bool(true); /// assert_eq!(value.to_ref_string_map::>(), Err(Error::StructureError("value is not a map".to_string()))) /// ``` - pub fn to_ref_string_map<'a, I: FromIterator<(String, &'a Value)>>(&'a self) -> Result { + pub fn to_ref_string_map<'a, I: FromIterator<(String, &'a Value)>>( + &'a self, + ) -> Result { Self::map_ref_into_string_map(self.to_map_ref()?) } @@ -199,7 +201,9 @@ impl Value { /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>` /// Returns a BTreeMap as long as each Key is a String /// Returns `Err(Error::Structure("reason"))` otherwise. - pub fn map_ref_into_btree_string_map(map: &ValueMap) -> Result, Error> { + pub fn map_ref_into_btree_string_map( + map: &ValueMap, + ) -> Result, Error> { map.iter() .map(|(key, value)| { let key = key From fde5bc48796fe31e827ad90fdf2c7c445c6c9f99 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Mar 2023 12:50:18 +0700 Subject: [PATCH 115/228] less errors --- .../asset_lock/instant/mod.rs | 42 ++++--- ..._create_transition_basic_validator_spec.rs | 19 +--- ...credit_withdrawal_transition_basic_spec.rs | 104 ++++++++++++------ .../validation/identity_validator_spec.rs | 2 - .../validation/public_keys_validator_spec.rs | 4 +- 5 files changed, 105 insertions(+), 66 deletions(-) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs index e8c7cad3b67..5d2309dcd7a 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs @@ -110,7 +110,7 @@ mod validate_instant_asset_lock_proof_structure_factory { #[tokio::test] async fn should_be_equal_to_0() { let mut test_data = setup_test(None); - test_data.raw_proof.set_key_value("type", -1); + test_data.raw_proof.set_into_value("type", -1).unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -133,7 +133,7 @@ mod validate_instant_asset_lock_proof_structure_factory { #[tokio::test] async fn should_be_present() { let mut test_data = setup_test(None); - test_data.raw_proof.remove_key("instantLock"); + test_data.raw_proof.remove("instantLock").unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -159,7 +159,8 @@ mod validate_instant_asset_lock_proof_structure_factory { let mut test_data = setup_test(None); test_data .raw_proof - .set_key_value("instantLock", vec!["string"; 165]); + .set_into_value("instantLock", vec!["string"; 165]) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -179,7 +180,8 @@ mod validate_instant_asset_lock_proof_structure_factory { let mut test_data = setup_test(None); test_data .raw_proof - .set_key_value("instantLock", vec![0u8; 159]); + .set_into_value("instantLock", vec![0u8; 159]) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -199,7 +201,8 @@ mod validate_instant_asset_lock_proof_structure_factory { let mut test_data = setup_test(None); test_data .raw_proof - .set_key_value("instantLock", vec![0u8; 100001]); + .set_into_value("instantLock", vec![0u8; 100001]) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -219,7 +222,8 @@ mod validate_instant_asset_lock_proof_structure_factory { let mut test_data = setup_test(None); test_data .raw_proof - .set_key_value("instantLock", vec![0u8; 200]); + .set_into_value("instantLock", vec![0u8; 200]) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -303,7 +307,7 @@ mod validate_instant_asset_lock_proof_structure_factory { #[tokio::test] async fn should_be_present() { let mut test_data = setup_test(None); - test_data.raw_proof.remove_key("transaction"); + test_data.raw_proof.remove("transaction").unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -329,7 +333,8 @@ mod validate_instant_asset_lock_proof_structure_factory { let mut test_data = setup_test(None); test_data .raw_proof - .set_key_value("instantLock", vec!["string"; 65]); + .set_into_value("instantLock", vec!["string"; 65]) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -349,7 +354,8 @@ mod validate_instant_asset_lock_proof_structure_factory { let mut test_data = setup_test(None); test_data .raw_proof - .set_key_value("instantLock", vec![0u8; 0]); + .set_into_value("instantLock", vec![0u8; 0]) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -369,7 +375,8 @@ mod validate_instant_asset_lock_proof_structure_factory { let mut test_data = setup_test(None); test_data .raw_proof - .set_key_value("instantLock", vec![0u8; 100001]); + .set_into_value("instantLock", vec![0u8; 100001]) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -389,7 +396,8 @@ mod validate_instant_asset_lock_proof_structure_factory { let mut test_data = setup_test(None); test_data .raw_proof - .set_key_value("transaction", vec![0u8; 64]); + .set_into_value("transaction", vec![0u8; 64]) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -414,7 +422,7 @@ mod validate_instant_asset_lock_proof_structure_factory { #[tokio::test] async fn should_be_present() { let mut test_data = setup_test(None); - test_data.raw_proof.remove_key("outputIndex"); + test_data.raw_proof.remove("outputIndex").unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -438,7 +446,10 @@ mod validate_instant_asset_lock_proof_structure_factory { #[tokio::test] async fn should_be_an_integer() { let mut test_data = setup_test(None); - test_data.raw_proof.set_key_value("outputIndex", 1.1); + test_data + .raw_proof + .set_into_value("outputIndex", 1.1) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure @@ -456,7 +467,10 @@ mod validate_instant_asset_lock_proof_structure_factory { #[tokio::test] async fn should_not_be_less_than_0() { let mut test_data = setup_test(None); - test_data.raw_proof.set_key_value("outputIndex", -1); + test_data + .raw_proof + .set_into_value("outputIndex", -1) + .unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index 2182b8d401b..4b05c8cbc36 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -356,7 +356,7 @@ mod validate_identity_create_transition_basic_factory { use std::sync::Arc; use jsonschema::error::ValidationErrorKind; - use serde_json::Value; + use platform_value::Value; use crate::assert_consensus_errors; use crate::consensus::basic::TestConsensusError; @@ -510,10 +510,7 @@ mod validate_identity_create_transition_basic_factory { assert_eq!( &pk_validator_mock.called_with(), - raw_state_transition - .get_value("publicKeys") - .as_array() - .unwrap() + raw_state_transition.get_array("publicKeys").unwrap() ); } @@ -545,10 +542,7 @@ mod validate_identity_create_transition_basic_factory { assert_eq!( &pk_validator_mock.called_with(), - raw_state_transition - .get_value("publicKeys") - .as_array() - .unwrap() + raw_state_transition.get_array("publicKeys").unwrap() ); } } @@ -574,7 +568,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.remove_key("signature"); + raw_state_transition.remove("signature").unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -689,10 +683,7 @@ mod validate_identity_create_transition_basic_factory { assert!(result.is_valid()); assert_eq!( &pk_validator_mock.called_with(), - raw_state_transition - .get_value("publicKeys") - .as_array() - .unwrap() + raw_state_transition.get_array("publicKeys").unwrap() ); } } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs index 22f0ea2d1f6..6ddb82ea47e 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs @@ -33,7 +33,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("protocolVersion"); + raw_state_transition.remove("protocolVersion").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -55,7 +55,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_integer() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("protocolVersion", "1"); + raw_state_transition + .set_into_value("protocolVersion", "1") + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -71,7 +73,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_valid() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("protocolVersion", -1); + raw_state_transition + .set_into_value("protocolVersion", -1i32) + .unwrap(); let result = validator.validate(&raw_state_transition).await; @@ -98,7 +102,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("type"); + raw_state_transition.remove("type").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -121,7 +125,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_integer() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("type", "1"); + raw_state_transition.set_into_value("type", "1").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -137,7 +141,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_equal_to_6() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("type", 42); + raw_state_transition.set_into_value("type", 42).unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -156,7 +160,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("identityId"); + raw_state_transition.remove("identityId").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -179,7 +183,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_a_byte_array() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("identityId", vec!["string"; 32]); + raw_state_transition + .set_into_value("identityId", vec!["string"; 32]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -195,7 +201,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_shorter_than_32_bytes() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("identityId", vec![0; 30]); + raw_state_transition + .set_into_value("identityId", vec![0; 30]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -211,7 +219,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_longer_than_32_bytes() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("identityId", vec![0; 33]); + raw_state_transition + .set_into_value("identityId", vec![0; 33]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -231,7 +241,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("amount"); + raw_state_transition.remove("amount").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -254,7 +264,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_integer() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("amount", "1"); + raw_state_transition.set_into_value("amount", "1").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -270,7 +280,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_less_than_1() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("amount", 900); + raw_state_transition.set_into_value("amount", 900).unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -290,7 +300,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("coreFeePerByte"); + raw_state_transition.remove("coreFeePerByte").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -313,7 +323,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_integer() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("coreFeePerByte", "1"); + raw_state_transition + .set_into_value("coreFeePerByte", "1") + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -329,7 +341,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_less_than_1() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("coreFeePerByte", -1); + raw_state_transition + .set_into_value("coreFeePerByte", -1) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -345,7 +359,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_more_than_u32_max() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("coreFeePerByte", u32::MAX as u64 + 1u64); + raw_state_transition + .set_into_value("coreFeePerByte", u32::MAX as u64 + 1u64) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -361,7 +377,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_in_a_fibonacci_sequence() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("coreFeePerByte", 6); + raw_state_transition + .set_into_value("coreFeePerByte", 6) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -384,7 +402,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("pooling"); + raw_state_transition.remove("pooling").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -407,7 +425,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_integer() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("pooling", "1"); + raw_state_transition.set_into_value("pooling", "1").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -423,7 +441,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_valid_enum_variant() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("pooling", 3); + raw_state_transition.set_into_value("pooling", 3).unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -439,7 +457,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_constraint_variant_to_0() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("pooling", 2); + raw_state_transition.set_into_value("pooling", 2).unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -463,7 +481,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("outputScript"); + raw_state_transition.remove("outputScript").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -486,7 +504,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_a_byte_array() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("outputScript", vec!["string"; 23]); + raw_state_transition + .set_into_value("outputScript", vec!["string"; 23]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -502,7 +522,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_shorter_than_23_bytes() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("outputScript", vec![0; 9]); + raw_state_transition + .set_into_value("outputScript", vec![0; 9]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -518,7 +540,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_longer_than_25_bytes() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("outputScript", vec![0; 10018]); + raw_state_transition + .set_into_value("outputScript", vec![0; 10018]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -534,7 +558,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_of_a_proper_type() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("outputScript", vec![6; 23]); + raw_state_transition + .set_into_value("outputScript", vec![6; 23]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -556,7 +582,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("signature"); + raw_state_transition.remove("signature").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -579,7 +605,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_a_byte_array() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("signature", vec!["string"; 65]); + raw_state_transition + .set_into_value("signature", vec!["string"; 65]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -595,7 +623,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_shorter_than_65_bytes() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("signature", vec![0; 64]); + raw_state_transition + .set_into_value("signature", vec![0; 64]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -611,7 +641,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_longer_than_65_bytes() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("signature", vec![0; 66]); + raw_state_transition + .set_into_value("signature", vec![0; 66]) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -631,7 +663,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove_key("signaturePublicKeyId"); + raw_state_transition.remove("signaturePublicKeyId").unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -654,7 +686,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { async fn should_be_integer() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("signaturePublicKeyId", "1"); + raw_state_transition + .set_into_value("signaturePublicKeyId", "1") + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -670,7 +704,9 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { pub async fn should_be_not_less_than_0() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.set_key_value("signaturePublicKeyId", -1); + raw_state_transition + .set_into_value("signaturePublicKeyId", -1) + .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); diff --git a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs index 11e9d4bbbd9..c434ad58d21 100644 --- a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs @@ -30,7 +30,6 @@ pub mod protocol_version { use crate::assert_consensus_errors; use crate::consensus::ConsensusError; use crate::tests::identity::validation::identity_validator_spec::setup_test; - use crate::tests::utils::{platform_value_set_ref, serde_set}; #[test] pub fn should_be_present() { @@ -87,7 +86,6 @@ pub mod protocol_version { pub mod id { use jsonschema::error::ValidationErrorKind; use platform_value::Value; - use serde_json::Value as JsonValue; use crate::assert_consensus_errors; use crate::consensus::ConsensusError; diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index 435b5989e35..76bc2d56579 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -360,7 +360,7 @@ pub fn should_return_invalid_result_if_there_are_duplicate_keys() { let (mut raw_public_keys, validator) = setup_test(); let key0 = raw_public_keys.get(0).unwrap().clone(); let key1 = raw_public_keys.get_mut(1).unwrap(); - key1.set_value("data", key0.get_value("data").unwrap()) + key1.set_value("data", key0.get_value("data").unwrap().clone()) .expect("expected to set data"); let result = validator.validate_keys(&raw_public_keys).unwrap(); @@ -440,7 +440,7 @@ pub fn should_return_invalid_result_if_key_has_an_invalid_combination_of_purpose assert_eq!(consensus_error.code(), 1047); assert_eq!( error.public_key_id(), - raw_public_keys[1].get_integer("id").unwrap() as KeyID + raw_public_keys[1].get_integer("id").unwrap() ); assert_eq!( error.security_level() as u8, From 90ad26044a0120820088fefd4e0a818a3a73fc17 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Mar 2023 13:08:40 +0700 Subject: [PATCH 116/228] more work --- .../mod.rs | 38 +++---------------- ...lidate_identity_update_transition_state.rs | 14 ++++--- .../data_contract_validator_spec.rs | 8 ++-- ..._documents_batch_transitions_basic_spec.rs | 2 +- .../fixtures/public_keys_validator_mock.rs | 3 +- ..._top_up_transition_basic_validator_spec.rs | 11 +++--- ...e_identity_update_transition_basic_spec.rs | 2 +- .../validate_public_keys.rs | 3 +- .../validation/public_keys_validator_spec.rs | 10 ++--- ...rpose_and_security_level_validator_spec.rs | 1 - packages/rs-dpp/src/tests/utils/utils.rs | 24 ------------ packages/rs-platform-value/src/inner_value.rs | 15 ++++++++ 12 files changed, 50 insertions(+), 81 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index b26d3a97afa..7f448ed7f82 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -170,40 +170,14 @@ impl StateTransitionConvert for IdentityCreditWithdrawalTransition { vec![PROPERTY_SIGNATURE] } - fn to_object(&self, skip_signature: bool) -> Result { - let mut json_value: JsonValue = serde_json::to_value(self)?; - - let output_script_option = json_value.get(PROPERTY_OUTPUT_SCRIPT); - - let output_script_bytes = output_script_option - .ok_or_else(|| anyhow!("uanble to get outputScript")) - .and_then(|value| serde_json::from_value(value.clone()).map_err(|e| anyhow!(e))) - .and_then(|string: String| { - string_encoding::decode(&string, Encoding::Base64).map_err(|e| anyhow!(e)) - })?; - - json_value.insert( - PROPERTY_OUTPUT_SCRIPT.to_owned(), - JsonValue::Array( - output_script_bytes - .into_iter() - .map(JsonValue::from) - .collect(), - ), - )?; - - json_value - .replace_identifier_paths(Self::identifiers_property_paths(), ReplaceWith::Bytes)?; - + fn to_object(&self, skip_signature: bool) -> Result { + let mut value = platform_value::to_value(self)?; if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { - for path in Self::signature_property_paths() { - o.remove(path); - } - } + value + .remove_many(&Self::signature_property_paths()) + .map_err(ProtocolError::ValueError)?; } - - Ok(json_value) + Ok(value) } fn to_json(&self, skip_signature: bool) -> Result { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs index c078da110b0..2568198b34e 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs @@ -1,5 +1,5 @@ use anyhow::anyhow; -use serde_json::Value; +use platform_value::Value; use std::convert::TryInto; use std::sync::Arc; @@ -10,7 +10,7 @@ use crate::{ state_repository::StateRepositoryLike, state_transition::StateTransitionLike, validation::SimpleValidationResult, - NonConsensusError, SerdeParsingError, StateError, + NonConsensusError, ProtocolError, SerdeParsingError, StateError, }; use super::identity_update_transition::{property_names, IdentityUpdateTransition}; @@ -147,13 +147,15 @@ where .map(|k| k.to_identity_public_key()), ); - let raw_public_keys: Vec = identity + let raw_public_keys = identity .public_keys .values() - .map(|pk| pk.to_raw_json_object()) - .collect::>()?; + .map(|pk| pk.try_into()) + .collect::, ProtocolError>>()?; - let result = self.public_keys_validator.validate_keys(&raw_public_keys)?; + let result = self + .public_keys_validator + .validate_keys(raw_public_keys.as_slice())?; if !result.is_valid() { return Ok(result); } diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index 4efde6fe5fd..ca0a7f82688 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -2499,7 +2499,7 @@ mod indices { .unwrap(); cloned_data_contract["documents"]["indexedDocument"]["required"] - .push(JsonValue::String(property_name.to_string())) + .push(Value::Text(property_name.to_string())) .unwrap(); let result = data_contract_validator @@ -2579,8 +2579,10 @@ mod indices { ] }); - if let Some(Value::Array(ref mut indices)) = - raw_data_contract["documents"]["indexedDocument"].get_mut("indices") + if let Some(Value::Array(ref mut indices)) = raw_data_contract["documents"] + ["indexedDocument"] + .get_mut("indices") + .unwrap() { indices.push(index_definition) } diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 4bc8922acb5..e05e2b94827 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -426,7 +426,7 @@ async fn property_in_document_transition_should_be_present(property: &str) { schema_error.kind(), ValidationErrorKind::Required { property: JsonValue::String(missing_property) - } if missing_property.into() == property + } if missing_property == property )); } diff --git a/packages/rs-dpp/src/tests/fixtures/public_keys_validator_mock.rs b/packages/rs-dpp/src/tests/fixtures/public_keys_validator_mock.rs index 373969e59bd..6453c70e943 100644 --- a/packages/rs-dpp/src/tests/fixtures/public_keys_validator_mock.rs +++ b/packages/rs-dpp/src/tests/fixtures/public_keys_validator_mock.rs @@ -1,7 +1,6 @@ +use platform_value::Value; use std::sync::Mutex; -use serde_json::Value; - use crate::identity::validation::TPublicKeysValidator; use crate::validation::ValidationResult; use crate::NonConsensusError; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs index be134b0f4c2..39a63086498 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs @@ -232,12 +232,13 @@ mod validate_identity_topup_transition_basic { #[tokio::test] pub async fn should_be_valid() { let (mut raw_state_transition, validator) = setup_test(MockStateRepositoryLike::new()); - let st_map = raw_state_transition - .get_mut("assetLockProof") - .unwrap() - .as_object_mut() + raw_state_transition + .set_value_at_path( + "assetLockProof", + "transaction", + "totally not a valid type".into(), + ) .unwrap(); - st_map.insert("transaction".into(), "totally not a valid type".into()); let result = validator .validate(&raw_state_transition, &Default::default()) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs index 9bdce486fe4..0bb4d9a45f4 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs @@ -50,7 +50,7 @@ impl TPublicKeysSignaturesValidator for SignaturesValidatorMock { fn validate_public_key_signatures<'a>( &self, _raw_state_transition: &Value, - _raw_public_keys: impl IntoIterator, + _raw_public_keys: impl IntoIterator, ) -> Result { Ok(SimpleValidationResult::default()) } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs index 6c52c703eae..56340aa5c36 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs @@ -8,6 +8,7 @@ use crate::{ }; use platform_value::Value; use serde_json::Value as JsonValue; +use std::convert::TryInto; struct TestData { raw_public_keys: Vec, @@ -19,7 +20,7 @@ fn setup_test() -> TestData { let raw_public_keys: Vec = identity .public_keys .values() - .map(|pk| pk.to_raw_json_object()) + .map(|pk| pk.try_into()) .collect::>() .unwrap(); diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index 76bc2d56579..c2001e93bfb 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -100,12 +100,12 @@ pub mod key_type { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::{platform_value_set_ref, serde_remove_ref}; + use crate::tests::utils::platform_value_set_ref; #[test] pub fn should_be_present() { let (mut raw_public_keys, validator) = setup_test(); - serde_remove_ref(raw_public_keys.get_mut(1).unwrap(), "type"); + raw_public_keys.get_mut(1).unwrap().remove("type").unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); // TODO: in the original code, there was only one error @@ -138,12 +138,12 @@ pub mod data { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::{platform_value_set_ref, serde_remove_ref}; + use crate::tests::utils::platform_value_set_ref; #[test] pub fn should_be_present() { let (mut raw_public_keys, validator) = setup_test(); - serde_remove_ref(raw_public_keys.get_mut(1).unwrap(), "data"); + raw_public_keys.get_mut(1).unwrap().remove("data").unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); @@ -440,7 +440,7 @@ pub fn should_return_invalid_result_if_key_has_an_invalid_combination_of_purpose assert_eq!(consensus_error.code(), 1047); assert_eq!( error.public_key_id(), - raw_public_keys[1].get_integer("id").unwrap() + raw_public_keys[1].get_integer::("id").unwrap() ); assert_eq!( error.security_level() as u8, diff --git a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs index f411932ad97..9b7040f3060 100644 --- a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs @@ -4,7 +4,6 @@ use crate::identity::{ }; use platform_value::platform_value; use platform_value::string_encoding::{decode, Encoding}; -use serde_json::json; #[test] fn should_return_invalid_result_if_state_transition_does_not_contain_master_key() { diff --git a/packages/rs-dpp/src/tests/utils/utils.rs b/packages/rs-dpp/src/tests/utils/utils.rs index eeba75fe519..f0aa057b189 100644 --- a/packages/rs-dpp/src/tests/utils/utils.rs +++ b/packages/rs-dpp/src/tests/utils/utils.rs @@ -61,30 +61,6 @@ where map.push((key.into(), value.into())); } -/// Removes a key value pair in serde_json object, returns the modified object -pub fn serde_remove(mut object: serde_json::Value, key: T) -> serde_json::Value -where - T: Into, -{ - let map = object - .as_object_mut() - .expect("Expected value to be an JSON object"); - map.remove(&key.into()); - - object -} - -/// Removes a key value pair in serde_json object, returns the modified object -pub fn serde_remove_ref(object: &mut Value, key: T) -where - T: Into, -{ - object - .as_object_mut() - .expect("Expected value to be an JSON object") - .remove(&key.into()); -} - pub fn generate_random_identifier_struct() -> Identifier { let mut buffer = [0u8; 32]; let _ = getrandom(&mut buffer); diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 845d207c42a..45b21a2dbd2 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -289,6 +289,21 @@ impl Value { Self::inner_bytes_value(map, key) } + pub fn get_optional_bytes_into>>(&self, key: &str) -> Result, Error> { + let map = self.to_map()?; + Ok(Self::inner_optional_bytes_value(map, key)?.map(|bytes| bytes.into())) + } + + pub fn get_optional_bytes_try_into, Error = Error>>( + &self, + key: &str, + ) -> Result, Error> { + let map = self.to_map()?; + Self::inner_optional_bytes_value(map, key)? + .map(|bytes| bytes.try_into()) + .transpose() + } + pub fn get_bytes_into>>(&self, key: &str) -> Result { let map = self.to_map()?; Ok(Self::inner_bytes_value(map, key)?.into()) From 5fd484df63dc133dd47edb35981bcaf672c49414 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 15 Mar 2023 17:33:31 +0700 Subject: [PATCH 117/228] more fixes --- ...lidate_documents_batch_transition_basic.rs | 5 ++-- packages/rs-dpp/src/identity/factory.rs | 8 +++--- packages/rs-dpp/src/identity/identity.rs | 17 +++++++++++++ .../rs-dpp/src/identity/identity_facade.rs | 4 +-- .../src/identity/identity_public_key/mod.rs | 8 +++--- .../asset_lock_transaction_output_fetcher.rs | 2 +- .../identity_create_transition.rs | 25 +++++++++++++------ .../identity_public_key_transitions.rs | 14 +++++------ .../identity_topup_transition.rs | 2 +- .../identity_update_transition.rs | 10 ++++---- ...lidate_identity_update_transition_basic.rs | 6 ++--- ...lidate_identity_update_transition_state.rs | 4 +-- .../validate_public_key_signatures.rs | 10 ++++---- ...ed_purpose_and_security_level_validator.rs | 16 ++++++------ .../state_transition_factory.rs | 21 ++++++---------- ...a_contract_update_transition_basic_spec.rs | 2 +- .../get_identity_update_transition_fixture.rs | 4 +-- .../asset_lock/instant/mod.rs | 2 +- ..._create_transition_basic_validator_spec.rs | 12 ++++----- .../identity_update_transition_spec.rs | 4 +-- packages/rs-dpp/src/tests/utils/utils.rs | 12 ++++----- .../wasm-dpp/src/identity/factory_utils.rs | 8 +++--- .../identity_create_transition.rs | 8 +++--- .../identity_create_transition/to_object.rs | 4 +-- .../identity_public_key_transitions.rs | 18 ++++++------- .../identity_update_public_keys_validator.rs | 4 +-- .../identity_update_transition.rs | 6 ++--- .../identity_update_transition/to_object.rs | 4 +-- .../validate_public_key_signatures.rs | 4 +-- 29 files changed, 133 insertions(+), 111 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 90ff60cda9f..7a8031d9751 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -35,6 +35,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::Value; use serde_json::Value as JsonValue; +use platform_value::converter::serde_json::BTreeValueRefJsonConverter; use super::{ find_duplicates_by_indices::find_duplicates_by_indices, @@ -233,7 +234,7 @@ fn validate_raw_transitions<'a>( return Ok(result); } - let Some(document_action) = raw_document_transition.get_optional_integer::("$action") else { + let Some(document_action) = raw_document_transition.get_optional_integer::("$action").map_err(ProtocolError::ValueError)? else { result.add_error(BasicError::MissingDocumentTransitionActionError); return Ok(result); }; @@ -288,7 +289,7 @@ fn validate_raw_transitions<'a>( Action::Delete => { let validator = JsonSchemaValidator::new(BASE_TRANSITION_SCHEMA.clone()) .map_err(|e| anyhow!("unable to compile base transition schema: {}", e))?; - let validation_result = validator.validate(raw_document_transition)?; + let validation_result = validator.validate(&raw_document_transition.to_validating_json_value().map_err(ProtocolError::ValueError)?)?; if !validation_result.is_valid() { result.merge(validation_result); return Ok(result); diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index 3ec1cd8a24f..bd49cf247a8 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -3,7 +3,7 @@ use crate::identity::identity_public_key::factory::KeyCount; use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; use crate::identity::state_transition::asset_lock_proof::{AssetLockProof, InstantAssetLockProof}; use crate::identity::state_transition::identity_create_transition::IdentityCreateTransition; -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::identity::state_transition::identity_topup_transition::IdentityTopUpTransition; use crate::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; use crate::identity::validation::{IdentityValidator, PublicKeysValidator}; @@ -151,7 +151,7 @@ where // TODO: the error originates here due to id having a wrong type - should be a base58 for the schema self.create_from_object( - raw_identity.try_into().map_err(ProtocolError::ValueError)?, + raw_identity, skip_validation, ) } @@ -182,7 +182,7 @@ where .get_public_keys() .iter() .map(|(_, public_key)| public_key.into()) - .collect::>(); + .collect::>(); identity_create_transition.set_public_keys(public_keys); let asset_lock_proof = identity.get_asset_lock_proof().ok_or_else(|| { @@ -215,7 +215,7 @@ where pub fn create_identity_update_transition( &self, identity: Identity, - add_public_keys: Option>, + add_public_keys: Option>, public_key_ids_to_disable: Option>, // Pass disable time as argument because SystemTime::now() does not work for wasm target // https://github.com/rust-lang/rust/issues/48564 diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 77d7b8f8948..a740bb3c428 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -1,4 +1,5 @@ use std::collections::BTreeMap; +use std::convert::TryFrom; use ciborium::value::Value as CborValue; use integer_encoding::VarInt; @@ -339,3 +340,19 @@ impl Identity { } } } + +impl TryFrom for Identity { + type Error = ProtocolError; + + fn try_from(value: Value) -> Result { + platform_value::from_value(value).map_err(ProtocolError::ValueError) + } +} + +impl TryFrom<&Value> for Identity { + type Error = ProtocolError; + + fn try_from(value: &Value) -> Result { + platform_value::from_value(value.clone()).map_err(ProtocolError::ValueError) + } +} diff --git a/packages/rs-dpp/src/identity/identity_facade.rs b/packages/rs-dpp/src/identity/identity_facade.rs index 8b0c7bd3a1a..218c4ff755b 100644 --- a/packages/rs-dpp/src/identity/identity_facade.rs +++ b/packages/rs-dpp/src/identity/identity_facade.rs @@ -7,7 +7,7 @@ use crate::identity::factory::IdentityFactory; use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; use crate::identity::state_transition::asset_lock_proof::{AssetLockProof, InstantAssetLockProof}; use crate::identity::state_transition::identity_create_transition::IdentityCreateTransition; -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::identity::state_transition::identity_topup_transition::IdentityTopUpTransition; use crate::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; use crate::identity::validation::{IdentityValidator, PublicKeysValidator}; @@ -114,7 +114,7 @@ where pub fn create_identity_update_transition( &self, identity: Identity, - add_public_keys: Option>, + add_public_keys: Option>, public_key_ids_to_disable: Option>, // Pass disable time as argument because SystemTime::now() does not work for wasm target // https://github.com/rust-lang/rust/issues/48564 diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index 44613a91706..fd417a9dab6 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -25,7 +25,7 @@ use crate::util::json_value::{JsonValueExt, ReplaceWith}; use crate::util::vec; use crate::SerdeParsingError; -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; pub type KeyID = u32; pub type TimestampMillis = u64; @@ -46,9 +46,9 @@ pub struct IdentityPublicKey { pub disabled_at: Option, } -impl Into for &IdentityPublicKey { - fn into(self) -> IdentityPublicKeyCreateTransition { - IdentityPublicKeyCreateTransition { +impl Into for &IdentityPublicKey { + fn into(self) -> IdentityPublicKeyWithWitness { + IdentityPublicKeyWithWitness { id: self.id, purpose: self.purpose, security_level: self.security_level, diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs index 01f1162207f..269a65e77b5 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs @@ -45,7 +45,7 @@ pub async fn fetch_asset_lock_transaction_output( .ok_or_else(|| DPPError::from(AssetLockOutputNotFoundError::new())) .cloned(), AssetLockProof::Chain(asset_lock_proof) => { - let out_point_buffer = *asset_lock_proof.out_point(); + let out_point_buffer = *asset_lock_proof.out_point; let out_point = OutPoint::from(out_point_buffer); let output_index = out_point.vout as usize; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 288fb65ee59..2fbe06ac7d4 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::prelude::Identifier; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::state_transition::{ @@ -32,21 +32,24 @@ mod property_names { #[derive(Debug, Copy, Clone, Default)] pub struct SerializationOptions { pub skip_signature: bool, + pub into_validating_json: bool, } -#[derive(Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct IdentityCreateTransition { // Own ST fields - pub public_keys: Vec, + pub public_keys: Vec, pub asset_lock_proof: AssetLockProof, pub identity_id: Identifier, // Generic identity ST fields pub protocol_version: u32, pub transition_type: StateTransitionType, pub signature: Vec, + #[serde(skip)] pub execution_context: StateTransitionExecutionContext, } +//todo: there shouldn't be a default impl Default for IdentityCreateTransition { fn default() -> Self { Self { @@ -106,7 +109,7 @@ impl IdentityCreateTransition { let keys = keys_value_array .into_iter() .map(|val| val.try_into()) - .collect::, ProtocolError>>()?; + .collect::, ProtocolError>>()?; state_transition.set_public_keys(keys); } @@ -143,14 +146,14 @@ impl IdentityCreateTransition { } /// Get identity public keys - pub fn get_public_keys(&self) -> &[IdentityPublicKeyCreateTransition] { + pub fn get_public_keys(&self) -> &[IdentityPublicKeyWithWitness] { &self.public_keys } /// Replaces existing set of public keys with a new one pub fn set_public_keys( &mut self, - public_keys: Vec, + public_keys: Vec, ) -> &mut Self { self.public_keys = public_keys; @@ -160,7 +163,7 @@ impl IdentityCreateTransition { /// Adds public keys to the existing public keys array pub fn add_public_keys( &mut self, - public_keys: &mut Vec, + public_keys: &mut Vec, ) -> &mut Self { self.public_keys.append(public_keys); @@ -181,7 +184,13 @@ impl IdentityCreateTransition { pub fn to_json_object( &self, options: SerializationOptions, - ) -> Result { + ) -> Result { + if options.into_validating_json { + self.to_object(options.skip_signature)?.try_into() + } else { + self.to_object(options.skip_signature)?.into() + } + let mut json_map = JsonValue::Object(Default::default()); json_map.insert( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 7fd7b5aab64..a551a2018a2 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -18,7 +18,7 @@ pub const BINARY_DATA_FIELDS: [&str; 2] = ["data", "signature"]; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct IdentityPublicKeyCreateTransition { +pub struct IdentityPublicKeyWithWitness { pub id: KeyID, pub purpose: Purpose, pub security_level: SecurityLevel, @@ -30,7 +30,7 @@ pub struct IdentityPublicKeyCreateTransition { pub signature: Vec, } -impl IdentityPublicKeyCreateTransition { +impl IdentityPublicKeyWithWitness { pub fn to_identity_public_key(self) -> IdentityPublicKey { let Self { id, @@ -227,8 +227,8 @@ impl IdentityPublicKeyCreateTransition { } } -impl From<&IdentityPublicKeyCreateTransition> for IdentityPublicKey { - fn from(val: &IdentityPublicKeyCreateTransition) -> Self { +impl From<&IdentityPublicKeyWithWitness> for IdentityPublicKey { + fn from(val: &IdentityPublicKeyWithWitness) -> Self { IdentityPublicKey { id: val.id, purpose: val.purpose, @@ -241,15 +241,15 @@ impl From<&IdentityPublicKeyCreateTransition> for IdentityPublicKey { } } -impl TryFrom for IdentityPublicKeyCreateTransition { +impl TryFrom for IdentityPublicKeyWithWitness { type Error = ProtocolError; fn try_from(value: Value) -> Result { - IdentityPublicKeyCreateTransition::from_raw_object(value) + IdentityPublicKeyWithWitness::from_raw_object(value) } } -impl TryInto for IdentityPublicKeyCreateTransition { +impl TryInto for IdentityPublicKeyWithWitness { type Error = ProtocolError; fn try_into(self) -> Result { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 288e2106ef3..ae70dba47e6 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -187,7 +187,7 @@ impl StateTransitionConvert for IdentityTopUpTransition { } fn to_json(&self, skip_signature: bool) -> Result { - self.to_object(skip_signature).map(|value| value.into()) + self.to_object(skip_signature).and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 8ad9559d66a..e054396344a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::convert::TryInto; -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::{ identity::{KeyID, SecurityLevel}, prelude::{Identifier, Revision, TimestampMillis}, @@ -52,7 +52,7 @@ pub struct IdentityUpdateTransition { /// Public Keys to add to the Identity /// we want to skip serialization of transitions, as we does it manually in `to_object()` and `to_json()` #[serde(skip, default)] - pub add_public_keys: Vec, + pub add_public_keys: Vec, /// Identity Public Keys ID's to disable for the Identity #[serde(skip_serializing_if = "Vec::is_empty", default)] @@ -151,16 +151,16 @@ impl IdentityUpdateTransition { pub fn set_public_keys_to_add( &mut self, - add_public_keys: Vec, + add_public_keys: Vec, ) { self.add_public_keys = add_public_keys; } - pub fn get_public_keys_to_add(&self) -> &[IdentityPublicKeyCreateTransition] { + pub fn get_public_keys_to_add(&self) -> &[IdentityPublicKeyWithWitness] { &self.add_public_keys } - pub fn get_public_keys_to_add_mut(&mut self) -> &mut [IdentityPublicKeyCreateTransition] { + pub fn get_public_keys_to_add_mut(&mut self) -> &mut [IdentityPublicKeyWithWitness] { &mut self.add_public_keys } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs index 17ee3791fb3..72120fc2c5b 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs @@ -63,14 +63,14 @@ where ) -> Result { let result = self .json_schema_validator - .validate(&raw_state_transition.into())?; + .validate(&raw_state_transition.try_into_validating_json().map_err(ProtocolError::ValueError)?)?; if !result.is_valid() { return Ok(result); } let protocol_version = raw_state_transition .get_integer(property_names::PROTOCOL_VERSION) - .map_err(ProtocolError::ValueError)?; + .map_err(NonConsensusError::ValueError)?; let result = self.protocol_version_validator.validate(protocol_version)?; if !result.is_valid() { @@ -80,7 +80,7 @@ where let maybe_raw_public_keys = raw_state_transition .get_optional_value(property_names::ADD_PUBLIC_KEYS) .and_then(|value| value.map(|value| value.to_array_slice()).transpose()) - .map_err(ProtocolError::ValueError)?; + .map_err(NonConsensusError::ValueError)?; match maybe_raw_public_keys { Some(raw_public_keys) => { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs index 2568198b34e..09bbe8d0323 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs @@ -150,8 +150,8 @@ where let raw_public_keys = identity .public_keys .values() - .map(|pk| pk.try_into()) - .collect::, ProtocolError>>()?; + .map(|pk| pk.try_into().map_err(NonConsensusError::ValueError)) + .collect::, NonConsensusError>>()?; let result = self .public_keys_validator diff --git a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 3a8b5f81630..63fd1722b80 100644 --- a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -3,7 +3,7 @@ use serde_json::Value as JsonValue; use crate::consensus::basic::identity::InvalidIdentityKeySignatureError; use crate::consensus::basic::state_transition::InvalidStateTransitionTypeError; -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::{ consensus::{basic::BasicError, ConsensusError}, object_names, @@ -86,10 +86,10 @@ pub fn validate_public_key_signatures<'a, T: BlsModule>( } }; - let add_public_key_transitions: Vec = raw_public_keys + let add_public_key_transitions: Vec = raw_public_keys .into_iter() .map(|k| { - IdentityPublicKeyCreateTransition::from_raw_json_object(k.to_owned()) + IdentityPublicKeyWithWitness::from_raw_json_object(k.to_owned()) .map_err(|e| NonConsensusError::IdentityPublicKeyCreateError(format!("{:#}", e))) }) .collect::>()?; @@ -115,9 +115,9 @@ fn invalid_state_transition_type_error(transition_type: u8) -> ProtocolError { fn find_invalid_public_key( state_transition: &mut impl StateTransitionLike, - public_keys: impl IntoIterator, + public_keys: impl IntoIterator, bls: &T, -) -> Option { +) -> Option { for public_key in public_keys { state_transition.set_signature(public_key.signature.clone()); if state_transition diff --git a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs index d7ab2278661..5b97d530358 100644 --- a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs +++ b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs @@ -26,16 +26,16 @@ impl TPublicKeysValidator for RequiredPurposeAndSecurityLevelValidator { let mut key_purposes_and_levels_count: HashMap = HashMap::new(); - for raw_public_key in raw_public_keys.iter().filter(|pk| { - if let Some(disabled_at) = pk - .get_optional_bool("disabledAt") - .map_err(NonConsensusError::ValueError)? + for raw_public_key in raw_public_keys.iter().filter_map(|pk| { + match pk + .get_optional_integer::("disabledAt") + .map_err(NonConsensusError::ValueError) { - disabled_at == false - } else { - true + Ok(Some(_)) => { Some(Ok(pk)) } + Ok(None) => { None } + Err(e) => { Some(Err(e))} } - }) { + }).collect::, NonConsensusError>>()? { let public_key: IdentityPublicKey = platform_value::from_value(raw_public_key.clone())?; let combo = PurposeKey { purpose: public_key.purpose, diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 49cf7209bb9..b24755b2f99 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -59,12 +59,8 @@ pub async fn create_state_transition( Ok(StateTransition::IdentityCreditWithdrawal(transition)) } StateTransitionType::DocumentsBatch => { - let maybe_transitions = raw_state_transition - .get("transitions") - .ok_or_else(|| anyhow!("the transitions property doesn't exist"))?; - let raw_transitions = maybe_transitions - .as_array() - .ok_or_else(|| anyhow!("property transitions isn't an array"))?; + let raw_transitions = raw_state_transition + .get_array_ref("transitions").map_err(ProtocolError::ValueError)?; let data_contracts = fetch_data_contracts_for_document_transition( state_repository, raw_transitions, @@ -139,7 +135,7 @@ fn missing_state_transition_error() -> ProtocolError { #[cfg(test)] mod test { use dashcore::network::constants::PROTOCOL_VERSION; - use platform_value::Value; + use platform_value::{platform_value, Value}; use serde_json::json; use std::collections::BTreeMap; @@ -167,10 +163,10 @@ mod test { .expect_fetch_data_contract() .returning(move |_, _| Ok(Some(data_contract_to_return.clone()))); - let state_transition_data = json!( { - "protocolVersion" : PROTOCOL_VERSION, + let state_transition_data = platform_value!( { + "protocolVersion" : PROTOCOL_VERSION as u32, "entropy": data_contract.entropy, - "dataContract": data_contract.to_object(false).unwrap(), + "dataContract": data_contract.to_object().unwrap(), } ); let data_contract_create_state_transition = @@ -249,9 +245,8 @@ mod test { #[tokio::test] async fn should_return_invalid_state_transition_type_if_type_is_invalid() { let state_repostiory_mock = MockStateRepositoryLike::new(); - let raw_state_transition = json!( { - "type" : 666 - + let raw_state_transition = platform_value!( { + "type" : 110u8 }); let result = create_state_transition(&state_repostiory_mock, raw_state_transition).await; diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 73503f42a45..1683561f876 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -89,7 +89,7 @@ async fn should_be_present(property: &str) { assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { - property: Value::String(missing_property) + property: JsonValue::String(missing_property) } if missing_property == property )); } diff --git a/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs index 10f052e8312..dd2f4e5e53b 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs @@ -1,4 +1,4 @@ -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::{ identity::{ state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, @@ -15,7 +15,7 @@ pub fn get_identity_update_transition_fixture() -> IdentityUpdateTransition { transition_type: StateTransitionType::IdentityUpdate, identity_id: generate_random_identifier_struct(), revision: 0, - add_public_keys: vec![IdentityPublicKeyCreateTransition { + add_public_keys: vec![IdentityPublicKeyWithWitness { id: 3, key_type: KeyType::ECDSA_SECP256K1, purpose: Purpose::AUTHENTICATION, diff --git a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs index 5d2309dcd7a..005fee594c7 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs @@ -86,7 +86,7 @@ mod validate_instant_asset_lock_proof_structure_factory { #[tokio::test] async fn should_be_present() { let mut test_data = setup_test(None); - test_data.raw_proof.remove_key("type"); + test_data.raw_proof.remove("type").unwrap(); let result = test_data .validate_instant_asset_lock_proof_structure diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index 4b05c8cbc36..b5e2159f904 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -509,7 +509,7 @@ mod validate_identity_create_transition_basic_factory { assert_eq!(error, &&pk_error); assert_eq!( - &pk_validator_mock.called_with(), + pk_validator_mock.called_with(), raw_state_transition.get_array("publicKeys").unwrap() ); } @@ -541,7 +541,7 @@ mod validate_identity_create_transition_basic_factory { assert_eq!(error, &&pk_error); assert_eq!( - &pk_validator_mock.called_with(), + pk_validator_mock.called_with(), raw_state_transition.get_array("publicKeys").unwrap() ); } @@ -597,7 +597,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_key_value("signature", vec!["string"; 65]); + raw_state_transition.set_into_value("signature", vec!["string"; 65]).unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -619,7 +619,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_key_value("signature", vec![0; 64]); + raw_state_transition.set_into_value("signature", vec![0; 64]).unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -641,7 +641,7 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_key_value("signature", vec![0; 66]); + raw_state_transition.set_into_value("signature", vec![0; 66]).unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -682,7 +682,7 @@ mod validate_identity_create_transition_basic_factory { assert!(result.is_valid()); assert_eq!( - &pk_validator_mock.called_with(), + pk_validator_mock.called_with(), raw_state_transition.get_array("publicKeys").unwrap() ); } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index 797193082c5..95704e2e972 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -3,7 +3,7 @@ use platform_value::string_encoding::Encoding; use platform_value::{platform_value, Value}; use serde_json::{json, Value as JsonValue}; -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::{ identity::{ state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, @@ -77,7 +77,7 @@ fn get_public_keys_to_add() { fn set_public_keys_to_add() { let TestData { mut transition, .. } = setup_test(); - let id_public_key = IdentityPublicKeyCreateTransition { + let id_public_key = IdentityPublicKeyWithWitness { id: 0, key_type: KeyType::BLS12_381, purpose: Purpose::AUTHENTICATION, diff --git a/packages/rs-dpp/src/tests/utils/utils.rs b/packages/rs-dpp/src/tests/utils/utils.rs index f0aa057b189..e29b5b3de26 100644 --- a/packages/rs-dpp/src/tests/utils/utils.rs +++ b/packages/rs-dpp/src/tests/utils/utils.rs @@ -82,8 +82,8 @@ pub trait SerdeTestExtension { T: Into, S: Into, serde_json::Value: From; - fn get_value(&self, key: impl Into) -> &Value; - fn get_value_mut(&mut self, key: impl Into) -> &mut Value; + fn get_value(&self, key: impl Into) -> &serde_json::Value; + fn get_value_mut(&mut self, key: impl Into) -> &mut serde_json::Value; } #[cfg(test)] @@ -97,8 +97,8 @@ impl SerdeTestExtension for serde_json::Value { fn set_key_value(&mut self, key: T, value: S) where T: Into, - S: Into, - Value: From, + S: Into, + JsonValue: From, { let map = self .as_object_mut() @@ -106,14 +106,14 @@ impl SerdeTestExtension for serde_json::Value { map.insert(key.into(), serde_json::Value::from(value)); } - fn get_value(&self, key: impl Into) -> &Value { + fn get_value(&self, key: impl Into) -> &JsonValue { self.as_object() .expect("Expected key to exist") .get(&key.into()) .expect("Expected key to exist") } - fn get_value_mut(&mut self, key: impl Into) -> &mut Value { + fn get_value_mut(&mut self, key: impl Into) -> &mut JsonValue { self.as_object_mut() .expect("Expected key to exist") .get_mut(&key.into()) diff --git a/packages/wasm-dpp/src/identity/factory_utils.rs b/packages/wasm-dpp/src/identity/factory_utils.rs index de0f337208b..840a5696806 100644 --- a/packages/wasm-dpp/src/identity/factory_utils.rs +++ b/packages/wasm-dpp/src/identity/factory_utils.rs @@ -3,7 +3,7 @@ use crate::identity::identity_public_key_transitions::IdentityPublicKeyCreateTra use crate::utils::{generic_of_js_val, to_vec_of_serde_values}; use crate::{create_asset_lock_proof_from_wasm_instance, IdentityPublicKeyWasm}; use dpp::identity::state_transition::asset_lock_proof::AssetLockProof; -use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::{IdentityPublicKey, KeyID}; use std::collections::BTreeMap; use wasm_bindgen::__rt::Ref; @@ -26,7 +26,7 @@ pub fn parse_create_args( Ok((asset_lock_proof, public_keys)) } -type AddPublicKeys = Option>; +type AddPublicKeys = Option>; type DisablePublicKeys = Option>; pub fn parse_create_identity_update_transition_keys( @@ -44,7 +44,7 @@ pub fn parse_create_identity_update_transition_keys( .to_js_value() })?; - let keys: Vec = add_public_keys_array + let keys: Vec = add_public_keys_array .iter() .map(|key| { let public_key: Ref = @@ -55,7 +55,7 @@ pub fn parse_create_identity_update_transition_keys( Ok(public_key.clone().into()) }) - .collect::, JsValue>>()?; + .collect::, JsValue>>()?; add_public_keys = Some(keys) } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 1147904e453..3c84e7b0386 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -25,7 +25,7 @@ use dpp::{ identifier::Identifier, identity::state_transition::{ asset_lock_proof::AssetLockProof, identity_create_transition::IdentityCreateTransition, - identity_public_key_transitions::IdentityPublicKeyCreateTransition, + identity_public_key_transitions::IdentityPublicKeyWithWitness, }, state_transition::StateTransitionLike, }; @@ -102,7 +102,7 @@ impl IdentityCreateTransitionWasm { )?; Ok(public_key.clone().into()) }) - .collect::, JsValue>>()?; + .collect::, JsValue>>()?; self.0.set_public_keys(public_keys); @@ -121,7 +121,7 @@ impl IdentityCreateTransitionWasm { )?; Ok(public_key.clone().into()) }) - .collect::, JsValue>>()?; + .collect::, JsValue>>()?; self.0.add_public_keys(&mut public_keys); @@ -133,7 +133,7 @@ impl IdentityCreateTransitionWasm { self.0 .get_public_keys() .iter() - .map(IdentityPublicKeyCreateTransition::to_owned) + .map(IdentityPublicKeyWithWitness::to_owned) .map(IdentityPublicKeyCreateTransitionWasm::from) .map(JsValue::from) .collect() diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/to_object.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/to_object.rs index c114b08791d..06c8ba4b46a 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/to_object.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/to_object.rs @@ -1,5 +1,5 @@ use dpp::identity::state_transition::asset_lock_proof::AssetLockProof; -use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::{ identifier::Identifier, identity::state_transition::identity_create_transition::IdentityCreateTransition, @@ -20,7 +20,7 @@ pub struct ToObject { pub protocol_version: u32, pub identity_id: Identifier, pub asset_lock_proof: AssetLockProof, - pub public_keys: Vec, + pub public_keys: Vec, pub signature: Option>, } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 2fff3a75751..4a5c2cae8ac 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -1,6 +1,6 @@ //todo: move this file to transition use dpp::dashcore::anyhow; -use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; pub use serde::{Deserialize, Serialize}; use std::convert::{TryFrom, TryInto}; use wasm_bindgen::prelude::*; @@ -16,7 +16,7 @@ struct ToObjectOptions { #[wasm_bindgen(js_name=IdentityPublicKeyCreateTransition)] #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct IdentityPublicKeyCreateTransitionWasm(IdentityPublicKeyCreateTransition); +pub struct IdentityPublicKeyCreateTransitionWasm(IdentityPublicKeyWithWitness); #[wasm_bindgen(js_class = IdentityPublicKeyCreateTransition)] impl IdentityPublicKeyCreateTransitionWasm { @@ -169,21 +169,21 @@ impl IdentityPublicKeyCreateTransitionWasm { } impl IdentityPublicKeyCreateTransitionWasm { - pub fn into_inner(self) -> IdentityPublicKeyCreateTransition { + pub fn into_inner(self) -> IdentityPublicKeyWithWitness { self.0 } - pub fn inner(&self) -> &IdentityPublicKeyCreateTransition { + pub fn inner(&self) -> &IdentityPublicKeyWithWitness { &self.0 } - pub fn inner_mut(&mut self) -> &mut IdentityPublicKeyCreateTransition { + pub fn inner_mut(&mut self) -> &mut IdentityPublicKeyWithWitness { &mut self.0 } } -impl From for IdentityPublicKeyCreateTransitionWasm { - fn from(v: IdentityPublicKeyCreateTransition) -> Self { +impl From for IdentityPublicKeyCreateTransitionWasm { + fn from(v: IdentityPublicKeyWithWitness) -> Self { IdentityPublicKeyCreateTransitionWasm(v) } } @@ -195,12 +195,12 @@ impl TryFrom for IdentityPublicKeyCreateTransitionWasm { let str = String::from(js_sys::JSON::stringify(&value)?); let val = serde_json::from_str(&str).map_err(|e| from_dpp_err(e.into()))?; Ok(Self( - IdentityPublicKeyCreateTransition::from_raw_json_object(val).map_err(from_dpp_err)?, + IdentityPublicKeyWithWitness::from_raw_json_object(val).map_err(from_dpp_err)?, )) } } -impl From for IdentityPublicKeyCreateTransition { +impl From for IdentityPublicKeyWithWitness { fn from(pk: IdentityPublicKeyCreateTransitionWasm) -> Self { pk.0 } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs index d2dc9dd2575..514b1ab47aa 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs @@ -2,7 +2,7 @@ use crate::errors::from_dpp_err; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransitionWasm; use crate::validation::ValidationResultWasm; use dpp::document::document_transition::document_base_transition::JsonValue; -use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::state_transition::identity_update_transition::validate_public_keys::IdentityUpdatePublicKeysValidator; use dpp::identity::validation::TPublicKeysValidator; use wasm_bindgen::prelude::wasm_bindgen; @@ -30,7 +30,7 @@ impl IdentityUpdatePublicKeysValidatorWasm { let public_keys = raw_public_keys .into_iter() .map(|raw_key| { - let parsed_key: IdentityPublicKeyCreateTransition = + let parsed_key: IdentityPublicKeyWithWitness = IdentityPublicKeyCreateTransitionWasm::new(raw_key)?.into(); parsed_key diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 5ccef15804f..6e9b21d7d3c 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -17,7 +17,7 @@ use crate::{ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; use crate::utils::generic_of_js_val; -use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::{KeyID, TimestampMillis}; use dpp::prelude::Revision; use dpp::state_transition::StateTransitionIdentitySigned; @@ -40,7 +40,7 @@ struct IdentityUpdateTransitionParams { protocol_version: u32, identity_id: Vec, revision: Revision, - add_public_keys: Option>, + add_public_keys: Option>, disable_public_keys: Option>, public_keys_disabled_at: Option, } @@ -89,7 +89,7 @@ impl IdentityUpdateTransitionWasm { )?; Ok(public_key.clone().into()) }) - .collect::, JsValue>>()?; + .collect::, JsValue>>()?; } self.0.set_public_keys_to_add(keys_to_add); diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/to_object.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/to_object.rs index bc2c03d3e98..a49dd019f9b 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/to_object.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/to_object.rs @@ -2,7 +2,7 @@ use dpp::identity::KeyID; use dpp::state_transition::StateTransitionIdentitySigned; use dpp::{ identifier::Identifier, - identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition, + identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness, identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, state_transition::StateTransitionLike, }; @@ -23,7 +23,7 @@ pub struct ToObject { pub signature: Option>, pub signature_public_key_id: Option, pub public_keys_disabled_at: Option, - pub public_keys_to_add: Option>, + pub public_keys_to_add: Option>, pub public_key_ids_to_disable: Option>, pub identity_id: Identifier, } diff --git a/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs index ef27bb23494..9dea396f180 100644 --- a/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -10,7 +10,7 @@ use dpp::identity::state_transition::validate_public_key_signatures::{ PublicKeysSignaturesValidator, TPublicKeysSignaturesValidator, }; -use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransition; +use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use serde_json::Value as JsonValue; use wasm_bindgen::prelude::wasm_bindgen; @@ -43,7 +43,7 @@ impl PublicKeysSignaturesValidatorWasm { let public_keys = raw_public_keys .into_iter() .map(|raw_key| { - let parsed_key: IdentityPublicKeyCreateTransition = + let parsed_key: IdentityPublicKeyWithWitness = IdentityPublicKeyCreateTransitionWasm::new(raw_key)?.into(); parsed_key .to_raw_json_object(false) From ac432b182801feec95ed1e60980911e4acedc758 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 01:22:05 +0700 Subject: [PATCH 118/228] work on platform value --- packages/rs-platform-value/Cargo.toml | 1 + packages/rs-platform-value/src/inner_value.rs | 1 - packages/rs-platform-value/src/lib.rs | 12 +- packages/rs-platform-value/src/patch/diff.rs | 315 ++++++++++++ packages/rs-platform-value/src/patch/mod.rs | 474 ++++++++++++++++++ packages/rs-platform-value/src/pointer.rs | 109 ++++ packages/rs-platform-value/src/value_map.rs | 33 +- .../src/value_serialization/mod.rs | 2 +- 8 files changed, 939 insertions(+), 8 deletions(-) create mode 100644 packages/rs-platform-value/src/patch/diff.rs create mode 100644 packages/rs-platform-value/src/patch/mod.rs create mode 100644 packages/rs-platform-value/src/pointer.rs diff --git a/packages/rs-platform-value/Cargo.toml b/packages/rs-platform-value/Cargo.toml index ae71e65cd45..d7fc1ddbd6d 100644 --- a/packages/rs-platform-value/Cargo.toml +++ b/packages/rs-platform-value/Cargo.toml @@ -15,6 +15,7 @@ hex = "0.4.3" serde = { version = "1.0.152", features = ["derive"] } serde_json = { version="1.0", features=["preserve_order"] } rand = { version = "0.8.4", features = ["small_rng"] } +treediff = "4.0.2" ### FEATURES ################################################################# diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 45b21a2dbd2..e144d109d37 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,6 +1,5 @@ use crate::value_map::{ValueMap, ValueMapHelper}; use crate::Identifier; -use crate::Value::Bool; use crate::{Error, Value}; use std::collections::BTreeMap; diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 4924b0f0d0e..5af6458227e 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -17,13 +17,13 @@ mod macros; pub mod string_encoding; pub mod system_bytes; mod types; -pub mod value_map; +mod value_map; mod value_serialization; +mod patch; +mod pointer; -use crate::value_map::{ValueMap, ValueMapHelper}; +pub use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; pub type Hash256 = [u8; 32]; @@ -33,6 +33,8 @@ pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; pub use value_serialization::{from_value, to_value}; +pub use patch::{Patch, patch}; + /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] #[derive(Clone, Debug, PartialEq, PartialOrd)] @@ -77,7 +79,7 @@ pub enum Value { EnumU8(Vec), /// An enumeration of strings - EnumString(String), + EnumString(Vec), /// Identifier /// The identifier is very similar to bytes, however it is serialized to Base58 when converted diff --git a/packages/rs-platform-value/src/patch/diff.rs b/packages/rs-platform-value/src/patch/diff.rs new file mode 100644 index 00000000000..9cf73897b00 --- /dev/null +++ b/packages/rs-platform-value/src/patch/diff.rs @@ -0,0 +1,315 @@ +use std::fmt; +use std::fmt::Display; +use crate::Value; + +struct PatchDiffer { + path: String, + patch: super::Patch, + shift: usize, +} + +impl PatchDiffer { + fn new() -> Self { + Self { + path: "/".to_string(), + patch: super::Patch(Vec::new()), + shift: 0, + } + } +} + +impl<'a> treediff::Delegate<'a, treediff::value::Key, Value> for PatchDiffer { + fn push(&mut self, key: &treediff::value::Key) { + use std::fmt::Write; + if self.path.len() != 1 { + self.path.push('/'); + } + match *key { + treediff::value::Key::Index(idx) => write!(self.path, "{}", idx - self.shift).unwrap(), + treediff::value::Key::String(ref key) => append_path(&mut self.path, key), + } + } + + fn pop(&mut self) { + let mut pos = self.path.rfind('/').unwrap_or(0); + if pos == 0 { + pos = 1; + } + self.path.truncate(pos); + self.shift = 0; + } + + fn removed<'b>(&mut self, k: &'b treediff::value::Key, _v: &'a Value) { + let len = self.path.len(); + self.push(k); + self.patch + .0 + .push(super::PatchOperation::Remove(super::RemoveOperation { + path: self.path.clone(), + })); + // Shift indices, we are deleting array elements + if let treediff::value::Key::Index(_) = k { + self.shift += 1; + } + self.path.truncate(len); + } + + fn added(&mut self, k: &treediff::value::Key, v: &Value) { + let len = self.path.len(); + self.push(k); + self.patch + .0 + .push(super::PatchOperation::Add(super::AddOperation { + path: self.path.clone(), + value: v.clone(), + })); + self.path.truncate(len); + } + + fn modified(&mut self, _old: &'a Value, new: &'a Value) { + self.patch + .0 + .push(super::PatchOperation::Replace(super::ReplaceOperation { + path: self.path.clone(), + value: new.clone(), + })); + } +} + +fn append_path(path: &mut String, key: &str) { + path.reserve(key.len()); + for ch in key.chars() { + if ch == '~' { + *path += "~0"; + } else if ch == '/' { + *path += "~1"; + } else { + path.push(ch); + } + } +} + +/// Diff two Platform Value documents and generate a Platform Value Patch (RFC 6902). +/// +/// # Example +/// Diff two JSONs: +/// +/// ```rust +/// #[macro_use] +/// +/// use platform_value::{from_value, patch, platform_value}; +/// +/// # pub fn main() { +/// use treediff::diff; +/// let left = platform_value!({ +/// "title": "Goodbye!", +/// "author" : { +/// "givenName" : "John", +/// "familyName" : "Doe" +/// }, +/// "tags":[ "example", "sample" ], +/// "content": "This will be unchanged" +/// }); +/// +/// let right = platform_value!({ +/// "title": "Hello!", +/// "author" : { +/// "givenName" : "John" +/// }, +/// "tags": [ "example" ], +/// "content": "This will be unchanged", +/// "phoneNumber": "+01-123-456-7890" +/// }); +/// +/// let p = diff(&left, &right); +/// assert_eq!(p, from_value(platform_value!([ +/// { "op": "remove", "path": "/author/familyName" }, +/// { "op": "remove", "path": "/tags/1" }, +/// { "op": "replace", "path": "/title", "value": "Hello!" }, +/// { "op": "add", "path": "/phoneNumber", "value": "+01-123-456-7890" }, +/// ])).unwrap()); +/// +/// let mut doc = left.clone(); +/// patch(&mut doc, &p).unwrap(); +/// assert_eq!(doc, right); +/// +/// # } +/// ``` +pub fn diff(left: &Value, right: &Value) -> super::Patch { + let mut differ = PatchDiffer::new(); + treediff::diff(left, right, &mut differ); + differ.patch +} + +/// A representation of all key types typical Value types will assume. +#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd)] +pub enum PlatformItemKey { + /// A big index + BigSignedIndex(i128), + /// A big index + BigIndex(u128), + /// An array index + SignedIndex(i64), + /// An array index + Index(u64), + /// An array index + Bytes(Vec), + /// A string index for mappings + String(String), +} + +impl Display for PlatformItemKey { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + PlatformItemKey::String(ref v) => v.fmt(f), + PlatformItemKey::Index(ref v) => v.fmt(f), + PlatformItemKey::BigSignedIndex(ref v) => v.fmt(f), + PlatformItemKey::BigIndex(ref v) => v.fmt(f), + PlatformItemKey::SignedIndex(ref v) => v.fmt(f), + PlatformItemKey::Bytes(ref v) => hex::encode(v).fmt(f), + } + } +} + +impl From for Option { + fn from(value: Value) -> Self { + match value { + Value::U128(i) => Some(PlatformItemKey::BigIndex(i)), + Value::I128(i) => Some(PlatformItemKey::BigSignedIndex(i)), + Value::U64(i) => Some(PlatformItemKey::Index(i)), + Value::I64(i) => Some(PlatformItemKey::SignedIndex(i)), + Value::U32(i) => Some(PlatformItemKey::Index(i as u64)), + Value::I32(i) => Some(PlatformItemKey::SignedIndex(i as i64)), + Value::U16(i) => Some(PlatformItemKey::Index(i as u64)), + Value::I16(i) => Some(PlatformItemKey::SignedIndex(i as i64)), + Value::U8(i) => Some(PlatformItemKey::Index(i as u64)), + Value::I8(i) => Some(PlatformItemKey::SignedIndex(i as i64)), + Value::Bytes(bytes) => Some(PlatformItemKey::Bytes(bytes)), + Value::Bytes32(bytes) => Some(PlatformItemKey::Bytes(bytes.into())), + Value::EnumU8(_) => None, + Value::EnumString(_) => None, + Value::Identifier(bytes) => Some(PlatformItemKey::Bytes(bytes.into())), + Value::Float(_) => None, + Value::Text(str) => Some(PlatformItemKey::String(str)), + Value::Bool(_) => None, + Value::Null => None, + Value::Array(_) => None, + Value::Map(_) => None, + } + } +} + +impl treediff::Value for Value { + type Key = PlatformItemKey; + /// The Value type itself. + type Item = Value; + /// Returns `None` if this is a scalar value, and an iterator yielding (Key, Value) pairs + /// otherwise. It is entirely possible for it to yield no values though. + #[allow(clippy::type_complexity)] + fn items<'a>(&'a self) -> Option + 'a>> { + match *self { + Value::Array(ref inner) => { + Some(Box::new(inner.iter().enumerate().map(|(i, v)| (PlatformItemKey::Index(i as u64), v)))) + } + Value::Map(ref inner) => { + Some(Box::new(inner.iter().filter_map(|(s, v)| { + let key : Option = s.clone().into(); + key.map(|k| (k, v)) + }))) + } + _ => None, + } + } +} + +#[cfg(test)] +mod tests { + use crate::{from_value, platform_value, Value}; + + #[test] + pub fn replace_all() { + let left = platform_value!({"title": "Hello!"}); + let p = super::diff(&left, &Value::Null); + assert_eq!( + p, + from_value(platform_value!([ + { "op": "replace", "path": "/", "value": null }, + ])) + .unwrap() + ); + } + + #[test] + pub fn add_all() { + let right = platform_value!({"title": "Hello!"}); + let p = super::diff(&Value::Null, &right); + assert_eq!( + p, + from_value(platform_value!([ + { "op": "replace", "path": "/", "value": { "title": "Hello!" } }, + ])) + .unwrap() + ); + } + + #[test] + pub fn remove_all() { + let left = platform_value!(["hello", "bye"]); + let right = platform_value!([]); + let p = super::diff(&left, &right); + assert_eq!( + p, + from_value(platform_value!([ + { "op": "remove", "path": "/0" }, + { "op": "remove", "path": "/0" }, + ])) + .unwrap() + ); + } + + #[test] + pub fn remove_tail() { + let left = platform_value!(["hello", "bye", "hi"]); + let right = platform_value!(["hello"]); + let p = super::diff(&left, &right); + assert_eq!( + p, + from_value(platform_value!([ + { "op": "remove", "path": "/1" }, + { "op": "remove", "path": "/1" }, + ])) + .unwrap() + ); + } + #[test] + pub fn replace_object() { + let left = platform_value!(["hello", "bye"]); + let right = platform_value!({"hello": "bye"}); + let p = super::diff(&left, &right); + assert_eq!( + p, + from_value(platform_value!([ + { "op": "add", "path": "/hello", "value": "bye" }, + { "op": "remove", "path": "/0" }, + { "op": "remove", "path": "/0" }, + ])) + .unwrap() + ); + } + + #[test] + fn escape_json_keys() { + let mut left = platform_value!({ + "/slashed/path": 1 + }); + let right = platform_value!({ + "/slashed/path": 2, + }); + let patch = super::diff(&left, &right); + + eprintln!("{:?}", patch); + + crate::patch(&mut left, &patch).unwrap(); + assert_eq!(left, right); + } +} diff --git a/packages/rs-platform-value/src/patch/mod.rs b/packages/rs-platform-value/src/patch/mod.rs new file mode 100644 index 00000000000..a11c2f5f888 --- /dev/null +++ b/packages/rs-platform-value/src/patch/mod.rs @@ -0,0 +1,474 @@ +//! A Platform Value Patch and Platform Value Merge Patch implementation for Rust. +//! +//! # Examples +//! Create and patch document using Platform Value Patch: +//! +//! ```rust +//! #[macro_use] +//! use platform_value::{Patch, patch, from_value, platform_value}; +//! +//! # pub fn main() { +//! let mut doc = platform_value!([ +//! { "name": "Andrew" }, +//! { "name": "Maxim" } +//! ]); +//! +//! let p: Patch = from_value(platform_value!([ +//! { "op": "test", "path": "/0/name", "value": "Andrew" }, +//! { "op": "add", "path": "/0/happy", "value": true } +//! ])).unwrap(); +//! +//! patch(&mut doc, &p).unwrap(); +//! assert_eq!(doc, platform_value!([ +//! { "name": "Andrew", "happy": true }, +//! { "name": "Maxim" } +//! ])); +//! +//! # } +//! ``` +//! +//! Create and patch document using Platform Value Merge Patch: +//! +//! ```rust +//! #[macro_use] +//! use platform_value::{merge, platform_value}; +//! +//! # pub fn main() { +//! let mut doc = platform_value!({ +//! "title": "Goodbye!", +//! "author" : { +//! "givenName" : "John", +//! "familyName" : "Doe" +//! }, +//! "tags":[ "example", "sample" ], +//! "content": "This will be unchanged" +//! }); +//! +//! let patch = platform_value!({ +//! "title": "Hello!", +//! "phoneNumber": "+01-123-456-7890", +//! "author": { +//! "familyName": null +//! }, +//! "tags": [ "example" ] +//! }); +//! +//! merge(&mut doc, &patch); +//! assert_eq!(doc, platform_value!({ +//! "title": "Hello!", +//! "author" : { +//! "givenName" : "John" +//! }, +//! "tags": [ "example" ], +//! "content": "This will be unchanged", +//! "phoneNumber": "+01-123-456-7890" +//! })); +//! # } +//! ``` + +use serde::{Deserialize, Serialize}; +use std::borrow::Cow; +use thiserror::Error; +use crate::{Value, ValueMapHelper}; +use crate::value_map::ValueMap; +pub use self::diff::diff; +mod diff; + +/// Representation of Platform Value Patch (list of patch operations) +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +pub struct Patch(pub Vec); + +impl std::ops::Deref for Patch { + type Target = [PatchOperation]; + + fn deref(&self) -> &[PatchOperation] { + &self.0 + } +} + +/// Platform Value Patch 'add' operation representation +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +pub struct AddOperation { + pub path: String, + /// Value to add to the target location. + pub value: Value, +} + +/// Platform Value Patch 'remove' operation representation +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +pub struct RemoveOperation { + pub path: String, +} + +/// Platform Value Patch 'replace' operation representation +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +pub struct ReplaceOperation { + /// The location within the target document where the operation is performed. + pub path: String, + /// Value to replace with. + pub value: Value, +} + +/// Platform Value Patch 'move' operation representation +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +pub struct MoveOperation { + /// The location to move value from. + pub from: String, + /// The location within the target document where the operation is performed. + pub path: String, +} + +/// Platform Value Patch 'copy' operation representation +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] +pub struct CopyOperation { + /// The location to copy value from. + pub from: String, + /// The location within the target document where the operation is performed. + pub path: String, +} + +/// Platform Value Patch 'test' operation representation +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +pub struct TestOperation { + /// The location within the target document where the operation is performed. + pub path: String, + /// Value to test against. + pub value: Value, +} + +/// Platform Value Patch single patch operation +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[serde(tag = "op")] +#[serde(rename_all = "lowercase")] +pub enum PatchOperation { + /// 'add' operation + Add(AddOperation), + /// 'remove' operation + Remove(RemoveOperation), + /// 'replace' operation + Replace(ReplaceOperation), + /// 'move' operation + Move(MoveOperation), + /// 'copy' operation + Copy(CopyOperation), + /// 'test' operation + Test(TestOperation), +} + +/// This type represents all possible errors that can occur when applying Platform Value patch +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum PatchErrorKind { + /// `test` operation failed because values did not match. + #[error("value did not match")] + TestFailed, + /// `from` Platform Value pointer in a `move` or a `copy` operation was incorrect. + #[error("\"from\" path is invalid")] + InvalidFromPointer, + /// `path` Platform Value pointer is incorrect. + #[error("path is invalid")] + InvalidPointer, + /// `move` operation failed because target is inside the `from` location. + #[error("cannot move the value inside itself")] + CannotMoveInsideItself, +} + +/// This type represents all possible errors that can occur when applying Platform Value patch +#[derive(Debug, Error)] +#[error("Operation '/{operation}' failed at path '{path}': {kind}")] +#[non_exhaustive] +pub struct PatchError { + /// Index of the operation that has failed. + pub operation: usize, + /// `path` of the operation. + pub path: String, + /// Kind of the error. + pub kind: PatchErrorKind, +} + +fn translate_error(kind: PatchErrorKind, operation: usize, path: &str) -> PatchError { + PatchError { + operation, + path: path.to_owned(), + kind, + } +} + +fn unescape(s: &str) -> Cow { + if s.contains('~') { + Cow::Owned(s.replace("~1", "/").replace("~0", "~")) + } else { + Cow::Borrowed(s) + } +} + +fn parse_index(str: &str, len: usize) -> Result { + // RFC 6901 prohibits leading zeroes in index + if (str.starts_with('0') && str.len() != 1) || str.starts_with('+') { + return Err(PatchErrorKind::InvalidPointer); + } + match str.parse::() { + Ok(index) if index < len => Ok(index), + _ => Err(PatchErrorKind::InvalidPointer), + } +} + +fn split_pointer(pointer: &str) -> Result<(&str, &str), PatchErrorKind> { + pointer + .rfind('/') + .ok_or(PatchErrorKind::InvalidPointer) + .map(|idx| (&pointer[0..idx], &pointer[idx + 1..])) +} + +fn add(doc: &mut Value, path: &str, value: Value) -> Result, PatchErrorKind> { + if path.is_empty() { + return Ok(Some(std::mem::replace(doc, value))); + } + + let (parent, last_unescaped) = split_pointer(path)?; + let parent = doc + .pointer_mut(parent) + .ok_or(PatchErrorKind::InvalidPointer)?; + + match *parent { + Value::Map(ref mut obj) => { + obj.insert_string_key_value(unescape(last_unescaped).into_owned(), value.clone()); + Ok(Some(value)) + }, + Value::Array(ref mut arr) if last_unescaped == "-" => { + arr.push(value); + Ok(None) + } + Value::Array(ref mut arr) => { + let idx = parse_index(last_unescaped, arr.len() + 1)?; + arr.insert(idx, value); + Ok(None) + } + _ => Err(PatchErrorKind::InvalidPointer), + } +} + +fn remove(doc: &mut Value, path: &str, allow_last: bool) -> Result { + let (parent, last_unescaped) = split_pointer(path)?; + let parent = doc + .pointer_mut(parent) + .ok_or(PatchErrorKind::InvalidPointer)?; + + match *parent { + Value::Map(ref mut obj) => match obj.remove_optional_key(unescape(last_unescaped).as_ref()) { + None => Err(PatchErrorKind::InvalidPointer), + Some(val) => Ok(val), + }, + Value::Array(ref mut arr) if allow_last && last_unescaped == "-" => Ok(arr.pop().unwrap()), + Value::Array(ref mut arr) => { + let idx = parse_index(last_unescaped, arr.len())?; + Ok(arr.remove(idx)) + } + _ => Err(PatchErrorKind::InvalidPointer), + } +} + +fn replace(doc: &mut Value, path: &str, value: Value) -> Result { + let target = doc + .pointer_mut(path) + .ok_or(PatchErrorKind::InvalidPointer)?; + Ok(std::mem::replace(target, value)) +} + +fn mov( + doc: &mut Value, + from: &str, + path: &str, + allow_last: bool, +) -> Result, PatchErrorKind> { + // Check we are not moving inside own child + if path.starts_with(from) && path[from.len()..].starts_with('/') { + return Err(PatchErrorKind::CannotMoveInsideItself); + } + let val = remove(doc, from, allow_last).map_err(|err| match err { + PatchErrorKind::InvalidPointer => PatchErrorKind::InvalidFromPointer, + err => err, + })?; + add(doc, path, val) +} + +fn copy(doc: &mut Value, from: &str, path: &str) -> Result, PatchErrorKind> { + let source = doc + .pointer(from) + .ok_or(PatchErrorKind::InvalidFromPointer)? + .clone(); + add(doc, path, source) +} + +fn test(doc: &Value, path: &str, expected: &Value) -> Result<(), PatchErrorKind> { + let target = doc.pointer(path).ok_or(PatchErrorKind::InvalidPointer)?; + if *target == *expected { + Ok(()) + } else { + Err(PatchErrorKind::TestFailed) + } +} + +/// Patch provided Platform Value document (given as `platform_value::Value`) in-place. If any of the patch is +/// failed, all previous operations are reverted. In case of internal error resulting in panic, +/// document might be left in inconsistent state. +/// +/// # Example +/// Create and patch document: +/// +/// ```rust +/// #[macro_use] +/// use platform_value::{Patch, patch, from_value, platform_value}; +/// +/// # pub fn main() { +/// let mut doc = platform_value!([ +/// { "name": "Andrew" }, +/// { "name": "Maxim" } +/// ]); +/// +/// let p: Patch = from_value(platform_value!([ +/// { "op": "test", "path": "/0/name", "value": "Andrew" }, +/// { "op": "add", "path": "/0/happy", "value": true } +/// ])).unwrap(); +/// +/// patch(&mut doc, &p).unwrap(); +/// assert_eq!(doc, platform_value!([ +/// { "name": "Andrew", "happy": true }, +/// { "name": "Maxim" } +/// ])); +/// +/// # } +/// ``` +pub fn patch(doc: &mut Value, patch: &[PatchOperation]) -> Result<(), PatchError> { + apply_patches(doc, 0, patch) +} + +// Apply patches while tracking all the changes being made so they can be reverted back in case +// subsequent patches fail. Uses stack recursion to keep the state. +fn apply_patches( + doc: &mut Value, + operation: usize, + patches: &[PatchOperation], +) -> Result<(), PatchError> { + let (patch, tail) = match patches.split_first() { + None => return Ok(()), + Some((patch, tail)) => (patch, tail), + }; + + match *patch { + PatchOperation::Add(ref op) => { + let prev = add(doc, &op.path, op.value.clone()) + .map_err(|e| translate_error(e, operation, &op.path))?; + apply_patches(doc, operation + 1, tail).map_err(move |e| { + match prev { + None => remove(doc, &op.path, true).unwrap(), + Some(v) => add(doc, &op.path, v).unwrap().unwrap(), + }; + e + }) + } + PatchOperation::Remove(ref op) => { + let prev = remove(doc, &op.path, false) + .map_err(|e| translate_error(e, operation, &op.path))?; + apply_patches(doc, operation + 1, tail).map_err(move |e| { + assert!(add(doc, &op.path, prev).unwrap().is_none()); + e + }) + } + PatchOperation::Replace(ref op) => { + let prev = replace(doc, &op.path, op.value.clone()) + .map_err(|e| translate_error(e, operation, &op.path))?; + apply_patches(doc, operation + 1, tail).map_err(move |e| { + replace(doc, &op.path, prev).unwrap(); + e + }) + } + PatchOperation::Move(ref op) => { + let prev = mov(doc, op.from.as_str(), &op.path, false) + .map_err(|e| translate_error(e, operation, &op.path))?; + apply_patches(doc, operation + 1, tail).map_err(move |e| { + mov(doc, &op.path, op.from.as_str(), true).unwrap(); + if let Some(prev) = prev { + assert!(add(doc, &op.path, prev).unwrap().is_none()); + } + e + }) + } + PatchOperation::Copy(ref op) => { + let prev = copy(doc, op.from.as_str(), &op.path) + .map_err(|e| translate_error(e, operation, &op.path))?; + apply_patches(doc, operation + 1, tail).map_err(move |e| { + match prev { + None => remove(doc, &op.path, true).unwrap(), + Some(v) => add(doc, &op.path, v).unwrap().unwrap(), + }; + e + }) + } + PatchOperation::Test(ref op) => { + test(doc, &op.path, &op.value).map_err(|e| translate_error(e, operation, &op.path))?; + apply_patches(doc, operation + 1, tail) + } + } +} + +/// Patch provided Platform Value document (given as `platform_value::Value`) in place with Platform Value Merge Patch +/// (RFC 7396). +/// +/// # Example +/// Create and patch document: +/// +/// ```rust +/// #[macro_use] +/// use platform_value::{merge, platform_value}; +/// +/// # pub fn main() { +/// let mut doc = platform_value!({ +/// "title": "Goodbye!", +/// "author" : { +/// "givenName" : "John", +/// "familyName" : "Doe" +/// }, +/// "tags":[ "example", "sample" ], +/// "content": "This will be unchanged" +/// }); +/// +/// let patch = platform_value!({ +/// "title": "Hello!", +/// "phoneNumber": "+01-123-456-7890", +/// "author": { +/// "familyName": null +/// }, +/// "tags": [ "example" ] +/// }); +/// +/// merge(&mut doc, &patch); +/// assert_eq!(doc, platform_value!({ +/// "title": "Hello!", +/// "author" : { +/// "givenName" : "John" +/// }, +/// "tags": [ "example" ], +/// "content": "This will be unchanged", +/// "phoneNumber": "+01-123-456-7890" +/// })); +/// # } +/// ``` +pub fn merge(doc: &mut Value, patch: &Value) { + if !patch.is_map() { + *doc = patch.clone(); + return; + } + + if !doc.is_map() { + *doc = Value::Map(ValueMap::new()); + } + let map = doc.as_map_mut().unwrap(); + for (key, value) in patch.as_map().unwrap() { + if value.is_null() { + map.remove_optional_key_value(value); + } else { + merge(map.get_key_by_value_mut_or_insert(key,Value::Null), value); + } + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/pointer.rs b/packages/rs-platform-value/src/pointer.rs new file mode 100644 index 00000000000..47d2b76e4b7 --- /dev/null +++ b/packages/rs-platform-value/src/pointer.rs @@ -0,0 +1,109 @@ +use crate::{Value, ValueMapHelper}; + +fn parse_index(s: &str) -> Option { + if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) { + return None; + } + s.parse().ok() +} + +impl Value { + /// Looks up a value by a Platform Value Pointer. + /// + /// Platform Value Pointer defines a string syntax for identifying a specific value + /// within a Platform Value document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Examples + /// + /// ``` + /// # use platform_value::platform_value; + /// # + /// let data = platform_value!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data.pointer("/x/y/1").unwrap(), &platform_value!("zz")); + /// assert_eq!(data.pointer("/a/b/c"), None); + /// ``` + pub fn pointer(&self, pointer: &str) -> Option<&Value> { + if pointer.is_empty() { + return Some(self); + } + if !pointer.starts_with('/') { + return None; + } + pointer + .split('/') + .skip(1) + .map(|x| x.replace("~1", "/").replace("~0", "~")) + .try_fold(self, |target, token| match target { + Value::Map(map) => map.get_key(&token), + Value::Array(list) => parse_index(&token).and_then(|x| list.get(x)), + _ => None, + }) + } + + /// Looks up a value by a Platform Value Pointer and returns a mutable reference to + /// that value. + /// + /// Platform Value Pointer defines a string syntax for identifying a specific value + /// within a Platform Value document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Example of Use + /// + /// ``` + /// use platform_value::Value; + /// + /// fn main() { + /// let s = r#"{"x": 1.0, "y": 2.0}"#; + /// let mut value: Value = serde_json::from_str(s).unwrap().into(); + /// + /// // Check value using read-only pointer + /// assert_eq!(value.pointer("/x"), Some(&1.0.into())); + /// // Change value with direct assignment + /// *value.pointer_mut("/x").unwrap() = 1.5.into(); + /// // Check that new value was written + /// assert_eq!(value.pointer("/x"), Some(&1.5.into())); + /// // Or change the value only if it exists + /// value.pointer_mut("/x").map(|v| *v = 1.5.into()); + /// + /// // "Steal" ownership of a value. Can replace with any valid Value. + /// let old_x = value.pointer_mut("/x").map(Value::take).unwrap(); + /// assert_eq!(old_x, 1.5); + /// assert_eq!(value.pointer("/x").unwrap(), &Value::Null); + /// } + /// ``` + pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut Value> { + if pointer.is_empty() { + return Some(self); + } + if !pointer.starts_with('/') { + return None; + } + pointer + .split('/') + .skip(1) + .map(|x| x.replace("~1", "/").replace("~0", "~")) + .try_fold(self, |target, token| match target { + Value::Map(map) => map.get_key_mut(&token), + Value::Array(list) => parse_index(&token).and_then(move |x| list.get_mut(x)), + _ => None, + }) + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index fbb269b6820..f6493ac8251 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,5 +1,4 @@ use crate::{Error, Value}; -use std::collections::hash_map::Entry; use std::collections::BTreeMap; pub type ValueMap = Vec<(Value, Value)>; @@ -8,8 +7,11 @@ pub trait ValueMapHelper { fn get_key(&self, key: &str) -> Option<&Value>; fn get_key_mut(&mut self, key: &str) -> Option<&mut Value>; fn get_key_mut_or_insert(&mut self, key: &str, value: Value) -> &mut Value; + fn get_key_by_value_mut_or_insert(&mut self, search_key: &Value, value: Value) -> &mut Value; + fn insert_string_key_value(&mut self, key: String, value: Value); fn remove_key(&mut self, search_key: &str) -> Result; fn remove_optional_key(&mut self, key: &str) -> Option; + fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option; } impl ValueMapHelper for ValueMap { @@ -62,6 +64,27 @@ impl ValueMapHelper for ValueMap { } } + fn get_key_by_value_mut_or_insert(&mut self, search_key: &Value, value: Value) -> &mut Value { + let found = self.iter().position(|(key, _)| { + search_key == key + }); + match found { + None => { + self.push((search_key.clone(), value)); + let (_, value) = self.last_mut().unwrap(); + value + } + Some(pos) => { + let (_, value) = self.get_mut(pos).unwrap(); + value + } + } + } + + fn insert_string_key_value(&mut self, key: String, value: Value) { + self.push((key.into(), value)) + } + fn remove_key(&mut self, search_key: &str) -> Result { self.iter() .position(|(key, _)| { @@ -89,6 +112,14 @@ impl ValueMapHelper for ValueMap { }) .map(|pos| self.remove(pos).1) } + + fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option { + self.iter() + .position(|(key, _)| { + search_key_value == key + }) + .map(|pos| self.remove(pos).1) + } } impl Value { diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index 29a5a340431..5e70b91bd4c 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -1,7 +1,7 @@ use crate::value_serialization::ser::Serializer; use crate::{Error, Value}; use serde::Serialize; -use serde::{de::DeserializeOwned, Deserialize}; +use serde::{Deserialize}; pub mod de; pub mod ser; From e45a7239ed99e1cb883b8e43bf098aa5f496c3f4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 02:26:23 +0700 Subject: [PATCH 119/228] fixes --- Cargo.lock | 11 ++++- .../src/data_contract/document_type/index.rs | 3 +- ...e_data_contract_update_transition_basic.rs | 19 ++++---- .../validation/multi_validator.rs | 8 ++-- .../withdrawals_data_triggers/mod.rs | 15 +++--- .../rs-dpp/src/document/document_factory.rs | 3 +- .../document_create_transition.rs | 29 ++++++------ .../basic/find_duplicates_by_indices.rs | 3 +- .../src/identity/identity_public_key/mod.rs | 15 ++++-- .../identity_create_transition.rs | 46 +++++++++---------- .../data_contract/data_contract_meta.rs | 2 +- .../tests/fixtures/get_documents_fixture.rs | 27 ++++++----- ...ternode_reward_shares_documents_fixture.rs | 11 ++--- ...ty_credit_withdrawal_transition_fixture.rs | 1 + .../src/tests/fixtures/identity_fixture.rs | 2 +- .../identity/identity_public_key_spec.rs | 27 +++++------ .../identity_update_transition_spec.rs | 2 +- .../src/inner_value_at_path.rs | 31 +++++++++++++ packages/rs-platform-value/src/macros.rs | 4 +- packages/rs-platform-value/src/patch/diff.rs | 26 +++++++---- .../wasm-dpp/src/identity/factory_utils.rs | 2 +- .../src/identity/identity_public_key/mod.rs | 2 +- 22 files changed, 172 insertions(+), 117 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39f840f83cc..58d2a59c32f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1593,7 +1593,7 @@ checksum = "eb3fa5a61630976fc4c353c70297f2e93f1930e3ccee574d59d618ccbd5154ce" dependencies = [ "serde", "serde_json", - "treediff", + "treediff 3.0.2", ] [[package]] @@ -1626,7 +1626,7 @@ source = "git+https://github.com/fominok/jsonschema-rs?branch=feat-unevaluated-p dependencies = [ "ahash 0.7.6", "anyhow", - "base64 0.13.1", + "base64 0.21.0", "bytecount", "fancy-regex", "fraction", @@ -2224,6 +2224,7 @@ dependencies = [ "serde", "serde_json", "thiserror", + "treediff 4.0.2", ] [[package]] @@ -3185,6 +3186,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "treediff" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52984d277bdf2a751072b5df30ec0377febdb02f7696d64c2d7d54630bac4303" + [[package]] name = "triomphe" version = "0.1.8" diff --git a/packages/rs-dpp/src/data_contract/document_type/index.rs b/packages/rs-dpp/src/data_contract/document_type/index.rs index 0368d08b574..5c7b7bb1874 100644 --- a/packages/rs-dpp/src/data_contract/document_type/index.rs +++ b/packages/rs-dpp/src/data_contract/document_type/index.rs @@ -2,8 +2,7 @@ use crate::data_contract::errors::{DataContractError, StructureError}; use crate::ProtocolError; use anyhow::bail; -use platform_value::value_map::ValueMap; -use platform_value::Value; +use platform_value::{Value, ValueMap}; use rand::distributions::{Alphanumeric, DistString}; use serde::{Deserialize, Serialize}; use std::{collections::BTreeMap, convert::TryFrom}; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index f5b510ba406..3a595ec988a 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -78,7 +78,7 @@ where let result = self.json_schema_validator.validate( &raw_state_transition .try_into_validating_json() - .map_err(ProtocolError::ValueError)?, + .map_err(ProtocolError::ValueError)? )?; if !result.is_valid() { return Ok(result); @@ -102,16 +102,15 @@ where } // Validate Data Contract - let data_contract_object = raw_state_transition.get_value(property_names::DATA_CONTRACT)?; + let new_data_contract_object = raw_state_transition.get_value(property_names::DATA_CONTRACT)?; let result = self .data_contract_validator - .validate(data_contract_object)?; + .validate(new_data_contract_object)?; if !result.is_valid() { return Ok(result); } - let raw_data_contract_id = data_contract_object.get_bytes(contract_property_names::ID)?; - let data_contract_id = Identifier::from_bytes(&raw_data_contract_id)?; + let data_contract_id = new_data_contract_object.get_identifier(contract_property_names::ID).map_err(ProtocolError::ValueError)?; if execution_context.is_dry_run() { return Ok(result); @@ -134,7 +133,7 @@ where } }; - let new_version = data_contract_object.get_integer(contract_property_names::VERSION)?; + let new_version = new_data_contract_object.get_integer(contract_property_names::VERSION)?; let old_version = existing_data_contract.version; if (new_version - old_version) != 1 { validation_result.add_error(BasicError::InvalidDataContractVersionError( @@ -151,7 +150,7 @@ where ]) .map_err(ProtocolError::ValueError)?; - let mut new_base_data_contract = data_contract_object.clone(); + let mut new_base_data_contract = new_data_contract_object.clone(); new_base_data_contract .remove(contract_property_names::DEFINITIONS) .ok(); @@ -159,7 +158,7 @@ where new_base_data_contract.remove(contract_property_names::VERSION)?; let base_data_contract_diff = - json_patch::diff(&old_base_data_contract, &new_base_data_contract); + json_patch::diff(&existing_data_contract_object, &new_base_data_contract); for diff in base_data_contract_diff.0.iter() { let (operation, property_name) = get_operation_and_property_name(diff); @@ -176,7 +175,7 @@ where // Schema should be backward compatible let old_schema = &existing_data_contract.documents; - let new_schema = data_contract_object.get_value("documents")?; + let new_schema = new_data_contract_object.get_value("documents")?; for (document_type, document_schema) in old_schema.iter() { let new_document_schema = new_schema.get(document_type).unwrap_or(&EMPTY_JSON); @@ -207,7 +206,7 @@ where } // check indices are not changed - let new_documents = data_contract_object + let new_documents = new_data_contract_object .get_value("documents")? .as_object() .ok_or_else(|| anyhow!("the 'documents' property is not an array"))?; diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index db08a5d10db..34a6f554b24 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -135,7 +135,7 @@ mod test { #[test] fn should_return_error_if_bytes_array_parent_contains_items_or_prefix_items() { - let schema: Value = json!( + let schema: Value = platform_value!( { "type": "object", "properties": { @@ -169,7 +169,7 @@ mod test { #[test] fn should_return_valid_result() { - let schema: Value = json!( + let schema: Value = platform_value!( { "type": "object", "properties": { @@ -190,7 +190,7 @@ mod test { #[test] fn should_return_invalid_result() { - let schema: Value = json!({ + let schema: Value = platform_value!({ "type": "object", "properties": { "foo": { "type": "integer" }, @@ -277,7 +277,7 @@ mod test { } fn get_document_schema() -> Value { - json!({ + platform_value!({ "properties": { "simple": { "type": "string" diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index 56f865e2d7d..154f170a67f 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -88,6 +88,7 @@ where #[cfg(test)] mod tests { + use platform_value::platform_value; use super::*; use crate::identity::state_transition::identity_credit_withdrawal_transition::Pooling; use crate::state_repository::MockStateRepositoryLike; @@ -138,14 +139,14 @@ mod tests { let document = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::BROADCASTED, - "transactionIndex": 1, - "transactionSignHeight": 93, + "status": withdrawals_contract::WithdrawalStatus::BROADCASTED as u8, + "transactionIndex": 1u32, + "transactionSignHeight": 93u64, "transactionId": vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], }), None, diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index cef41d68562..e8b4f96e44b 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -433,6 +433,7 @@ mod test { use platform_value::string_encoding::Encoding; use serde_json::json; use std::sync::Arc; + use platform_value::platform_value; use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ @@ -476,7 +477,7 @@ mod test { data_contract, owner_id, document_type.to_string(), - json!({ "name": name }).into(), + platform_value!({ "name": name }), ) .expect("document creation shouldn't fail"); assert_eq!(document_type, document.document_type_name); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index e13b33d8849..d852bb86328 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -209,6 +209,8 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { #[cfg(test)] mod test { use serde_json::json; + use platform_value::{Identifier, platform_value}; + use platform_value::string_encoding::Encoding; use super::*; @@ -275,25 +277,26 @@ mod test { #[test] fn convert_to_json_with_dynamic_binary_paths() { let data_contract = data_contract_with_dynamic_properties(); - let alpha_value = vec![10_u8; 32]; - let id = vec![11_u8; 32]; - let data_contract_id = vec![13_u8; 32]; + let alpha_binary = vec![10_u8; 32]; + let alpha_identifier = Identifier::from([10_u8; 32]); + let id = Identifier::from([11_u8; 32]); + let data_contract_id = Identifier::from([13_u8; 32]); let entropy = vec![14_u8; 32]; - let raw_document = json!({ - "$protocolVersion" : 0, + let raw_document = platform_value!({ + "$protocolVersion" : 0u32, "$id" : id, "$type" : "test", "$dataContractId" : data_contract_id, - "revision" : 1, - "alphaBinary" : alpha_value, - "alphaIdentifier" : alpha_value, + "revision" : 1u32, + "alphaBinary" : alpha_binary, + "alphaIdentifier" : alpha_identifier, "$entropy" : entropy, - "$action": 0 , + "$action": 0u8, }); let transition: DocumentCreateTransition = - DocumentCreateTransition::from_json_object(raw_document, data_contract).unwrap(); + DocumentCreateTransition::from_raw_object(raw_document, data_contract).unwrap(); let json_transition = transition.to_json().expect("no errors"); assert_eq!( @@ -306,11 +309,11 @@ mod test { ); assert_eq!( json_transition["alphaBinary"], - JsonValue::String(base64::encode(&alpha_value)) + JsonValue::String(base64::encode(&alpha_binary)) ); assert_eq!( json_transition["alphaIdentifier"], - JsonValue::String(bs58::encode(&alpha_value).into_string()) + JsonValue::String(alpha_identifier.to_string(Encoding::Base58)) ); assert_eq!( json_transition["$entropy"], @@ -319,7 +322,7 @@ mod test { } #[test] - fn covert_to_object_with_dynamic_binary_paths() { + fn covert_to_object_from_json_value_with_dynamic_binary_paths() { let data_contract = data_contract_with_dynamic_properties(); let alpha_value = vec![10_u8; 32]; let id = vec![11_u8; 32]; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index 6a14b568fa0..454c1041170 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -1,6 +1,5 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::value_map::ValueMap; -use platform_value::Value; +use platform_value::{Value, ValueMap}; use std::collections::btree_map::Entry; use std::collections::BTreeMap; diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index fd417a9dab6..525e01a3fa0 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -6,7 +6,7 @@ pub mod purpose; pub mod security_level; pub mod serialize; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; use ciborium::value::Value as CborValue; @@ -115,9 +115,8 @@ impl IdentityPublicKey { vec::vec_to_array::<33>(&self.data) } - pub fn from_raw_object(raw_object: JsonValue) -> Result { - let identity_public_key: IdentityPublicKey = serde_json::from_value(raw_object)?; - Ok(identity_public_key) + pub fn from_value(value: Value) -> Result { + value.try_into() } pub fn from_json_object(mut raw_object: JsonValue) -> Result { @@ -219,6 +218,14 @@ impl TryInto for IdentityPublicKey { } } +impl TryFrom for IdentityPublicKey { + type Error = ProtocolError; + + fn try_from(value: Value) -> Result { + platform_value::from_value(value).map_err(ProtocolError::ValueError) + } +} + pub fn de_base64_to_vec<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { let data: String = Deserialize::deserialize(d)?; base64::decode(data) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 2fbe06ac7d4..b8e333ba20e 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -70,29 +70,29 @@ impl From for StateTransition { } } -impl Serialize for IdentityCreateTransition { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let raw = self - .to_json_object(Default::default()) - .map_err(|e| S::Error::custom(e.to_string()))?; - - raw.serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for IdentityCreateTransition { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let value = platform_value::Value::deserialize(deserializer)?; - - Self::new(value).map_err(|e| D::Error::custom(e.to_string())) - } -} +// impl Serialize for IdentityCreateTransition { +// fn serialize(&self, serializer: S) -> Result +// where +// S: Serializer, +// { +// let raw = self +// .to_json_object(Default::default()) +// .map_err(|e| S::Error::custom(e.to_string()))?; +// +// raw.serialize(serializer) +// } +// } +// +// impl<'de> Deserialize<'de> for IdentityCreateTransition { +// fn deserialize(deserializer: D) -> Result +// where +// D: Deserializer<'de>, +// { +// let value = platform_value::Value::deserialize(deserializer)?; +// +// Self::new(value).map_err(|e| D::Error::custom(e.to_string())) +// } +// } /// Main state transition functionality implementation impl IdentityCreateTransition { diff --git a/packages/rs-dpp/src/schema/data_contract/data_contract_meta.rs b/packages/rs-dpp/src/schema/data_contract/data_contract_meta.rs index 9784e895e89..9440ad18698 100644 --- a/packages/rs-dpp/src/schema/data_contract/data_contract_meta.rs +++ b/packages/rs-dpp/src/schema/data_contract/data_contract_meta.rs @@ -453,7 +453,7 @@ // }"#; // // let json_schema = serde_json::from_str(data)?; -// let kek = json!({ "string": "yes" }); +// let kek = platform_value!({ "string": "yes" }); // // JSONSchema::compile(&kek) // } diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 245a4a61c64..a098f84ae39 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -3,7 +3,7 @@ use rand::SeedableRng; use std::sync::Arc; -use platform_value::Value; +use platform_value::{platform_value, Value}; use serde_json::{json, Value as JsonValue}; use crate::contracts::withdrawals_contract::document_types; @@ -71,56 +71,56 @@ fn get_extended_documents( data_contract.clone(), owner_id, "niceDocument".to_string(), - json!({ "name": "Cutie" }).into(), + platform_value!({ "name": "Cutie" }).into(), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "prettyDocument".to_string(), - json!({ "lastName": "Shiny" }).into(), + platform_value!({ "lastName": "Shiny" }).into(), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "prettyDocument".to_string(), - json!({ "lastName": "Sweety" }).into(), + platform_value!({ "lastName": "Sweety" }).into(), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - json!( { "firstName": "William", "lastName": "Birkin" }).into(), + platform_value!( { "firstName": "William", "lastName": "Birkin" }).into(), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - json!( { "firstName": "Leon", "lastName": "Kennedy" }).into(), + platform_value!( { "firstName": "Leon", "lastName": "Kennedy" }).into(), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "noTimeDocument".to_string(), - json!({ "name": "ImOutOfTime" }).into(), + platform_value!({ "name": "ImOutOfTime" }).into(), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "uniqueDates".to_string(), - json!({ "firstName": "John" }).into(), + platform_value!({ "firstName": "John" }).into(), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - json!( { "firstName": "Bill", "lastName": "Gates" }).into(), + platform_value!( { "firstName": "Bill", "lastName": "Gates" }).into(), )?, - factory.create_extended_document_for_state_transition(data_contract.clone(), owner_id, "withByteArrays".to_string(), json!( { "byteArrayField": get_random_10_bytes(), "identifierField": gen_owner_id().to_buffer() }).into())?, + factory.create_extended_document_for_state_transition(data_contract.clone(), owner_id, "withByteArrays".to_string(), platform_value!( { "byteArrayField": get_random_10_bytes(), "identifierField": gen_owner_id().to_buffer() }).into())?, factory.create_extended_document_for_state_transition( data_contract, owner_id, "optionalUniqueIndexedDocument".to_string(), - json!({ "firstName": "Jacques-Yves", "lastName": "Cousteau" }).into() + platform_value!({ "firstName": "Jacques-Yves", "lastName": "Cousteau" }).into() )?, ]; @@ -130,7 +130,7 @@ fn get_extended_documents( pub fn get_withdrawal_document_fixture( data_contract: &DataContract, owner_id: Identifier, - data: JsonValue, + data: Value, seed: Option, ) -> Result { let mut rng = match seed { @@ -140,8 +140,7 @@ pub fn get_withdrawal_document_fixture( let document_type = data_contract.document_type_for_name(document_types::WITHDRAWAL)?; - let value: Value = data.into(); - let properties = value + let properties = data .into_btree_string_map() .map_err(ProtocolError::ValueError)?; diff --git a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs index 317ff0acc78..0ee58dc6971 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_masternode_reward_shares_documents_fixture.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use data_contracts::SystemDataContract; -use serde_json::json; +use platform_value::platform_value; use crate::document::ExtendedDocument; use crate::system_data_contracts::load_system_data_contract; @@ -38,11 +38,10 @@ pub fn get_masternode_reward_shares_documents_fixture() -> (Vec platform_value::Value { } pub fn identity_fixture_json() -> serde_json::Value { - json!({ + platform_value!({ "protocolVersion": 1, "id": "3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT", "publicKeys": [ diff --git a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs index a6c4a4fd651..33a2b86c9d7 100644 --- a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs +++ b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs @@ -2,12 +2,13 @@ mod from_raw_object { use bls_signatures::Serialize; use dashcore::PublicKey; use serde_json::json; + use platform_value::platform_value; use crate::identity::{KeyType, Purpose, SecurityLevel}; use crate::prelude::IdentityPublicKey; #[test] - pub fn should_parse_raw_key() { + pub fn should_parse_raw_json_key() { let public_key_json = json!({ "id": 0, "type": 0, @@ -149,16 +150,16 @@ mod from_raw_object { .unwrap() .to_bytes(); - let public_key_json = json!({ - "id": 0, - "type": KeyType::ECDSA_SECP256K1, - "purpose": Purpose::AUTHENTICATION, - "securityLevel": SecurityLevel::MASTER, + let public_key_json = platform_value!({ + "id": 0u32, + "type": KeyType::ECDSA_SECP256K1 as u8, + "purpose": Purpose::AUTHENTICATION as u8, + "securityLevel": SecurityLevel::MASTER as u8, "data": public_key, "readOnly": false }); - let public_key = IdentityPublicKey::from_raw_object(public_key_json) + let public_key = IdentityPublicKey::from_value(public_key_json) .expect("the public key should be created"); assert_eq!(public_key.key_type, KeyType::ECDSA_SECP256K1); assert_eq!( @@ -177,16 +178,16 @@ mod from_raw_object { .public_key() .as_bytes(); - let public_key_json = json!({ - "id": 0, - "type": KeyType::BLS12_381, - "purpose": Purpose::AUTHENTICATION, - "securityLevel": SecurityLevel::MASTER, + let public_key_json = platform_value!({ + "id": 0u32, + "type": KeyType::BLS12_381 as u8, + "purpose": Purpose::AUTHENTICATION as u8, + "securityLevel": SecurityLevel::MASTER as u8, "data": bls_public_key, "readOnly": false }); - let public_key = IdentityPublicKey::from_raw_object(public_key_json) + let public_key = IdentityPublicKey::from_value(public_key_json) .expect("the public key should be created"); assert_eq!(public_key.key_type, KeyType::BLS12_381); assert_eq!( diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index 95704e2e972..ff421a644a5 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -199,7 +199,7 @@ fn to_json() { .to_json(false) .expect("conversion to json shouldn't fail"); - let expected_raw_state_transition = json!({ + let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1, "type" : 5, "signature" : "", diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index 92e073965cf..e84c25ae530 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -120,3 +120,34 @@ impl Value { Ok(Self::insert_in_map(map, key, value)) } } +#[cfg(test)] +mod test { + use crate::platform_value; + + #[test] + fn insert_with_parents() { + let mut document = platform_value!({ + "root" : { + "from" : { + "id": "123", + "message": "text_message", + }, + } + }); + + document + .set_value_at_full_path("root.to.new_field", platform_value!("new_value")) + .expect("no errors"); + document + .set_value_at_full_path("root.array[0].new_field", platform_value!("new_value")) + .expect("no errors"); + + assert_eq!(document["root"]["from"]["id"], platform_value!("123")); + assert_eq!(document["root"]["from"]["message"], platform_value!("text_message")); + assert_eq!(document["root"]["to"]["new_field"], platform_value!("new_value")); + assert_eq!( + document["root"]["array"][0]["new_field"], + platform_value!("new_value") + ); + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index 4ed24d50373..285c064ddb2 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -256,12 +256,12 @@ macro_rules! platform_value_internal { }; ({}) => { - $crate::Value::Map($crate::value_map::ValueMap::new()) + $crate::Value::Map($crate::ValueMap::new()) }; ({ $($tt:tt)+ }) => { $crate::Value::Map({ - let mut object = $crate::value_map::ValueMap::new(); + let mut object = $crate::ValueMap::new(); platform_value_internal!(@object object () ($($tt)+) ($($tt)+)); object }) diff --git a/packages/rs-platform-value/src/patch/diff.rs b/packages/rs-platform-value/src/patch/diff.rs index 9cf73897b00..8962d6d2ace 100644 --- a/packages/rs-platform-value/src/patch/diff.rs +++ b/packages/rs-platform-value/src/patch/diff.rs @@ -18,15 +18,20 @@ impl PatchDiffer { } } -impl<'a> treediff::Delegate<'a, treediff::value::Key, Value> for PatchDiffer { - fn push(&mut self, key: &treediff::value::Key) { +impl<'a> treediff::Delegate<'a, PlatformItemKey, Value> for PatchDiffer { + fn push(&mut self, key: &PlatformItemKey) { use std::fmt::Write; if self.path.len() != 1 { self.path.push('/'); } - match *key { - treediff::value::Key::Index(idx) => write!(self.path, "{}", idx - self.shift).unwrap(), - treediff::value::Key::String(ref key) => append_path(&mut self.path, key), + match key { + PlatformItemKey::Index(idx) => write!(self.path, "{}", *idx).unwrap(), + PlatformItemKey::String(ref key) => append_path(&mut self.path, key), + PlatformItemKey::BigSignedIndex(idx) => write!(self.path, "{}", *idx).unwrap(), + PlatformItemKey::BigIndex(idx) => write!(self.path, "{}", *idx).unwrap(), + PlatformItemKey::SignedIndex(idx) => write!(self.path, "{}", *idx).unwrap(), + PlatformItemKey::Bytes(bytes) => write!(self.path, "{}", hex::encode(bytes)).unwrap(), + PlatformItemKey::ArrayIndex(idx) => write!(self.path, "{}", *idx - self.shift).unwrap(), } } @@ -39,7 +44,7 @@ impl<'a> treediff::Delegate<'a, treediff::value::Key, Value> for PatchDiffer { self.shift = 0; } - fn removed<'b>(&mut self, k: &'b treediff::value::Key, _v: &'a Value) { + fn removed<'b>(&mut self, k: &'b PlatformItemKey, _v: &'a Value) { let len = self.path.len(); self.push(k); self.patch @@ -48,13 +53,13 @@ impl<'a> treediff::Delegate<'a, treediff::value::Key, Value> for PatchDiffer { path: self.path.clone(), })); // Shift indices, we are deleting array elements - if let treediff::value::Key::Index(_) = k { + if let PlatformItemKey::ArrayIndex(_) = k { self.shift += 1; } self.path.truncate(len); } - fn added(&mut self, k: &treediff::value::Key, v: &Value) { + fn added(&mut self, k: &PlatformItemKey, v: &Value) { let len = self.path.len(); self.push(k); self.patch @@ -153,6 +158,8 @@ pub enum PlatformItemKey { /// An array index Index(u64), /// An array index + ArrayIndex(usize), + /// Bytes Bytes(Vec), /// A string index for mappings String(String), @@ -167,6 +174,7 @@ impl Display for PlatformItemKey { PlatformItemKey::BigIndex(ref v) => v.fmt(f), PlatformItemKey::SignedIndex(ref v) => v.fmt(f), PlatformItemKey::Bytes(ref v) => hex::encode(v).fmt(f), + PlatformItemKey::ArrayIndex(ref v) => v.fmt(f), } } } @@ -209,7 +217,7 @@ impl treediff::Value for Value { fn items<'a>(&'a self) -> Option + 'a>> { match *self { Value::Array(ref inner) => { - Some(Box::new(inner.iter().enumerate().map(|(i, v)| (PlatformItemKey::Index(i as u64), v)))) + Some(Box::new(inner.iter().enumerate().map(|(i, v)| (PlatformItemKey::ArrayIndex(i), v)))) } Value::Map(ref inner) => { Some(Box::new(inner.iter().filter_map(|(s, v)| { diff --git a/packages/wasm-dpp/src/identity/factory_utils.rs b/packages/wasm-dpp/src/identity/factory_utils.rs index 840a5696806..0f2d77b998c 100644 --- a/packages/wasm-dpp/src/identity/factory_utils.rs +++ b/packages/wasm-dpp/src/identity/factory_utils.rs @@ -19,7 +19,7 @@ pub fn parse_create_args( let public_keys = raw_public_keys .into_iter() - .map(|v| IdentityPublicKey::from_raw_object(v).map(|key| (key.id, key))) + .map(|v| IdentityPublicKey::from_value(v).map(|key| (key.id, key))) .collect::>() .map_err(|e| format!("converting to collection of IdentityPublicKeys failed: {e:#}"))?; diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index 64c062e1e7b..263b9d599e4 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -188,7 +188,7 @@ impl TryFrom for IdentityPublicKeyWasm { let str = String::from(js_sys::JSON::stringify(&value)?); let val = serde_json::from_str(&str).map_err(|e| from_dpp_err(e.into()))?; Ok(Self( - IdentityPublicKey::from_raw_object(val).map_err(from_dpp_err)?, + IdentityPublicKey::from_value(val).map_err(from_dpp_err)?, )) } } From b892dc1f0575dfed81e02723266edc23d162f7e9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 03:02:01 +0700 Subject: [PATCH 120/228] more work --- ...e_data_contract_update_transition_basic.rs | 18 ++++++---- .../withdrawals_data_triggers/mod.rs | 2 +- .../rs-dpp/src/document/document_factory.rs | 2 +- .../rs-dpp/src/document/document_validator.rs | 6 +--- .../rs-dpp/src/document/extended_document.rs | 1 - .../document_create_transition.rs | 4 +-- ...lidate_documents_batch_transition_basic.rs | 8 +++-- packages/rs-dpp/src/errors/errors.rs | 1 - packages/rs-dpp/src/identity/factory.rs | 5 +-- .../src/identity/identity_public_key/mod.rs | 14 ++++---- .../asset_lock_transaction_output_fetcher.rs | 3 +- .../identity_create_transition.rs | 5 +-- ...tity_credit_withdrawal_transition_basic.rs | 10 +++--- .../identity_topup_transition.rs | 15 ++++----- ...entity_topup_transition_basic_validator.rs | 14 ++++---- .../identity_update_transition.rs | 5 +-- ...lidate_identity_update_transition_basic.rs | 8 +++-- ...lidate_identity_update_transition_state.rs | 2 +- .../validate_public_key_signatures.rs | 4 +-- .../identity/validation/identity_validator.rs | 4 +-- .../validation/public_keys_validator.rs | 3 +- ...ed_purpose_and_security_level_validator.rs | 27 ++++++++------- .../state_transition_factory.rs | 7 ++-- .../validation/validator_transaction_basic.rs | 4 --- .../data_contract_validator_spec.rs | 3 +- .../tests/fixtures/get_documents_fixture.rs | 1 - ...ty_credit_withdrawal_transition_fixture.rs | 2 +- .../src/tests/fixtures/identity_fixture.rs | 2 +- .../identity_topup_transition_fixture.rs | 1 - .../identity/identity_public_key_spec.rs | 2 +- .../asset_lock/instant/mod.rs | 2 -- ..._create_transition_basic_validator_spec.rs | 18 +++++----- .../identity_update_transition_spec.rs | 33 +++++++++---------- ...e_identity_update_transition_basic_spec.rs | 3 +- .../validate_public_keys.rs | 1 - .../validation/public_keys_validator_spec.rs | 1 - packages/rs-dpp/src/util/deserializer.rs | 4 +-- .../src/inner_value_at_path.rs | 12 +++++-- packages/rs-platform-value/src/lib.rs | 6 ++-- packages/rs-platform-value/src/patch/diff.rs | 31 ++++++++--------- packages/rs-platform-value/src/patch/mod.rs | 20 +++++------ packages/rs-platform-value/src/pointer.rs | 2 +- packages/rs-platform-value/src/value_map.rs | 8 ++--- .../src/value_serialization/mod.rs | 2 +- 44 files changed, 153 insertions(+), 173 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 3a595ec988a..343873f8ab5 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -23,8 +23,8 @@ use crate::{ }; use anyhow::anyhow; use anyhow::Context; -use json_patch::PatchOperation; use lazy_static::lazy_static; +use platform_value::patch::PatchOperation; use platform_value::Value; use serde_json::{json, Value as JsonValue}; use std::sync::Arc; @@ -78,7 +78,7 @@ where let result = self.json_schema_validator.validate( &raw_state_transition .try_into_validating_json() - .map_err(ProtocolError::ValueError)? + .map_err(ProtocolError::ValueError)?, )?; if !result.is_valid() { return Ok(result); @@ -102,7 +102,8 @@ where } // Validate Data Contract - let new_data_contract_object = raw_state_transition.get_value(property_names::DATA_CONTRACT)?; + let new_data_contract_object = + raw_state_transition.get_value(property_names::DATA_CONTRACT)?; let result = self .data_contract_validator .validate(new_data_contract_object)?; @@ -110,7 +111,9 @@ where return Ok(result); } - let data_contract_id = new_data_contract_object.get_identifier(contract_property_names::ID).map_err(ProtocolError::ValueError)?; + let data_contract_id = new_data_contract_object + .get_identifier(contract_property_names::ID) + .map_err(ProtocolError::ValueError)?; if execution_context.is_dry_run() { return Ok(result); @@ -158,7 +161,7 @@ where new_base_data_contract.remove(contract_property_names::VERSION)?; let base_data_contract_diff = - json_patch::diff(&existing_data_contract_object, &new_base_data_contract); + platform_value::patch::diff(&existing_data_contract_object, &new_base_data_contract); for diff in base_data_contract_diff.0.iter() { let (operation, property_name) = get_operation_and_property_name(diff); @@ -175,7 +178,10 @@ where // Schema should be backward compatible let old_schema = &existing_data_contract.documents; - let new_schema = new_data_contract_object.get_value("documents")?; + let new_schema: JsonValue = new_data_contract_object + .get_value("documents")? + .clone() + .into(); for (document_type, document_schema) in old_schema.iter() { let new_document_schema = new_schema.get(document_type).unwrap_or(&EMPTY_JSON); diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index 154f170a67f..bfc737bf823 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -88,13 +88,13 @@ where #[cfg(test)] mod tests { - use platform_value::platform_value; use super::*; use crate::identity::state_transition::identity_credit_withdrawal_transition::Pooling; use crate::state_repository::MockStateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::system_data_contracts::load_system_data_contract; use crate::tests::fixtures::{get_data_contract_fixture, get_withdrawal_document_fixture}; + use platform_value::platform_value; #[tokio::test] async fn should_throw_error_if_withdrawal_not_found() { diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index e8b4f96e44b..cd9996879d3 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -430,10 +430,10 @@ where #[cfg(test)] mod test { use platform_value::btreemap_extensions::BTreeValueMapHelper; + use platform_value::platform_value; use platform_value::string_encoding::Encoding; use serde_json::json; use std::sync::Arc; - use platform_value::platform_value; use crate::tests::fixtures::get_extended_documents_fixture; use crate::{ diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index a39f4d40061..91914843adc 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -5,7 +5,6 @@ use lazy_static::lazy_static; use platform_value::Value; use serde_json::Value as JsonValue; -use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::data_contract::document_type::DocumentType; use crate::data_contract::DriveContractExt; use crate::{ @@ -14,7 +13,6 @@ use crate::{ enrich_data_contract_with_base_schema::enrich_data_contract_with_base_schema, enrich_data_contract_with_base_schema::PREFIX_BYTE_0, DataContract, }, - util::json_value::JsonValueExt, validation::{JsonSchemaValidator, ValidationResult}, version::ProtocolVersionValidator, ProtocolError, @@ -95,7 +93,7 @@ impl DocumentValidator { return Ok(result); }; - /// check if there is a document type + // check if there is a document type data_contract.document_type_for_name(document_type_name)?; let enriched_data_contract = enrich_data_contract_with_base_schema( @@ -143,7 +141,6 @@ mod test { primitive_type::PrimitiveType, }; use platform_value::Value; - use serde_json::json; use serde_json::Value as JsonValue; use test_case::test_case; @@ -153,7 +150,6 @@ mod test { consensus::{basic::JsonSchemaError, ConsensusError}, data_contract::DataContract, tests::fixtures::get_data_contract_fixture, - util::json_value::JsonValueExt, validation::ValidationResult, version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}, }; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 00c568587f0..7d8dd73dc57 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -14,7 +14,6 @@ use integer_encoding::VarInt; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; use crate::data_contract::document_type::DocumentType; use crate::document::Document; -use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapInsertionPathHelper; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index d852bb86328..b2531fbeaf5 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -208,9 +208,9 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { #[cfg(test)] mod test { - use serde_json::json; - use platform_value::{Identifier, platform_value}; use platform_value::string_encoding::Encoding; + use platform_value::{platform_value, Identifier}; + use serde_json::json; use super::*; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 7a8031d9751..fb89254e06c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -33,9 +33,9 @@ use anyhow::anyhow; use lazy_static::lazy_static; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; +use platform_value::converter::serde_json::BTreeValueRefJsonConverter; use platform_value::Value; use serde_json::Value as JsonValue; -use platform_value::converter::serde_json::BTreeValueRefJsonConverter; use super::{ find_duplicates_by_indices::find_duplicates_by_indices, @@ -289,7 +289,11 @@ fn validate_raw_transitions<'a>( Action::Delete => { let validator = JsonSchemaValidator::new(BASE_TRANSITION_SCHEMA.clone()) .map_err(|e| anyhow!("unable to compile base transition schema: {}", e))?; - let validation_result = validator.validate(&raw_document_transition.to_validating_json_value().map_err(ProtocolError::ValueError)?)?; + let validation_result = validator.validate( + &raw_document_transition + .to_validating_json_value() + .map_err(ProtocolError::ValueError)?, + )?; if !validation_result.is_valid() { result.merge(validation_result); return Ok(result); diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index 14692f83f1b..3716e019cc7 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -1,4 +1,3 @@ -use serde_json::Value as JsonValue; use thiserror::Error; use crate::consensus::basic::state_transition::InvalidStateTransitionTypeError; diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index bd49cf247a8..0d8d910f39e 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -150,10 +150,7 @@ where // TODO: the error originates here due to id having a wrong type - should be a base58 for the schema - self.create_from_object( - raw_identity, - skip_validation, - ) + self.create_from_object(raw_identity, skip_validation) } pub fn create_instant_lock_proof( diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index 525e01a3fa0..c69ed106a39 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -116,7 +116,7 @@ impl IdentityPublicKey { } pub fn from_value(value: Value) -> Result { - value.try_into() + value.try_into().map_err(ProtocolError::ValueError) } pub fn from_json_object(mut raw_object: JsonValue) -> Result { @@ -203,26 +203,26 @@ impl Into for &IdentityPublicKey { } impl TryInto for &IdentityPublicKey { - type Error = ProtocolError; + type Error = platform_value::Error; fn try_into(self) -> Result { - platform_value::to_value(self).map_err(ProtocolError::ValueError) + platform_value::to_value(self) } } impl TryInto for IdentityPublicKey { - type Error = ProtocolError; + type Error = platform_value::Error; fn try_into(self) -> Result { - platform_value::to_value(self).map_err(ProtocolError::ValueError) + platform_value::to_value(self) } } impl TryFrom for IdentityPublicKey { - type Error = ProtocolError; + type Error = platform_value::Error; fn try_from(value: Value) -> Result { - platform_value::from_value(value).map_err(ProtocolError::ValueError) + platform_value::from_value(value) } } diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs index 269a65e77b5..fe951b16d53 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs @@ -45,8 +45,7 @@ pub async fn fetch_asset_lock_transaction_output( .ok_or_else(|| DPPError::from(AssetLockOutputNotFoundError::new())) .cloned(), AssetLockProof::Chain(asset_lock_proof) => { - let out_point_buffer = *asset_lock_proof.out_point; - let out_point = OutPoint::from(out_point_buffer); + let out_point = OutPoint::from(asset_lock_proof.out_point); let output_index = out_point.vout as usize; let transaction_hash = out_point.txid; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index b8e333ba20e..88a30ff896f 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -151,10 +151,7 @@ impl IdentityCreateTransition { } /// Replaces existing set of public keys with a new one - pub fn set_public_keys( - &mut self, - public_keys: Vec, - ) -> &mut Self { + pub fn set_public_keys(&mut self, public_keys: Vec) -> &mut Self { self.public_keys = public_keys; self diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs index ebae1d172fb..4dcc74638b6 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs @@ -56,7 +56,7 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { let mut result = self.json_schema_validator.validate( &transition_object .try_into_validating_json() - .map_err(ProtocolError::ValueError)?, + .map_err(NonConsensusError::ValueError)?, )?; if !result.is_valid() { @@ -67,7 +67,7 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { self.protocol_version_validator.validate( transition_object .get_integer("protocolVersion") - .map_err(ProtocolError::ValueError)?, + .map_err(NonConsensusError::ValueError)?, )?, ); @@ -78,7 +78,7 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { // validate pooling is always equals to 0 let pooling = transition_object .get_integer(withdrawals_contract::property_names::POOLING) - .map_err(ProtocolError::ValueError)?; + .map_err(NonConsensusError::ValueError)?; if pooling > 0 { result.add_error( @@ -91,7 +91,7 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { // validate core_fee is in fibonacci sequence let core_fee_per_byte = transition_object .get_integer(withdrawals_contract::property_names::CORE_FEE_PER_BYTE) - .map_err(ProtocolError::ValueError)?; + .map_err(NonConsensusError::ValueError)?; if !is_fibonacci_number(core_fee_per_byte) { result.add_error(InvalidIdentityCreditWithdrawalTransitionCoreFeeError::new( @@ -104,7 +104,7 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { // validate output_script types let output_script: CoreScript = transition_object .get_bytes_into(withdrawals_contract::property_names::OUTPUT_SCRIPT) - .map_err(ProtocolError::ValueError)?; + .map_err(NonConsensusError::ValueError)?; if !output_script.is_p2pkh() && !output_script.is_p2sh() { result.add_error( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index ae70dba47e6..d0f346249dd 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -173,21 +173,20 @@ impl StateTransitionConvert for IdentityTopUpTransition { } fn to_object(&self, skip_signature: bool) -> Result { - let mut json_value: Value = platform_value::to_value(self)?; + let mut value: Value = platform_value::to_value(self)?; if skip_signature { - if let Value::Object(ref mut o) = json_value { - for path in Self::signature_property_paths() { - o.remove(path); - } - } + value + .remove_values_at_paths(Self::signature_property_paths()) + .map_err(ProtocolError::ValueError)?; } - Ok(json_value) + Ok(value) } fn to_json(&self, skip_signature: bool) -> Result { - self.to_object(skip_signature).and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) + self.to_object(skip_signature) + .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs index 6939dd03b72..e616e61096d 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; use std::sync::Arc; use lazy_static::lazy_static; -use platform_value::Value; +use platform_value::{Value, ValueMapHelper}; use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProofValidator; @@ -47,18 +47,18 @@ impl IdentityTopUpTransitionBasicValidator { pub async fn validate( &self, - identity_topup_transition_json: &Value, + identity_topup_transition_object: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result, NonConsensusError> { let mut result = self.json_schema_validator.validate( - &identity_topup_transition_json + &identity_topup_transition_object .try_into_validating_json() - .map_err(ProtocolError::ValueError)?, + .map_err(NonConsensusError::ValueError)?, )?; let identity_transition_map = - identity_topup_transition_json.as_object().ok_or_else(|| { - SerdeParsingError::new("Expected identity top up transition to be a json object") + identity_topup_transition_object.as_map().ok_or_else(|| { + SerdeParsingError::new("Expected identity top up transition to be a map object") })?; if !result.is_valid() { @@ -78,7 +78,7 @@ impl IdentityTopUpTransitionBasicValidator { self.asset_lock_proof_validator .validate_structure( identity_transition_map - .get(ASSET_LOCK_PROOF_PROPERTY_NAME) + .get_key(ASSET_LOCK_PROOF_PROPERTY_NAME) .ok_or_else(|| { NonConsensusError::SerdeJsonError(String::from( "identity state transition must contain an asset lock proof", diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index e054396344a..7669d66ce31 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -149,10 +149,7 @@ impl IdentityUpdateTransition { self.revision } - pub fn set_public_keys_to_add( - &mut self, - add_public_keys: Vec, - ) { + pub fn set_public_keys_to_add(&mut self, add_public_keys: Vec) { self.add_public_keys = add_public_keys; } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs index 72120fc2c5b..edbb15be9d7 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs @@ -61,9 +61,11 @@ where &self, raw_state_transition: &Value, ) -> Result { - let result = self - .json_schema_validator - .validate(&raw_state_transition.try_into_validating_json().map_err(ProtocolError::ValueError)?)?; + let result = self.json_schema_validator.validate( + &raw_state_transition + .try_into_validating_json() + .map_err(NonConsensusError::ValueError)?, + )?; if !result.is_valid() { return Ok(result); } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs index 09bbe8d0323..5c411894d67 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs @@ -10,7 +10,7 @@ use crate::{ state_repository::StateRepositoryLike, state_transition::StateTransitionLike, validation::SimpleValidationResult, - NonConsensusError, ProtocolError, SerdeParsingError, StateError, + NonConsensusError, StateError, }; use super::identity_update_transition::{property_names, IdentityUpdateTransition}; diff --git a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 63fd1722b80..18386f2cee5 100644 --- a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -89,7 +89,7 @@ pub fn validate_public_key_signatures<'a, T: BlsModule>( let add_public_key_transitions: Vec = raw_public_keys .into_iter() .map(|k| { - IdentityPublicKeyWithWitness::from_raw_json_object(k.to_owned()) + IdentityPublicKeyWithWitness::from_raw_object(k.to_owned()) .map_err(|e| NonConsensusError::IdentityPublicKeyCreateError(format!("{:#}", e))) }) .collect::>()?; @@ -115,7 +115,7 @@ fn invalid_state_transition_type_error(transition_type: u8) -> ProtocolError { fn find_invalid_public_key( state_transition: &mut impl StateTransitionLike, - public_keys: impl IntoIterator, + public_keys: impl IntoIterator, bls: &T, ) -> Option { for public_key in public_keys { diff --git a/packages/rs-dpp/src/identity/validation/identity_validator.rs b/packages/rs-dpp/src/identity/validation/identity_validator.rs index f9acb163e62..f098c6f95b6 100644 --- a/packages/rs-dpp/src/identity/validation/identity_validator.rs +++ b/packages/rs-dpp/src/identity/validation/identity_validator.rs @@ -4,11 +4,9 @@ use serde_json::Value as JsonValue; use std::sync::Arc; use crate::identity::validation::TPublicKeysValidator; -use crate::util::protocol_data::{get_protocol_version, get_raw_public_keys}; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::version::ProtocolVersionValidator; -use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError}; -use crate::consensus::ConsensusError; +use crate::{DashPlatformProtocolInitError, NonConsensusError}; use crate::identity::state_transition::identity_update_transition::identity_update_transition::property_names::PROTOCOL_VERSION; lazy_static! { diff --git a/packages/rs-dpp/src/identity/validation/public_keys_validator.rs b/packages/rs-dpp/src/identity/validation/public_keys_validator.rs index b29431e4f19..31cca957ab2 100644 --- a/packages/rs-dpp/src/identity/validation/public_keys_validator.rs +++ b/packages/rs-dpp/src/identity/validation/public_keys_validator.rs @@ -10,8 +10,7 @@ use crate::errors::consensus::basic::identity::{ use crate::identity::{IdentityPublicKey, KeyID, KeyType}; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::{ - BlsModule, DashPlatformProtocolInitError, NonConsensusError, ProtocolError, - PublicKeyValidationError, + BlsModule, DashPlatformProtocolInitError, NonConsensusError, PublicKeyValidationError, }; use crate::identity::security_level::ALLOWED_SECURITY_LEVELS; diff --git a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs index 5b97d530358..774fc06280e 100644 --- a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs +++ b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs @@ -1,12 +1,11 @@ use platform_value::Value; -use platform_value::Value::Null; use std::collections::HashMap; use crate::consensus::basic::identity::MissingMasterPublicKeyError; use crate::identity::validation::TPublicKeysValidator; use crate::identity::{IdentityPublicKey, Purpose, SecurityLevel}; use crate::validation::ValidationResult; -use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError}; +use crate::{DashPlatformProtocolInitError, NonConsensusError}; #[derive(Eq, Hash, PartialEq)] struct PurposeKey { @@ -26,16 +25,20 @@ impl TPublicKeysValidator for RequiredPurposeAndSecurityLevelValidator { let mut key_purposes_and_levels_count: HashMap = HashMap::new(); - for raw_public_key in raw_public_keys.iter().filter_map(|pk| { - match pk - .get_optional_integer::("disabledAt") - .map_err(NonConsensusError::ValueError) - { - Ok(Some(_)) => { Some(Ok(pk)) } - Ok(None) => { None } - Err(e) => { Some(Err(e))} - } - }).collect::, NonConsensusError>>()? { + for raw_public_key in raw_public_keys + .iter() + .filter_map(|pk| { + match pk + .get_optional_integer::("disabledAt") + .map_err(NonConsensusError::ValueError) + { + Ok(Some(_)) => Some(Ok(pk)), + Ok(None) => None, + Err(e) => Some(Err(e)), + } + }) + .collect::, NonConsensusError>>()? + { let public_key: IdentityPublicKey = platform_value::from_value(raw_public_key.clone())?; let combo = PurposeKey { purpose: public_key.purpose, diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index b24755b2f99..550eeaea809 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -1,4 +1,3 @@ -use anyhow::anyhow; use std::convert::{TryFrom, TryInto}; use crate::consensus::basic::state_transition::InvalidStateTransitionTypeError; @@ -18,11 +17,9 @@ use crate::{ }, prelude::Identifier, state_repository::StateRepositoryLike, - util::json_value::JsonValueExt, ProtocolError, }; use platform_value::Value; -use serde_json::Value as JsonValue; use super::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, @@ -60,7 +57,8 @@ pub async fn create_state_transition( } StateTransitionType::DocumentsBatch => { let raw_transitions = raw_state_transition - .get_array_ref("transitions").map_err(ProtocolError::ValueError)?; + .get_array_ref("transitions") + .map_err(ProtocolError::ValueError)?; let data_contracts = fetch_data_contracts_for_document_transition( state_repository, raw_transitions, @@ -136,7 +134,6 @@ fn missing_state_transition_error() -> ProtocolError { mod test { use dashcore::network::constants::PROTOCOL_VERSION; use platform_value::{platform_value, Value}; - use serde_json::json; use std::collections::BTreeMap; use crate::{ diff --git a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs b/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs index d548cda4756..b47c9e4b6b8 100644 --- a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs +++ b/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs @@ -4,7 +4,6 @@ use async_trait::async_trait; #[cfg(test)] use mockall::{automock, predicate::*}; use platform_value::Value; -use serde_json::Value as JsonValue; use crate::consensus::basic::state_transition::{ InvalidStateTransitionTypeError, StateTransitionMaxSizeExceededError, @@ -13,7 +12,6 @@ use crate::{ consensus::basic::BasicError, state_repository::StateRepositoryLike, state_transition::{create_state_transition, StateTransitionConvert, StateTransitionType}, - util::json_value::JsonValueExt, validation::SimpleValidationResult, ProtocolError, }; @@ -79,7 +77,6 @@ pub trait ValidatorByStateTransitionType: Sync { #[cfg(test)] mod test { use platform_value::{platform_value, Value}; - use serde_json::{json, Value as JsonValue}; use std::sync::Arc; use crate::{ @@ -92,7 +89,6 @@ mod test { state_repository::MockStateRepositoryLike, state_transition::{StateTransitionConvert, StateTransitionLike}, tests::{fixtures::get_data_contract_fixture, utils::get_basic_error_from_result}, - util::json_value::JsonValueExt, validation::ValidationResult, version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}, NativeBlsModule, diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index ca0a7f82688..53cdc9c66ee 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use jsonschema::error::ValidationErrorKind; use log::trace; use platform_value::{platform_value, Value}; -use serde_json::{json, Value as JsonValue}; +use serde_json::Value as JsonValue; use test_case::test_case; use crate::{ @@ -13,7 +13,6 @@ use crate::{ errors::consensus::basic::{BasicError, IndexError}, prelude::*, tests::fixtures::get_data_contract_fixture, - util::json_value::JsonValueExt, version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}, }; diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index a098f84ae39..0d9ec8befaf 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -4,7 +4,6 @@ use rand::SeedableRng; use std::sync::Arc; use platform_value::{platform_value, Value}; -use serde_json::{json, Value as JsonValue}; use crate::contracts::withdrawals_contract::document_types; use crate::data_contract::DriveContractExt; diff --git a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs index f06ab882753..4e476d8da23 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs @@ -1,8 +1,8 @@ +use crate::prelude::Identifier; use dashcore::{hashes::hex::FromHex, PubkeyHash, Script}; use platform_value::string_encoding::{encode, Encoding}; use platform_value::{platform_value, Value}; use serde_json::{json, Value as JsonValue}; -use crate::prelude::Identifier; use crate::{ identity::state_transition::identity_credit_withdrawal_transition::Pooling, diff --git a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs index d764664ded2..0451e10e6c7 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs @@ -35,7 +35,7 @@ pub fn identity_fixture_raw_object() -> platform_value::Value { } pub fn identity_fixture_json() -> serde_json::Value { - platform_value!({ + json!({ "protocolVersion": 1, "id": "3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT", "publicKeys": [ diff --git a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs index 58e89760b94..5290ed4111e 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs @@ -3,7 +3,6 @@ use std::convert::TryInto; use dashcore::PrivateKey; use platform_value::Value; -use crate::state_transition::StateTransitionType; use crate::tests::fixtures::instant_asset_lock_proof_fixture; use crate::version; diff --git a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs index 33a2b86c9d7..aa35afc01d1 100644 --- a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs +++ b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs @@ -1,8 +1,8 @@ mod from_raw_object { use bls_signatures::Serialize; use dashcore::PublicKey; - use serde_json::json; use platform_value::platform_value; + use serde_json::json; use crate::identity::{KeyType, Purpose, SecurityLevel}; use crate::prelude::IdentityPublicKey; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs index 005fee594c7..9d371d12c3d 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/asset_lock/instant/mod.rs @@ -9,7 +9,6 @@ mod validate_instant_asset_lock_proof_structure_factory { use dashcore::{PrivateKey, Transaction}; use jsonschema::error::ValidationErrorKind; use platform_value::Value; - use serde_json::Value as JsonValue; use crate::assert_consensus_errors; use crate::consensus::ConsensusError; @@ -24,7 +23,6 @@ mod validate_instant_asset_lock_proof_structure_factory { use crate::tests::fixtures::{ instant_asset_lock_is_lock_fixture, instant_asset_lock_proof_transaction_fixture, }; - use crate::tests::utils::SerdeTestExtension; struct TestData { pub validate_instant_asset_lock_proof_structure: diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index b5e2159f904..de0d0443946 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -82,7 +82,6 @@ mod validate_identity_create_transition_basic_factory { use crate::identity::validation::RequiredPurposeAndSecurityLevelValidator; use crate::state_repository::MockStateRepositoryLike; use crate::tests::fixtures::PublicKeysValidatorMock; - use crate::tests::utils::SerdeTestExtension; use crate::validation::ValidationResult; pub use super::setup_test; @@ -96,7 +95,6 @@ mod validate_identity_create_transition_basic_factory { use crate::identity::validation::RequiredPurposeAndSecurityLevelValidator; use crate::state_repository::MockStateRepositoryLike; use crate::tests::fixtures::get_public_keys_validator_for_transition; - use crate::tests::utils::SerdeTestExtension; use crate::{assert_consensus_errors, NonConsensusError}; use super::setup_test; @@ -195,7 +193,6 @@ mod validate_identity_create_transition_basic_factory { use crate::identity::validation::RequiredPurposeAndSecurityLevelValidator; use crate::state_repository::MockStateRepositoryLike; use crate::tests::fixtures::get_public_keys_validator_for_transition; - use crate::tests::utils::SerdeTestExtension; use super::super::setup_test; @@ -267,7 +264,6 @@ mod validate_identity_create_transition_basic_factory { use crate::identity::validation::RequiredPurposeAndSecurityLevelValidator; use crate::state_repository::MockStateRepositoryLike; use crate::tests::fixtures::get_public_keys_validator_for_transition; - use crate::tests::utils::SerdeTestExtension; use super::super::setup_test; @@ -366,7 +362,6 @@ mod validate_identity_create_transition_basic_factory { use crate::tests::fixtures::{ get_public_keys_validator_for_transition, PublicKeysValidatorMock, }; - use crate::tests::utils::SerdeTestExtension; use crate::validation::ValidationResult; use super::super::setup_test; @@ -557,7 +552,6 @@ mod validate_identity_create_transition_basic_factory { use crate::identity::validation::RequiredPurposeAndSecurityLevelValidator; use crate::state_repository::MockStateRepositoryLike; use crate::tests::fixtures::get_public_keys_validator_for_transition; - use crate::tests::utils::SerdeTestExtension; use super::super::setup_test; @@ -597,7 +591,9 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_into_value("signature", vec!["string"; 65]).unwrap(); + raw_state_transition + .set_into_value("signature", vec!["string"; 65]) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -619,7 +615,9 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_into_value("signature", vec![0; 64]).unwrap(); + raw_state_transition + .set_into_value("signature", vec![0; 64]) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) @@ -641,7 +639,9 @@ mod validate_identity_create_transition_basic_factory { Arc::new(RequiredPurposeAndSecurityLevelValidator::default()), MockStateRepositoryLike::new(), ); - raw_state_transition.set_into_value("signature", vec![0; 66]).unwrap(); + raw_state_transition + .set_into_value("signature", vec![0; 66]) + .unwrap(); let result = validator .validate(&raw_state_transition, &Default::default()) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index ff421a644a5..75c85730c5f 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -1,7 +1,6 @@ use chrono::Utc; use platform_value::string_encoding::Encoding; use platform_value::{platform_value, Value}; -use serde_json::{json, Value as JsonValue}; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::{ @@ -196,28 +195,28 @@ fn to_object_with_signature_skipped() { fn to_json() { let TestData { transition, .. } = setup_test(); let result = transition - .to_json(false) - .expect("conversion to json shouldn't fail"); + .to_object(false) + .expect("conversion to platform value shouldn't fail"); let expected_raw_state_transition = platform_value!({ - "protocolVersion" : 1, - "type" : 5, - "signature" : "", - "signaturePublicKeyId": 0, - "identityId" : transition.identity_id.to_string(Encoding::Base58), - "revision": 0, - "disablePublicKeys" : [0], - "publicKeysDisabledAt" : 1234567, + "protocolVersion" : 1u32, + "type" : 5u8, + "signature" : vec![], + "signaturePublicKeyId": 0u32, + "identityId" : transition.identity_id, + "revision": 0u8, + "disablePublicKeys" : [0u8], + "publicKeysDisabledAt" : 1234567u64, "addPublicKeys" : [ { - "id" : 3, - "purpose" : 0, - "type": 0, - "securityLevel" : 0, - "data" : "AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH", + "id" : 3u32, + "purpose" : 0u8, + "type": 0u8, + "securityLevel" : 0u8, + "data" : base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH"), "readOnly" : false, - "signature" : base64::encode(vec![0;65]), + "signature" : vec![0;65], } ] }); diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs index 0bb4d9a45f4..0b8f1a4e4ac 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs @@ -20,14 +20,13 @@ use crate::{ }, utils::get_schema_error, }, - util::json_value::JsonValueExt, validation::SimpleValidationResult, version::ProtocolVersionValidator, NativeBlsModule, NonConsensusError, }; use jsonschema::error::ValidationErrorKind; use platform_value::{platform_value, Value}; -use serde_json::{json, Value as JsonValue}; +use serde_json::Value as JsonValue; use std::{convert::TryInto, sync::Arc}; use test_case::test_case; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs index 56340aa5c36..5e84258e858 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_public_keys.rs @@ -7,7 +7,6 @@ use crate::{ StateError, }; use platform_value::Value; -use serde_json::Value as JsonValue; use std::convert::TryInto; struct TestData { diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index c2001e93bfb..7a4cd2b8c40 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -25,7 +25,6 @@ pub mod id { use crate::identity::KeyID; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; use crate::tests::utils::platform_value_set_ref; - use crate::tests::utils::SerdeTestExtension; #[test] pub fn should_be_present() { diff --git a/packages/rs-dpp/src/util/deserializer.rs b/packages/rs-dpp/src/util/deserializer.rs index 4a058b64c92..e22a9ab881f 100644 --- a/packages/rs-dpp/src/util/deserializer.rs +++ b/packages/rs-dpp/src/util/deserializer.rs @@ -1,11 +1,9 @@ -use anyhow::anyhow; use integer_encoding::VarInt; use serde_json::{Map, Number, Value as JsonValue}; -use crate::consensus::basic::decode::ProtocolVersionParsingError; use crate::data_contract::errors::StructureError; use crate::data_contract::extra::common::check_protocol_version; -use crate::{errors::consensus::ConsensusError, errors::ProtocolError}; +use crate::errors::ProtocolError; pub fn parse_protocol_version( protocol_bytes: &[u8], diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index e84c25ae530..41673410b0d 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -143,11 +143,17 @@ mod test { .expect("no errors"); assert_eq!(document["root"]["from"]["id"], platform_value!("123")); - assert_eq!(document["root"]["from"]["message"], platform_value!("text_message")); - assert_eq!(document["root"]["to"]["new_field"], platform_value!("new_value")); + assert_eq!( + document["root"]["from"]["message"], + platform_value!("text_message") + ); + assert_eq!( + document["root"]["to"]["new_field"], + platform_value!("new_value") + ); assert_eq!( document["root"]["array"][0]["new_field"], platform_value!("new_value") ); } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 5af6458227e..3e260e7295a 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -14,13 +14,13 @@ mod inner_array_value; pub mod inner_value; mod inner_value_at_path; mod macros; +pub mod patch; +mod pointer; pub mod string_encoding; pub mod system_bytes; mod types; mod value_map; mod value_serialization; -mod patch; -mod pointer; pub use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; @@ -33,7 +33,7 @@ pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; pub use value_serialization::{from_value, to_value}; -pub use patch::{Patch, patch}; +pub use patch::{patch, Patch}; /// A representation of a dynamic value that can handled dynamically #[non_exhaustive] diff --git a/packages/rs-platform-value/src/patch/diff.rs b/packages/rs-platform-value/src/patch/diff.rs index 8962d6d2ace..471eefac823 100644 --- a/packages/rs-platform-value/src/patch/diff.rs +++ b/packages/rs-platform-value/src/patch/diff.rs @@ -1,6 +1,6 @@ +use crate::Value; use std::fmt; use std::fmt::Display; -use crate::Value; struct PatchDiffer { path: String, @@ -216,15 +216,16 @@ impl treediff::Value for Value { #[allow(clippy::type_complexity)] fn items<'a>(&'a self) -> Option + 'a>> { match *self { - Value::Array(ref inner) => { - Some(Box::new(inner.iter().enumerate().map(|(i, v)| (PlatformItemKey::ArrayIndex(i), v)))) - } - Value::Map(ref inner) => { - Some(Box::new(inner.iter().filter_map(|(s, v)| { - let key : Option = s.clone().into(); - key.map(|k| (k, v)) - }))) - } + Value::Array(ref inner) => Some(Box::new( + inner + .iter() + .enumerate() + .map(|(i, v)| (PlatformItemKey::ArrayIndex(i), v)), + )), + Value::Map(ref inner) => Some(Box::new(inner.iter().filter_map(|(s, v)| { + let key: Option = s.clone().into(); + key.map(|k| (k, v)) + }))), _ => None, } } @@ -243,7 +244,7 @@ mod tests { from_value(platform_value!([ { "op": "replace", "path": "/", "value": null }, ])) - .unwrap() + .unwrap() ); } @@ -256,7 +257,7 @@ mod tests { from_value(platform_value!([ { "op": "replace", "path": "/", "value": { "title": "Hello!" } }, ])) - .unwrap() + .unwrap() ); } @@ -271,7 +272,7 @@ mod tests { { "op": "remove", "path": "/0" }, { "op": "remove", "path": "/0" }, ])) - .unwrap() + .unwrap() ); } @@ -286,7 +287,7 @@ mod tests { { "op": "remove", "path": "/1" }, { "op": "remove", "path": "/1" }, ])) - .unwrap() + .unwrap() ); } #[test] @@ -301,7 +302,7 @@ mod tests { { "op": "remove", "path": "/0" }, { "op": "remove", "path": "/0" }, ])) - .unwrap() + .unwrap() ); } diff --git a/packages/rs-platform-value/src/patch/mod.rs b/packages/rs-platform-value/src/patch/mod.rs index a11c2f5f888..8502fa8d370 100644 --- a/packages/rs-platform-value/src/patch/mod.rs +++ b/packages/rs-platform-value/src/patch/mod.rs @@ -31,7 +31,7 @@ //! //! ```rust //! #[macro_use] -//! use platform_value::{merge, platform_value}; +//! use platform_value::{patch::merge, platform_value}; //! //! # pub fn main() { //! let mut doc = platform_value!({ @@ -66,12 +66,12 @@ //! # } //! ``` +pub use self::diff::diff; +use crate::value_map::ValueMap; +use crate::{Value, ValueMapHelper}; use serde::{Deserialize, Serialize}; use std::borrow::Cow; use thiserror::Error; -use crate::{Value, ValueMapHelper}; -use crate::value_map::ValueMap; -pub use self::diff::diff; mod diff; /// Representation of Platform Value Patch (list of patch operations) @@ -234,7 +234,7 @@ fn add(doc: &mut Value, path: &str, value: Value) -> Result, Patch Value::Map(ref mut obj) => { obj.insert_string_key_value(unescape(last_unescaped).into_owned(), value.clone()); Ok(Some(value)) - }, + } Value::Array(ref mut arr) if last_unescaped == "-" => { arr.push(value); Ok(None) @@ -255,7 +255,8 @@ fn remove(doc: &mut Value, path: &str, allow_last: bool) -> Result match obj.remove_optional_key(unescape(last_unescaped).as_ref()) { + Value::Map(ref mut obj) => match obj.remove_optional_key(unescape(last_unescaped).as_ref()) + { None => Err(PatchErrorKind::InvalidPointer), Some(val) => Ok(val), }, @@ -420,7 +421,7 @@ fn apply_patches( /// /// ```rust /// #[macro_use] -/// use platform_value::{merge, platform_value}; +/// use platform_value::{patch::merge, platform_value}; /// /// # pub fn main() { /// let mut doc = platform_value!({ @@ -442,7 +443,6 @@ fn apply_patches( /// "tags": [ "example" ] /// }); /// -/// merge(&mut doc, &patch); /// assert_eq!(doc, platform_value!({ /// "title": "Hello!", /// "author" : { @@ -468,7 +468,7 @@ pub fn merge(doc: &mut Value, patch: &Value) { if value.is_null() { map.remove_optional_key_value(value); } else { - merge(map.get_key_by_value_mut_or_insert(key,Value::Null), value); + merge(map.get_key_by_value_mut_or_insert(key, Value::Null), value); } } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/pointer.rs b/packages/rs-platform-value/src/pointer.rs index 47d2b76e4b7..098e6669541 100644 --- a/packages/rs-platform-value/src/pointer.rs +++ b/packages/rs-platform-value/src/pointer.rs @@ -106,4 +106,4 @@ impl Value { _ => None, }) } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index f6493ac8251..55039119282 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -65,9 +65,7 @@ impl ValueMapHelper for ValueMap { } fn get_key_by_value_mut_or_insert(&mut self, search_key: &Value, value: Value) -> &mut Value { - let found = self.iter().position(|(key, _)| { - search_key == key - }); + let found = self.iter().position(|(key, _)| search_key == key); match found { None => { self.push((search_key.clone(), value)); @@ -115,9 +113,7 @@ impl ValueMapHelper for ValueMap { fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option { self.iter() - .position(|(key, _)| { - search_key_value == key - }) + .position(|(key, _)| search_key_value == key) .map(|pos| self.remove(pos).1) } } diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index 5e70b91bd4c..a5e8953f123 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -1,7 +1,7 @@ use crate::value_serialization::ser::Serializer; use crate::{Error, Value}; +use serde::Deserialize; use serde::Serialize; -use serde::{Deserialize}; pub mod de; pub mod ser; From b1a4d2e8a66f18a014cc233db45291697bb07c4a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 03:23:26 +0700 Subject: [PATCH 121/228] more work --- .../rs-dpp/src/document/document_factory.rs | 1 - ...lidate_documents_batch_transition_basic.rs | 8 +++-- packages/rs-dpp/src/identity/factory.rs | 2 -- ...nt_asset_lock_proof_structure_validator.rs | 3 +- .../identity_create_transition.rs | 5 +--- ...ntity_create_transition_basic_validator.rs | 23 +++++++------- .../mod.rs | 2 -- ...tity_credit_withdrawal_transition_basic.rs | 7 ++--- .../identity_topup_transition.rs | 4 +-- ...entity_topup_transition_basic_validator.rs | 30 +++++++------------ .../identity_update_transition.rs | 8 +++-- ...lidate_identity_update_transition_basic.rs | 1 - .../validate_public_key_signatures.rs | 1 - ...a_contract_update_transition_basic_spec.rs | 3 +- ...credit_withdrawal_transition_basic_spec.rs | 2 -- ..._top_up_transition_basic_validator_spec.rs | 1 - .../validation/public_keys_validator_spec.rs | 1 - packages/rs-dpp/src/util/protocol_data.rs | 11 ------- 18 files changed, 37 insertions(+), 76 deletions(-) diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index cd9996879d3..9fca556ae1a 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -432,7 +432,6 @@ mod test { use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::platform_value; use platform_value::string_encoding::Encoding; - use serde_json::json; use std::sync::Arc; use crate::tests::fixtures::get_extended_documents_fixture; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index fb89254e06c..61ccae9ae09 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -24,7 +24,6 @@ use crate::{ prelude::Identifier, state_repository::StateRepositoryLike, state_transition::state_transition_execution_context::StateTransitionExecutionContext, - util::json_value::JsonValueExt, validation::{JsonSchemaValidator, ValidationResult}, version::ProtocolVersionValidator, ProtocolError, @@ -32,7 +31,6 @@ use crate::{ use anyhow::anyhow; use lazy_static::lazy_static; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::converter::serde_json::BTreeValueRefJsonConverter; use platform_value::Value; use serde_json::Value as JsonValue; @@ -261,7 +259,11 @@ fn validate_raw_transitions<'a>( } .map_err(|e| anyhow!("unable to compile enriched schema: {}", e))?; - let schema_result = schema_validator.validate(raw_document_transition.into())?; + let schema_result = schema_validator.validate( + &raw_document_transition + .to_validating_json_value() + .map_err(ProtocolError::ValueError)?, + )?; if !schema_result.is_valid() { result.merge(schema_result); return Ok(result); diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index 0d8d910f39e..3255da0feb5 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -15,9 +15,7 @@ use crate::{BlsModule, ProtocolError}; use dashcore::{InstantLock, Transaction}; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; -use serde_json::Value as JsonValue; use std::collections::BTreeMap; -use std::convert::TryInto; use platform_value::Value; use std::sync::Arc; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs index 1ef974c19bd..03d481c70bc 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs @@ -13,9 +13,8 @@ use crate::consensus::basic::identity::{ use crate::identity::state_transition::asset_lock_proof::AssetLockTransactionValidator; use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; -use crate::util::json_value::JsonValueExt; use crate::validation::{JsonSchemaValidator, ValidationResult}; -use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError}; +use crate::{DashPlatformProtocolInitError, NonConsensusError}; lazy_static! { static ref INSTANT_ASSET_LOCK_PROOF_SCHEMA: JsonValue = serde_json::from_str(include_str!( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 88a30ff896f..402cf15a194 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -1,11 +1,8 @@ use std::convert::{TryFrom, TryInto}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::Value; -use serde::de::Error as DeError; -use serde::ser::Error as SerError; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs index 4426e112de7..b9d0d1f809e 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs @@ -10,10 +10,9 @@ use crate::identity::state_transition::validate_public_key_signatures::TPublicKe use crate::identity::validation::TPublicKeysValidator; use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; -use crate::util::protocol_data::{get_protocol_version, get_raw_public_keys}; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::version::ProtocolVersionValidator; -use crate::{BlsModule, DashPlatformProtocolInitError, NonConsensusError, ProtocolError}; +use crate::{BlsModule, DashPlatformProtocolInitError, NonConsensusError}; lazy_static! { static ref INDENTITY_CREATE_TRANSITION_SCHEMA: JsonValue = serde_json::from_str(include_str!( @@ -72,9 +71,11 @@ impl< transition_object: &Value, execution_context: &StateTransitionExecutionContext, ) -> Result, NonConsensusError> { - let mut result = self - .json_schema_validator - .validate(&transition_object.into())?; + let mut result = self.json_schema_validator.validate( + &transition_object + .try_to_validating_json() + .map_err(NonConsensusError::ValueError)?, + )?; if !result.is_valid() { return Ok(result); @@ -84,7 +85,7 @@ impl< self.protocol_version_validator.validate( transition_object .get_integer(property_names::PROTOCOL_VERSION) - .map_err(ProtocolError::ValueError)?, + .map_err(NonConsensusError::ValueError)?, )?, ); if !result.is_valid() { @@ -93,7 +94,7 @@ impl< let public_keys = transition_object .get_array_slice("publicKeys") - .map_err(ProtocolError::ValueError)?; + .map_err(NonConsensusError::ValueError)?; result.merge(self.public_keys_validator.validate_keys(public_keys)?); if !result.is_valid() { return Ok(result); @@ -120,12 +121,8 @@ impl< self.asset_lock_proof_validator .validate_structure( transition_object - .get(ASSET_LOCK_PROOF_PROPERTY_NAME) - .ok_or_else(|| { - NonConsensusError::SerdeJsonError(String::from( - "identity state transition must contain an asset lock proof", - )) - })?, + .get_value(ASSET_LOCK_PROOF_PROPERTY_NAME) + .map_err(NonConsensusError::ValueError)?, execution_context, ) .await?, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index 7f448ed7f82..87d809c32ec 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -1,5 +1,3 @@ -use anyhow::anyhow; -use platform_value::string_encoding::{self, Encoding}; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs index 4dcc74638b6..0364fc7d6dc 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs @@ -12,10 +12,7 @@ use crate::{ }, contracts::withdrawals_contract, identity::core_script::CoreScript, - util::{ - is_fibonacci_number::is_fibonacci_number, json_value::JsonValueExt, - protocol_data::get_protocol_version, - }, + util::{is_fibonacci_number::is_fibonacci_number, json_value::JsonValueExt}, validation::{JsonSchemaValidator, ValidationResult}, version::ProtocolVersionValidator, DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError, @@ -55,7 +52,7 @@ impl IdentityCreditWithdrawalTransitionBasicValidator { ) -> Result, NonConsensusError> { let mut result = self.json_schema_validator.validate( &transition_object - .try_into_validating_json() + .try_to_validating_json() .map_err(NonConsensusError::ValueError)?, )?; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index d0f346249dd..7fa40604c97 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -7,15 +7,13 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; -use crate::identity::state_transition::identity_create_transition::SerializationOptions; use crate::prelude::Identifier; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::state_transition::{ StateTransition, StateTransitionConvert, StateTransitionLike, StateTransitionType, }; use crate::version::LATEST_VERSION; -use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; -use platform_value::string_encoding::Encoding; +use crate::{NonConsensusError, ProtocolError}; mod property_names { pub const ASSET_LOCK_PROOF: &str = "assetLockProof"; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs index e616e61096d..b711bf9133d 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/basic/identity_topup_transition_basic_validator.rs @@ -1,17 +1,15 @@ -use std::convert::TryInto; use std::sync::Arc; use lazy_static::lazy_static; -use platform_value::{Value, ValueMapHelper}; +use platform_value::Value; use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProofValidator; use crate::state_repository::StateRepositoryLike; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; -use crate::util::protocol_data::get_protocol_version; use crate::validation::{JsonSchemaValidator, ValidationResult}; use crate::version::ProtocolVersionValidator; -use crate::{DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError}; +use crate::{DashPlatformProtocolInitError, NonConsensusError}; lazy_static! { static ref INDENTITY_CREATE_TRANSITION_SCHEMA: JsonValue = serde_json::from_str(include_str!( @@ -52,22 +50,20 @@ impl IdentityTopUpTransitionBasicValidator { ) -> Result, NonConsensusError> { let mut result = self.json_schema_validator.validate( &identity_topup_transition_object - .try_into_validating_json() + .try_to_validating_json() .map_err(NonConsensusError::ValueError)?, )?; - let identity_transition_map = - identity_topup_transition_object.as_map().ok_or_else(|| { - SerdeParsingError::new("Expected identity top up transition to be a map object") - })?; - if !result.is_valid() { return Ok(result); } result.merge( - self.protocol_version_validator - .validate(get_protocol_version(identity_transition_map)?)?, + self.protocol_version_validator.validate( + identity_topup_transition_object + .get_integer("protocolVersion") + .map_err(NonConsensusError::ValueError)?, + )?, ); if !result.is_valid() { @@ -77,13 +73,9 @@ impl IdentityTopUpTransitionBasicValidator { result.merge( self.asset_lock_proof_validator .validate_structure( - identity_transition_map - .get_key(ASSET_LOCK_PROOF_PROPERTY_NAME) - .ok_or_else(|| { - NonConsensusError::SerdeJsonError(String::from( - "identity state transition must contain an asset lock proof", - )) - })?, + identity_topup_transition_object + .get_value(ASSET_LOCK_PROOF_PROPERTY_NAME) + .map_err(NonConsensusError::ValueError)?, execution_context, ) .await?, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 7669d66ce31..d33927cf062 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -1,8 +1,7 @@ -use anyhow::anyhow; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use std::convert::TryInto; +use std::convert::{TryFrom, TryInto}; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use crate::{ @@ -192,7 +191,10 @@ impl IdentityUpdateTransition { /// if the property isn't present the empty list is returned. If property is defined, the function /// might return some serialization-related errors -fn get_list(value: &mut Value, property_name: &str) -> Result, ProtocolError> { +fn get_list>( + value: &mut Value, + property_name: &str, +) -> Result, ProtocolError> { value .remove_optional_array(property_name) .map_err(ProtocolError::ValueError)? diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs index edbb15be9d7..9297329d5d6 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs @@ -9,7 +9,6 @@ use crate::{ state_transition::validate_public_key_signatures::TPublicKeysSignaturesValidator, validation::TPublicKeysValidator, }, - util::json_value::JsonValueExt, validation::{JsonSchemaValidator, SimpleValidationResult}, version::ProtocolVersionValidator, NonConsensusError, ProtocolError, diff --git a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 18386f2cee5..19114b0dfa5 100644 --- a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -1,5 +1,4 @@ use platform_value::Value; -use serde_json::Value as JsonValue; use crate::consensus::basic::identity::InvalidIdentityKeySignatureError; use crate::consensus::basic::state_transition::InvalidStateTransitionTypeError; diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 1683561f876..5b0286a6522 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -17,13 +17,12 @@ use crate::{ fixtures::{get_data_contract_fixture, get_protocol_version_validator_fixture}, utils::{get_basic_error_from_result, get_schema_error}, }, - util::json_value::JsonValueExt, version::{ProtocolVersionValidator, LATEST_VERSION}, }; use jsonschema::error::ValidationErrorKind; use platform_value::{platform_value, Value}; -use serde_json::{json, Value as JsonValue}; +use serde_json::Value as JsonValue; struct TestData { version_validator: ProtocolVersionValidator, diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs index 6ddb82ea47e..32d9d194980 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs @@ -1,7 +1,6 @@ use std::sync::Arc; use platform_value::Value; -use serde_json::Value as JsonValue; use crate::{identity::state_transition::identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, tests::fixtures::identity_credit_withdrawal_transition_fixture_raw_object, version::ProtocolVersionValidator}; @@ -22,7 +21,6 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { use crate::assert_consensus_errors; use crate::consensus::ConsensusError; - use crate::tests::utils::SerdeTestExtension; use crate::NonConsensusError; use jsonschema::error::ValidationErrorKind; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs index 39a63086498..402d234298c 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs @@ -11,7 +11,6 @@ use crate::identity::state_transition::asset_lock_proof::{ }; use crate::identity::state_transition::identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator; use crate::state_repository::MockStateRepositoryLike; -use crate::tests::utils::SerdeTestExtension; use crate::version::ProtocolVersionValidator; use crate::NonConsensusError; diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index 7a4cd2b8c40..b53b3e746c6 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -137,7 +137,6 @@ pub mod data { use crate::errors::consensus::ConsensusError; use crate::identity::validation::TPublicKeysValidator; use crate::tests::identity::validation::public_keys_validator_spec::setup_test; - use crate::tests::utils::platform_value_set_ref; #[test] pub fn should_be_present() { diff --git a/packages/rs-dpp/src/util/protocol_data.rs b/packages/rs-dpp/src/util/protocol_data.rs index d09c87c90e0..66eec25f86d 100644 --- a/packages/rs-dpp/src/util/protocol_data.rs +++ b/packages/rs-dpp/src/util/protocol_data.rs @@ -2,17 +2,6 @@ use serde_json::{Map, Value}; use crate::SerdeParsingError; -pub fn get_protocol_version( - protocol_structure_json: &Map, -) -> Result { - Ok(protocol_structure_json - .get("protocolVersion") - .ok_or_else(|| SerdeParsingError::new("Expected identity to have protocolVersion"))? - .as_u64() - .ok_or_else(|| SerdeParsingError::new("Expected protocolVersion to be a uint"))? - as u32) -} - pub fn get_raw_public_keys( identity_map: &Map, ) -> Result<&Vec, SerdeParsingError> { From 7b6b9f8398d77a30fdd232cf042734fa7dff3f28 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 04:07:17 +0700 Subject: [PATCH 122/228] more work --- .../validation/multi_validator.rs | 3 +- .../validate_data_contract_max_depth.rs | 2 - ...tity_credit_withdrawal_transition_basic.rs | 4 +- .../identity_public_key_transitions.rs | 63 ++++++++++--------- .../identity_update_transition.rs | 30 ++++++++- .../identity_update_transition_spec.rs | 5 +- packages/rs-platform-value/src/inner_value.rs | 2 +- 7 files changed, 66 insertions(+), 43 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 34a6f554b24..625ffc3503b 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -5,7 +5,7 @@ use crate::consensus::basic::data_contract::IncompatibleRe2PatternError; use crate::{ consensus::{basic::BasicError, ConsensusError}, validation::ValidationResult, - NonConsensusError, ProtocolError, SerdeParsingError, + NonConsensusError, SerdeParsingError, }; pub type SubValidator = @@ -123,7 +123,6 @@ pub fn byte_array_has_no_items_as_parent_validator( #[cfg(test)] mod test { use platform_value::platform_value; - use serde_json::json; use super::*; diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index 3b6be104a86..c81d1f47d63 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -1,6 +1,4 @@ use std::collections::BTreeSet; - -use anyhow::bail; use platform_value::Value; use crate::consensus::basic::data_contract::InvalidJsonSchemaRefError; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs index 0364fc7d6dc..9d8ead86fad 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs @@ -12,10 +12,10 @@ use crate::{ }, contracts::withdrawals_contract, identity::core_script::CoreScript, - util::{is_fibonacci_number::is_fibonacci_number, json_value::JsonValueExt}, + util::{is_fibonacci_number::is_fibonacci_number}, validation::{JsonSchemaValidator, ValidationResult}, version::ProtocolVersionValidator, - DashPlatformProtocolInitError, NonConsensusError, ProtocolError, SerdeParsingError, + DashPlatformProtocolInitError, NonConsensusError, }; lazy_static! { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index a551a2018a2..1d46a8b00ac 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -52,33 +52,34 @@ impl IdentityPublicKeyWithWitness { } } - pub fn from_raw_object(mut raw_object: Value) -> Result { - Ok(Self { - id: raw_object - .get_integer("id") - .map_err(ProtocolError::ValueError)?, - purpose: raw_object - .get_integer::("purpose") - .map_err(ProtocolError::ValueError)? - .try_into()?, - security_level: raw_object - .get_integer::("securityLevel") - .map_err(ProtocolError::ValueError)? - .try_into()?, - key_type: raw_object - .get_integer::("keyType") - .map_err(ProtocolError::ValueError)? - .try_into()?, - data: raw_object - .remove_bytes("data") - .map_err(ProtocolError::ValueError)?, - read_only: raw_object - .get_bool("readOnly") - .map_err(ProtocolError::ValueError)?, - signature: raw_object - .remove_bytes("signature") - .map_err(ProtocolError::ValueError)?, - }) + pub fn from_raw_object(raw_object: Value) -> Result { + raw_object.try_into().map_err(ProtocolError::ValueError) + // Ok(Self { + // id: raw_object + // .get_integer("id") + // .map_err(ProtocolError::ValueError)?, + // purpose: raw_object + // .get_integer::("purpose") + // .map_err(ProtocolError::ValueError)? + // .try_into()?, + // security_level: raw_object + // .get_integer::("securityLevel") + // .map_err(ProtocolError::ValueError)? + // .try_into()?, + // key_type: raw_object + // .get_integer::("keyType") + // .map_err(ProtocolError::ValueError)? + // .try_into()?, + // data: raw_object + // .remove_bytes("data") + // .map_err(ProtocolError::ValueError)?, + // read_only: raw_object + // .get_bool("readOnly") + // .map_err(ProtocolError::ValueError)?, + // signature: raw_object + // .remove_bytes("signature") + // .map_err(ProtocolError::ValueError)?, + // }) } pub fn from_value_map(mut value_map: BTreeMap) -> Result { @@ -242,17 +243,17 @@ impl From<&IdentityPublicKeyWithWitness> for IdentityPublicKey { } impl TryFrom for IdentityPublicKeyWithWitness { - type Error = ProtocolError; + type Error = platform_value::Error; fn try_from(value: Value) -> Result { - IdentityPublicKeyWithWitness::from_raw_object(value) + platform_value::from_value(value) } } impl TryInto for IdentityPublicKeyWithWitness { - type Error = ProtocolError; + type Error = platform_value::Error; fn try_into(self) -> Result { - self.to_raw_object(false) + platform_value::to_value(self) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index d33927cf062..8293ad0b3ec 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -108,7 +108,7 @@ impl IdentityUpdateTransition { .get_integer(property_names::REVISION) .map_err(ProtocolError::ValueError)?; let add_public_keys = get_list(&mut raw_object, property_names::ADD_PUBLIC_KEYS)?; - let disable_public_keys = get_list(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; + let disable_public_keys = get_integer_list(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; let public_keys_disabled_at = raw_object .remove_optional_integer(property_names::PUBLIC_KEYS_DISABLED_AT) .map_err(ProtocolError::ValueError)?; @@ -200,7 +200,33 @@ fn get_list>( .map_err(ProtocolError::ValueError)? .unwrap_or_default() .into_iter() - .map(|value| value.try_into()) + .map(|value| value.try_into().map_err(ProtocolError::ValueError)) + .collect() +} + +/// if the property isn't present the empty list is returned. If property is defined, the function +/// might return some serialization-related errors +fn get_integer_list( + value: &mut Value, + property_name: &str, +) -> Result, ProtocolError> + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom { + value + .remove_optional_array(property_name) + .map_err(ProtocolError::ValueError)? + .unwrap_or_default() + .into_iter() + .map(|value| value.to_integer().map_err(ProtocolError::ValueError)) .collect() } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index 75c85730c5f..2a935999c3f 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -1,5 +1,4 @@ use chrono::Utc; -use platform_value::string_encoding::Encoding; use platform_value::{platform_value, Value}; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; @@ -201,7 +200,7 @@ fn to_json() { let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1u32, "type" : 5u8, - "signature" : vec![], + "signature" : Vec::::new(), "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id, "revision": 0u8, @@ -214,7 +213,7 @@ fn to_json() { "purpose" : 0u8, "type": 0u8, "securityLevel" : 0u8, - "data" : base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH"), + "data" : base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap(), "readOnly" : false, "signature" : vec![0;65], } diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index e144d109d37..f60ff7a5bb9 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -142,7 +142,7 @@ impl Value { value.into_array() } - pub fn remove_optional_array(&mut self, key: &str) -> Result>, Error> { + pub fn remove_optional_array(&mut self, key: &str) -> Result>, Error> { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) .map(|v| v.into_array()) From 040170ad91b8a56c981129dd48eb2f00fd7d387e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 10:15:39 +0700 Subject: [PATCH 123/228] more fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 11 +- .../data_contract/data_contract_factory.rs | 6 +- .../document_type/document_type.rs | 1 + ...e_data_contract_create_transition_basic.rs | 2 +- .../data_contract_update_transition/mod.rs | 5 +- ...e_data_contract_update_transition_basic.rs | 29 +++-- .../validation/multi_validator.rs | 22 ++-- .../validate_data_contract_max_depth.rs | 2 +- .../rs-dpp/src/document/document_validator.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 55 +-------- .../document_create_transition.rs | 4 +- packages/rs-dpp/src/errors/codes.rs | 1 + .../consensus/abstract_consensus_error.rs | 5 + .../chain/chain_asset_lock_proof.rs | 9 ++ .../instant/instant_asset_lock_proof.rs | 8 ++ .../state_transition/asset_lock_proof/mod.rs | 6 +- .../identity_create_transition.rs | 106 ++---------------- .../mod.rs | 2 +- ...tity_credit_withdrawal_transition_basic.rs | 2 +- .../identity_update_transition.rs | 15 ++- ...e_documents_batch_transition_state_spec.rs | 6 +- .../src/inner_value_at_path.rs | 2 +- 22 files changed, 102 insertions(+), 199 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 911149c5427..902778deb62 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -139,7 +139,11 @@ impl DataContract { let defs = data_contract_map.get_optional_inner_str_json_value_map::>("$defs")?; - let mut data_contract = DataContract { + let binary_properties = documents + .iter() + .map(|(doc_type, schema)| (String::from(doc_type), get_binary_properties(schema))) + .collect(); + let data_contract = DataContract { protocol_version: 0, id: Identifier::from( data_contract_map @@ -165,10 +169,7 @@ impl DataContract { entropy: data_contract_map .remove_hash256_bytes(property_names::ENTROPY) .map_err(ProtocolError::ValueError)?, - binary_properties: documents - .iter() - .map(|(doc_type, schema)| (String::from(doc_type), get_binary_properties(schema))) - .collect(), + binary_properties, }; Ok(data_contract) diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 7bbeb41d3cf..a456f0dca30 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -144,6 +144,7 @@ impl DataContractFactory { &self, data_contract: DataContract, ) -> Result { + let entropy = Value::Bytes32(data_contract.entropy); let raw_object = BTreeMap::from([ ( st_prop::PROTOCOL_VERSION.to_string(), @@ -153,10 +154,7 @@ impl DataContractFactory { st_prop::DATA_CONTRACT.to_string(), data_contract.try_into()?, ), - ( - st_prop::ENTROPY.to_string(), - Value::Bytes32(data_contract.entropy), - ), + (st_prop::ENTROPY.to_string(), entropy), ]); DataContractCreateTransition::from_value_map(raw_object) } diff --git a/packages/rs-dpp/src/data_contract/document_type/document_type.rs b/packages/rs-dpp/src/data_contract/document_type/document_type.rs index 193c40a8e3c..a59b16000ad 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_type.rs @@ -28,6 +28,7 @@ pub const MAX_INDEX_SIZE: usize = 255; pub const STORAGE_FLAGS_SIZE: usize = 2; #[derive(Serialize, Deserialize, Debug, PartialEq, Default, Clone)] +#[serde(rename_all = "camelCase")] pub struct DocumentType { pub name: String, pub indices: Vec, diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs index 5be18d1c356..0b3cfe4f0b8 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_basic.rs @@ -77,7 +77,7 @@ fn validate_data_contract_create_transition_basic( ) -> Result { let result = json_schema_validator.validate( &raw_state_transition - .try_into_validating_json() + .try_to_validating_json() .map_err(ProtocolError::ValueError)?, )?; if !result.is_valid() { diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 7e23e3c5802..87b5cc0295e 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -236,7 +236,10 @@ mod test { PROTOCOL_VERSION.to_string(), Value::U32(version::LATEST_VERSION), ), - (DATA_CONTRACT.to_string(), data_contract.try_into().unwrap()), + ( + DATA_CONTRACT.to_string(), + data_contract.clone().try_into().unwrap(), + ), ]); let state_transition = DataContractUpdateTransition::from_value_map(value_map) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 343873f8ab5..7cc0bda57cc 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -1,4 +1,4 @@ -use std::convert::{TryFrom, TryInto}; +use std::convert::TryInto; use crate::consensus::basic::data_contract::{ DataContractImmutablePropertiesUpdateError, IncompatibleDataContractSchemaError, @@ -7,14 +7,12 @@ use crate::consensus::basic::decode::ProtocolVersionParsingError; use crate::consensus::basic::invalid_data_contract_version_error::InvalidDataContractVersionError; use crate::consensus::ConsensusError; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; -use crate::tests::utils::SerdeTestExtension; use crate::{ consensus::basic::BasicError, data_contract::{ property_names as contract_property_names, state_transition::property_names, validation::data_contract_validator::DataContractValidator, DataContract, }, - prelude::Identifier, state_repository::StateRepositoryLike, util::json_value::JsonValueExt, validation::{JsonSchemaValidator, SimpleValidationResult}, @@ -77,7 +75,7 @@ where let result = self.json_schema_validator.validate( &raw_state_transition - .try_into_validating_json() + .try_to_validating_json() .map_err(ProtocolError::ValueError)?, )?; if !result.is_valid() { @@ -181,7 +179,8 @@ where let new_schema: JsonValue = new_data_contract_object .get_value("documents")? .clone() - .into(); + .try_into() + .map_err(ProtocolError::ValueError)?; for (document_type, document_schema) in old_schema.iter() { let new_document_schema = new_schema.get(document_type).unwrap_or(&EMPTY_JSON); @@ -190,7 +189,7 @@ where Ok(_) => {} Err(DiffVAlidatorError::SchemaCompatibilityError { diffs }) => { let (operation_name, property_name) = - get_operation_and_property_name(&diffs[0]); + get_operation_and_property_name_json(&diffs[0]); validation_result.add_error(BasicError::IncompatibleDataContractSchemaError( IncompatibleDataContractSchemaError::new( existing_data_contract.id.clone(), @@ -212,8 +211,11 @@ where } // check indices are not changed - let new_documents = new_data_contract_object - .get_value("documents")? + let new_documents: JsonValue = new_data_contract_object + .get_value("documents") + .and_then(|a| a.clone().try_into()) + .map_err(ProtocolError::ValueError)?; + let new_documents = new_documents .as_object() .ok_or_else(|| anyhow!("the 'documents' property is not an array"))?; let result = validate_indices_are_backward_compatible( @@ -253,6 +255,17 @@ fn get_operation_and_property_name(p: &PatchOperation) -> (&'static str, &str) { } } +fn get_operation_and_property_name_json(p: &json_patch::PatchOperation) -> (&'static str, &str) { + match &p { + json_patch::PatchOperation::Add(ref o) => ("add", o.path.as_str()), + json_patch::PatchOperation::Copy(ref o) => ("copy", o.path.as_str()), + json_patch::PatchOperation::Remove(ref o) => ("remove", o.path.as_str()), + json_patch::PatchOperation::Replace(ref o) => ("replace", o.path.as_str()), + json_patch::PatchOperation::Move(ref o) => ("move", o.path.as_str()), + json_patch::PatchOperation::Test(ref o) => ("test", o.path.as_str()), + } +} + #[cfg(test)] mod test { use super::replace_bytes_with_hex_string; diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 625ffc3503b..31e57e33af6 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -5,7 +5,6 @@ use crate::consensus::basic::data_contract::IncompatibleRe2PatternError; use crate::{ consensus::{basic::BasicError, ConsensusError}, validation::ValidationResult, - NonConsensusError, SerdeParsingError, }; pub type SubValidator = @@ -23,14 +22,13 @@ pub fn validate(raw_data_contract: &Value, validators: &[SubValidator]) -> Valid let new_path = format!("{}/{}", path, key); values_queue.push((current_value, new_path)) } - if let Some(key) = key.as_str() { - for validator in validators { - validator(&path, key, value, current_value, &mut result); + match key.to_str().map_err(ConsensusError::ValueError) { + Ok(key) => { + for validator in validators { + validator(&path, key, value, current_value, &mut result); + } } - } else { - result.add_error(NonConsensusError::SerdeParsingError( - SerdeParsingError::new("keys of properties must be strings"), - )); + Err(err) => result.add_error(err), } } } @@ -79,13 +77,13 @@ pub fn pattern_is_valid_regex_validator( } fn unwrap_error_to_result<'a, 'b>( - v: Result, NonConsensusError>, + v: Result, ConsensusError>, result: &'b mut ValidationResult<()>, ) -> Option<&'a Value> { match v { Ok(v) => v, Err(e) => { - result.add_error::(e.into()); + result.add_error(e); None } } @@ -101,14 +99,14 @@ pub fn byte_array_has_no_items_as_parent_validator( if key == "byteArray" && value.is_bool() && (unwrap_error_to_result( - parent.get("items").map_err(NonConsensusError::ValueError), + parent.get("items").map_err(ConsensusError::ValueError), result, ) .is_some() || unwrap_error_to_result( parent .get("prefixItems") - .map_err(NonConsensusError::ValueError), + .map_err(ConsensusError::ValueError), result, ) .is_some()) diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index c81d1f47d63..e4b275d7e93 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -1,5 +1,5 @@ -use std::collections::BTreeSet; use platform_value::Value; +use std::collections::BTreeSet; use crate::consensus::basic::data_contract::InvalidJsonSchemaRefError; use crate::{consensus::basic::BasicError, validation::ValidationResult, ProtocolError}; diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 91914843adc..ed8b8acbcee 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -114,7 +114,7 @@ impl DocumentValidator { .map_err(|e| anyhow!("unable to process the contract: {}", e))?; let json_value = raw_document - .try_into_validating_json() + .try_to_validating_json() .map_err(ProtocolError::ValueError)?; let json_schema_validation_result = json_schema_validator.validate(&json_value)?; result.merge(json_schema_validation_result); diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 7d8dd73dc57..f19d9ce1d08 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -6,7 +6,6 @@ use crate::util::cbor_value::CborCanonicalMap; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::util::hash::hash; -use crate::util::json_value::JsonValueExt; use crate::ProtocolError; use ciborium::Value as CborValue; use integer_encoding::VarInt; @@ -125,11 +124,11 @@ impl ExtendedDocument { Self::from_untrusted_platform_value(json_value.into(), contract) } - pub fn from_raw_document( + pub fn from_raw_json_document( raw_document: JsonValue, data_contract: DataContract, ) -> Result { - Self::from_json_value::>(raw_document, data_contract) + Self::from_untrusted_platform_value(raw_document.into(), data_contract) } /// Create an extended document from a platform value object where fields are already in the @@ -211,53 +210,6 @@ impl ExtendedDocument { Ok(extended_document) } - fn from_json_value( - mut document_value: JsonValue, - data_contract: DataContract, - ) -> Result - where - for<'de> S: Deserialize<'de> + TryInto, - { - let document_type_name: String = - if let Ok(document_type_name) = document_value.remove(property_names::DOCUMENT_TYPE) { - serde_json::from_value(document_type_name)? - } else { - return Err(ProtocolError::DecodingError( - "no document type in json value".to_string(), - )); - }; - - //Because we don't know how the json came in we need to sanitize it - let (identifiers, binary_paths) = - data_contract.get_identifiers_and_binary_paths_owned(document_type_name.as_str())?; - - let mut extended_document = Self { - data_contract, - document_type_name, - ..Default::default() - }; - - if let Ok(value) = document_value.remove(property_names::PROTOCOL_VERSION) { - extended_document.protocol_version = serde_json::from_value(value)? - } - - if let Ok(value) = document_value.remove(property_names::DATA_CONTRACT_ID) { - let data: S = serde_json::from_value(value)?; - extended_document.data_contract_id = data.try_into()? - } - extended_document.document = Document::from_json_value::(document_value)?; - - extended_document - .document - .properties - .replace_at_paths(identifiers, ReplacementType::Identifier)?; - extended_document - .document - .properties - .replace_at_paths(binary_paths, ReplacementType::Bytes)?; - Ok(extended_document) - } - pub fn to_json(&self) -> Result { let mut value = self.document.to_json()?; let value_mut = value.as_object_mut().unwrap(); @@ -723,7 +675,8 @@ mod test { "alphaIdentifier" : alpha_value, }); - let document = ExtendedDocument::from_raw_document(raw_document, data_contract).unwrap(); + let document = + ExtendedDocument::from_raw_json_document(raw_document, data_contract).unwrap(); let json_document = document.to_pretty_json().expect("no errors"); assert_eq!( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index b2531fbeaf5..121649d4d19 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -301,11 +301,11 @@ mod test { let json_transition = transition.to_json().expect("no errors"); assert_eq!( json_transition["$id"], - JsonValue::String(bs58::encode(&id).into_string()) + JsonValue::String(id.to_string(Encoding::Base58)) ); assert_eq!( json_transition["$dataContractId"], - JsonValue::String(bs58::encode(&data_contract_id).into_string()) + JsonValue::String(data_contract_id.to_string(Encoding::Base58)) ); assert_eq!( json_transition["alphaBinary"], diff --git a/packages/rs-dpp/src/errors/codes.rs b/packages/rs-dpp/src/errors/codes.rs index 65a6c763704..fdae7d707a4 100644 --- a/packages/rs-dpp/src/errors/codes.rs +++ b/packages/rs-dpp/src/errors/codes.rs @@ -55,6 +55,7 @@ impl ErrorWithCode for ConsensusError { #[cfg(test)] ConsensusError::TestConsensusError(_) => 1000, + ConsensusError::ValueError(_) => 5000, } } } diff --git a/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs b/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs index 0cf072fa401..7875823ce28 100644 --- a/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs +++ b/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs @@ -23,6 +23,7 @@ use crate::errors::consensus::basic::{ BasicError, IncompatibleProtocolVersionError, JsonSchemaError, UnsupportedProtocolVersionError, }; use crate::errors::StateError; +use platform_value::Error as ValueError; use super::basic::identity::{ IdentityInsufficientBalanceError, InvalidIdentityCreditWithdrawalTransitionCoreFeeError, @@ -122,6 +123,9 @@ pub enum ConsensusError { #[error(transparent)] FeeError(FeeError), + #[error(transparent)] + ValueError(ValueError), + #[cfg(test)] #[cfg_attr(test, error(transparent))] TestConsensusError(TestConsensusError), @@ -179,6 +183,7 @@ impl ConsensusError { // Custom error for tests #[cfg(test)] ConsensusError::TestConsensusError(_) => 1000, + ConsensusError::ValueError(_) => 5000, } } } diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index 853890731f7..f5319ff3f94 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -1,5 +1,7 @@ +use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_big_array::BigArray; +use std::convert::TryFrom; use crate::{ errors::NonConsensusError, identifier::Identifier, util::hash::hash, util::vec::vec_to_array, @@ -15,6 +17,13 @@ pub struct ChainAssetLockProof { pub out_point: [u8; 36], } +impl TryFrom for ChainAssetLockProof { + type Error = platform_value::Error; + fn try_from(value: Value) -> Result { + platform_value::from_value(value) + } +} + impl ChainAssetLockProof { pub fn new(core_chain_locked_height: u32, out_point: [u8; 36]) -> Self { Self { diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs index 7d6b2d4c69d..106b72d0de2 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs @@ -2,6 +2,7 @@ use std::convert::{TryFrom, TryInto}; use dashcore::consensus::{Decodable, Encodable}; use dashcore::{InstantLock, Transaction, TxOut}; +use platform_value::Value; use serde::de::Error as DeError; use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -56,6 +57,13 @@ impl<'de> Deserialize<'de> for InstantAssetLockProof { } } +impl TryFrom for InstantAssetLockProof { + type Error = platform_value::Error; + fn try_from(value: Value) -> Result { + platform_value::from_value(value) + } +} + impl Default for InstantAssetLockProof { fn default() -> Self { Self { diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index e528ae2bdf6..346e0f6ee51 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -3,7 +3,6 @@ use std::convert::{TryFrom, TryInto}; use dashcore::Transaction; use serde::de::Error as DeError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde_json::Value as JsonValue; pub use asset_lock_proof_validator::*; pub use asset_lock_public_key_hash_fetcher::*; @@ -15,7 +14,6 @@ use platform_value::Value; use crate::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; use crate::prelude::Identifier; -use crate::util::json_value::JsonValueExt; use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; mod asset_lock_proof_validator; @@ -62,7 +60,7 @@ impl<'de> Deserialize<'de> for AssetLockProof { { let value = platform_value::Value::deserialize(deserializer)?; - let proof_type_int = value + let proof_type_int: u8 = value .get_integer("type") .map_err(|e| D::Error::custom(e.to_string()))?; let proof_type = AssetLockProofType::try_from(proof_type_int) @@ -122,7 +120,7 @@ impl AssetLockProof { pub fn out_point(&self) -> Option<[u8; 36]> { match self { AssetLockProof::Instant(proof) => proof.out_point(), - AssetLockProof::Chain(proof) => Some(*proof.out_point()), + AssetLockProof::Chain(proof) => Some(proof.out_point), } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 402cf15a194..f407225d60f 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -12,10 +12,8 @@ use crate::state_transition::state_transition_execution_context::StateTransition use crate::state_transition::{ StateTransition, StateTransitionConvert, StateTransitionLike, StateTransitionType, }; -use crate::util::json_value::JsonValueExt; -use crate::{NonConsensusError, ProtocolError, SerdeParsingError}; +use crate::{NonConsensusError, ProtocolError}; use platform_value::btreemap_extensions::BTreeValueRemoveInnerValueFromMapHelper; -use platform_value::string_encoding::Encoding; mod property_names { pub const PUBLIC_KEYS: &str = "publicKeys"; @@ -105,7 +103,7 @@ impl IdentityCreateTransition { { let keys = keys_value_array .into_iter() - .map(|val| val.try_into()) + .map(|val| val.try_into().map_err(ProtocolError::ValueError)) .collect::, ProtocolError>>()?; state_transition.set_public_keys(keys); } @@ -180,66 +178,14 @@ impl IdentityCreateTransition { options: SerializationOptions, ) -> Result { if options.into_validating_json { - self.to_object(options.skip_signature)?.try_into() + self.to_object(options.skip_signature)? + .try_into_validating_json() + .map_err(ProtocolError::ValueError) } else { - self.to_object(options.skip_signature)?.into() + self.to_object(options.skip_signature)? + .try_into() + .map_err(ProtocolError::ValueError) } - - let mut json_map = JsonValue::Object(Default::default()); - - json_map.insert( - property_names::TRANSITION_TYPE.to_string(), - serde_json::Value::from(Self::get_type() as u8), - )?; - - if !options.skip_signature { - let sig = self.signature.iter().map(|num| JsonValue::from(*num)); - json_map.insert( - property_names::SIGNATURE.to_string(), - JsonValue::Array(sig.collect()), - )?; - } - - if !options.skip_identifiers_conversion { - let bytes = self - .identity_id - .as_bytes() - .iter() - .map(|num| JsonValue::from(*num)); - json_map.insert( - property_names::IDENTITY_ID.to_string(), - JsonValue::Array(bytes.collect()), - )?; - } else { - json_map.insert( - property_names::IDENTITY_ID.to_string(), - JsonValue::String(self.identity_id.to_string(Encoding::Base58)), - )?; - } - - let pk_values = self - .public_keys - .iter() - .map(|pk| pk.to_raw_json_object(options.skip_signature)) - .collect::, SerdeParsingError>>()?; - - json_map.insert( - property_names::PUBLIC_KEYS.to_string(), - JsonValue::Array(pk_values), - )?; - - json_map.insert( - property_names::ASSET_LOCK_PROOF.to_string(), - self.asset_lock_proof.as_ref().try_into()?, - )?; - - // TODO ?? - json_map.insert( - property_names::PROTOCOL_VERSION.to_string(), - JsonValue::Number(self.get_protocol_version().into()), - )?; - - Ok(json_map) } /// Returns ids of created identities @@ -269,7 +215,7 @@ impl StateTransitionConvert for IdentityCreateTransition { if skip_signature { value .remove_values_at_paths(Self::signature_property_paths()) - .map_err(ProtocolError::ValueError)? + .map_err(ProtocolError::ValueError)?; } let mut public_keys: Vec = vec![]; @@ -286,38 +232,8 @@ impl StateTransitionConvert for IdentityCreateTransition { } fn to_json(&self, skip_signature: bool) -> Result { - let mut json = serde_json::Value::Object(Default::default()); - - json.insert( - property_names::TRANSITION_TYPE.to_string(), - serde_json::Value::from(Self::get_type() as u8), - )?; - - json.insert( - property_names::ASSET_LOCK_PROOF.to_string(), - self.asset_lock_proof.as_ref().try_into()?, - )?; - - let public_keys = self - .public_keys - .iter() - .map(|pk| pk.to_json()) - .collect::, SerdeParsingError>>()?; - - json.insert( - property_names::PUBLIC_KEYS.to_string(), - serde_json::Value::Array(public_keys), - )?; - - if skip_signature { - if let JsonValue::Object(ref mut o) = json { - for path in Self::signature_property_paths() { - o.remove(path); - } - } - } - - Ok(json) + self.to_object(skip_signature) + .and_then(|v| v.try_into().map_err(ProtocolError::ValueError)) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index 87d809c32ec..31c0797ecea 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -88,7 +88,7 @@ impl IdentityCreditWithdrawalTransition { } pub fn from_raw_object( - mut raw_object: Value, + raw_object: Value, ) -> Result { Self::from_value(raw_object) } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs index 9d8ead86fad..95f70f2bbe1 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic.rs @@ -12,7 +12,7 @@ use crate::{ }, contracts::withdrawals_contract, identity::core_script::CoreScript, - util::{is_fibonacci_number::is_fibonacci_number}, + util::is_fibonacci_number::is_fibonacci_number, validation::{JsonSchemaValidator, ValidationResult}, version::ProtocolVersionValidator, DashPlatformProtocolInitError, NonConsensusError, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 8293ad0b3ec..a70837e9c92 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -108,7 +108,8 @@ impl IdentityUpdateTransition { .get_integer(property_names::REVISION) .map_err(ProtocolError::ValueError)?; let add_public_keys = get_list(&mut raw_object, property_names::ADD_PUBLIC_KEYS)?; - let disable_public_keys = get_integer_list(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; + let disable_public_keys = + get_integer_list(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; let public_keys_disabled_at = raw_object .remove_optional_integer(property_names::PUBLIC_KEYS_DISABLED_AT) .map_err(ProtocolError::ValueError)?; @@ -206,12 +207,9 @@ fn get_list>( /// if the property isn't present the empty list is returned. If property is defined, the function /// might return some serialization-related errors -fn get_integer_list( - value: &mut Value, - property_name: &str, -) -> Result, ProtocolError> - where - T: TryFrom +fn get_integer_list(value: &mut Value, property_name: &str) -> Result, ProtocolError> +where + T: TryFrom + TryFrom + TryFrom + TryFrom @@ -220,7 +218,8 @@ fn get_integer_list( + TryFrom + TryFrom + TryFrom - + TryFrom { + + TryFrom, +{ value .remove_optional_array(property_name) .map_err(ProtocolError::ValueError)? diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index c25268f202b..f19481fe49f 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -212,7 +212,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace .map(|extended_document| extended_document.document) .collect::>(); - let mut replace_document = ExtendedDocument::from_raw_document( + let mut replace_document = ExtendedDocument::from_raw_json_document( extended_documents[0] .to_json_object_for_validation() .unwrap(), @@ -281,7 +281,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace mut state_repository_mock, .. } = setup_test(); - let mut replace_document = ExtendedDocument::from_raw_document( + let mut replace_document = ExtendedDocument::from_raw_json_document( extended_documents[0] .to_json_object_for_validation() .unwrap() @@ -292,7 +292,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace .expect("document should be created"); replace_document.document.revision = Some(1); - let mut fetched_document = ExtendedDocument::from_raw_document( + let mut fetched_document = ExtendedDocument::from_raw_json_document( extended_documents[0] .to_json_object_for_validation() .unwrap() diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index 41673410b0d..b9f59de315a 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -36,7 +36,7 @@ impl Value { .collect() } - pub fn get_value_at_path<'a>(&'a self, path: &'a str) -> Result<&'a Value, Error> { + pub fn get_value_at_path<'a, 'b>(&'a self, path: &'b str) -> Result<&'a Value, Error> { let split = path.split('.'); let mut current_value = self; for path_component in split { From 8a9736b01b0bccfa98c972837920023c8280ac14 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 10:35:27 +0700 Subject: [PATCH 124/228] compiling --- .../validate_documents_batch_transition_basic.rs | 8 ++------ packages/rs-dpp/src/identity/identity.rs | 2 +- .../identity_credit_withdrawal_transition/mod.rs | 3 +-- .../validate_identity_update_transition_basic.rs | 2 +- .../validation/data_contract_validator_spec.rs | 2 +- ...identity_create_transition_basic_validator_spec.rs | 4 ++-- ...dentity_credit_withdrawal_transition_basic_spec.rs | 11 ++++++----- 7 files changed, 14 insertions(+), 18 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 61ccae9ae09..4734e71e3cd 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -218,7 +218,7 @@ fn validate_raw_transitions<'a>( owner_id: &Identifier, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); - + let mut raw_document_transitions_as_value: Vec = vec![]; for raw_document_transition in raw_document_transitions { let Some(document_type) = raw_document_transition.get_optional_str("$type").map_err(ProtocolError::ValueError)? else { result.add_error(BasicError::MissingDocumentTransitionTypeError); @@ -302,12 +302,8 @@ fn validate_raw_transitions<'a>( } } } + raw_document_transitions_as_value.push(raw_document_transition.into()) } - - let raw_document_transitions_as_value: Vec = raw_document_transitions - .into_iter() - .map(|v| v.clone().into()) - .collect(); let raw_document_transitions_as_value_iter = raw_document_transitions_as_value.iter(); let duplicate_transitions = find_duplicates_by_id(raw_document_transitions_as_value_iter.clone())?; diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index a740bb3c428..e003ee9bcb5 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -298,7 +298,7 @@ impl Identity { } /// Creates an identity from a raw object - pub fn from_raw_object(mut raw_object: Value) -> Result { + pub fn from_raw_object(raw_object: Value) -> Result { let identity: Identity = platform_value::from_value(raw_object)?; Ok(identity) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index 31c0797ecea..38449b654ba 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -17,8 +17,7 @@ use crate::{ }; use super::properties::{ - PROPERTY_IDENTITY_ID, PROPERTY_OUTPUT_SCRIPT, PROPERTY_SIGNATURE, - PROPERTY_SIGNATURE_PUBLIC_KEY_ID, + PROPERTY_IDENTITY_ID, PROPERTY_SIGNATURE, PROPERTY_SIGNATURE_PUBLIC_KEY_ID, }; pub mod apply_identity_credit_withdrawal_transition_factory; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs index 9297329d5d6..c3e4eb1db06 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs @@ -62,7 +62,7 @@ where ) -> Result { let result = self.json_schema_validator.validate( &raw_state_transition - .try_into_validating_json() + .try_to_validating_json() .map_err(NonConsensusError::ValueError)?, )?; if !result.is_valid() { diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index 53cdc9c66ee..d3e471e0fdb 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -26,7 +26,7 @@ fn setup_test() -> TestData { init(); let data_contract = get_data_contract_fixture(None); - let raw_data_contract = data_contract.into_object().unwrap(); + let raw_data_contract = data_contract.to_object().unwrap(); let protocol_version_validator = ProtocolVersionValidator::new(LATEST_VERSION, LATEST_VERSION, COMPATIBILITY_MAP.clone()); diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index de0d0443946..0b923adab31 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -427,7 +427,7 @@ mod validate_identity_create_transition_basic_factory { MockStateRepositoryLike::new(), ); - let mut public_keys = raw_state_transition + let public_keys = raw_state_transition .get_array_mut_ref("publicKeys") .unwrap(); let key = public_keys.first().unwrap().clone(); @@ -457,7 +457,7 @@ mod validate_identity_create_transition_basic_factory { MockStateRepositoryLike::new(), ); - let mut public_keys = raw_state_transition + let public_keys = raw_state_transition .get_array_mut_ref("publicKeys") .unwrap(); let key = public_keys.first().unwrap().clone(); diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs index 32d9d194980..9e59421ad52 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs @@ -473,13 +473,14 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { mod output_script { use crate::identity::core_script::CoreScript; + use crate::identity::state_transition::properties::PROPERTY_OUTPUT_SCRIPT; use super::*; pub async fn should_be_present() { let (mut raw_state_transition, validator) = setup_test(); - raw_state_transition.remove("outputScript").unwrap(); + raw_state_transition.remove(PROPERTY_OUTPUT_SCRIPT).unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -503,7 +504,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { let (mut raw_state_transition, validator) = setup_test(); raw_state_transition - .set_into_value("outputScript", vec!["string"; 23]) + .set_into_value(PROPERTY_OUTPUT_SCRIPT, vec!["string"; 23]) .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -521,7 +522,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { let (mut raw_state_transition, validator) = setup_test(); raw_state_transition - .set_into_value("outputScript", vec![0; 9]) + .set_into_value(PROPERTY_OUTPUT_SCRIPT, vec![0; 9]) .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -539,7 +540,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { let (mut raw_state_transition, validator) = setup_test(); raw_state_transition - .set_into_value("outputScript", vec![0; 10018]) + .set_into_value(PROPERTY_OUTPUT_SCRIPT, vec![0; 10018]) .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); @@ -557,7 +558,7 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { let (mut raw_state_transition, validator) = setup_test(); raw_state_transition - .set_into_value("outputScript", vec![6; 23]) + .set_into_value(PROPERTY_OUTPUT_SCRIPT, vec![6; 23]) .unwrap(); let result = validator.validate(&raw_state_transition).await.unwrap(); From c4439de82ca3f862aa97a25b5d8d81fd6f4dd1b7 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 11:40:49 +0700 Subject: [PATCH 125/228] added arrays to set value at path --- Cargo.lock | 2 + packages/rs-dpp/src/identity/factory.rs | 2 +- .../rs-dpp/src/identity/identity_facade.rs | 2 +- .../identity/validation/identity_validator.rs | 2 +- .../validation/identity_validator_spec.rs | 42 +++++++++---------- packages/rs-platform-value/Cargo.toml | 2 + .../src/inner_value_at_path.rs | 39 +++++++++++++---- packages/rs-platform-value/src/lib.rs | 2 +- .../identity/validation/identity_validator.rs | 2 +- 9 files changed, 61 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 58d2a59c32f..7e73edf0c5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2220,7 +2220,9 @@ dependencies = [ "bs58", "ciborium", "hex", + "lazy_static", "rand", + "regex", "serde", "serde_json", "thiserror", diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index 3255da0feb5..19692a6b375 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -122,7 +122,7 @@ where skip_validation: bool, ) -> Result { if !skip_validation { - let result = self.identity_validator.validate_identity(&raw_identity)?; + let result = self.identity_validator.validate_identity_object(&raw_identity)?; if !result.is_valid() { return Err(ProtocolError::InvalidIdentityError { diff --git a/packages/rs-dpp/src/identity/identity_facade.rs b/packages/rs-dpp/src/identity/identity_facade.rs index 218c4ff755b..1aac3233563 100644 --- a/packages/rs-dpp/src/identity/identity_facade.rs +++ b/packages/rs-dpp/src/identity/identity_facade.rs @@ -73,7 +73,7 @@ where &self, identity_object: &Value, ) -> Result, NonConsensusError> { - self.identity_validator.validate_identity(identity_object) + self.identity_validator.validate_identity_object(identity_object) } pub fn create_instant_lock_proof( diff --git a/packages/rs-dpp/src/identity/validation/identity_validator.rs b/packages/rs-dpp/src/identity/validation/identity_validator.rs index f098c6f95b6..3f23539e0a2 100644 --- a/packages/rs-dpp/src/identity/validation/identity_validator.rs +++ b/packages/rs-dpp/src/identity/validation/identity_validator.rs @@ -37,7 +37,7 @@ impl IdentityValidator { Ok(identity_validator) } - pub fn validate_identity( + pub fn validate_identity_object( &self, identity_object: &Value, ) -> Result, NonConsensusError> { diff --git a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs index c434ad58d21..35c8344a817 100644 --- a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs @@ -38,7 +38,7 @@ pub mod protocol_version { .remove("protocolVersion") .expect("expected to remove protocol version"); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -59,7 +59,7 @@ pub mod protocol_version { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("protocolVersion", "1").unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -73,7 +73,7 @@ pub mod protocol_version { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("protocolVersion", -1i32).unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -96,7 +96,7 @@ pub mod id { let (mut identity, identity_validator) = setup_test(); identity.remove("id").expect("expected to remove id"); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -119,7 +119,7 @@ pub mod id { .set_into_value("id", vec![Value::from("string"); 32]) .unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 32); for (i, err) in errors.iter().enumerate() { @@ -135,7 +135,7 @@ pub mod id { .set_into_value("id", vec![Value::from(15); 31]) .unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -151,7 +151,7 @@ pub mod id { .set_into_value("id", vec![Value::from(15); 33]) .unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -175,7 +175,7 @@ pub mod balance { .remove("balance") .expect("expected to remove balance"); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -196,7 +196,7 @@ pub mod balance { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("balance", 1.2).unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -210,7 +210,7 @@ pub mod balance { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("balance", -1i64).unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -219,7 +219,7 @@ pub mod balance { assert_eq!(error.instance_path().to_string(), "/balance"); identity.set_into_value("balance", 0u64).unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); assert!(result.is_valid()); } @@ -239,7 +239,7 @@ pub mod public_keys { .remove("publicKeys") .expect("expected to remove public keys"); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -260,7 +260,7 @@ pub mod public_keys { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("publicKeys", 1u64).unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -276,7 +276,7 @@ pub mod public_keys { .set_into_value("publicKeys", Value::Array(vec![])) .unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -303,7 +303,7 @@ pub mod public_keys { ) .unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -327,7 +327,7 @@ pub mod public_keys { .set_into_value("publicKeys", Value::Array(vec![public_key; 101])) .unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 2); let error = errors.first().unwrap(); @@ -352,7 +352,7 @@ pub mod revision { .remove("protocolVersion") .expect("expected to remove revision"); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -374,7 +374,7 @@ pub mod revision { identity.set_into_value("revision", 1.2).unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors @@ -391,7 +391,7 @@ pub mod revision { identity.set_into_value("revision", -1i32).unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors @@ -403,7 +403,7 @@ pub mod revision { identity.set_into_value("revision", 0).unwrap(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); assert!(result.is_valid()); } @@ -413,7 +413,7 @@ pub mod revision { pub fn should_return_valid_result_if_a_raw_identity_is_valid() { let (identity, identity_validator) = setup_test(); - let result = identity_validator.validate_identity(&identity).unwrap(); + let result = identity_validator.validate_identity_object(&identity).unwrap(); assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 0); assert!(result.is_valid()); diff --git a/packages/rs-platform-value/Cargo.toml b/packages/rs-platform-value/Cargo.toml index d7fc1ddbd6d..05c70528f27 100644 --- a/packages/rs-platform-value/Cargo.toml +++ b/packages/rs-platform-value/Cargo.toml @@ -16,6 +16,8 @@ serde = { version = "1.0.152", features = ["derive"] } serde_json = { version="1.0", features=["preserve_order"] } rand = { version = "0.8.4", features = ["small_rng"] } treediff = "4.0.2" +regex = "1.7.1" +lazy_static = "1.4.0" ### FEATURES ################################################################# diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index b9f59de315a..bb6a63c1d5c 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -1,6 +1,17 @@ use crate::value_map::ValueMapHelper; -use crate::{Error, Value}; +use crate::{Error, Value, ValueMap}; use std::collections::BTreeMap; +use regex::Regex; +use lazy_static::lazy_static; + +fn is_array_path(text: &str) -> Option<(&str, usize)> { + lazy_static! { + static ref RE: Regex = Regex::new(r"(\w+)\[(\d+)\]").unwrap(); + } + RE.captures(text).map(|captures| { + (captures.get(1).unwrap().as_str(), captures.get(2).unwrap().as_str().parse::().unwrap()) + }) +} impl Value { pub fn remove_value_at_path(&mut self, path: &str) -> Result { @@ -100,18 +111,30 @@ impl Value { if split.peek().is_none() { last_path_component = Some(path_component); } else { - let map = current_value.to_map_mut()?; - current_value = map.get_key_mut(path_component).ok_or_else(|| { - Error::StructureError(format!( - "unable to get property {path_component} in {path}" - )) - })?; + if let Some((string_part, number_part)) = is_array_path(path_component) { + let map = current_value.to_map_mut()?; + let array_value = map.get_key_mut_or_insert(string_part, Value::Array(vec![])); + let array = array_value.to_array_mut()?; + if array.len() < number_part { + //this already exists + current_value = array.get_mut(number_part).unwrap() + } else if array.len() == number_part { + //we should create a new map + array.push(Value::Map(ValueMap::new())); + current_value = array.get_mut(number_part).unwrap(); + } else { + return Err(Error::StructureError(format!("trying to insert into an array path higher than current array length"))); + } + } else { + let map = current_value.to_map_mut()?; + current_value = map.get_key_mut_or_insert(path_component, Value::Map(ValueMap::new())); + } }; } let Some(last_path_component) = last_path_component else { return Err(Error::StructureError(format!("path was empty"))); }; - let map = current_value.as_map_mut_ref()?; + let map = current_value.to_map_mut()?; Ok(Self::insert_in_map(map, last_path_component, value)) } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 3e260e7295a..f50403883a7 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -964,7 +964,7 @@ impl Value { /// assert_eq!(value, Value::Map(vec![])); /// assert_eq!(value.as_map().unwrap().len(), 0); /// ``` - pub fn to_map_mut(&mut self) -> Result<&mut Vec<(Value, Value)>, Error> { + pub fn to_map_mut(&mut self) -> Result<&mut ValueMap, Error> { match *self { Value::Map(ref mut map) => Ok(map), _ => Err(Error::StructureError("value is not a map".to_string())), diff --git a/packages/wasm-dpp/src/identity/validation/identity_validator.rs b/packages/wasm-dpp/src/identity/validation/identity_validator.rs index 2f7b948f2f5..8a75891f4ca 100644 --- a/packages/wasm-dpp/src/identity/validation/identity_validator.rs +++ b/packages/wasm-dpp/src/identity/validation/identity_validator.rs @@ -42,7 +42,7 @@ impl IdentityValidatorWasm { serde_json::from_str(&identity_json).map_err(|e| e.to_string())?; let result = self .0 - .validate_identity(&raw_identity) + .validate_identity_object(&raw_identity) .map_err(|e| from_dpp_err(e.into()))?; Ok(result.map(|_| JsValue::undefined()).into()) From 3a553c42a14825c0484f6b088545ed4e40203723 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 18:26:27 +0700 Subject: [PATCH 126/228] more fixes --- Cargo.lock | 10 ++ packages/rs-platform-value/Cargo.toml | 1 + .../src/inner_value_at_path.rs | 16 ++- packages/rs-platform-value/src/lib.rs | 2 + packages/rs-platform-value/src/macros.rs | 14 +++ .../rs-platform-value/src/types/identifier.rs | 105 ++++++++++++------ .../src/value_serialization/de.rs | 4 +- .../src/value_serialization/mod.rs | 16 +++ .../src/value_serialization/ser.rs | 49 +++++++- 9 files changed, 175 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e73edf0c5a..79e2b7eab59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2224,6 +2224,7 @@ dependencies = [ "rand", "regex", "serde", + "serde_bytes", "serde_json", "thiserror", "treediff 4.0.2", @@ -2721,6 +2722,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde_bytes" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +dependencies = [ + "serde", +] + [[package]] name = "serde_cbor" version = "0.11.2" diff --git a/packages/rs-platform-value/Cargo.toml b/packages/rs-platform-value/Cargo.toml index 05c70528f27..a31a718ef44 100644 --- a/packages/rs-platform-value/Cargo.toml +++ b/packages/rs-platform-value/Cargo.toml @@ -18,6 +18,7 @@ rand = { version = "0.8.4", features = ["small_rng"] } treediff = "4.0.2" regex = "1.7.1" lazy_static = "1.4.0" +serde_bytes = "0.11.9" ### FEATURES ################################################################# diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index bb6a63c1d5c..b90568964e8 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -1,15 +1,18 @@ use crate::value_map::ValueMapHelper; use crate::{Error, Value, ValueMap}; -use std::collections::BTreeMap; -use regex::Regex; use lazy_static::lazy_static; +use regex::Regex; +use std::collections::BTreeMap; fn is_array_path(text: &str) -> Option<(&str, usize)> { lazy_static! { static ref RE: Regex = Regex::new(r"(\w+)\[(\d+)\]").unwrap(); } RE.captures(text).map(|captures| { - (captures.get(1).unwrap().as_str(), captures.get(2).unwrap().as_str().parse::().unwrap()) + ( + captures.get(1).unwrap().as_str(), + captures.get(2).unwrap().as_str().parse::().unwrap(), + ) }) } @@ -123,11 +126,14 @@ impl Value { array.push(Value::Map(ValueMap::new())); current_value = array.get_mut(number_part).unwrap(); } else { - return Err(Error::StructureError(format!("trying to insert into an array path higher than current array length"))); + return Err(Error::StructureError(format!( + "trying to insert into an array path higher than current array length" + ))); } } else { let map = current_value.to_map_mut()?; - current_value = map.get_key_mut_or_insert(path_component, Value::Map(ValueMap::new())); + current_value = + map.get_key_mut_or_insert(path_component, Value::Map(ValueMap::new())); } }; } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index f50403883a7..b369db316a8 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -5,6 +5,8 @@ //! Forked from ciborium value //! //! +extern crate core; + pub mod btreemap_extensions; pub mod converter; pub mod display; diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index 285c064ddb2..47ad3a5ed96 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -296,3 +296,17 @@ macro_rules! platform_value_unexpected { macro_rules! platform_value_expect_expr_comma { ($e:expr , $($tt:tt)*) => {}; } + +#[cfg(test)] +mod test { + use crate::{platform_value, to_value, Identifier, Value}; + + #[test] + fn test_identity_is_kept() { + let id = Identifier::new([0; 32]); + let value = to_value(id).unwrap(); + assert_eq!(value, Value::Identifier(id.to_buffer())); + let value = platform_value!(id); + assert_eq!(value, Value::Identifier(id.to_buffer())) + } +} diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index bd03368d84c..e6beb6176e5 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -1,7 +1,9 @@ use rand::rngs::StdRng; use rand::Rng; use std::convert::{TryFrom, TryInto}; +use std::fmt; +use serde::de::Visitor; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; @@ -11,10 +13,67 @@ use crate::{string_encoding, Error, Value}; pub const IDENTIFIER_MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy)] -pub struct Identifier { - pub buffer: [u8; 32], +pub struct Bytes([u8; 32]); + +#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy, Serialize, Deserialize)] +pub struct Identifier(Bytes); + +impl Serialize for Bytes { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_bytes(&self.0) + } +} + +impl<'de> Deserialize<'de> for Bytes { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct BytesVisitor; + + impl<'de> Visitor<'de> for BytesVisitor { + type Value = Bytes; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array with length 32") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + let mut bytes = [0u8; 32]; + if v.len() != 32 { + return Err(E::invalid_length(v.len(), &self)); + } + bytes.copy_from_slice(v); + Ok(Bytes(bytes)) + } + } + + deserializer.deserialize_bytes(BytesVisitor) + } } +// impl<'de> Deserialize<'de> for Identifier { +// fn deserialize(deserializer: D) -> Result +// where +// D: serde::Deserializer<'de>, +// { +// let data: DocumentValue = Deserialize::deserialize(deserializer)?; +// if let DocumentValue::Bytes(bytes) = data { +// return Ok(Identifier::from(bytes.0)); +// } +// Err(serde::de::Error::custom(format!( +// "expected bytes, got: {:?}", +// data +// ))) +// } +// } + fn encoding_string_to_encoding(encoding_string: Option<&str>) -> Encoding { match encoding_string { Some(str) => { @@ -31,19 +90,19 @@ fn encoding_string_to_encoding(encoding_string: Option<&str>) -> Encoding { impl Identifier { pub fn new(buffer: [u8; 32]) -> Identifier { - Identifier { buffer } + Identifier(Bytes(buffer)) } pub fn random(rng: &mut StdRng) -> Identifier { - Identifier { buffer: rng.gen() } + Identifier(Bytes(rng.gen())) } pub fn as_bytes(&self) -> &[u8; 32] { - &self.buffer + &self.0 .0 } pub fn as_slice(&self) -> &[u8] { - self.buffer.as_slice() + self.0 .0.as_slice() } pub fn from_string(encoded_value: &str, encoding: Encoding) -> Result { @@ -82,16 +141,16 @@ impl Identifier { // TODO - consider to change the name to 'asBuffer` pub fn to_buffer(&self) -> [u8; 32] { - self.buffer + self.0 .0 } /// Convenience method to get underlying buffer as a vec pub fn to_buffer_vec(&self) -> Vec { - self.buffer.to_vec() + self.0 .0.to_vec() } pub fn to_string(&self, encoding: Encoding) -> String { - string_encoding::encode(&self.buffer, encoding) + string_encoding::encode(&self.0 .0, encoding) } pub fn to_string_with_encoding_string(&self, encoding_string: Option<&str>) -> String { @@ -131,26 +190,6 @@ impl From<[u8; 32]> for Identifier { } } -// TODO change default serialization to bytes -impl Serialize for Identifier { - fn serialize(self: &Identifier, serializer: S) -> Result - where - S: Serializer, - { - // by default we use base58 as Identifier type should be encoded in that way - serializer.serialize_str(&self.to_string(Encoding::Base58)) - } -} - -impl<'de> Deserialize<'de> for Identifier { - fn deserialize>(d: D) -> Result { - let data: String = Deserialize::deserialize(d)?; - // by default we use base58 as Identifier type should be encoded in that way - Identifier::from_string_with_encoding_string(&data, Some("base58")) - .map_err(|e| serde::de::Error::custom(e.to_string())) - } -} - impl std::fmt::Display for Identifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.to_string(Encoding::Base58)) @@ -159,13 +198,13 @@ impl std::fmt::Display for Identifier { impl PartialEq<[u8; 32]> for Identifier { fn eq(&self, other: &[u8; 32]) -> bool { - &self.buffer == other + &self.0 .0 == other } } impl PartialEq for [u8; 32] { fn eq(&self, other: &Identifier) -> bool { - self == &other.buffer + self == &other.0 .0 } } @@ -187,12 +226,12 @@ impl TryFrom<&Value> for Identifier { impl From for Value { fn from(value: Identifier) -> Self { - Value::Identifier(value.buffer) + Value::Identifier(value.0 .0) } } impl From<&Identifier> for Value { fn from(value: &Identifier) -> Self { - Value::Identifier(value.buffer) + Value::Identifier(value.0 .0) } } diff --git a/packages/rs-platform-value/src/value_serialization/de.rs b/packages/rs-platform-value/src/value_serialization/de.rs index 311d249c70f..7060d8e937a 100644 --- a/packages/rs-platform-value/src/value_serialization/de.rs +++ b/packages/rs-platform-value/src/value_serialization/de.rs @@ -28,7 +28,7 @@ impl<'a> From<&'a Value> for de::Unexpected<'a> { Value::Bytes32(_) => Self::Seq, Value::EnumU8(_x) => todo!(), Value::EnumString(_x) => todo!(), - Value::Identifier(_x) => todo!(), + Value::Identifier(x) => Self::Bytes(x), } } } @@ -292,6 +292,8 @@ impl<'de> de::Deserializer<'de> for Deserializer { match value { Value::Bytes(x) => visitor.visit_bytes(&x), + Value::Bytes32(x) => visitor.visit_bytes(x.as_slice()), + Value::Identifier(x) => visitor.visit_bytes(x.as_slice()), _ => Err(de::Error::invalid_type((&value).into(), &"bytes")), } } diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index a5e8953f123..7a603e23b40 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -113,10 +113,26 @@ where mod tests { use std::collections::HashMap; + use crate::Identifier; use serde::{Deserialize, Serialize}; use super::*; + #[test] + fn test_identity_is_kept() { + let id = Identifier::new([0; 32]); + let value = to_value(id).unwrap(); + assert_eq!(value, Value::Identifier(id.to_buffer())); + } + + #[test] + fn test_identity_value_desialization() { + let id = Identifier::new([0; 32]); + let value = Value::Identifier(id.to_buffer()); + let new_id: Identifier = from_value(value).unwrap(); + assert_eq!(id, new_id); + } + #[test] fn yeet() { #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index f7ba14f7402..cecd4cc5a4f 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -167,7 +167,11 @@ impl serde::Serializer for Serializer { #[inline] fn serialize_bytes(self, value: &[u8]) -> Result { - Ok(Value::Bytes(value.to_vec())) + if value.len() == 32 { + Ok(Value::Bytes32(value.try_into().unwrap())) + } else { + Ok(Value::Bytes(value.to_vec())) + } } #[inline] @@ -191,11 +195,21 @@ impl serde::Serializer for Serializer { } #[inline] - fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + fn serialize_newtype_struct(self, name: &'static str, value: &T) -> Result where T: ?Sized + Serialize, { - value.serialize(self) + match name { + "Identifier" => match value.serialize(self)? { + Value::Bytes32(b) => { + return Ok(Value::Identifier(b)); + } + data => { + panic!("expected Value::Bytes32, got: {data:#?}") + } + }, + _ => value.serialize(self), + } } fn serialize_newtype_variant( @@ -234,6 +248,10 @@ impl serde::Serializer for Serializer { fn serialize_tuple(self, len: usize) -> Result { self.serialize_seq(Some(len)) + // Ok(SerializeSizedVec { + // size: len, + // vec: Vec::with_capacity(len), + // }) } fn serialize_tuple_struct( @@ -295,6 +313,11 @@ impl serde::Serializer for Serializer { } } +pub struct SerializeSizedVec { + size: usize, + vec: Vec, +} + pub struct SerializeVec { vec: Vec, } @@ -349,6 +372,26 @@ impl serde::ser::SerializeTuple for SerializeVec { } } +// impl serde::ser::SerializeTuple for SerializeSizedVec { +// type Ok = Value; +// type Error = Error; +// +// fn serialize_element(&mut self, value: &T) -> Result<(), Error> +// where +// T: ?Sized + Serialize, +// { +// serde::ser::SerializeSeq::serialize_element(self, value) +// } +// +// fn end(self) -> Result { +// if self.size == 32 { +// Ok(Value::Bytes32(self.vec)) +// } else { +// serde::ser::SerializeSeq::end(self) +// } +// } +// } + impl serde::ser::SerializeTupleStruct for SerializeVec { type Ok = Value; type Error = Error; From f35c9c12b124ab5a2720086c6e4fa5382d507de6 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 16 Mar 2023 23:00:36 +0700 Subject: [PATCH 127/228] fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 8 +++--- .../data_contract/data_contract_factory.rs | 2 +- .../enrich_data_contract_with_base_schema.rs | 8 +++--- .../src/data_contract/extra/drive_api.rs | 8 +++--- .../src/data_trigger/dpns_triggers/mod.rs | 4 +-- packages/rs-dpp/src/document/document.rs | 4 +-- .../rs-dpp/src/document/document_factory.rs | 6 ++--- .../rs-dpp/src/document/extended_document.rs | 4 +-- ...pply_documents_batch_transition_factory.rs | 4 +-- .../document_base_transition.rs | 6 ++--- .../document_replace_transition.rs | 2 +- .../documents_batch_transition/mod.rs | 2 +- .../basic/find_duplicates_by_indices.rs | 16 ++++++------ ...ty_credit_withdrawal_transition_factory.rs | 4 +-- .../state_transition_factory.rs | 2 +- ...e_documents_batch_transition_state_spec.rs | 2 +- ..._documents_batch_transitions_basic_spec.rs | 4 +-- .../fixtures/get_dpns_document_fixture.rs | 2 +- .../execution/fee_pools/fee_distribution.rs | 2 +- .../src/test/helpers/fee_pools.rs | 2 +- .../src/drive/batch/drive_op_batch/mod.rs | 4 +-- .../rs-drive/src/drive/identity/insert.rs | 2 +- .../rs-platform-value/src/types/identifier.rs | 26 +++++++++++++++---- .../src/data_contract/data_contract.rs | 4 +-- .../identity_topup_transition.rs | 2 +- .../identity_update_transition.rs | 2 +- 26 files changed, 75 insertions(+), 57 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 902778deb62..7ada4c09f64 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -209,8 +209,8 @@ impl DataContract { platform_value::to_value(self).map_err(ProtocolError::ValueError) // let mut raw_object = BTreeMap::from([ // (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), - // (property_names::ID.to_string(), Value::Identifier(self.id.buffer)), - // (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.buffer)), + // (property_names::ID.to_string(), Value::Identifier(self.id.to_buffer())), + // (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.to_buffer())), // (property_names::SCHEMA.to_string(), Value::Text(self.schema.clone())), // (property_names::VERSION.to_string(), Value::U32(self.version)), // (property_names::DOCUMENTS.to_string(), self.documents.into()), @@ -226,8 +226,8 @@ impl DataContract { platform_value::to_value(self).map_err(ProtocolError::ValueError) // let mut raw_object = BTreeMap::from([ // (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), - // (property_names::ID.to_string(), Value::Identifier(self.id.buffer)), - // (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.buffer)), + // (property_names::ID.to_string(), Value::Identifier(self.id.to_buffer())), + // (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.to_buffer())), // (property_names::SCHEMA.to_string(), Value::Text(self.schema)), // (property_names::VERSION.to_string(), Value::U32(self.version)), // (property_names::DOCUMENTS.to_string(), self.documents.into()), diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index a456f0dca30..d2c33b63b91 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -235,7 +235,7 @@ mod tests { assert_eq!(data_contract.protocol_version, result.protocol_version); // id is generated based on entropy which is different every time the `create` call is used - assert_eq!(data_contract.id.buffer.len(), result.id.buffer.len()); + assert_eq!(data_contract.id.len(), result.id.len()); assert_ne!(data_contract.id, result.id); assert_eq!(data_contract.schema, result.schema); assert_eq!(data_contract.owner_id, result.owner_id); diff --git a/packages/rs-dpp/src/data_contract/enrich_data_contract_with_base_schema.rs b/packages/rs-dpp/src/data_contract/enrich_data_contract_with_base_schema.rs index b8bbb1943d4..65766d5bf85 100644 --- a/packages/rs-dpp/src/data_contract/enrich_data_contract_with_base_schema.rs +++ b/packages/rs-dpp/src/data_contract/enrich_data_contract_with_base_schema.rs @@ -61,9 +61,9 @@ pub fn enrich_data_contract_with_base_schema( // so we can't pass two different schemas with the same $id. // Hacky solution for that is to replace first four bytes // in $id with passed prefix byte - cloned_data_contract.id.buffer[0] = schema_id_byte_prefix; - cloned_data_contract.id.buffer[1] = schema_id_byte_prefix; - cloned_data_contract.id.buffer[2] = schema_id_byte_prefix; - cloned_data_contract.id.buffer[3] = schema_id_byte_prefix; + cloned_data_contract.id.0.0[0] = schema_id_byte_prefix; + cloned_data_contract.id.0.0[1] = schema_id_byte_prefix; + cloned_data_contract.id.0.0[2] = schema_id_byte_prefix; + cloned_data_contract.id.0.0[3] = schema_id_byte_prefix; Ok(cloned_data_contract) } diff --git a/packages/rs-dpp/src/data_contract/extra/drive_api.rs b/packages/rs-dpp/src/data_contract/extra/drive_api.rs index ec0c40a99a6..ee0a7422fc0 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -1,5 +1,7 @@ use integer_encoding::VarInt; use std::collections::BTreeMap; +use futures::sink::Buffer; +use platform_value::Identifier; use crate::data_contract::document_type::DocumentType; use crate::data_contract::DataContract; @@ -61,7 +63,7 @@ pub trait DriveContractExt { impl DriveContractExt for DataContract { fn id(&self) -> &[u8; 32] { - &self.id.buffer + &self.id.0.0 } fn document_types(&self) -> &BTreeMap { &self.document_types @@ -124,7 +126,7 @@ impl DriveContractExt for DataContract { } }; if let Some(id) = contract_id { - data_contract.id.buffer = id + data_contract.id = Identifier::new(id) } Ok(data_contract) } @@ -135,7 +137,7 @@ impl DriveContractExt for DataContract { { let mut data_contract = DataContract::from_cbor(contract_cbor)?; if let Some(id) = contract_id { - data_contract.id.buffer = id + data_contract.id = Identifier::from(id) } Ok(data_contract) diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 98093d008fa..cb6481fd739 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -106,7 +106,7 @@ where .get_optional_identifier(PROPERTY_DASH_UNIQUE_IDENTITY_ID) .map_err(ProtocolError::ValueError)? { - if id != owner_id.buffer { + if id != owner_id { let err = create_error( context, dt_create, @@ -125,7 +125,7 @@ where .get_optional_identifier(PROPERTY_DASH_ALIAS_IDENTITY_ID) .map_err(ProtocolError::ValueError)? { - if id != owner_id.buffer { + if id != owner_id { let err = create_error( context, dt_create, diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index b18b032e24d..19caa7e0aa2 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -452,11 +452,11 @@ impl Document { if let Ok(value) = document_value.remove(property_names::ID) { let data: S = serde_json::from_value(value)?; - document.id = data.try_into()?.buffer; + document.id = data.try_into()?.to_buffer(); } if let Ok(value) = document_value.remove(property_names::OWNER_ID) { let data: S = serde_json::from_value(value)?; - document.owner_id = data.try_into()?.buffer; + document.owner_id = data.try_into()?.to_buffer(); } if let Ok(value) = document_value.remove(property_names::REVISION) { document.revision = serde_json::from_value(value)? diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 9fca556ae1a..55acf9b5329 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -241,7 +241,7 @@ where ), ( PROPERTY_OWNER_ID.to_string(), - Value::Identifier(owner_id.buffer), + Value::Identifier(owner_id.to_buffer()), ), ( PROPERTY_TRANSITIONS.to_string(), @@ -411,7 +411,7 @@ where ); map.insert( PROPERTY_DATA_CONTRACT_ID.to_string(), - Value::Identifier(document.data_contract_id.buffer), + Value::Identifier(document.data_contract_id.to_buffer()), ); map.into() }) @@ -521,7 +521,7 @@ mod test { DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())), None, ); - documents[0].document.owner_id = generate_random_identifier_struct().buffer; + documents[0].document.owner_id = generate_random_identifier_struct().to_buffer(); let result = factory.create_state_transition(vec![(Action::Create, documents)]); assert_error_contains!(result, "Documents have mixed owner ids") diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index f19d9ce1d08..ad1e02d162e 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -158,7 +158,7 @@ impl ExtendedDocument { extended_document.data_contract_id = Identifier::new( properties .remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? - .unwrap_or(extended_document.data_contract.id.buffer), + .unwrap_or(extended_document.data_contract.id.to_buffer()), ); extended_document.document = Document::from_map(properties, None, None)?; Ok(extended_document) @@ -195,7 +195,7 @@ impl ExtendedDocument { extended_document.data_contract_id = Identifier::new( properties .remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? - .unwrap_or(extended_document.data_contract.id.buffer), + .unwrap_or(extended_document.data_contract.id.to_buffer()), ); extended_document.document = Document::from_map(properties, None, None)?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 1f03682c534..88a97697f47 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -124,8 +124,8 @@ fn document_from_transition_replace( data_contract: Default::default(), entropy: Default::default(), document: Document { - id: document_replace_transition.base.id.buffer, - owner_id: state_transition.owner_id.buffer, + id: document_replace_transition.base.id.to_buffer(), + owner_id: state_transition.owner_id.to_buffer(), properties: document_replace_transition.data.clone().unwrap_or_default(), revision: Some(document_replace_transition.revision), created_at: Some(created_at), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index 11beb54e512..c579655e1d1 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -124,7 +124,7 @@ impl DocumentBaseTransition { data_contract_id: Identifier::new( map.remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID) .map_err(ProtocolError::ValueError)? - .unwrap_or(data_contract.id.buffer), + .unwrap_or(data_contract.id.to_buffer()), ), data_contract, }) @@ -182,11 +182,11 @@ impl DocumentTransitionObjectLike for DocumentBaseTransition { let mut btree_map = BTreeMap::new(); btree_map.insert( property_names::ID.to_string(), - Value::Identifier(self.id.buffer), + Value::Identifier(self.id.to_buffer()), ); btree_map.insert( property_names::DATA_CONTRACT_ID.to_string(), - Value::Identifier(self.data_contract_id.buffer), + Value::Identifier(self.data_contract_id.to_buffer()), ); btree_map.insert( property_names::ACTION.to_string(), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index e6ad667522d..f9f71ae1108 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -44,7 +44,7 @@ impl DocumentReplaceTransition { let properties = self.data.clone().unwrap_or_default(); Ok(Document { id: self.base.id.to_buffer(), - owner_id: owner_id.buffer, + owner_id: owner_id.to_buffer(), properties, created_at: self.updated_at, // we can use the same time, as it can't be worse updated_at: self.updated_at, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index f1e56f66182..daff0b26ff1 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -307,7 +307,7 @@ impl DocumentsBatchTransition { ); map.insert( property_names::OWNER_ID.to_string(), - Value::Identifier(self.owner_id.buffer), + Value::Identifier(self.owner_id.to_buffer()), ); if !skip_signature { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs index 454c1041170..1bb2105076d 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -199,7 +199,7 @@ mod test { ) .unwrap(); let document_raw_transition_1: Value = BTreeMap::from([ - ("$id".to_string(), Value::Identifier(id_1.buffer)), + ("$id".to_string(), Value::Identifier(id_1.to_buffer())), ( "$type".to_string(), Value::Text("indexedDocument".to_string()), @@ -236,7 +236,7 @@ mod test { .unwrap(); let document_create_transition_2: Value = BTreeMap::from([ - ("$id".to_string(), Value::Identifier(id_2.buffer)), + ("$id".to_string(), Value::Identifier(id_2.to_buffer())), ( "$type".to_string(), Value::Text("indexedDocument".to_string()), @@ -324,8 +324,8 @@ mod test { ) .unwrap(); let document_raw_transition_1: Value = BTreeMap::from([ - ("$ownerId".to_string(), Value::Identifier(id_1.buffer)), - ("$id".to_string(), Value::Identifier(id_1.buffer)), + ("$ownerId".to_string(), Value::Identifier(id_1.to_buffer())), + ("$id".to_string(), Value::Identifier(id_1.to_buffer())), ( "$type".to_string(), Value::Text("indexedDocument".to_string()), @@ -362,8 +362,8 @@ mod test { .unwrap(); let document_create_transition_2: Value = BTreeMap::from([ - ("$ownerId".to_string(), Value::Identifier(id_1.buffer)), - ("$id".to_string(), Value::Identifier(id_2.buffer)), + ("$ownerId".to_string(), Value::Identifier(id_1.to_buffer())), + ("$id".to_string(), Value::Identifier(id_2.to_buffer())), ( "$type".to_string(), Value::Text("indexedDocument".to_string()), @@ -450,7 +450,7 @@ mod test { ) .unwrap(); let document_raw_transition_1: Value = BTreeMap::from([ - ("$id".to_string(), Value::Identifier(id_1.buffer)), + ("$id".to_string(), Value::Identifier(id_1.to_buffer())), ( "$type".to_string(), Value::Text("indexedDocument".to_string()), @@ -487,7 +487,7 @@ mod test { .unwrap(); let document_create_transition_2: Value = BTreeMap::from([ - ("$id".to_string(), Value::Identifier(id_2.buffer)), + ("$id".to_string(), Value::Identifier(id_2.to_buffer())), ( "$type".to_string(), Value::Text("indexedDocument".to_string()), diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs index 9e4ed613390..3db89412adc 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs @@ -120,9 +120,9 @@ where } let withdrawal_document = Document { - id: document_id.buffer, + id: document_id.to_buffer(), revision: None, - owner_id: state_transition.identity_id.buffer, + owner_id: state_transition.identity_id.to_buffer(), created_at: Some(document_created_at_millis), updated_at: Some(document_created_at_millis), properties: document_properties, diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 550eeaea809..5633596d227 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -208,7 +208,7 @@ mod test { map.insert("protocolVersion".to_string(), Value::U32(PROTOCOL_VERSION)); map.insert( "ownerId".to_string(), - Value::Identifier(data_contract.owner_id.buffer), + Value::Identifier(data_contract.owner_id.to_buffer()), ); map.insert( "transitions".to_string(), diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index f19481fe49f..d6e611a3240 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -302,7 +302,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace ) .expect("document should be created"); let another_owner_id = generate_random_identifier_struct(); - fetched_document.document.owner_id = another_owner_id.buffer; + fetched_document.document.owner_id = another_owner_id.to_buffer(); let document_transitions = get_document_transitions_fixture([ (Action::Create, vec![]), diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index e05e2b94827..d3783941f37 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -57,10 +57,10 @@ fn setup_test(action: Action) -> TestData { let signature = [0_u8; 65].to_vec(); let mut map = BTreeMap::new(); map.insert("protocolVersion".to_string(), Value::U32(LATEST_VERSION)); - map.insert("ownerId".to_string(), Value::Identifier(owner_id.buffer)); + map.insert("ownerId".to_string(), Value::Identifier(owner_id.to_buffer())); map.insert( "contractId".to_string(), - Value::Identifier(data_contract.id.buffer), + Value::Identifier(data_contract.id.to_buffer()), ); map.insert("signature".to_string(), Value::Bytes(signature)); map.insert("signaturePublicKeyId".to_string(), Value::U32(0)); diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs index 8c60782bec9..5ec2af7c669 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_document_fixture.rs @@ -60,7 +60,7 @@ pub fn get_dpns_parent_document_fixture(options: ParentDocumentOptions) -> Exten "records".to_string(), Value::Map(vec![( Value::Text("dashUniqueIdentityId".to_string()), - Value::Identifier(options.owner_id.buffer), + Value::Identifier(options.owner_id.to_buffer()), )]), ); map.insert( diff --git a/packages/rs-drive-abci/src/execution/fee_pools/fee_distribution.rs b/packages/rs-drive-abci/src/execution/fee_pools/fee_distribution.rs index 4b7820f8e96..54c56a90317 100644 --- a/packages/rs-drive-abci/src/execution/fee_pools/fee_distribution.rs +++ b/packages/rs-drive-abci/src/execution/fee_pools/fee_distribution.rs @@ -1305,7 +1305,7 @@ mod tests { let share_identities = share_identities_and_documents .iter() - .map(|(identity, _)| identity.id.buffer) + .map(|(identity, _)| identity.id.to_buffer()) .collect(); let refetched_share_identities_balances = platform diff --git a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs index cad89c426cf..12aab9caf46 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -69,7 +69,7 @@ fn create_test_mn_share_document( properties.insert( String::from("payToId"), - Value::Bytes(pay_to_identity.id.buffer.to_vec()), + Value::Bytes(pay_to_identity.id.to_buffer().to_vec()), ); properties.insert(String::from("percentage"), percentage.into()); diff --git a/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs index 71656e0bf6e..ff06542f882 100644 --- a/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/drive/batch/drive_op_batch/mod.rs @@ -294,7 +294,7 @@ mod tests { let element = drive .grove .get( - contract_root_path(&contract.id.buffer), + contract_root_path(&contract.id.to_buffer()), &[0], Some(&db_transaction), ) @@ -515,7 +515,7 @@ mod tests { let element = drive .grove .get( - contract_root_path(&contract.id.buffer), + contract_root_path(&contract.id.to_buffer()), &[0], Some(&db_transaction), ) diff --git a/packages/rs-drive/src/drive/identity/insert.rs b/packages/rs-drive/src/drive/identity/insert.rs index 4162b1be9b2..c25b6464d22 100644 --- a/packages/rs-drive/src/drive/identity/insert.rs +++ b/packages/rs-drive/src/drive/identity/insert.rs @@ -190,7 +190,7 @@ mod tests { .expect("expected to insert identity"); let fetched_identity = drive - .fetch_full_identity(identity.id.buffer, Some(&transaction)) + .fetch_full_identity(identity.id.to_buffer(), Some(&transaction)) .expect("should fetch an identity") .expect("should have an identity"); diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index e6beb6176e5..6006d6258b6 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -13,10 +13,10 @@ use crate::{string_encoding, Error, Value}; pub const IDENTIFIER_MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy)] -pub struct Bytes([u8; 32]); +pub struct Bytes(pub [u8; 32]); #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy, Serialize, Deserialize)] -pub struct Identifier(Bytes); +pub struct Identifier(pub Bytes); impl Serialize for Bytes { fn serialize(&self, serializer: S) -> Result @@ -139,9 +139,13 @@ impl Identifier { .collect() } + pub fn len(&self) -> usize { + 32 + } + // TODO - consider to change the name to 'asBuffer` pub fn to_buffer(&self) -> [u8; 32] { - self.0 .0 + self.0.0 } /// Convenience method to get underlying buffer as a vec @@ -198,13 +202,25 @@ impl std::fmt::Display for Identifier { impl PartialEq<[u8; 32]> for Identifier { fn eq(&self, other: &[u8; 32]) -> bool { - &self.0 .0 == other + &self.0.0 == other + } +} + +impl PartialEq<[u8; 32]> for &Identifier { + fn eq(&self, other: &[u8; 32]) -> bool { + &self.0.0 == other } } impl PartialEq for [u8; 32] { fn eq(&self, other: &Identifier) -> bool { - self == &other.0 .0 + self == &other.0.0 + } +} + +impl PartialEq<&Identifier> for [u8; 32] { + fn eq(&self, other: &&Identifier) -> bool { + self == &other.0.0 } } diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index 5a2280363e0..eb371168181 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -277,13 +277,13 @@ impl DataContractWasm { js_sys::Reflect::set( &object, &Into::::into("$id".to_owned()), - &Into::::into(Buffer::from_bytes(&self.0.id.buffer)), + &Into::::into(Buffer::from_bytes(&self.0.id.to_buffer())), ) .expect("target is an object"); js_sys::Reflect::set( &object, &Into::::into("ownerId".to_owned()), - &Into::::into(Buffer::from_bytes(&self.0.owner_id.buffer)), + &Into::::into(Buffer::from_bytes(&self.0.owner_id.to_buffer())), ) .expect("target is an object"); Ok(object) diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index ecfd45c8100..44702a346a9 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -161,7 +161,7 @@ impl IdentityTopUpTransitionWasm { js_sys::Reflect::set( &js_object, &"identityId".to_owned().into(), - &Buffer::from_bytes(object.identity_id.buffer.as_slice()), + &Buffer::from_bytes(object.identity_id.to_buffer().as_slice()), )?; Ok(js_object.into()) diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 6e9b21d7d3c..f118b3497e3 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -267,7 +267,7 @@ impl IdentityUpdateTransitionWasm { js_sys::Reflect::set( &js_object, &"identityId".to_owned().into(), - &Buffer::from_bytes(object.identity_id.buffer.as_slice()), + &Buffer::from_bytes(object.identity_id.to_buffer().as_slice()), )?; Ok(js_object.into()) From 87c252221b186a1451a4eaf6a828196b3fce4221 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 01:56:36 +0700 Subject: [PATCH 128/228] more fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 35 +++--- .../enrich_data_contract_with_base_schema.rs | 8 +- .../src/data_contract/extra/drive_api.rs | 5 +- .../validation/multi_validator.rs | 1 + packages/rs-dpp/src/identity/factory.rs | 4 +- .../rs-dpp/src/identity/identity_facade.rs | 3 +- ..._documents_batch_transitions_basic_spec.rs | 5 +- .../identity_update_transition_spec.rs | 11 +- .../validation/identity_validator_spec.rs | 84 ++++++++++---- .../btreemap_path_extensions.rs | 18 +-- .../btreemap_removal_extensions.rs | 40 ++++++- packages/rs-platform-value/src/inner_value.rs | 46 ++++++++ packages/rs-platform-value/src/lib.rs | 2 + packages/rs-platform-value/src/macros.rs | 12 ++ .../src/types/binary_data.rs | 107 ++++++++++++++++++ .../rs-platform-value/src/types/bytes_32.rs | 79 +++++++++++++ .../rs-platform-value/src/types/identifier.rs | 103 +++++++++++++---- packages/rs-platform-value/src/types/mod.rs | 2 + packages/rs-platform-value/src/value_map.rs | 6 + .../src/value_serialization/de.rs | 4 + .../src/value_serialization/mod.rs | 16 +-- .../src/value_serialization/ser.rs | 11 +- 22 files changed, 499 insertions(+), 103 deletions(-) create mode 100644 packages/rs-platform-value/src/types/binary_data.rs create mode 100644 packages/rs-platform-value/src/types/bytes_32.rs diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 7ada4c09f64..9e31e40e03f 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -4,7 +4,9 @@ use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; use itertools::{Either, Itertools}; -use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; +use platform_value::btreemap_extensions::{ + BTreeValueMapHelper, BTreeValueMapPathHelper, BTreeValueRemoveFromMapHelper, +}; use platform_value::Identifier; use platform_value::Value; use serde::{Deserialize, Serialize}; @@ -145,30 +147,27 @@ impl DataContract { .collect(); let data_contract = DataContract { protocol_version: 0, - id: Identifier::from( - data_contract_map - .remove_hash256_bytes(property_names::ID) - .map_err(ProtocolError::ValueError)?, - ), + id: data_contract_map + .remove_identifier(property_names::ID) + .map_err(ProtocolError::ValueError)?, schema: data_contract_map .remove_string(property_names::SCHEMA) .map_err(ProtocolError::ValueError)?, version: data_contract_map .remove_integer(property_names::VERSION) .map_err(ProtocolError::ValueError)?, - owner_id: Identifier::from( - data_contract_map - .remove_hash256_bytes(property_names::OWNER_ID) - .map_err(ProtocolError::ValueError)?, - ), + owner_id: data_contract_map + .remove_identifier(property_names::OWNER_ID) + .map_err(ProtocolError::ValueError)?, document_types, metadata: None, config: mutability, documents, defs, entropy: data_contract_map - .remove_hash256_bytes(property_names::ENTROPY) - .map_err(ProtocolError::ValueError)?, + .remove_optional_hash256_bytes(property_names::ENTROPY) + .map_err(ProtocolError::ValueError)? + .unwrap_or_default(), binary_properties, }; @@ -467,9 +466,10 @@ impl TryFrom<&str> for DataContract { type Error = ProtocolError; fn try_from(v: &str) -> Result { let mut data_contract: DataContract = serde_json::from_str(v)?; - data_contract.generate_binary_properties(); - - Ok(data_contract) + //todo: there's a better to do this, find it + let value = data_contract.to_object()?; + dbg!(&value); + DataContract::from_raw_object(value) } } @@ -704,8 +704,9 @@ mod test { init(); let string_contract = get_data_from_file("src/tests/payloads/contract_example.json")?; + dbg!(&string_contract); let contract = DataContract::try_from(string_contract.as_str())?; - + dbg!(&contract); assert_eq!(contract.protocol_version, 0); assert_eq!( contract.schema, diff --git a/packages/rs-dpp/src/data_contract/enrich_data_contract_with_base_schema.rs b/packages/rs-dpp/src/data_contract/enrich_data_contract_with_base_schema.rs index 65766d5bf85..26040109386 100644 --- a/packages/rs-dpp/src/data_contract/enrich_data_contract_with_base_schema.rs +++ b/packages/rs-dpp/src/data_contract/enrich_data_contract_with_base_schema.rs @@ -61,9 +61,9 @@ pub fn enrich_data_contract_with_base_schema( // so we can't pass two different schemas with the same $id. // Hacky solution for that is to replace first four bytes // in $id with passed prefix byte - cloned_data_contract.id.0.0[0] = schema_id_byte_prefix; - cloned_data_contract.id.0.0[1] = schema_id_byte_prefix; - cloned_data_contract.id.0.0[2] = schema_id_byte_prefix; - cloned_data_contract.id.0.0[3] = schema_id_byte_prefix; + cloned_data_contract.id.0 .0[0] = schema_id_byte_prefix; + cloned_data_contract.id.0 .0[1] = schema_id_byte_prefix; + cloned_data_contract.id.0 .0[2] = schema_id_byte_prefix; + cloned_data_contract.id.0 .0[3] = schema_id_byte_prefix; Ok(cloned_data_contract) } diff --git a/packages/rs-dpp/src/data_contract/extra/drive_api.rs b/packages/rs-dpp/src/data_contract/extra/drive_api.rs index ee0a7422fc0..46f76da7b8e 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -1,7 +1,6 @@ use integer_encoding::VarInt; -use std::collections::BTreeMap; -use futures::sink::Buffer; use platform_value::Identifier; +use std::collections::BTreeMap; use crate::data_contract::document_type::DocumentType; use crate::data_contract::DataContract; @@ -63,7 +62,7 @@ pub trait DriveContractExt { impl DriveContractExt for DataContract { fn id(&self) -> &[u8; 32] { - &self.id.0.0 + &self.id.0 .0 } fn document_types(&self) -> &BTreeMap { &self.document_types diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 31e57e33af6..92770e6d3c2 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -121,6 +121,7 @@ pub fn byte_array_has_no_items_as_parent_validator( #[cfg(test)] mod test { use platform_value::platform_value; + use platform_value::ValueMapHelper; use super::*; diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index 19692a6b375..9d1cd8205b2 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -122,7 +122,9 @@ where skip_validation: bool, ) -> Result { if !skip_validation { - let result = self.identity_validator.validate_identity_object(&raw_identity)?; + let result = self + .identity_validator + .validate_identity_object(&raw_identity)?; if !result.is_valid() { return Err(ProtocolError::InvalidIdentityError { diff --git a/packages/rs-dpp/src/identity/identity_facade.rs b/packages/rs-dpp/src/identity/identity_facade.rs index 1aac3233563..5d494ad8f77 100644 --- a/packages/rs-dpp/src/identity/identity_facade.rs +++ b/packages/rs-dpp/src/identity/identity_facade.rs @@ -73,7 +73,8 @@ where &self, identity_object: &Value, ) -> Result, NonConsensusError> { - self.identity_validator.validate_identity_object(identity_object) + self.identity_validator + .validate_identity_object(identity_object) } pub fn create_instant_lock_proof( diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index d3783941f37..e9ab0a850b2 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -57,7 +57,10 @@ fn setup_test(action: Action) -> TestData { let signature = [0_u8; 65].to_vec(); let mut map = BTreeMap::new(); map.insert("protocolVersion".to_string(), Value::U32(LATEST_VERSION)); - map.insert("ownerId".to_string(), Value::Identifier(owner_id.to_buffer())); + map.insert( + "ownerId".to_string(), + Value::Identifier(owner_id.to_buffer()), + ); map.insert( "contractId".to_string(), Value::Identifier(data_contract.id.to_buffer()), diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index 2a935999c3f..1016fe0572b 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -1,7 +1,8 @@ use chrono::Utc; -use platform_value::{platform_value, Value}; +use platform_value::{platform_value, BinaryData, Value}; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; +use crate::prelude::Revision; use crate::{ identity::{ state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, @@ -203,8 +204,8 @@ fn to_json() { "signature" : Vec::::new(), "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id, - "revision": 0u8, - "disablePublicKeys" : [0u8], + "revision": 0 as Revision, + "disablePublicKeys" : [0u32], "publicKeysDisabledAt" : 1234567u64, "addPublicKeys" : [ { @@ -213,9 +214,9 @@ fn to_json() { "purpose" : 0u8, "type": 0u8, "securityLevel" : 0u8, - "data" : base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap(), + "data" : BinaryData::new(base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap()), "readOnly" : false, - "signature" : vec![0;65], + "signature" : BinaryData::new(vec![0;65]), } ] }); diff --git a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs index 35c8344a817..becbb2c1657 100644 --- a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs @@ -38,7 +38,9 @@ pub mod protocol_version { .remove("protocolVersion") .expect("expected to remove protocol version"); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -59,7 +61,9 @@ pub mod protocol_version { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("protocolVersion", "1").unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -73,7 +77,9 @@ pub mod protocol_version { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("protocolVersion", -1i32).unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -96,7 +102,9 @@ pub mod id { let (mut identity, identity_validator) = setup_test(); identity.remove("id").expect("expected to remove id"); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -119,7 +127,9 @@ pub mod id { .set_into_value("id", vec![Value::from("string"); 32]) .unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 32); for (i, err) in errors.iter().enumerate() { @@ -135,7 +145,9 @@ pub mod id { .set_into_value("id", vec![Value::from(15); 31]) .unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -151,7 +163,9 @@ pub mod id { .set_into_value("id", vec![Value::from(15); 33]) .unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -175,7 +189,9 @@ pub mod balance { .remove("balance") .expect("expected to remove balance"); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -196,7 +212,9 @@ pub mod balance { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("balance", 1.2).unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -210,7 +228,9 @@ pub mod balance { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("balance", -1i64).unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -219,7 +239,9 @@ pub mod balance { assert_eq!(error.instance_path().to_string(), "/balance"); identity.set_into_value("balance", 0u64).unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); assert!(result.is_valid()); } @@ -239,7 +261,9 @@ pub mod public_keys { .remove("publicKeys") .expect("expected to remove public keys"); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -260,7 +284,9 @@ pub mod public_keys { let (mut identity, identity_validator) = setup_test(); identity.set_into_value("publicKeys", 1u64).unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -276,7 +302,9 @@ pub mod public_keys { .set_into_value("publicKeys", Value::Array(vec![])) .unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -303,7 +331,9 @@ pub mod public_keys { ) .unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -327,7 +357,9 @@ pub mod public_keys { .set_into_value("publicKeys", Value::Array(vec![public_key; 101])) .unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 2); let error = errors.first().unwrap(); @@ -352,7 +384,9 @@ pub mod revision { .remove("protocolVersion") .expect("expected to remove revision"); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); @@ -374,7 +408,9 @@ pub mod revision { identity.set_into_value("revision", 1.2).unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors @@ -391,7 +427,9 @@ pub mod revision { identity.set_into_value("revision", -1i32).unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); let errors = assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 1); let error = errors @@ -403,7 +441,9 @@ pub mod revision { identity.set_into_value("revision", 0).unwrap(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); assert!(result.is_valid()); } @@ -413,7 +453,9 @@ pub mod revision { pub fn should_return_valid_result_if_a_raw_identity_is_valid() { let (identity, identity_validator) = setup_test(); - let result = identity_validator.validate_identity_object(&identity).unwrap(); + let result = identity_validator + .validate_identity_object(&identity) + .unwrap(); assert_consensus_errors!(&result, ConsensusError::JsonSchemaError, 0); assert!(result.is_valid()); diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs index c56c659f085..27cf40aaaa4 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs @@ -6,7 +6,7 @@ use std::iter::FromIterator; use std::{collections::BTreeMap, convert::TryInto}; use crate::value_map::ValueMapHelper; -use crate::{Error, Value}; +use crate::{Error, Identifier, Value}; pub trait BTreeValueMapPathHelper { fn get_at_path(&self, path: &str) -> Result<&Value, Error>; @@ -118,11 +118,11 @@ pub trait BTreeValueMapPathHelper { path: &str, ) -> Result, Error>; fn remove_hash256_bytes_at_path(&mut self, path: &str) -> Result<[u8; 32], Error>; - fn remove_optional_identifier_bytes_at_path( + fn remove_optional_identifier_at_path( &mut self, path: &str, - ) -> Result>, Error>; - fn remove_identifier_bytes_at_path(&mut self, path: &str) -> Result, Error>; + ) -> Result, Error>; + fn remove_identifier_at_path(&mut self, path: &str) -> Result; fn get_optional_bytes_at_path(&self, path: &str) -> Result>, Error>; fn get_bytes_at_path(&self, path: &str) -> Result, Error>; fn get_optional_binary_bytes_at_path(&self, path: &str) -> Result>, Error>; @@ -525,17 +525,17 @@ where }) } - fn remove_optional_identifier_bytes_at_path( + fn remove_optional_identifier_at_path( &mut self, path: &str, - ) -> Result>, Error> { + ) -> Result, Error> { self.remove(path) - .map(|v| v.borrow().to_identifier_bytes()) + .map(|v| v.borrow().to_identifier()) .transpose() } - fn remove_identifier_bytes_at_path(&mut self, path: &str) -> Result, Error> { - self.remove_optional_identifier_bytes_at_path(path)? + fn remove_identifier_at_path(&mut self, path: &str) -> Result { + self.remove_optional_identifier_at_path(path)? .ok_or_else(|| { Error::StructureError(format!("unable to remove system bytes property {path}")) }) diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs index 3df915d54ff..18eee60ac72 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs @@ -1,4 +1,4 @@ -use crate::{Error, Value}; +use crate::{Error, Identifier, Value}; use std::collections::BTreeMap; pub trait BTreeValueRemoveFromMapHelper { @@ -36,6 +36,8 @@ pub trait BTreeValueRemoveFromMapHelper { fn remove_bytes(&mut self, key: &str) -> Result, Error>; fn remove_optional_bool(&mut self, key: &str) -> Result, Error>; fn remove_bool(&mut self, key: &str) -> Result; + fn remove_optional_identifier(&mut self, key: &str) -> Result, Error>; + fn remove_identifier(&mut self, key: &str) -> Result; } impl BTreeValueRemoveFromMapHelper for BTreeMap { @@ -81,6 +83,24 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { }) } + fn remove_optional_identifier(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_identifier()) + } + }) + .transpose() + } + + fn remove_identifier(&mut self, key: &str) -> Result { + self.remove_optional_identifier(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove identifier property {key}")) + }) + } + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { self.remove(key) .and_then(|v| { @@ -199,6 +219,24 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { }) } + fn remove_optional_identifier(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_identifier()) + } + }) + .transpose() + } + + fn remove_identifier(&mut self, key: &str) -> Result { + self.remove_optional_identifier(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove identifier property {key}")) + }) + } + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { self.remove(key) .and_then(|v| { diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index f60ff7a5bb9..765b1e84f20 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,3 +1,4 @@ +use std::cmp::Ordering; use crate::value_map::{ValueMap, ValueMapHelper}; use crate::Identifier; use crate::{Error, Value}; @@ -110,6 +111,20 @@ impl Value { .transpose() } + pub fn remove_identifier(&mut self, key: &str) -> Result { + let map = self.as_map_mut_ref()?; + let value = map.remove_key(key)?; + value.into_identifier() + } + + pub fn remove_optional_identifier(&mut self, key: &str) -> Result, Error> { + let map = self.as_map_mut_ref()?; + map.remove_optional_key(key) + .map(|v| v.into_identifier()) + .transpose() + } + + pub fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error> { let map = self.as_map_mut_ref()?; let value = map.remove_key(key)?; @@ -691,6 +706,37 @@ impl Value { map: &mut ValueMap, inserting_key: String, inserting_value: Value, + ) { + let mut found_value = None; + let mut pos = 0; + for (key, value) in map.iter_mut() { + if let Value::Text(text) = key { + match inserting_key.cmp(text) { + Ordering::Less => { + } + Ordering::Equal => { + found_value = Some(value); + break; + } + Ordering::Greater => { + pos += 1; + } + } + } + } + if let Some(value) = found_value { + *value = inserting_value; + } else { + map.insert(pos,(Value::Text(inserting_key), inserting_value)) + } + } + + /// Inserts into a map + /// If the element already existed it will replace it + pub fn push_to_map_string_value( + map: &mut ValueMap, + inserting_key: String, + inserting_value: Value, ) { let mut found_value = None; for (key, value) in map.iter_mut() { diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index b369db316a8..ee0eeabd9ce 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -32,6 +32,8 @@ pub type Hash256 = [u8; 32]; pub use btreemap_extensions::btreemap_field_replacement::ReplacementType; pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; +pub use types::binary_data::BinaryData; +pub use types::bytes_32::Bytes32; pub use value_serialization::{from_value, to_value}; diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index 47ad3a5ed96..a0243a4e384 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -261,8 +261,10 @@ macro_rules! platform_value_internal { ({ $($tt:tt)+ }) => { $crate::Value::Map({ + use platform_value::ValueMapHelper; let mut object = $crate::ValueMap::new(); platform_value_internal!(@object object () ($($tt)+) ($($tt)+)); + object.sort_by_keys(); object }) }; @@ -300,6 +302,7 @@ macro_rules! platform_value_expect_expr_comma { #[cfg(test)] mod test { use crate::{platform_value, to_value, Identifier, Value}; + use crate::types::binary_data::BinaryData; #[test] fn test_identity_is_kept() { @@ -309,4 +312,13 @@ mod test { let value = platform_value!(id); assert_eq!(value, Value::Identifier(id.to_buffer())) } + + #[test] + fn test_binary_is_kept() { + let id = BinaryData::new([0; 44].to_vec()); + let value = to_value(id.clone()).unwrap(); + assert_eq!(value, Value::Bytes(id.clone().to_vec())); + let value = platform_value!(id.clone()); + assert_eq!(value, Value::Bytes(id.to_vec())); + } } diff --git a/packages/rs-platform-value/src/types/binary_data.rs b/packages/rs-platform-value/src/types/binary_data.rs new file mode 100644 index 00000000000..a9ff0a17b9f --- /dev/null +++ b/packages/rs-platform-value/src/types/binary_data.rs @@ -0,0 +1,107 @@ +use std::fmt; +use serde::{Deserialize, Serialize}; +use serde::de::Visitor; + +#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)] +pub struct BinaryData(pub Vec); + +impl Serialize for BinaryData { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if serializer.is_human_readable() { + serializer.serialize_str(&base64::encode(self.0.as_slice())) + } else { + serializer.serialize_bytes(&self.0) + } + } +} + +impl<'de> Deserialize<'de> for BinaryData { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + if deserializer.is_human_readable() { + + struct StringVisitor; + + impl<'de> Visitor<'de> for StringVisitor { + type Value = BinaryData; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a base64-encoded string") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + let bytes = base64::decode(v).map_err(|e| E::custom(format!("{}", e)))?; + Ok(BinaryData(bytes)) + } + } + + deserializer.deserialize_string(StringVisitor) + } else { + struct BytesVisitor; + + impl<'de> Visitor<'de> for BytesVisitor { + type Value = BinaryData; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array with length 32") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + Ok(BinaryData(v.to_vec())) + } + } + + deserializer.deserialize_bytes(BytesVisitor) + } + } +} + +impl BinaryData { + pub fn new(buffer: Vec) -> BinaryData { + BinaryData(buffer) + } + + pub fn as_slice(&self) -> &[u8] { + self.0.as_slice() + } + + pub fn to_vec(&self) -> Vec { + self.0.clone() + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use crate::{from_value, Identifier, to_value, Value}; + use serde::{Deserialize, Serialize}; + + use super::*; + + #[test] + fn test_binary_data_serialization() { + let id = BinaryData::new([2; 34].to_vec()); + let value = to_value(id.clone()).unwrap(); + assert_eq!(value, Value::Bytes(id.to_vec())); + } + + #[test] + fn test_identifier_value_deserialization() { + let id = Identifier::new([3; 32]); + let value = Value::Identifier(id.to_buffer()); + let new_id: Identifier = from_value(value).unwrap(); + assert_eq!(id, new_id); + } +} diff --git a/packages/rs-platform-value/src/types/bytes_32.rs b/packages/rs-platform-value/src/types/bytes_32.rs new file mode 100644 index 00000000000..9122f496f50 --- /dev/null +++ b/packages/rs-platform-value/src/types/bytes_32.rs @@ -0,0 +1,79 @@ +use std::fmt; +use std::fmt::Write; +use serde::{Deserialize, Serialize}; +use serde::de::Visitor; + +#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy)] +pub struct Bytes32(pub [u8; 32]); + +impl Serialize for Bytes32 { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if serializer.is_human_readable() { + serializer.serialize_str(&base64::encode(self.0)) + } else { + serializer.serialize_bytes(&self.0) + } + } +} + +impl<'de> Deserialize<'de> for Bytes32 { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + if deserializer.is_human_readable() { + + struct StringVisitor; + + impl<'de> Visitor<'de> for StringVisitor { + type Value = Bytes32; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a base64-encoded string with length 44") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + let bytes = base64::decode(v).map_err(|e| E::custom(format!("{}", e)))?; + if bytes.len() != 32 { + return Err(E::invalid_length(bytes.len(), &self)); + } + let mut array = [0u8; 32]; + array.copy_from_slice(&bytes); + Ok(Bytes32(array)) + } + } + + deserializer.deserialize_string(StringVisitor) + } else { + struct BytesVisitor; + + impl<'de> Visitor<'de> for BytesVisitor { + type Value = Bytes32; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array with length 32") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + let mut bytes = [0u8; 32]; + if v.len() != 32 { + return Err(E::invalid_length(v.len(), &self)); + } + bytes.copy_from_slice(v); + Ok(Bytes32(bytes)) + } + } + + deserializer.deserialize_bytes(BytesVisitor) + } + } +} \ No newline at end of file diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 6006d6258b6..42a65797485 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -13,48 +13,80 @@ use crate::{string_encoding, Error, Value}; pub const IDENTIFIER_MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy)] -pub struct Bytes(pub [u8; 32]); +pub struct IdentifierBytes32(pub [u8; 32]); #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy, Serialize, Deserialize)] -pub struct Identifier(pub Bytes); +pub struct Identifier(pub IdentifierBytes32); -impl Serialize for Bytes { +impl Serialize for IdentifierBytes32 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { - serializer.serialize_bytes(&self.0) + if serializer.is_human_readable() { + serializer.serialize_str(&bs58::encode(self.0).into_string()) + } else { + serializer.serialize_bytes(&self.0) + } } } -impl<'de> Deserialize<'de> for Bytes { +impl<'de> Deserialize<'de> for IdentifierBytes32 { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { - struct BytesVisitor; + if deserializer.is_human_readable() { + + struct StringVisitor; - impl<'de> Visitor<'de> for BytesVisitor { - type Value = Bytes; + impl<'de> Visitor<'de> for StringVisitor { + type Value = IdentifierBytes32; - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a byte array with length 32") + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a base58-encoded string") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + let bytes = bs58::decode(v).into_vec().map_err(|e| E::custom(format!("{}", e)))?; + if bytes.len() != 32 { + return Err(E::invalid_length(bytes.len(), &self)); + } + let mut array = [0u8; 32]; + array.copy_from_slice(&bytes); + Ok(IdentifierBytes32(array)) + } } - fn visit_bytes(self, v: &[u8]) -> Result - where - E: serde::de::Error, - { - let mut bytes = [0u8; 32]; - if v.len() != 32 { - return Err(E::invalid_length(v.len(), &self)); + deserializer.deserialize_string(StringVisitor) + } else { + struct BytesVisitor; + + impl<'de> Visitor<'de> for BytesVisitor { + type Value = IdentifierBytes32; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array with length 32") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + let mut bytes = [0u8; 32]; + if v.len() != 32 { + return Err(E::invalid_length(v.len(), &self)); + } + bytes.copy_from_slice(v); + Ok(IdentifierBytes32(bytes)) } - bytes.copy_from_slice(v); - Ok(Bytes(bytes)) } - } - deserializer.deserialize_bytes(BytesVisitor) + deserializer.deserialize_bytes(BytesVisitor) + } } } @@ -90,11 +122,11 @@ fn encoding_string_to_encoding(encoding_string: Option<&str>) -> Encoding { impl Identifier { pub fn new(buffer: [u8; 32]) -> Identifier { - Identifier(Bytes(buffer)) + Identifier(IdentifierBytes32(buffer)) } pub fn random(rng: &mut StdRng) -> Identifier { - Identifier(Bytes(rng.gen())) + Identifier(IdentifierBytes32(rng.gen())) } pub fn as_bytes(&self) -> &[u8; 32] { @@ -251,3 +283,28 @@ impl From<&Identifier> for Value { Value::Identifier(value.0 .0) } } + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use crate::{from_value, Identifier, to_value}; + use serde::{Deserialize, Serialize}; + + use super::*; + + #[test] + fn test_identifier_value_serialization() { + let id = Identifier::new([2; 32]); + let value = to_value(id).unwrap(); + assert_eq!(value, Value::Identifier(id.to_buffer())); + } + + #[test] + fn test_identifier_value_deserialization() { + let id = Identifier::new([3; 32]); + let value = Value::Identifier(id.to_buffer()); + let new_id: Identifier = from_value(value).unwrap(); + assert_eq!(id, new_id); + } +} diff --git a/packages/rs-platform-value/src/types/mod.rs b/packages/rs-platform-value/src/types/mod.rs index 7db6becf372..2ab9a4c9d1f 100644 --- a/packages/rs-platform-value/src/types/mod.rs +++ b/packages/rs-platform-value/src/types/mod.rs @@ -1 +1,3 @@ pub(crate) mod identifier; +pub(crate) mod bytes_32; +pub(crate) mod binary_data; diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 55039119282..12cf8f3e738 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,9 +1,11 @@ +use std::cmp::Ordering; use crate::{Error, Value}; use std::collections::BTreeMap; pub type ValueMap = Vec<(Value, Value)>; pub trait ValueMapHelper { + fn sort_by_keys(&mut self); fn get_key(&self, key: &str) -> Option<&Value>; fn get_key_mut(&mut self, key: &str) -> Option<&mut Value>; fn get_key_mut_or_insert(&mut self, key: &str, value: Value) -> &mut Value; @@ -15,6 +17,10 @@ pub trait ValueMapHelper { } impl ValueMapHelper for ValueMap { + fn sort_by_keys(&mut self) { + self.sort_by(|(key1, _), (key2, _)| key1.partial_cmp(key2).unwrap_or(Ordering::Less)) + } + fn get_key(&self, search_key: &str) -> Option<&Value> { self.iter().find_map(|(key, value)| { if let Value::Text(text) = key { diff --git a/packages/rs-platform-value/src/value_serialization/de.rs b/packages/rs-platform-value/src/value_serialization/de.rs index 7060d8e937a..4cc9ddbe558 100644 --- a/packages/rs-platform-value/src/value_serialization/de.rs +++ b/packages/rs-platform-value/src/value_serialization/de.rs @@ -406,6 +406,10 @@ impl<'de> de::Deserializer<'de> for Deserializer { // } todo!() } + + fn is_human_readable(&self) -> bool { + false + } } struct ArrayDeserializer<'a>(slice::Iter<'a, Value>); diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index 7a603e23b40..f770ef15dd4 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -118,21 +118,6 @@ mod tests { use super::*; - #[test] - fn test_identity_is_kept() { - let id = Identifier::new([0; 32]); - let value = to_value(id).unwrap(); - assert_eq!(value, Value::Identifier(id.to_buffer())); - } - - #[test] - fn test_identity_value_desialization() { - let id = Identifier::new([0; 32]); - let value = Value::Identifier(id.to_buffer()); - let new_id: Identifier = from_value(value).unwrap(); - assert_eq!(id, new_id); - } - #[test] fn yeet() { #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] @@ -155,6 +140,7 @@ mod tests { }; let platform_value = to_value(yeet.clone()).expect("please"); + dbg!(&platform_value); let yeet_back: Yeet = from_value(platform_value).expect("please once again"); assert_eq!(yeet, yeet_back); diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index cecd4cc5a4f..720d057da6b 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -1,6 +1,6 @@ use crate::error::Error; use crate::value_map::ValueMap; -use crate::{to_value, Value}; +use crate::{to_value, Value, ValueMapHelper}; use serde::ser::{Impossible, Serialize}; use std::fmt::Display; @@ -311,6 +311,10 @@ impl serde::Serializer for Serializer { { Ok(Value::Text(value.to_string())) } + + fn is_human_readable(&self) -> bool { + false + } } pub struct SerializeSizedVec { @@ -463,7 +467,10 @@ impl serde::ser::SerializeMap for SerializeMap { fn end(self) -> Result { match self { - SerializeMap::Map { map, .. } => Ok(Value::Map(map)), + SerializeMap::Map { mut map, .. } => { + map.sort_by_keys(); + Ok(Value::Map(map)) + }, } } } From eeedb8436036ac9dea440d2253b3e498e47dc64b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 02:44:14 +0700 Subject: [PATCH 129/228] more fixes --- packages/rs-dpp/src/data_contract/data_contract.rs | 1 + .../rs-dpp/src/state_transition/state_transition_factory.rs | 2 +- .../validation/data_contract_validator_spec.rs | 5 +++-- .../identity_update_transition_spec.rs | 6 +++--- packages/rs-platform-value/src/value_serialization/ser.rs | 1 - 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 9e31e40e03f..464fbb678b8 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -736,6 +736,7 @@ mod test { let contract = DataContract::try_from(string_contract.as_str())?; let serialized_contract = serde_json::to_string(&contract.to_json()?)?; + ///they will be out of order so won't be exactly the same assert_eq!(serialized_contract, string_contract); Ok(()) } diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 5633596d227..10713ac03de 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -251,7 +251,7 @@ mod test { match err { ProtocolError::InvalidStateTransitionTypeError(err) => { - assert_eq!(err.transition_type(), 154); + assert_eq!(err.transition_type(), 110); } _ => panic!("expected InvalidStateTransitionTypeError, got {}", err), } diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index d3e471e0fdb..acac93a6964 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -1373,7 +1373,7 @@ mod documents { "properties": { "something": { "type": "string", - "maxLength": 100, + "maxLength": 100u64, "pattern": "^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$", }, }, @@ -1383,7 +1383,8 @@ mod documents { let result = data_contract_validator .validate(&raw_data_contract) .expect("validation result should be returned"); - + dbg!(&raw_data_contract); +dbg!(&result); let pattern_error = result .errors .get(0) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index 1016fe0572b..ddb2d4b0a32 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -171,8 +171,8 @@ fn to_object_with_signature_skipped() { "protocolVersion" : 1u32, "type" : 5u8, "signaturePublicKeyId": 0u32, - "identityId" : transition.identity_id.to_buffer(), - "revision": 0u8, + "identityId" : transition.identity_id, + "revision": 0 as Revision, "disablePublicKeys" : [0u32], "publicKeysDisabledAt" : 1234567u64, "addPublicKeys" : [ @@ -182,7 +182,7 @@ fn to_object_with_signature_skipped() { "purpose" : 0u8, "type": 0u8, "securityLevel" : 0u8, - "data" :base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap(), + "data" :BinaryData(base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap()), "readOnly" : false, } ] diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index 720d057da6b..4481dce5c69 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -468,7 +468,6 @@ impl serde::ser::SerializeMap for SerializeMap { fn end(self) -> Result { match self { SerializeMap::Map { mut map, .. } => { - map.sort_by_keys(); Ok(Value::Map(map)) }, } From be510bbc375b4351fa1164b88e5e8143f50d01cf Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 03:53:15 +0700 Subject: [PATCH 130/228] dbg --- .../rs-dpp/src/state_transition/abstract_state_transition.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 98229121390..2536950ffb5 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -209,6 +209,7 @@ pub trait StateTransitionConvert: Serialize { // Returns the cibor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { let mut value = self.to_object(skip_signature)?; + dbg!(&value); let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; serializer::serializable_value_to_cbor(&value, Some(protocol_version)) From 62823e90e4e8cc74d7f37b954fd1f01aa6597edc Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 04:14:31 +0700 Subject: [PATCH 131/228] more fixes --- .../state_transition/abstract_state_transition.rs | 5 +++-- .../abstract_state_transition_identity_signed.rs | 11 +++++------ .../rs-platform-value/src/converter/ciborium.rs | 15 +++++++++------ 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 2536950ffb5..401a54f09bf 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -2,7 +2,7 @@ use std::fmt::Debug; use dashcore::signer; -use platform_value::Value; +use platform_value::{Value, ValueMapHelper}; use serde::Serialize; use serde_json::Value as JsonValue; @@ -209,9 +209,10 @@ pub trait StateTransitionConvert: Serialize { // Returns the cibor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { let mut value = self.to_object(skip_signature)?; - dbg!(&value); let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; + value.as_map_mut_ref().unwrap().sort_by_keys(); + serializer::serializable_value_to_cbor(&value, Some(protocol_version)) } diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index 9f5a2753d50..8b637bc11c1 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -364,8 +364,8 @@ mod test { assert_eq!(st_object["protocolVersion"].to_integer::().unwrap(), 1); assert_eq!(st_object["transitionType"].to_integer::().unwrap(), 1); - assert!(st_object.has("signaturePublicKeyId").unwrap()); - assert!(st_object.has("signature").unwrap()); + assert!(!st_object.has("signaturePublicKeyId").unwrap()); + assert!(!st_object.has("signature").unwrap()); } #[test] @@ -389,7 +389,7 @@ mod test { let st = get_mock_state_transition(); let hash = st.hash(false).unwrap(); assert_eq!( - "b067b5f84b748080684f3b203b07227a3b2db9f745815e3449113ac9e5619523", + "bb9f19724ffe1be08e6f9d111c8930a3a6de59a6653ad983f922a3523d75d33b", hex::encode(hash) ) } @@ -400,8 +400,7 @@ mod test { let hash = st.to_buffer(false).unwrap(); let result = hex::encode(hash); - assert_eq!(210, result.len()); - assert!(result.starts_with("01")) + assert_eq!("01a4676f776e6572496458208d6e06cac6cd2c4b9020806a3f1a4ec48fc90defd314330a5ce7d8548dfc2524697369676e617475726580747369676e61747572655075626c69634b65794964016e7472616e736974696f6e5479706501", result.as_str()); } #[test] @@ -410,7 +409,7 @@ mod test { let hash = st.to_buffer(true).unwrap(); let result = hex::encode(hash); - assert_eq!("01a26e7472616e736974696f6e5479706501676f776e65724964782c4158356f323241525746595a45394a5a5441355353657976707274657442637662514c53425a376352374777", result); + assert_eq!("01a2676f776e6572496458208d6e06cac6cd2c4b9020806a3f1a4ec48fc90defd314330a5ce7d8548dfc25246e7472616e736974696f6e5479706501", result); } #[test] diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 5506e094944..9b0d9828ea7 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -1,5 +1,5 @@ use crate::value_map::ValueMap; -use crate::{Error, Value}; +use crate::{Error, Value, ValueMapHelper}; use ciborium::value::Integer; use ciborium::Value as CborValue; @@ -109,11 +109,14 @@ impl TryInto for Value { .map(|value| value.try_into()) .collect::, Error>>()?, ), - Value::Map(map) => CborValue::Map( - map.into_iter() - .map(|(k, v)| Ok((k.try_into()?, v.try_into()?))) - .collect::, Error>>()?, - ), + Value::Map(mut map) => { + map.sort_by_keys(); + CborValue::Map( + map.into_iter() + .map(|(k, v)| Ok((k.try_into()?, v.try_into()?))) + .collect::, Error>>()?, + ) + }, Value::Identifier(bytes) => CborValue::Bytes(bytes.to_vec()), Value::EnumU8(_) => todo!(), Value::EnumString(_) => todo!(), From c624e26bfc663d8de2d22f7e0bca6f29e3ff6284 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 14:54:41 +0700 Subject: [PATCH 132/228] more fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 66 +++++---- .../src/data_contract/data_contract_facade.rs | 9 +- .../data_contract/data_contract_factory.rs | 126 +++++++++++------- .../src/data_contract/serialization/cbor.rs | 21 ++- .../data_contract_create_transition/mod.rs | 40 +++--- .../data_contract_update_transition/mod.rs | 40 +++--- .../validation/multi_validator.rs | 1 - .../rs-dpp/src/document/document_validator.rs | 8 +- .../rs-dpp/src/document/extended_document.rs | 2 +- .../document_create_transition.rs | 2 +- .../document_replace_transition.rs | 2 +- .../documents_batch_transition/mod.rs | 45 +++---- ...lidate_documents_batch_transition_basic.rs | 7 +- .../instant/instant_asset_lock_proof.rs | 26 +--- .../identity_create_transition.rs | 12 +- .../mod.rs | 42 +++--- .../identity_topup_transition.rs | 14 +- .../identity_update_transition.rs | 39 ++---- .../validate_public_key_signatures.rs | 2 +- .../abstract_state_transition.rs | 17 +-- ...stract_state_transition_identity_signed.rs | 15 ++- .../rs-dpp/src/state_transition/example.rs | 11 +- packages/rs-dpp/src/state_transition/mod.rs | 9 +- ...ate_state_transition_identity_signature.rs | 11 +- ...validate_state_transition_key_signature.rs | 5 +- packages/rs-dpp/src/system_data_contracts.rs | 7 +- ...a_contract_update_transition_basic_spec.rs | 4 +- .../data_contract_validator_spec.rs | 2 - .../src/tests/fixtures/get_data_contract.rs | 25 ++-- .../tests/fixtures/get_dpns_data_contract.rs | 7 +- .../identity_topup_transition_fixture.rs | 26 ++-- ...ntity_credit_withdrawal_transition_spec.rs | 3 +- .../btreemap_field_replacement.rs | 9 +- .../btreemap_removal_extensions.rs | 39 +++++- .../src/btreemap_extensions/mod.rs | 15 ++- packages/rs-platform-value/src/inner_value.rs | 45 ++++++- packages/rs-platform-value/src/lib.rs | 33 ++++- .../rs-platform-value/src/system_bytes.rs | 28 +++- .../src/types/binary_data.rs | 28 ++++ .../src/value_serialization/mod.rs | 1 - 40 files changed, 524 insertions(+), 320 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 464fbb678b8..a326029b26c 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -4,9 +4,7 @@ use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; use itertools::{Either, Itertools}; -use platform_value::btreemap_extensions::{ - BTreeValueMapHelper, BTreeValueMapPathHelper, BTreeValueRemoveFromMapHelper, -}; +use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; use platform_value::Identifier; use platform_value::Value; use serde::{Deserialize, Serialize}; @@ -97,8 +95,8 @@ pub struct DataContract { pub documents: BTreeMap, // TODO we may ensure in compile time that defs are not empty if we define a type for it - #[serde(skip_serializing_if = "Option::is_none", rename = "$defs", default)] - pub defs: Option>, + #[serde(rename = "$defs", default)] + pub defs: BTreeMap, #[serde(skip)] pub entropy: [u8; 32], @@ -120,14 +118,18 @@ impl DataContract { let mutability = get_contract_configuration_properties(&data_contract_map) .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; let definition_references = get_definitions(&data_contract_map)?; - let document_types = get_document_types( + let document_types = get_document_types_from_contract( &data_contract_map, - definition_references, + &definition_references, mutability.documents_keep_history_contract_default, mutability.documents_mutable_contract_default, ) .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + let protocol_version = data_contract_map + .remove_integer(property_names::PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)?; + let documents = data_contract_map .remove(property_names::DOCUMENTS) .map(|value| value.try_into_validating_btree_map_json()) @@ -138,15 +140,16 @@ impl DataContract { .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; // Defs - let defs = - data_contract_map.get_optional_inner_str_json_value_map::>("$defs")?; + let defs = data_contract_map + .get_optional_inner_str_json_value_map::>("$defs")? + .unwrap_or_default(); let binary_properties = documents .iter() .map(|(doc_type, schema)| (String::from(doc_type), get_binary_properties(schema))) .collect(); let data_contract = DataContract { - protocol_version: 0, + protocol_version, id: data_contract_map .remove_identifier(property_names::ID) .map_err(ProtocolError::ValueError)?, @@ -187,9 +190,9 @@ impl DataContract { let mutability = get_contract_configuration_properties(&data_contract_map) .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; let definition_references = get_definitions(&data_contract_map)?; - let document_types = get_document_types( + let document_types = get_document_types_from_contract( &data_contract_map, - definition_references, + &definition_references, mutability.documents_keep_history_contract_default, mutability.documents_mutable_contract_default, ) @@ -263,8 +266,8 @@ impl DataContract { self.to_cbor() } - pub fn definitions(&self) -> Option<&BTreeMap> { - self.defs.as_ref() + pub fn definitions(&self) -> &BTreeMap { + &self.defs } // Returns hash from Data Contract @@ -468,7 +471,6 @@ impl TryFrom<&str> for DataContract { let mut data_contract: DataContract = serde_json::from_str(v)?; //todo: there's a better to do this, find it let value = data_contract.to_object()?; - dbg!(&value); DataContract::from_raw_object(value) } } @@ -520,17 +522,12 @@ pub fn get_contract_configuration_properties( }) } -pub fn get_document_types( - contract: &BTreeMap, - definition_references: BTreeMap, +pub fn get_document_types_from_value( + documents_value: &Value, + definition_references: &BTreeMap, documents_keep_history_contract_default: bool, documents_mutable_contract_default: bool, ) -> Result, ProtocolError> { - let Some(documents_value) = - contract - .get("documents") else { - return Ok(BTreeMap::new()); - }; let contract_document_types_raw = documents_value .as_map() @@ -555,7 +552,7 @@ pub fn get_document_types( let document_type = DocumentType::from_platform_value( type_key_str, document_type_value_map, - &definition_references, + definition_references, documents_keep_history_contract_default, documents_mutable_contract_default, )?; @@ -564,6 +561,25 @@ pub fn get_document_types( Ok(contract_document_types) } +pub fn get_document_types_from_contract( + contract: &BTreeMap, + definition_references: &BTreeMap, + documents_keep_history_contract_default: bool, + documents_mutable_contract_default: bool, +) -> Result, ProtocolError> { + let Some(documents_value) = + contract + .get("documents") else { + return Ok(BTreeMap::new()); + }; + get_document_types_from_value( + documents_value, + definition_references, + documents_keep_history_contract_default, + documents_mutable_contract_default, + ) +} + pub fn get_definitions( contract: &BTreeMap, ) -> Result, ProtocolError> { @@ -704,9 +720,7 @@ mod test { init(); let string_contract = get_data_from_file("src/tests/payloads/contract_example.json")?; - dbg!(&string_contract); let contract = DataContract::try_from(string_contract.as_str())?; - dbg!(&contract); assert_eq!(contract.protocol_version, 0); assert_eq!( contract.schema, diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index 50c397428f8..ffef6971bea 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -1,3 +1,4 @@ +use crate::data_contract::contract_config::ContractConfig; use crate::data_contract::state_transition::{ DataContractCreateTransition, DataContractUpdateTransition, }; @@ -31,10 +32,12 @@ impl DataContractFacade { pub fn create( &self, owner_id: Identifier, - documents: JsonValue, - definitions: Option, + documents: Value, + config: Option, + definitions: Option, ) -> Result { - self.factory.create(owner_id, documents, definitions) + self.factory + .create(owner_id, documents, config, definitions) } /// Create Data Contract from plain object diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index d2c33b63b91..614ae9eb65c 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -6,8 +6,10 @@ use std::sync::Arc; use data_contract::state_transition::property_names as st_prop; use platform_value::Value; +use crate::data_contract::contract_config::ContractConfig; use crate::data_contract::errors::InvalidDataContractError; use crate::data_contract::property_names; +use crate::data_contract::property_names::PROTOCOL_VERSION; use crate::util::serializer::serializable_value_to_cbor; use crate::{ data_contract::{self, generate_data_contract_id}, @@ -67,62 +69,99 @@ impl DataContractFactory { pub fn create( &self, owner_id: Identifier, - documents: JsonValue, - definitions: Option, + documents: Value, + config: Option, + definitions: Option, ) -> Result { let entropy = self.entropy_generator.generate(); let data_contract_id = Identifier::from_bytes(&generate_data_contract_id(owner_id.to_buffer(), entropy))?; - // todo: workaround - - let mut root_map = Map::new(); - - root_map.insert( - property_names::ID.to_string(), - JsonValue::String(bs58::encode(data_contract_id.to_buffer().as_slice()).into_string()), - ); - root_map.insert( - property_names::OWNER_ID.to_string(), - JsonValue::String(bs58::encode(owner_id.to_buffer().as_slice()).into_string()), - ); - root_map.insert( - property_names::SCHEMA.to_string(), - JsonValue::String(data_contract::SCHEMA_URI.to_string()), - ); - root_map.insert( - property_names::VERSION.to_string(), - JsonValue::Number(1.into()), - ); - - if let Some(defs) = definitions { - root_map.insert(property_names::DEFINITIONS.to_string(), defs); - } - - root_map.insert(property_names::DOCUMENTS.to_string(), documents); - - let cbor = serializable_value_to_cbor(&JsonValue::Object(root_map), Some(1))?; - - DataContract::from_cbor(cbor) + let definition_references = definitions + .as_ref() + .map(|defs| defs.to_btree_ref_string_map()) + .transpose() + .map_err(ProtocolError::ValueError)? + .unwrap_or_default(); + + let config = config.unwrap_or_default(); + let document_types = data_contract::get_document_types_from_value( + &documents, + &definition_references, + config.documents_keep_history_contract_default, + config.documents_mutable_contract_default, + ) + .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + + let document_values = documents + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?; + let documents = document_values + .into_iter() + .map(|(key, value)| Ok((key, value.try_into().map_err(ProtocolError::ValueError)?))) + .collect::, ProtocolError>>()?; + + let json_defs = definition_references + .into_iter() + .map(|(key, value)| { + Ok(( + key, + value + .clone() + .try_into() + .map_err(ProtocolError::ValueError)?, + )) + }) + .collect::, ProtocolError>>()?; + let mut data_contract = DataContract { + protocol_version: self.protocol_version, + id: data_contract_id, + schema: data_contract::SCHEMA_URI.to_string(), + version: 1, + owner_id, + document_types, + metadata: None, + config, + documents, + defs: json_defs, + entropy, + binary_properties: Default::default(), + }; + + data_contract.generate_binary_properties(); + Ok(data_contract) } /// Create Data Contract from plain object pub async fn create_from_object( &self, - raw_data_contract: Value, + mut data_contract_object: Value, skip_validation: bool, ) -> Result { if !skip_validation { - let result = self.validate_data_contract.validate(&raw_data_contract)?; + let result = self + .validate_data_contract + .validate(&data_contract_object)?; if !result.is_valid() { return Err(ProtocolError::InvalidDataContractError( - InvalidDataContractError::new(result.errors, raw_data_contract), + InvalidDataContractError::new(result.errors, data_contract_object), )); } } - DataContract::from_raw_object(raw_data_contract) + if !data_contract_object + .has(PROTOCOL_VERSION) + .map_err(ProtocolError::ValueError)? + { + data_contract_object + .insert( + PROTOCOL_VERSION.to_string(), + Value::U32(self.protocol_version), + ) + .map_err(ProtocolError::ValueError)?; + } + DataContract::from_raw_object(data_contract_object) } /// Create Data Contract from buffer @@ -187,13 +226,13 @@ mod tests { pub struct TestData { data_contract: DataContract, - raw_data_contract: JsonValue, + raw_data_contract: Value, factory: DataContractFactory, } fn get_test_data() -> TestData { let data_contract = get_data_contract_fixture(None); - let raw_data_contract = data_contract.to_json_object(false).unwrap(); + let raw_data_contract = data_contract.to_object().unwrap(); let protocol_version_validator = ProtocolVersionValidator::new( LATEST_VERSION, LATEST_VERSION, @@ -220,17 +259,17 @@ mod tests { } = get_test_data(); let raw_defs = raw_data_contract - .get(property_names::DEFINITIONS) + .get_value(property_names::DEFINITIONS) .expect("documents property should exist") .clone(); let raw_documents = raw_data_contract - .get(property_names::DOCUMENTS) + .get_value(property_names::DOCUMENTS) .expect("documents property should exist") .clone(); let result = factory - .create(data_contract.owner_id, raw_documents, Some(raw_defs)) + .create(data_contract.owner_id, raw_documents, None, Some(raw_defs)) .expect("Data Contract should be created"); assert_eq!(data_contract.protocol_version, result.protocol_version); @@ -306,9 +345,6 @@ mod tests { assert_eq!(1, result.get_protocol_version()); assert_eq!(&data_contract.entropy, result.get_entropy()); - assert_eq!( - raw_data_contract, - result.data_contract.to_json_object(false).unwrap() - ); + assert_eq!(raw_data_contract, result.data_contract.to_object().unwrap()); } } diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index 4011f6f684f..3e88a48414e 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -36,8 +36,9 @@ impl DataContract { let version = data_contract_map.get_integer(property_names::VERSION)?; // Defs - let defs = - data_contract_map.get_optional_inner_str_json_value_map::>("$defs")?; + let defs = data_contract_map + .get_optional_inner_str_json_value_map::>("$defs")? + .unwrap_or_default(); // Documents let documents: BTreeMap = data_contract_map @@ -47,9 +48,9 @@ impl DataContract { let mutability = data_contract::get_contract_configuration_properties(&data_contract_map) .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; let definition_references = data_contract::get_definitions(&data_contract_map)?; - let document_types = data_contract::get_document_types( + let document_types = data_contract::get_document_types_from_contract( &data_contract_map, - definition_references, + &definition_references, mutability.documents_keep_history_contract_default, mutability.documents_mutable_contract_default, ) @@ -100,13 +101,11 @@ impl DataContract { contract_cbor_map.insert(property_names::DOCUMENTS, docs); - if let Some(defs) = &self.defs { - contract_cbor_map.insert( - property_names::DEFINITIONS, - CborValue::serialized(defs) - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?, - ); - } + contract_cbor_map.insert( + property_names::DEFINITIONS, + CborValue::serialized(&self.defs) + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?, + ); Ok(contract_cbor_map) } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index b5f0892e6bb..ee26c2ecfed 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -1,8 +1,9 @@ use std::collections::BTreeMap; +use std::convert::TryInto; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::Value; +use platform_value::{BinaryData, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -15,7 +16,7 @@ use crate::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::json_value::{JsonValueExt, ReplaceWith}, + util::json_value::JsonValueExt, ProtocolError, }; @@ -35,7 +36,7 @@ pub struct DataContractCreateTransition { pub data_contract: DataContract, pub entropy: [u8; 32], pub signature_public_key_id: KeyID, - pub signature: Vec, + pub signature: BinaryData, #[serde(skip)] pub execution_context: StateTransitionExecutionContext, } @@ -47,7 +48,7 @@ impl std::default::Default for DataContractCreateTransition { transition_type: StateTransitionType::DataContractCreate, entropy: [0u8; 32], signature_public_key_id: 0, - signature: vec![], + signature: BinaryData::default(), data_contract: Default::default(), execution_context: Default::default(), } @@ -61,7 +62,7 @@ impl DataContractCreateTransition { Ok(DataContractCreateTransition { protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION)?, signature: raw_data_contract_update_transition - .remove_optional_bytes(SIGNATURE) + .remove_optional_binary_data(SIGNATURE) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition @@ -93,7 +94,7 @@ impl DataContractCreateTransition { .get_integer(PROTOCOL_VERSION) .map_err(ProtocolError::ValueError)?, signature: raw_data_contract_update_transition - .remove_optional_bytes(SIGNATURE) + .remove_optional_binary_data(SIGNATURE) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition @@ -161,14 +162,18 @@ impl StateTransitionLike for DataContractCreateTransition { self.transition_type } /// returns the signature as a byte-array - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } /// set a new signature - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature } + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } + fn get_execution_context(&self) -> &StateTransitionExecutionContext { &self.execution_context } @@ -196,23 +201,8 @@ impl StateTransitionConvert for DataContractCreateTransition { } fn to_json(&self, skip_signature: bool) -> Result { - let mut json_value: JsonValue = serde_json::to_value(self)?; - - if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { - for path in Self::signature_property_paths() { - o.remove(path); - } - } - } - - json_value.replace_binary_paths(Self::binary_property_paths(), ReplaceWith::Base64)?; - json_value - .replace_identifier_paths(Self::identifiers_property_paths(), ReplaceWith::Base58)?; - - json_value.insert(DATA_CONTRACT.to_string(), self.data_contract.to_json()?)?; - - Ok(json_value) + self.to_object(skip_signature) + .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } fn to_object(&self, skip_signature: bool) -> Result { diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 87b5cc0295e..e8a907231dd 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -1,9 +1,10 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::Value; +use platform_value::{BinaryData, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; +use std::convert::TryInto; use crate::{ data_contract::DataContract, @@ -14,7 +15,7 @@ use crate::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::json_value::{JsonValueExt, ReplaceWith}, + util::json_value::JsonValueExt, ProtocolError, }; @@ -33,7 +34,7 @@ pub struct DataContractUpdateTransition { #[serde(skip_serializing)] pub data_contract: DataContract, pub signature_public_key_id: KeyID, - pub signature: Vec, + pub signature: BinaryData, #[serde(skip)] pub execution_context: StateTransitionExecutionContext, } @@ -44,7 +45,7 @@ impl std::default::Default for DataContractUpdateTransition { protocol_version: Default::default(), transition_type: StateTransitionType::DataContractUpdate, signature_public_key_id: 0, - signature: vec![], + signature: BinaryData::default(), data_contract: Default::default(), execution_context: Default::default(), } @@ -58,7 +59,7 @@ impl DataContractUpdateTransition { Ok(DataContractUpdateTransition { protocol_version: raw_data_contract_update_transition.get_integer(PROTOCOL_VERSION)?, signature: raw_data_contract_update_transition - .remove_optional_bytes(SIGNATURE) + .remove_optional_binary_data(SIGNATURE) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition @@ -86,7 +87,7 @@ impl DataContractUpdateTransition { .get_integer(PROTOCOL_VERSION) .map_err(ProtocolError::ValueError)?, signature: raw_data_contract_update_transition - .remove_optional_bytes(SIGNATURE) + .remove_optional_binary_data(SIGNATURE) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), signature_public_key_id: raw_data_contract_update_transition @@ -142,14 +143,18 @@ impl StateTransitionLike for DataContractUpdateTransition { self.transition_type } /// returns the signature as a byte-array - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } /// set a new signature - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature } + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } + fn get_execution_context(&self) -> &StateTransitionExecutionContext { &self.execution_context } @@ -177,23 +182,8 @@ impl StateTransitionConvert for DataContractUpdateTransition { } fn to_json(&self, skip_signature: bool) -> Result { - let mut json_value: JsonValue = serde_json::to_value(self)?; - - if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { - for path in Self::signature_property_paths() { - o.remove(path); - } - } - } - - json_value.replace_binary_paths(Self::binary_property_paths(), ReplaceWith::Base64)?; - json_value - .replace_identifier_paths(Self::identifiers_property_paths(), ReplaceWith::Base58)?; - - json_value.insert(DATA_CONTRACT.to_string(), self.data_contract.to_json()?)?; - - Ok(json_value) + self.to_object(skip_signature) + .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } fn to_object(&self, skip_signature: bool) -> Result { diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 92770e6d3c2..31e57e33af6 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -121,7 +121,6 @@ pub fn byte_array_has_no_items_as_parent_validator( #[cfg(test)] mod test { use platform_value::platform_value; - use platform_value::ValueMapHelper; use super::*; diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index ed8b8acbcee..7404cf36e7d 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -63,8 +63,8 @@ impl DocumentValidator { .get_document_schema(document_type.name.as_str())? .to_owned(); - let json_schema_validator = if let Some(defs) = &data_contract.defs { - JsonSchemaValidator::new_with_definitions(document_schema, defs.iter()) + let json_schema_validator = if !data_contract.defs.is_empty() { + JsonSchemaValidator::new_with_definitions(document_schema, data_contract.defs.iter()) } else { JsonSchemaValidator::new(document_schema) } @@ -106,8 +106,8 @@ impl DocumentValidator { .get_document_schema(document_type_name)? .to_owned(); - let json_schema_validator = if let Some(defs) = &data_contract.defs { - JsonSchemaValidator::new_with_definitions(document_schema, defs.iter()) + let json_schema_validator = if !data_contract.defs.is_empty() { + JsonSchemaValidator::new_with_definitions(document_schema, data_contract.defs.iter()) } else { JsonSchemaValidator::new(document_schema) } diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index ad1e02d162e..40d1ead714f 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -206,7 +206,7 @@ impl ExtendedDocument { extended_document .document .properties - .replace_at_paths(binary_paths, ReplacementType::Bytes)?; + .replace_at_paths(binary_paths, ReplacementType::BinaryBytes)?; Ok(extended_document) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 121649d4d19..e377bcf0a4c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -128,7 +128,7 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { binary_paths .into_iter() .chain(BINARY_FIELDS.iter().map(|a| a.to_string())), - ReplacementType::Bytes, + ReplacementType::BinaryBytes, )?; map.replace_at_paths( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index f9f71ae1108..574f6bbe4bd 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -121,7 +121,7 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { let (identifiers_paths, binary_paths) = data_contract.get_identifiers_and_binary_paths_owned(document_type)?; - map.replace_at_paths(binary_paths.into_iter(), ReplacementType::Bytes)?; + map.replace_at_paths(binary_paths.into_iter(), ReplacementType::BinaryBytes)?; map.replace_at_paths( identifiers_paths diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index daff0b26ff1..972f80f4415 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -7,7 +7,7 @@ use integer_encoding::VarInt; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; -use platform_value::{ReplacementType, Value}; +use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -68,7 +68,7 @@ pub struct DocumentsBatchTransition { pub signature_public_key_id: Option, #[serde(default, skip_serializing_if = "Option::is_none")] - pub signature: Option>, + pub signature: Option, #[serde(skip)] pub execution_context: StateTransitionExecutionContext, @@ -97,7 +97,9 @@ impl DocumentsBatchTransition { let maybe_signature = json_value.get_string(property_names::SIGNATURE).ok(); let signature = if let Some(signature) = maybe_signature { - Some(base64::decode(signature).context("signature exists but isn't valid base64")?) + Some(BinaryData( + base64::decode(signature).context("signature exists but isn't valid base64")?, + )) } else { None }; @@ -173,7 +175,7 @@ impl DocumentsBatchTransition { // js-dpp allows `protocolVersion` to be undefined .unwrap_or(LATEST_VERSION as u64) as u32, signature: map - .get_optional_bytes(property_names::SIGNATURE) + .get_optional_binary_data(property_names::SIGNATURE) .map_err(ProtocolError::ValueError)?, signature_public_key_id: map .get_optional_integer(property_names::SIGNATURE_PUBLIC_KEY_ID) @@ -226,7 +228,7 @@ impl DocumentsBatchTransition { binary_paths .into_iter() .chain(BINARY_FIELDS.iter().map(|a| a.to_string())), - ReplacementType::Bytes, + ReplacementType::BinaryBytes, ) .map_err(ProtocolError::ValueError)?; @@ -314,7 +316,7 @@ impl DocumentsBatchTransition { if let Some(signature) = self.signature.as_ref() { map.insert( property_names::SIGNATURE.to_string(), - Value::Bytes(signature.clone()), + Value::Bytes(signature.to_vec()), ); } if let Some(signature_key_id) = self.signature_public_key_id { @@ -351,28 +353,8 @@ impl StateTransitionConvert for DocumentsBatchTransition { } fn to_json(&self, skip_signature: bool) -> Result { - let mut json_value: JsonValue = serde_json::to_value(self)?; - - if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { - for path in Self::signature_property_paths() { - o.remove(path); - } - } - } - - json_value.replace_binary_paths(Self::binary_property_paths(), ReplaceWith::Base64)?; - - let mut transitions = vec![]; - for transition in self.transitions.iter() { - transitions.push(transition.to_json()?) - } - json_value.insert( - String::from(property_names::TRANSITIONS), - JsonValue::Array(transitions), - )?; - - Ok(json_value) + self.to_object(skip_signature) + .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } fn to_object(&self, skip_signature: bool) -> Result { @@ -470,7 +452,7 @@ impl StateTransitionLike for DocumentsBatchTransition { self.protocol_version } - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { if let Some(ref signature) = self.signature { signature } else { @@ -484,9 +466,12 @@ impl StateTransitionLike for DocumentsBatchTransition { self.transition_type } - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = Some(signature); } + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = Some(BinaryData::new(signature)); + } fn get_execution_context(&self) -> &StateTransitionExecutionContext { &self.execution_context } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 4734e71e3cd..4df4dcbac92 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -252,8 +252,11 @@ fn validate_raw_transitions<'a>( let enriched_data_contract = &enriched_contracts_by_action[&action]; let document_schema = enriched_data_contract.get_document_schema(document_type)?; - let schema_validator = if let Some(defs) = enriched_data_contract.definitions() { - JsonSchemaValidator::new_with_definitions(document_schema.clone(), defs) + let schema_validator = if !enriched_data_contract.defs.is_empty() { + JsonSchemaValidator::new_with_definitions( + document_schema.clone(), + enriched_data_contract.defs.iter(), + ) } else { JsonSchemaValidator::new(document_schema.clone()) } diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs index 106b72d0de2..30da46607cc 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs @@ -2,7 +2,7 @@ use std::convert::{TryFrom, TryInto}; use dashcore::consensus::{Decodable, Encodable}; use dashcore::{InstantLock, Transaction, TxOut}; -use platform_value::Value; +use platform_value::{BinaryData, Value}; use serde::de::Error as DeError; use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -21,20 +21,6 @@ pub struct InstantAssetLockProof { output_index: u32, } -/// Deterministically sorts the keys in the serialized value. Needed to serialize and hash -/// binaries. -pub fn serialize_deterministically(raw: &T, serializer: S) -> Result -where - T: Serialize, - S: Serializer, -{ - let cbor_map = - CborCanonicalMap::from_serializable(&raw).map_err(|e| S::Error::custom(e.to_string()))?; - let sorted_cbor = cbor_map.to_value_sorted(); - - sorted_cbor.serialize(serializer) -} - impl Serialize for InstantAssetLockProof { fn serialize(&self, serializer: S) -> Result where @@ -42,7 +28,7 @@ impl Serialize for InstantAssetLockProof { { let raw = RawInstantLock::try_from(self).map_err(|e| S::Error::custom(e.to_string()))?; - serialize_deterministically(&raw, serializer) + raw.serialize(serializer) } } @@ -159,8 +145,8 @@ impl InstantAssetLockProof { pub struct RawInstantLock { #[serde(rename = "type")] lock_type: u8, - instant_lock: Vec, - transaction: Vec, + instant_lock: BinaryData, + transaction: BinaryData, output_index: u32, } @@ -199,8 +185,8 @@ impl TryFrom<&InstantAssetLockProof> for RawInstantLock { Ok(Self { lock_type: instant_asset_lock_proof.asset_lock_type, - instant_lock: is_lock_buffer, - transaction: transaction_buffer, + instant_lock: BinaryData::new(is_lock_buffer), + transaction: BinaryData::new(transaction_buffer), output_index: instant_asset_lock_proof.output_index, }) } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index f407225d60f..861f4a109cd 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -1,7 +1,7 @@ use std::convert::{TryFrom, TryInto}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::Value; +use platform_value::{BinaryData, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -39,7 +39,7 @@ pub struct IdentityCreateTransition { // Generic identity ST fields pub protocol_version: u32, pub transition_type: StateTransitionType, - pub signature: Vec, + pub signature: BinaryData, #[serde(skip)] pub execution_context: StateTransitionExecutionContext, } @@ -246,13 +246,17 @@ impl StateTransitionLike for IdentityCreateTransition { StateTransitionType::IdentityCreate } /// returns the signature as a byte-array - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } /// set a new signature - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature } + + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } fn get_execution_context(&self) -> &StateTransitionExecutionContext { &self.execution_context } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index 38449b654ba..d2b995b0123 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -1,7 +1,8 @@ -use platform_value::Value; +use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use serde_repr::{Deserialize_repr, Serialize_repr}; +use std::convert::TryInto; use crate::version::LATEST_VERSION; use crate::{ @@ -12,7 +13,6 @@ use crate::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::json_value::{JsonValueExt, ReplaceWith}, ProtocolError, }; @@ -50,7 +50,7 @@ pub struct IdentityCreditWithdrawalTransition { pub output_script: CoreScript, pub revision: Revision, pub signature_public_key_id: KeyID, - pub signature: Vec, + pub signature: BinaryData, #[serde(skip)] pub execution_context: StateTransitionExecutionContext, } @@ -81,9 +81,18 @@ impl IdentityCreditWithdrawalTransition { } pub fn from_json(mut value: JsonValue) -> Result { - value.replace_binary_paths(Self::binary_property_paths(), ReplaceWith::Bytes)?; + let mut value: Value = value.into(); + value + .replace_at_paths(Self::binary_property_paths(), ReplacementType::BinaryBytes) + .map_err(ProtocolError::ValueError)?; + value + .replace_at_paths( + Self::identifiers_property_paths(), + ReplacementType::Identifier, + ) + .map_err(ProtocolError::ValueError)?; - Self::from_value(value.into()) + Self::from_value(value) } pub fn from_raw_object( @@ -132,15 +141,19 @@ impl StateTransitionLike for IdentityCreditWithdrawalTransition { } /// returns the signature as a byte-array - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } /// set a new signature - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature } + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } + fn get_execution_context(&self) -> &StateTransitionExecutionContext { &self.execution_context } @@ -178,18 +191,7 @@ impl StateTransitionConvert for IdentityCreditWithdrawalTransition { } fn to_json(&self, skip_signature: bool) -> Result { - let mut json_value: JsonValue = serde_json::to_value(self)?; - - if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { - for path in Self::signature_property_paths() { - o.remove(path); - } - } - } - - json_value.replace_binary_paths(Self::binary_property_paths(), ReplaceWith::Base64)?; - - Ok(json_value) + self.to_object(skip_signature) + .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 7fa40604c97..71c3e823f2d 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -1,6 +1,6 @@ use std::convert::{TryFrom, TryInto}; -use platform_value::Value; +use platform_value::{BinaryData, Value}; use serde::de::Error as DeError; use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -31,7 +31,7 @@ pub struct IdentityTopUpTransition { // Generic identity ST fields pub protocol_version: u32, pub transition_type: StateTransitionType, - pub signature: Vec, + pub signature: BinaryData, pub execution_context: StateTransitionExecutionContext, } @@ -90,7 +90,7 @@ impl IdentityTopUpTransition { .map_err(ProtocolError::ValueError)? .unwrap_or(LATEST_VERSION); let signature = raw_object - .get_optional_bytes(property_names::SIGNATURE) + .get_optional_binary_data(property_names::SIGNATURE) .map_err(ProtocolError::ValueError)? .unwrap_or_default(); let identity_id = Identifier::from( @@ -197,14 +197,18 @@ impl StateTransitionLike for IdentityTopUpTransition { StateTransitionType::IdentityTopUp } /// returns the signature as a byte-array - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } /// set a new signature - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature } + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } + fn get_execution_context(&self) -> &StateTransitionExecutionContext { &self.execution_context } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index a70837e9c92..8bf9c594db8 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -1,4 +1,4 @@ -use platform_value::Value; +use platform_value::{BinaryData, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::convert::{TryFrom, TryInto}; @@ -37,7 +37,7 @@ pub struct IdentityUpdateTransition { pub transition_type: StateTransitionType, /// Cryptographic signature of the State Transition - pub signature: Vec, + pub signature: BinaryData, /// The ID of the public key used to sing the State Transition pub signature_public_key_id: KeyID, @@ -95,7 +95,7 @@ impl IdentityUpdateTransition { .map_err(ProtocolError::ValueError)? .unwrap_or(LATEST_VERSION); let signature = raw_object - .get_bytes(property_names::SIGNATURE) + .get_binary_data(property_names::SIGNATURE) .map_err(ProtocolError::ValueError)?; let signature_public_key_id = raw_object .get_integer(property_names::SIGNATURE_PUBLIC_KEY_ID) @@ -267,25 +267,8 @@ impl StateTransitionConvert for IdentityUpdateTransition { } fn to_json(&self, skip_signature: bool) -> Result { - // The [state_transition_helpers::to_json] doesn't convert the `add_public_keys` property. - // The property must be serialized manually - let mut add_public_keys: Vec = vec![]; - for key in self.add_public_keys.iter() { - add_public_keys.push(key.to_json()?); - } - - let mut json_object: JsonValue = state_transition_helpers::to_json( - self, - Self::binary_property_paths(), - Self::signature_property_paths(), - skip_signature, - )?; - json_object.insert( - property_names::ADD_PUBLIC_KEYS.to_owned(), - JsonValue::Array(add_public_keys), - )?; - - Ok(json_object) + self.to_object(skip_signature) + .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } } @@ -294,7 +277,7 @@ impl StateTransitionLike for IdentityUpdateTransition { self.protocol_version } - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } @@ -302,7 +285,7 @@ impl StateTransitionLike for IdentityUpdateTransition { self.transition_type } - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature; } @@ -317,6 +300,10 @@ impl StateTransitionLike for IdentityUpdateTransition { fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext) { self.execution_context = execution_context } + + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } } impl StateTransitionIdentitySigned for IdentityUpdateTransition { @@ -353,7 +340,7 @@ mod test { let transition = IdentityUpdateTransition { identity_id: generate_random_identifier_struct(), add_public_keys: vec![(&public_key).into()], - signature: generate_random_identifier().to_vec(), + signature: BinaryData::new(generate_random_identifier().to_vec()), ..Default::default() }; @@ -381,7 +368,7 @@ mod test { let transition = IdentityUpdateTransition { identity_id: generate_random_identifier_struct(), add_public_keys: vec![(&public_key).into()], - signature: generate_random_identifier().to_vec(), + signature: BinaryData::new(generate_random_identifier().to_vec()), ..Default::default() }; diff --git a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 19114b0dfa5..3990fa9aadb 100644 --- a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -118,7 +118,7 @@ fn find_invalid_public_key( bls: &T, ) -> Option { for public_key in public_keys { - state_transition.set_signature(public_key.signature.clone()); + state_transition.set_signature_bytes(public_key.signature.clone()); if state_transition .verify_by_public_key(&public_key.data, public_key.key_type, bls) .is_err() diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 401a54f09bf..814788ea059 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -2,7 +2,7 @@ use std::fmt::Debug; use dashcore::signer; -use platform_value::{Value, ValueMapHelper}; +use platform_value::{BinaryData, Value, ValueMapHelper}; use serde::Serialize; use serde_json::Value as JsonValue; @@ -53,9 +53,9 @@ pub trait StateTransitionLike: /// returns the type of State Transition fn get_type(&self) -> StateTransitionType; /// returns the signature as a byte-array - fn get_signature(&self) -> &Vec; + fn get_signature(&self) -> &BinaryData; /// set a new signature - fn set_signature(&mut self, signature: Vec); + fn set_signature(&mut self, signature: BinaryData); /// Calculates the ST fee in credits fn calculate_fee(&self) -> i64 { calculate_state_transition_fee(self) @@ -70,12 +70,12 @@ pub trait StateTransitionLike: ) -> Result<(), ProtocolError> { let data = self.to_buffer(true)?; match key_type { - KeyType::BLS12_381 => self.set_signature(bls.sign(&data, private_key)?), + KeyType::BLS12_381 => self.set_signature(bls.sign(&data, private_key)?.into()), // https://github.com/dashevo/platform/blob/9c8e6a3b6afbc330a6ab551a689de8ccd63f9120/packages/js-dpp/lib/stateTransition/AbstractStateTransition.js#L169 KeyType::ECDSA_SECP256K1 | KeyType::ECDSA_HASH160 => { let signature = signer::sign(&data, private_key)?; - self.set_signature(signature.to_vec()); + self.set_signature(signature.to_vec().into()); } // the default behavior from @@ -120,7 +120,7 @@ pub trait StateTransitionLike: let data_hash = self.hash(true)?; Ok(signer::verify_hash_signature( &data_hash, - self.get_signature(), + self.get_signature().as_slice(), public_key_hash, )?) } @@ -135,7 +135,7 @@ pub trait StateTransitionLike: let data = self.to_buffer(true)?; Ok(signer::verify_data_signature( &data, - self.get_signature(), + self.get_signature().as_slice(), public_key, )?) } @@ -154,7 +154,7 @@ pub trait StateTransitionLike: let data = self.to_buffer(true)?; - bls.verify_signature(self.get_signature(), &data, public_key) + bls.verify_signature(self.get_signature().as_slice(), &data, public_key) .map(|_| ()) } @@ -174,6 +174,7 @@ pub trait StateTransitionLike: fn get_execution_context(&self) -> &StateTransitionExecutionContext; fn get_execution_context_mut(&mut self) -> &mut StateTransitionExecutionContext; fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext); + fn set_signature_bytes(&mut self, signature: Vec); } /// The trait contains methods related to conversion of StateTransition into different formats diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index 8b637bc11c1..8d7c3fed3b3 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -183,6 +183,7 @@ pub fn get_compressed_public_ec_key(private_key: &[u8]) -> Result<[u8; 33], Prot mod test { use bls_signatures::Serialize as BlsSerialize; use chrono::Utc; + use platform_value::BinaryData; use serde::{Deserialize, Serialize}; use serde_json::json; use std::convert::TryInto; @@ -207,7 +208,7 @@ mod test { #[serde(rename_all = "camelCase")] struct ExampleStateTransition { pub protocol_version: u32, - pub signature: Vec, + pub signature: BinaryData, pub signature_public_key_id: KeyID, pub transition_type: StateTransitionType, pub owner_id: Identifier, @@ -241,10 +242,10 @@ mod test { fn get_type(&self) -> StateTransitionType { StateTransitionType::DocumentsBatch } - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature } fn get_execution_context(&self) -> &StateTransitionExecutionContext { @@ -258,6 +259,10 @@ mod test { fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext) { self.execution_context = execution_context } + + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } } impl StateTransitionIdentitySigned for ExampleStateTransition { @@ -555,8 +560,8 @@ mod test { fn set_signature() { let mut st = get_mock_state_transition(); let signature = "some_signature"; - st.set_signature(signature.as_bytes().to_owned()); - assert_eq!(signature.as_bytes(), st.get_signature()); + st.set_signature(BinaryData::new(signature.as_bytes().to_owned())); + assert_eq!(signature.as_bytes(), st.get_signature().as_slice()); } #[test] diff --git a/packages/rs-dpp/src/state_transition/example.rs b/packages/rs-dpp/src/state_transition/example.rs index 60f942f2c57..44b23c4118a 100644 --- a/packages/rs-dpp/src/state_transition/example.rs +++ b/packages/rs-dpp/src/state_transition/example.rs @@ -1,3 +1,4 @@ +use platform_value::BinaryData; use serde::{Deserialize, Serialize}; use super::{ @@ -13,7 +14,7 @@ const PROPERTY_PROTOCOL_VERSION: &str = "protocolVersion"; #[serde(rename_all = "camelCase")] struct ExampleStateTransition { pub protocol_version: u32, - pub signature: Vec, + pub signature: BinaryData, pub transition_type: StateTransitionType, #[serde(skip)] pub execution_context: StateTransitionExecutionContext, @@ -30,7 +31,7 @@ impl StateTransitionLike for ExampleStateTransition { self.protocol_version } - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } @@ -38,9 +39,13 @@ impl StateTransitionLike for ExampleStateTransition { self.transition_type } - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature } + + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } fn get_execution_context(&self) -> &StateTransitionExecutionContext { &self.execution_context } diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 7b4e835d2e4..bf8fbabbd0a 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -4,6 +4,7 @@ pub use abstract_state_transition::{ state_transition_helpers, StateTransitionConvert, StateTransitionLike, }; pub use abstract_state_transition_identity_signed::StateTransitionIdentitySigned; +use platform_value::BinaryData; pub use state_transition_types::*; use crate::data_contract::state_transition::{ @@ -139,12 +140,12 @@ impl StateTransitionLike for StateTransition { call_method!(self, get_type) } /// returns the signature as a byte-array - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { call_method!(self, get_signature) } /// set a new signature - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { call_method!(self, set_signature, signature) } @@ -159,6 +160,10 @@ impl StateTransitionLike for StateTransition { fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext) { call_method!(self, set_execution_context, execution_context) } + + fn set_signature_bytes(&mut self, signature: Vec) { + call_method!(self, set_signature_bytes, signature) + } } impl From for StateTransition { diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs index cb414c28c99..e87c3f7a8db 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs @@ -162,13 +162,14 @@ mod test { }, NativeBlsModule, }; + use platform_value::BinaryData; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct ExampleStateTransition { pub protocol_version: u32, - pub signature: Vec, + pub signature: BinaryData, pub signature_public_key_id: KeyID, pub transition_type: StateTransitionType, pub owner_id: Identifier, @@ -204,10 +205,10 @@ mod test { fn get_type(&self) -> StateTransitionType { StateTransitionType::DocumentsBatch } - fn get_signature(&self) -> &Vec { + fn get_signature(&self) -> &BinaryData { &self.signature } - fn set_signature(&mut self, signature: Vec) { + fn set_signature(&mut self, signature: BinaryData) { self.signature = signature } fn get_execution_context(&self) -> &StateTransitionExecutionContext { @@ -221,6 +222,10 @@ mod test { fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext) { self.execution_context = execution_context } + + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } } impl StateTransitionIdentitySigned for ExampleStateTransition { diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs index be94595b0d0..b12b6b6137b 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs @@ -106,7 +106,7 @@ pub async fn validate_state_transition_key_signature( let verification_result = verify_hash_signature( &state_transition_hash, - state_transition.get_signature(), + state_transition.get_signature().as_slice(), &public_key_hash, ); if verification_result.is_err() { @@ -134,6 +134,7 @@ fn get_asset_lock_proof( #[cfg(test)] mod test { use dashcore::{secp256k1::SecretKey, Network, PrivateKey}; + use platform_value::BinaryData; use std::sync::Arc; use crate::{ @@ -269,7 +270,7 @@ mod test { .expect("state transition should be signed"); // setting an invalid signature - state_transition.set_signature(vec![0u8; 65]); + state_transition.set_signature(BinaryData::new(vec![0u8; 65])); let result = validate_state_transition_key_signature( &state_repository, diff --git a/packages/rs-dpp/src/system_data_contracts.rs b/packages/rs-dpp/src/system_data_contracts.rs index c9acf146b11..d19c16922d2 100644 --- a/packages/rs-dpp/src/system_data_contracts.rs +++ b/packages/rs-dpp/src/system_data_contracts.rs @@ -34,7 +34,12 @@ fn create_data_contract( let id = Identifier::from(id_bytes); let owner_id = Identifier::from(owner_id_bytes); - let mut data_contract = factory.create(owner_id, document_schemas, definitions)?; + let mut data_contract = factory.create( + owner_id, + document_schemas.into(), + None, + definitions.map(|def| def.into()), + )?; data_contract.id = id; diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 5b0286a6522..e2f6174b8a1 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -21,7 +21,7 @@ use crate::{ }; use jsonschema::error::ValidationErrorKind; -use platform_value::{platform_value, Value}; +use platform_value::{platform_value, BinaryData, Value}; use serde_json::Value as JsonValue; struct TestData { @@ -38,7 +38,7 @@ fn setup_test() -> TestData { let state_transition = DataContractUpdateTransition { protocol_version: LATEST_VERSION, data_contract: updated_data_contract, - signature: vec![0; 65], + signature: BinaryData::new(vec![0; 65]), signature_public_key_id: 0, transition_type: StateTransitionType::DataContractUpdate, execution_context: Default::default(), diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index acac93a6964..2543c87a885 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -1383,8 +1383,6 @@ mod documents { let result = data_contract_validator .validate(&raw_data_contract) .expect("validation result should be returned"); - dbg!(&raw_data_contract); -dbg!(&result); let pattern_error = result .errors .get(0) diff --git a/packages/rs-dpp/src/tests/fixtures/get_data_contract.rs b/packages/rs-dpp/src/tests/fixtures/get_data_contract.rs index ba57e13fcba..94b53ca9fc9 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_data_contract.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_data_contract.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use platform_value::platform_value; use serde_json::json; use crate::prelude::*; @@ -12,14 +13,14 @@ use crate::{ }; pub fn get_data_contract_fixture(owner_id: Option) -> DataContract { - let defs = json!( + let defs = platform_value!( { "lastName": { "type" : "string", }, }); - let documents = json!( + let documents = platform_value!( { "niceDocument": { "type": "object", @@ -113,11 +114,11 @@ pub fn get_data_contract_fixture(owner_id: Option) -> DataContract { "properties": { "firstName": { "type": "string", - "maxLength": 63 + "maxLength": 63u32 }, "lastName": { "type": "string", - "maxLength": 63 + "maxLength": 63u32 } }, "required": [ @@ -198,14 +199,14 @@ pub fn get_data_contract_fixture(owner_id: Option) -> DataContract { "byteArrayField": { "type": "array", "byteArray": true, - "maxItems": 16, + "maxItems": 16u32, }, "identifierField": { "type": "array", "byteArray": true, "contentMediaType": identifier::MEDIA_TYPE, - "minItems": 32, - "maxItems": 32 + "minItems": 32u32, + "maxItems": 32u32 } }, "required": [ @@ -218,19 +219,19 @@ pub fn get_data_contract_fixture(owner_id: Option) -> DataContract { "properties": { "firstName": { "type": "string", - "maxLength": 63 + "maxLength": 63u32 }, "lastName": { "type": "string", - "maxLength": 63 + "maxLength": 63u32 }, "country": { "type": "string", - "maxLength": 63 + "maxLength": 63u32 }, "city": { "type": "string", - "maxLength": 63 + "maxLength": 63u32 } }, "indices": [ @@ -287,6 +288,6 @@ pub fn get_data_contract_fixture(owner_id: Option) -> DataContract { let owner_id = owner_id.unwrap_or_else(generate_random_identifier_struct); factory - .create(owner_id, documents, Some(defs)) + .create(owner_id, documents, None, Some(defs)) .expect("data in fixture should be correct") } diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs index 07bcc5bcfd8..e8a01442d40 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs @@ -1,8 +1,10 @@ use std::sync::Arc; use data_contracts::{DataContractSource, SystemDataContract}; +use platform_value::platform_value; use serde_json::json; +use crate::data_contract::contract_config::ContractConfig; use crate::prelude::*; use crate::{ data_contract::validation::data_contract_validator::DataContractValidator, @@ -26,14 +28,15 @@ pub fn get_dpns_data_contract_fixture(owner_id: Option) -> DataContr .source() .expect("should return DPNS data contract source"); - let defs = json!({ + let defs = platform_value!({ "lastName": { "type" : "string"}, }); // TODO the pattern is invalid as it's a re2 document_schemas["domain"]["properties"]["normalizedParentDomainName"]["pattern"] = json!(".*"); + //todo: the config should not be None factory - .create(owner_id, document_schemas, Some(defs)) + .create(owner_id, document_schemas.into(), None, Some(defs)) .expect("data in fixture should be correct") } diff --git a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs index 5290ed4111e..c2f882b15d6 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs @@ -1,7 +1,6 @@ -use std::convert::TryInto; - +use crate::state_transition::StateTransitionType; use dashcore::PrivateKey; -use platform_value::Value; +use platform_value::{platform_value, BinaryData, Identifier, Value}; use crate::tests::fixtures::instant_asset_lock_proof_fixture; use crate::version; @@ -11,18 +10,11 @@ use crate::version; pub fn identity_topup_transition_fixture(one_time_private_key: Option) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); - - Value::from([ - ("protocolVersion", Value::U32(version::LATEST_VERSION)), - ("type", Value::U8(2)), - ("assetLockProof", asset_lock_proof.try_into().unwrap()), - ( - "identityId", - Value::Identifier([ - 198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, - 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237, - ]), - ), - ("signature", Value::Bytes(vec![0_u8; 65])), - ]) + platform_value!({ + "protocolVersion": version::LATEST_VERSION as u32, + "type": StateTransitionType::IdentityTopUp as u8, + "assetLockProof": asset_lock_proof, + "identityId": Identifier::new([198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237]), + "signature": BinaryData::new(vec![0_u8; 65]) + }) } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/identity_credit_withdrawal_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/identity_credit_withdrawal_transition_spec.rs index df1fba47cdb..652dbc3eecb 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/identity_credit_withdrawal_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/identity_credit_withdrawal_transition_spec.rs @@ -11,6 +11,7 @@ use crate::{ mod deserialization { use dashcore::{hashes::hex::FromHex, PubkeyHash, Script}; use lazy_static::__Deref; + use platform_value::BinaryData; use super::*; @@ -31,7 +32,7 @@ mod deserialization { &PubkeyHash::from_hex("0000000000000000000000000000000000000000").unwrap() ) ); - assert_eq!(state_transition.signature, vec![0; 65]); + assert_eq!(state_transition.signature, BinaryData::new(vec![0; 65])); } #[test] diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs index a71ea025a15..245b218655b 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs @@ -8,7 +8,8 @@ use std::vec::IntoIter; #[derive(Debug, Clone, Copy)] pub enum ReplacementType { Identifier, - Bytes, + IdentifierBytes, + BinaryBytes, TextBase58, TextBase64, } @@ -23,7 +24,8 @@ impl ReplacementType { )) })?)) } - ReplacementType::Bytes => Ok(Value::Bytes(bytes)), + ReplacementType::BinaryBytes + | ReplacementType::IdentifierBytes => Ok(Value::Bytes(bytes)), ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), } @@ -32,7 +34,8 @@ impl ReplacementType { pub fn replace_for_bytes_32(&self, bytes: [u8; 32]) -> Result { match self { ReplacementType::Identifier => Ok(Value::Identifier(bytes)), - ReplacementType::Bytes => Ok(Value::Bytes32(bytes)), + ReplacementType::BinaryBytes + | ReplacementType::IdentifierBytes => Ok(Value::Bytes32(bytes)), ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), } diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs index 18eee60ac72..577363176e8 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs @@ -1,4 +1,4 @@ -use crate::{Error, Identifier, Value}; +use crate::{BinaryData, Error, Identifier, Value}; use std::collections::BTreeMap; pub trait BTreeValueRemoveFromMapHelper { @@ -38,6 +38,8 @@ pub trait BTreeValueRemoveFromMapHelper { fn remove_bool(&mut self, key: &str) -> Result; fn remove_optional_identifier(&mut self, key: &str) -> Result, Error>; fn remove_identifier(&mut self, key: &str) -> Result; + fn remove_binary_data(&mut self, key: &str) -> Result; + fn remove_optional_binary_data(&mut self, key: &str) -> Result, Error>; } impl BTreeValueRemoveFromMapHelper for BTreeMap { @@ -174,6 +176,24 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { self.remove_optional_bool(key)? .ok_or_else(|| Error::StructureError(format!("unable to remove float property {key}"))) } + + fn remove_binary_data(&mut self, key: &str) -> Result { + self.remove_optional_binary_data(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove binary data property {key}")) + }) + } + + fn remove_optional_binary_data(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_binary_data()) + } + }) + .transpose() + } } impl BTreeValueRemoveFromMapHelper for BTreeMap { @@ -272,6 +292,23 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { .ok_or_else(|| Error::StructureError(format!("unable to remove bytes property {key}"))) } + fn remove_optional_binary_data(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_binary_data()) + } + }) + .transpose() + } + + fn remove_binary_data(&mut self, key: &str) -> Result { + self.remove_optional_binary_data(key)? + .ok_or_else(|| Error::StructureError(format!("unable to remove bytes property {key}"))) + } + fn remove_optional_string(&mut self, key: &str) -> Result, Error> { self.remove(key) .and_then(|v| { diff --git a/packages/rs-platform-value/src/btreemap_extensions/mod.rs b/packages/rs-platform-value/src/btreemap_extensions/mod.rs index fee49f10c2f..cccaab0610f 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/mod.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/mod.rs @@ -4,7 +4,7 @@ use std::convert::TryFrom; use std::iter::FromIterator; use std::{collections::BTreeMap, convert::TryInto}; -use crate::{Error, Value, ValueMap}; +use crate::{BinaryData, Error, Value, ValueMap}; pub(crate) mod btreemap_field_replacement; mod btreemap_mut_value_extensions; @@ -108,6 +108,8 @@ pub trait BTreeValueMapHelper { fn get_bytes(&self, key: &str) -> Result, Error>; fn get_optional_binary_bytes(&self, key: &str) -> Result>, Error>; fn get_binary_bytes(&self, key: &str) -> Result, Error>; + fn get_optional_binary_data(&self, key: &str) -> Result, Error>; + fn get_binary_data(&self, key: &str) -> Result; } impl BTreeValueMapHelper for BTreeMap @@ -415,6 +417,17 @@ where .ok_or_else(|| Error::StructureError(format!("unable to get bytes property {key}"))) } + fn get_optional_binary_data(&self, key: &str) -> Result, Error> { + self.get(key) + .map(|v| v.borrow().to_binary_data()) + .transpose() + } + + fn get_binary_data(&self, key: &str) -> Result { + self.get_optional_binary_data(key)? + .ok_or_else(|| Error::StructureError(format!("unable to get binary data property {key}"))) + } + fn get_optional_float(&self, key: &str) -> Result, Error> { self.get(key) .and_then(|v| { diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 765b1e84f20..62d12b2ae6c 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; use crate::value_map::{ValueMap, ValueMapHelper}; -use crate::Identifier; +use crate::{BinaryData, Identifier}; use crate::{Error, Value}; use std::collections::BTreeMap; @@ -151,6 +151,19 @@ impl Value { .transpose() } + pub fn remove_binary_data(&mut self, key: &str) -> Result { + let map = self.as_map_mut_ref()?; + let value = map.remove_key(key)?; + value.into_binary_data() + } + + pub fn remove_optional_binary_data(&mut self, key: &str) -> Result, Error> { + let map = self.as_map_mut_ref()?; + map.remove_optional_key(key) + .map(|v| v.into_binary_data()) + .transpose() + } + pub fn remove_array(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; let value = map.remove_key(key)?; @@ -293,6 +306,16 @@ impl Value { Self::inner_array_slice(map, key) } + pub fn get_optional_binary_data<'a>(&'a self, key: &'a str) -> Result, Error> { + let map = self.to_map()?; + Self::inner_optional_binary_data_value(map, key) + } + + pub fn get_binary_data<'a>(&'a self, key: &'a str) -> Result { + let map = self.to_map()?; + Self::inner_binary_data_value(map, key) + } + pub fn get_optional_bytes<'a>(&'a self, key: &'a str) -> Result>, Error> { let map = self.to_map()?; Self::inner_optional_bytes_value(map, key) @@ -583,6 +606,26 @@ impl Value { Self::get_from_map(document_type, key).map(|v| v.to_hash256())? } + /// Retrieves the value of a key from a map if it's a byte array. + pub fn inner_optional_binary_data_value<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result, Error> { + Self::get_optional_from_map(document_type, key) + .map(|v| v.to_binary_data()) + .transpose() + } + + /// Retrieves the value of a key from a map if it's a byte array. + pub fn inner_binary_data_value<'a>( + document_type: &'a [(Value, Value)], + key: &'a str, + ) -> Result { + Self::get_from_map(document_type, key).map(|v| v.to_binary_data())? + } + + /// Retrieves the val + /// /// Retrieves the value of a key from a map if it's a byte array. pub fn inner_optional_bytes_value<'a>( document_type: &'a [(Value, Value)], diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index ee0eeabd9ce..efb4a47b176 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -352,6 +352,31 @@ impl Value { } } + /// If the `Value` is a ref to `Bytes`, returns a the associated `BinaryData` data as `Ok`. + /// BinaryData wraps Vec + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{BinaryData, Error, Value}; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]); + /// assert_eq!(value.to_binary_data(), Ok(BinaryData::new(vec![104, 101, 108, 108, 111]))); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_binary_data(), Err(Error::StructureError("ref value are not bytes found true instead".to_string()))); + /// ``` + pub fn to_binary_data(&self) -> Result { + match self { + Value::Bytes(vec) => Ok(BinaryData::new(vec.clone())), + Value::Bytes32(vec) => Ok(BinaryData::new(vec.to_vec())), + Value::Identifier(vec) => Ok(BinaryData::new(vec.to_vec())), + other => Err(Error::StructureError(format!( + "ref value are not bytes found {} instead", + other + ))), + } + } + /// If the `Value` is a ref to `Bytes`, returns a the associated `&[u8]` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. /// @@ -1085,7 +1110,13 @@ impl Value { }; if split.peek().is_none() { - let bytes = new_value.to_identifier_bytes()?; + let bytes = match replacement_type { + ReplacementType::Identifier + | ReplacementType::IdentifierBytes + | ReplacementType::TextBase58 => new_value.to_identifier_bytes(), + ReplacementType::BinaryBytes + | ReplacementType::TextBase64 => new_value.to_binary_bytes(), + }?; *new_value = replacement_type.replace_for_bytes(bytes)?; return Ok(true); } diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index 80caa90ea15..a6c9ddd9ca8 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -1,4 +1,4 @@ -use crate::{Error, Identifier, Value}; +use crate::{BinaryData, Error, Identifier, Value}; impl Value { /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the @@ -139,6 +139,32 @@ impl Value { } } + /// If the `Value` is a `Bytes`, a `Text` using base 64 or Vector of `U8`, returns the + /// associated `Vec` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{BinaryData, Error, Value}; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]); + /// assert_eq!(value.into_binary_data(), Ok(BinaryData::new(vec![104, 101, 108, 108, 111]))); /// + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.into_binary_data(), Ok(BinaryData::new(vec![107, 205, 117]))); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108)]); + /// assert_eq!(value.into_binary_data(), Ok(BinaryData::new(vec![104, 101, 108]))); + /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.into_binary_data(), Ok(BinaryData::new(vec![5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5]))); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.into_binary_data(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn into_binary_data(self) -> Result { + Ok(BinaryData::new(self.into_binary_bytes()?)) + } + /// If the `Value` is a ref to a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the /// associated `Vec` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. diff --git a/packages/rs-platform-value/src/types/binary_data.rs b/packages/rs-platform-value/src/types/binary_data.rs index a9ff0a17b9f..76fc000922f 100644 --- a/packages/rs-platform-value/src/types/binary_data.rs +++ b/packages/rs-platform-value/src/types/binary_data.rs @@ -79,6 +79,34 @@ impl BinaryData { pub fn to_vec(&self) -> Vec { self.0.clone() } + + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl From> for BinaryData { + fn from(value: Vec) -> Self { + BinaryData::new(value) + } +} + +impl PartialEq<&[u8]> for BinaryData { + fn eq(&self, other: &&[u8]) -> bool { + self.as_slice() == *other + } +} + +impl PartialEq<[u8]> for BinaryData { + fn eq(&self, other: &[u8]) -> bool { + self.as_slice() == other + } +} + +impl PartialEq> for BinaryData { + fn eq(&self, other: &Vec) -> bool { + self.as_slice() == other + } } #[cfg(test)] diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index f770ef15dd4..5a9db9c6949 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -140,7 +140,6 @@ mod tests { }; let platform_value = to_value(yeet.clone()).expect("please"); - dbg!(&platform_value); let yeet_back: Yeet = from_value(platform_value).expect("please once again"); assert_eq!(yeet, yeet_back); From 82f4dad9044b3fd5e707683841e727d7f20af720 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 17:12:37 +0700 Subject: [PATCH 133/228] more fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 6 +- .../data_contract/data_contract_factory.rs | 10 +- .../src/data_contract/serialization/cbor.rs | 4 +- .../data_contract_create_transition/mod.rs | 18 ++-- .../validate_data_contract_max_depth.rs | 8 +- .../consensus/abstract_consensus_error.rs | 7 ++ .../data_contract_validator_spec.rs | 10 +- .../btreemap_removal_extensions.rs | 40 +++++++- packages/rs-platform-value/src/inner_value.rs | 14 ++- .../rs-platform-value/src/system_bytes.rs | 99 ++++++++++++++++++- .../rs-platform-value/src/types/bytes_32.rs | 99 +++++++++++++++++++ .../rs-platform-value/src/types/identifier.rs | 14 +-- packages/rs-platform-value/src/types/mod.rs | 16 +++ 13 files changed, 303 insertions(+), 42 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index a326029b26c..c7d315b4ce4 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -5,7 +5,7 @@ use anyhow::anyhow; use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; -use platform_value::Identifier; +use platform_value::{BinaryData, Bytes32, Identifier}; use platform_value::Value; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -99,7 +99,7 @@ pub struct DataContract { pub defs: BTreeMap, #[serde(skip)] - pub entropy: [u8; 32], + pub entropy: Bytes32, #[serde(skip)] pub binary_properties: BTreeMap>, @@ -168,7 +168,7 @@ impl DataContract { documents, defs, entropy: data_contract_map - .remove_optional_hash256_bytes(property_names::ENTROPY) + .remove_optional_bytes_32(property_names::ENTROPY) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), binary_properties, diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 614ae9eb65c..3bbfe6b0b60 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -4,7 +4,7 @@ use std::convert::TryInto; use std::sync::Arc; use data_contract::state_transition::property_names as st_prop; -use platform_value::Value; +use platform_value::{Bytes32, Value}; use crate::data_contract::contract_config::ContractConfig; use crate::data_contract::errors::InvalidDataContractError; @@ -73,10 +73,10 @@ impl DataContractFactory { config: Option, definitions: Option, ) -> Result { - let entropy = self.entropy_generator.generate(); + let entropy = Bytes32::new(self.entropy_generator.generate()); let data_contract_id = - Identifier::from_bytes(&generate_data_contract_id(owner_id.to_buffer(), entropy))?; + Identifier::from_bytes(&generate_data_contract_id(owner_id.to_buffer(), entropy.to_buffer()))?; let definition_references = definitions .as_ref() @@ -183,7 +183,7 @@ impl DataContractFactory { &self, data_contract: DataContract, ) -> Result { - let entropy = Value::Bytes32(data_contract.entropy); + let entropy = Value::Bytes32(data_contract.entropy.to_buffer()); let raw_object = BTreeMap::from([ ( st_prop::PROTOCOL_VERSION.to_string(), @@ -344,7 +344,7 @@ mod tests { .expect("Data Contract Transition should be created"); assert_eq!(1, result.get_protocol_version()); - assert_eq!(&data_contract.entropy, result.get_entropy()); + assert_eq!(&data_contract.entropy, &result.entropy); assert_eq!(raw_data_contract, result.data_contract.to_object().unwrap()); } } diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index 3e88a48414e..22839a77ed3 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -7,7 +7,7 @@ use crate::{data_contract, ProtocolError}; use ciborium::Value as CborValue; use integer_encoding::VarInt; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::Value; +use platform_value::{Bytes32, Value}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; @@ -65,7 +65,7 @@ impl DataContract { documents, defs, metadata: None, - entropy: [0; 32], + entropy: Bytes32::default(), binary_properties: Default::default(), document_types, config: mutability, diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index ee26c2ecfed..690c716ab92 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::{BinaryData, Value}; +use platform_value::{BinaryData, Bytes32, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -34,7 +34,7 @@ pub struct DataContractCreateTransition { // we want to skip serialization of transitions, as we does it manually in `to_object()` and `to_json()` #[serde(skip_serializing)] pub data_contract: DataContract, - pub entropy: [u8; 32], + pub entropy: Bytes32, pub signature_public_key_id: KeyID, pub signature: BinaryData, #[serde(skip)] @@ -46,7 +46,7 @@ impl std::default::Default for DataContractCreateTransition { DataContractCreateTransition { protocol_version: Default::default(), transition_type: StateTransitionType::DataContractCreate, - entropy: [0u8; 32], + entropy: Bytes32::default(), signature_public_key_id: 0, signature: BinaryData::default(), data_contract: Default::default(), @@ -70,7 +70,7 @@ impl DataContractCreateTransition { .map_err(ProtocolError::ValueError)? .unwrap_or_default(), entropy: raw_data_contract_update_transition - .remove_optional_hash256_bytes(ENTROPY) + .remove_optional_bytes_32(ENTROPY) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), data_contract: DataContract::from_raw_object( @@ -102,7 +102,7 @@ impl DataContractCreateTransition { .map_err(ProtocolError::ValueError)? .unwrap_or_default(), entropy: raw_data_contract_update_transition - .remove_optional_hash256_bytes(ENTROPY) + .remove_optional_bytes_32(ENTROPY) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), data_contract: DataContract::from_raw_object( @@ -128,10 +128,6 @@ impl DataContractCreateTransition { self.data_contract = data_contract; } - pub fn get_entropy(&self) -> &[u8; 32] { - &self.entropy - } - /// Returns ID of the created contract pub fn get_modified_data_ids(&self) -> Vec<&Identifier> { vec![&self.data_contract.id] @@ -241,7 +237,7 @@ mod test { let state_transition = DataContractCreateTransition::from_raw_object(Value::from([ (PROTOCOL_VERSION, version::LATEST_VERSION.into()), - (ENTROPY, Value::Bytes32(data_contract.entropy)), + (ENTROPY, data_contract.entropy.into()), (DATA_CONTRACT, data_contract.to_object().unwrap()), ])) .expect("state transition should be created without errors"); @@ -320,7 +316,7 @@ mod test { ); assert_eq!( - base64::encode(data.data_contract.entropy), + >::into(data.data_contract.entropy), json_object .remove_into::(ENTROPY) .expect("the entropy should be present") diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index e4b275d7e93..fd28ec30fde 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -22,8 +22,8 @@ pub fn validate_data_contract_max_depth(data_contract_object: &Value) -> Validat result } -fn calc_max_depth(value: &Value) -> Result { - let mut values_depth_queue: Vec<(&Value, usize)> = vec![(value, 0)]; +fn calc_max_depth(platform_value: &Value) -> Result { + let mut values_depth_queue: Vec<(&Value, usize)> = vec![(platform_value, 0)]; let mut max_depth: usize = 0; let mut visited: BTreeSet<*const Value> = BTreeSet::new(); let ref_value = Value::Text("$ref".to_string()); @@ -39,10 +39,10 @@ fn calc_max_depth(value: &Value) -> Result { // handling the internal references if property_name == &ref_value { if let Some(uri) = v.as_str() { - let resolved = resolve_uri(value, uri).map_err(|e| { + let resolved = resolve_uri(platform_value, uri).map_err(|e| { BasicError::InvalidJsonSchemaRefError( InvalidJsonSchemaRefError::new(format!( - "invalid ref '{}': {}", + "invalid ref for max depth '{}': {}", uri, e )), ) diff --git a/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs b/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs index 7875823ce28..a6b2f2c7fe7 100644 --- a/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs +++ b/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs @@ -139,6 +139,13 @@ impl ConsensusError { } } + pub fn value_error(&self) -> Option<&ValueError> { + match self { + ConsensusError::ValueError(err) => Some(err), + _ => None, + } + } + pub fn code(&self) -> u32 { match self { // Decoding diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index 2543c87a885..b571a744848 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -55,6 +55,15 @@ fn get_schema_error(result: &ValidationResult<()>, number: usize) -> &JsonSchema .expect("the error should be json schema error") } +fn get_value_error(result: &ValidationResult<()>, number: usize) -> &platform_value::Error { + result + .errors + .get(number) + .expect("the error should be returned in validation result") + .value_error() + .expect("the error should be a value error") +} + fn get_basic_error(consensus_error: &ConsensusError) -> &BasicError { match consensus_error { ConsensusError::BasicError(basic_error) => basic_error, @@ -1270,7 +1279,6 @@ mod documents { }, "additionalProperties": false, }); - let result = data_contract_validator .validate(&raw_data_contract) .expect("validation result should be returned"); diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs index 577363176e8..a4b1ccfabab 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs @@ -1,4 +1,4 @@ -use crate::{BinaryData, Error, Identifier, Value}; +use crate::{BinaryData, Bytes32, Error, Identifier, Value}; use std::collections::BTreeMap; pub trait BTreeValueRemoveFromMapHelper { @@ -40,6 +40,8 @@ pub trait BTreeValueRemoveFromMapHelper { fn remove_identifier(&mut self, key: &str) -> Result; fn remove_binary_data(&mut self, key: &str) -> Result; fn remove_optional_binary_data(&mut self, key: &str) -> Result, Error>; + fn remove_optional_bytes_32(&mut self, key: &str) -> Result, Error>; + fn remove_bytes_32(&mut self, key: &str) -> Result; } impl BTreeValueRemoveFromMapHelper for BTreeMap { @@ -103,6 +105,24 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { }) } + fn remove_optional_bytes_32(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.to_bytes_32()) + } + }) + .transpose() + } + + fn remove_bytes_32(&mut self, key: &str) -> Result { + self.remove_optional_bytes_32(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove hash256 property {key}")) + }) + } + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { self.remove(key) .and_then(|v| { @@ -257,6 +277,24 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { }) } + fn remove_optional_bytes_32(&mut self, key: &str) -> Result, Error> { + self.remove(key) + .and_then(|v| { + if v.is_null() { + None + } else { + Some(v.into_bytes_32()) + } + }) + .transpose() + } + + fn remove_bytes_32(&mut self, key: &str) -> Result { + self.remove_optional_bytes_32(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to remove hash256 property {key}")) + }) + } + fn remove_optional_hash256_bytes(&mut self, key: &str) -> Result, Error> { self.remove(key) .and_then(|v| { diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 62d12b2ae6c..3bb5c94586d 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,6 +1,6 @@ use std::cmp::Ordering; use crate::value_map::{ValueMap, ValueMapHelper}; -use crate::{BinaryData, Identifier}; +use crate::{BinaryData, Bytes32, Identifier}; use crate::{Error, Value}; use std::collections::BTreeMap; @@ -124,6 +124,18 @@ impl Value { .transpose() } + pub fn remove_bytes_32(&mut self, key: &str) -> Result { + let map = self.as_map_mut_ref()?; + let value = map.remove_key(key)?; + value.into_bytes_32() + } + + pub fn remove_optional_bytes_32(&mut self, key: &str) -> Result, Error> { + let map = self.as_map_mut_ref()?; + map.remove_optional_key(key) + .map(|v| v.into_bytes_32()) + .transpose() + } pub fn remove_hash256_bytes(&mut self, key: &str) -> Result<[u8; 32], Error> { let map = self.as_map_mut_ref()?; diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index a6c9ddd9ca8..5516263b718 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -1,4 +1,4 @@ -use crate::{BinaryData, Error, Identifier, Value}; +use crate::{BinaryData, Bytes32, Error, Identifier, Value}; impl Value { /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the @@ -324,6 +324,103 @@ impl Value { } } + /// If the `Value` is a `Bytes`, a `Text` using base 64 or Vector of `U8`, returns the + /// associated `Bytes32` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Value}; + /// use platform_value::Value::Bytes32; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]); + /// assert_eq!(value.into_bytes_32(), Ok(Bytes32([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]))); /// + /// + /// let value = Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string()); + /// assert_eq!(value.into_bytes_32(), Ok(Bytes32([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.into_bytes_32(), Err(Error::StructureError("buffer was not 32 bytes long".to_string()))); + /// + /// let value = Value::Text("a811Ii".to_string()); + /// assert_eq!(value.into_bytes_32(), Err(Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); + /// assert_eq!(value.into_bytes_32(), Ok(Bytes32([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); + /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.into_bytes_32(), Ok(Bytes32([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5]))); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.into_bytes_32(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn into_bytes_32(self) -> Result { + match self { + Value::Text(text) => { + Bytes32::from_vec(base64::decode(text).map_err(|_| Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))?) + }, + Value::Array(array) => { + Bytes32::from_vec(array + .iter() + .map(|byte| byte.to_integer()) + .collect::, Error>>()?) + }, + Value::Bytes32(bytes) => Ok(Bytes32::new(bytes)), + Value::Bytes(vec) => { + Bytes32::from_vec(vec) + }, + Value::Identifier(identifier) => Ok(Bytes32::new(identifier)), + _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), + } + } + + /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the + /// associated `Vec` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Error, Value}; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]); + /// assert_eq!(value.to_bytes_32(), Ok([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50])); /// + /// + /// let value = Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string()); + /// assert_eq!(value.to_bytes_32(), Ok([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117])); + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.to_bytes_32(), Err(Error::StructureError("buffer was not 32 bytes long".to_string()))); + /// + /// let value = Value::Text("a811Ii".to_string()); + /// assert_eq!(value.to_bytes_32(), Err(Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); + /// assert_eq!(value.to_bytes_32(), Ok([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101])); + /// + /// let value = Value::Identifier([5u8;32]); + /// assert_eq!(value.to_bytes_32(), Ok([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_bytes_32(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn to_bytes_32(&self) -> Result { + match self { + Value::Text(text) => { + Bytes32::from_vec(base64::decode(text).map_err(|_| Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))?) + }, + Value::Array(array) => { + Bytes32::from_vec(array + .iter() + .map(|byte| byte.to_integer()) + .collect::, Error>>()?) + }, + Value::Bytes32(bytes) => Ok(Bytes32::new(*bytes)), + Value::Bytes(vec) => { + Bytes32::from_vec(vec.clone()) + }, + Value::Identifier(identifier) => Ok(Bytes32::new(*identifier)), + _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), + } + } + /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the /// associated `Identifier` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. diff --git a/packages/rs-platform-value/src/types/bytes_32.rs b/packages/rs-platform-value/src/types/bytes_32.rs index 9122f496f50..98795d4f503 100644 --- a/packages/rs-platform-value/src/types/bytes_32.rs +++ b/packages/rs-platform-value/src/types/bytes_32.rs @@ -2,10 +2,61 @@ use std::fmt; use std::fmt::Write; use serde::{Deserialize, Serialize}; use serde::de::Visitor; +use crate::{Error, string_encoding, Value}; +use crate::string_encoding::Encoding; +use crate::types::encoding_string_to_encoding; #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy)] pub struct Bytes32(pub [u8; 32]); +impl Bytes32 { + pub fn new(buffer: [u8; 32]) -> Self { + Bytes32(buffer) + } + + pub fn from_vec(buffer: Vec) -> Result { + let buffer : [u8; 32] = buffer.try_into().map_err(|_| Error::ByteLengthNot32BytesError("buffer was not 32 bytes long".to_string()))?; + Ok(Bytes32::new(buffer)) + } + + pub fn as_slice(&self) -> &[u8] { + self.0.as_slice() + } + + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } + + pub fn to_buffer(&self) -> [u8; 32] { + self.0 + } + + pub fn from_string(encoded_value: &str, encoding: Encoding) -> Result { + let vec = string_encoding::decode(encoded_value, encoding)?; + + Bytes32::from_vec(vec) + } + + pub fn from_string_with_encoding_string( + encoded_value: &str, + encoding_string: Option<&str>, + ) -> Result { + let encoding = encoding_string_to_encoding(encoding_string); + + Bytes32::from_string(encoded_value, encoding) + } + + pub fn to_string(&self, encoding: Encoding) -> String { + string_encoding::encode(&self.0, encoding) + } + + pub fn to_string_with_encoding_string(&self, encoding_string: Option<&str>) -> String { + let encoding = encoding_string_to_encoding(encoding_string); + + self.to_string(encoding) + } +} + impl Serialize for Bytes32 { fn serialize(&self, serializer: S) -> Result where @@ -76,4 +127,52 @@ impl<'de> Deserialize<'de> for Bytes32 { deserializer.deserialize_bytes(BytesVisitor) } } +} + +impl TryFrom for Bytes32 { + type Error = Error; + + fn try_from(value: Value) -> Result { + value.into_bytes_32() + } +} + +impl TryFrom<&Value> for Bytes32 { + type Error = Error; + + fn try_from(value: &Value) -> Result { + value.to_bytes_32() + } +} + +impl From for Value { + fn from(value: Bytes32) -> Self { + Value::Bytes32(value.0) + } +} + +impl From<&Bytes32> for Value { + fn from(value: &Bytes32) -> Self { + Value::Bytes32(value.0) + } +} + +impl TryFrom for Bytes32 { + type Error = Error; + + fn try_from(data: String) -> Result { + Self::from_string(&data, Encoding::Base64) + } +} + +impl Into for Bytes32 { + fn into(self) -> String { + self.to_string(Encoding::Base64) + } +} + +impl Into for &Bytes32 { + fn into(self) -> String { + self.to_string(Encoding::Base64) + } } \ No newline at end of file diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 42a65797485..0cc9a6b0c4d 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -9,6 +9,7 @@ use serde_json::Value as JsonValue; use crate::string_encoding::Encoding; use crate::{string_encoding, Error, Value}; +use crate::types::encoding_string_to_encoding; pub const IDENTIFIER_MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; @@ -106,19 +107,6 @@ impl<'de> Deserialize<'de> for IdentifierBytes32 { // } // } -fn encoding_string_to_encoding(encoding_string: Option<&str>) -> Encoding { - match encoding_string { - Some(str) => { - //? should it be case-sensitive?? - if str == "base58" { - Encoding::Base58 - } else { - Encoding::Base64 - } - } - None => Encoding::Base58, - } -} impl Identifier { pub fn new(buffer: [u8; 32]) -> Identifier { diff --git a/packages/rs-platform-value/src/types/mod.rs b/packages/rs-platform-value/src/types/mod.rs index 2ab9a4c9d1f..68c1d791fd6 100644 --- a/packages/rs-platform-value/src/types/mod.rs +++ b/packages/rs-platform-value/src/types/mod.rs @@ -1,3 +1,19 @@ +use crate::string_encoding::Encoding; + pub(crate) mod identifier; pub(crate) mod bytes_32; pub(crate) mod binary_data; + +fn encoding_string_to_encoding(encoding_string: Option<&str>) -> Encoding { + match encoding_string { + Some(str) => { + //? should it be case-sensitive?? + if str == "base58" { + Encoding::Base58 + } else { + Encoding::Base64 + } + } + None => Encoding::Base58, + } +} From 2fa3dd40e49990cd83d9fd58de37b480a6e444cf Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 17:35:23 +0700 Subject: [PATCH 134/228] more work --- .../rs-dpp/src/data_contract/data_contract.rs | 2 +- .../data_contract/data_contract_factory.rs | 6 +- .../identity/identity_public_key/factory.rs | 9 +- .../src/identity/identity_public_key/mod.rs | 12 +-- .../identity_public_key_transitions.rs | 18 ++-- .../validate_public_key_signatures.rs | 4 +- ...stract_state_transition_identity_signed.rs | 17 ++-- .../get_identity_update_transition_fixture.rs | 10 ++- .../identity/identity_public_key_spec.rs | 4 +- .../src/tests/identity/identity_spec.rs | 5 +- .../identity_update_transition_spec.rs | 2 +- ...e_identity_update_transition_basic_spec.rs | 4 +- .../src/types/binary_data.rs | 89 ++++++++++++++++++- .../rs-platform-value/src/types/bytes_32.rs | 2 +- .../rs-platform-value/src/types/identifier.rs | 4 +- 15 files changed, 143 insertions(+), 45 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index c7d315b4ce4..dd4caad6526 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -5,8 +5,8 @@ use anyhow::anyhow; use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; -use platform_value::{BinaryData, Bytes32, Identifier}; use platform_value::Value; +use platform_value::{BinaryData, Bytes32, Identifier}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 3bbfe6b0b60..cde4c121118 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -75,8 +75,10 @@ impl DataContractFactory { ) -> Result { let entropy = Bytes32::new(self.entropy_generator.generate()); - let data_contract_id = - Identifier::from_bytes(&generate_data_contract_id(owner_id.to_buffer(), entropy.to_buffer()))?; + let data_contract_id = Identifier::from_bytes(&generate_data_contract_id( + owner_id.to_buffer(), + entropy.to_buffer(), + ))?; let definition_references = definitions .as_ref() diff --git a/packages/rs-dpp/src/identity/identity_public_key/factory.rs b/packages/rs-dpp/src/identity/identity_public_key/factory.rs index 905c9e59516..3007ebc2035 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/factory.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/factory.rs @@ -4,6 +4,7 @@ use crate::identity::Purpose::AUTHENTICATION; use crate::identity::SecurityLevel::MASTER; use crate::identity::{IdentityPublicKey, KeyID, KeyType, Purpose, SecurityLevel}; use crate::ProtocolError; +use platform_value::BinaryData; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; use std::convert::TryFrom; @@ -88,7 +89,7 @@ impl IdentityPublicKey { let security_level = SecurityLevel::try_from(security_level).unwrap(); let key_type = KeyType::try_from(key_type).unwrap(); let read_only = false; - let data = key_type.random_public_key_data(rng); + let data = BinaryData::new(key_type.random_public_key_data(rng)); Ok(IdentityPublicKey { id, key_type, @@ -138,7 +139,7 @@ impl IdentityPublicKey { let purpose = Purpose::try_from(purpose).unwrap(); let key_type = KeyType::try_from(key_type).unwrap(); let read_only = false; - let data = key_type.random_public_key_data(rng); + let data = BinaryData::new(key_type.random_public_key_data(rng)); Ok(IdentityPublicKey { id, key_type, @@ -156,7 +157,7 @@ impl IdentityPublicKey { let purpose = AUTHENTICATION; let security_level = MASTER; let read_only = false; - let data = vec![255; key_type.default_size()]; + let data = BinaryData::new(vec![255; key_type.default_size()]); IdentityPublicKey { id, @@ -175,7 +176,7 @@ impl IdentityPublicKey { let purpose = AUTHENTICATION; let security_level = MASTER; let read_only = false; - let data = key_type.random_public_key_data(rng); + let data = BinaryData::new(key_type.random_public_key_data(rng)); IdentityPublicKey { id, key_type, diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index c69ed106a39..58f8e2524d2 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -11,7 +11,7 @@ use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; use ciborium::value::Value as CborValue; use dashcore::PublicKey as ECDSAPublicKey; -use platform_value::Value; +use platform_value::{BinaryData, Value}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; @@ -41,7 +41,7 @@ pub struct IdentityPublicKey { #[serde(rename = "type")] pub key_type: KeyType, pub read_only: bool, - pub data: Vec, + pub data: BinaryData, #[serde(default)] pub disabled_at: Option, } @@ -55,7 +55,7 @@ impl Into for &IdentityPublicKey { key_type: self.key_type, read_only: self.read_only, data: self.data.clone(), - signature: vec![], + signature: BinaryData::default(), } } } @@ -107,12 +107,12 @@ impl IdentityPublicKey { Ok(ripemd160_sha256(self.data.as_slice())) } } - KeyType::ECDSA_HASH160 | KeyType::BIP13_SCRIPT_HASH => Ok(self.data.clone()), + KeyType::ECDSA_HASH160 | KeyType::BIP13_SCRIPT_HASH => Ok(self.data.to_vec()), } } pub fn as_ecdsa_array(&self) -> Result<[u8; 33], InvalidVectorSizeError> { - vec::vec_to_array::<33>(&self.data) + vec::vec_to_array::<33>(self.data.as_slice()) } pub fn from_value(value: Value) -> Result { @@ -173,7 +173,7 @@ impl IdentityPublicKey { purpose: purpose.try_into()?, security_level: security_level.try_into()?, key_type: key_type.try_into()?, - data: public_key_bytes, + data: BinaryData::new(public_key_bytes), read_only: readonly, disabled_at, }) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 1d46a8b00ac..0522ad257f6 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -5,7 +5,7 @@ use std::convert::{TryFrom, TryInto}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::Value; +use platform_value::{BinaryData, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -24,10 +24,10 @@ pub struct IdentityPublicKeyWithWitness { pub security_level: SecurityLevel, #[serde(rename = "type")] pub key_type: KeyType, - pub data: Vec, + pub data: BinaryData, pub read_only: bool, /// The signature is needed for ECDSA_SECP256K1 Key type and BLS12_381 Key type - pub signature: Vec, + pub signature: BinaryData, } impl IdentityPublicKeyWithWitness { @@ -100,13 +100,13 @@ impl IdentityPublicKeyWithWitness { .map_err(ProtocolError::ValueError)? .try_into()?, data: value_map - .remove_bytes("data") + .remove_binary_data("data") .map_err(ProtocolError::ValueError)?, read_only: value_map .get_bool("readOnly") .map_err(ProtocolError::ValueError)?, signature: value_map - .remove_bytes("signature") + .remove_binary_data("signature") .map_err(ProtocolError::ValueError)?, }) } @@ -133,14 +133,14 @@ impl IdentityPublicKeyWithWitness { Value::U8(self.security_level as u8), ), ("keyType".to_string(), Value::U8(self.key_type as u8)), - ("data".to_string(), Value::Bytes(self.data.clone())), + ("data".to_string(), Value::Bytes(self.data.to_vec())), ("readOnly".to_string(), Value::Bool(self.read_only)), ]); if !skip_signature && !self.signature.is_empty() { map.insert( "signature".to_string(), - Value::Bytes(self.signature.clone()), + Value::Bytes(self.signature.to_vec()), ); } @@ -204,9 +204,9 @@ impl IdentityPublicKeyWithWitness { purpose: purpose.try_into()?, security_level: security_level.try_into()?, key_type: key_type.try_into()?, - data: public_key_bytes, + data: BinaryData::from(public_key_bytes), read_only: readonly, - signature: signature_bytes, + signature: BinaryData::from(signature_bytes), }) } diff --git a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 3990fa9aadb..62e6153d156 100644 --- a/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/rs-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -118,9 +118,9 @@ fn find_invalid_public_key( bls: &T, ) -> Option { for public_key in public_keys { - state_transition.set_signature_bytes(public_key.signature.clone()); + state_transition.set_signature(public_key.signature.clone()); if state_transition - .verify_by_public_key(&public_key.data, public_key.key_type, bls) + .verify_by_public_key(public_key.data.as_slice(), public_key.key_type, bls) .is_err() { return Some(public_key); diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index 8d7c3fed3b3..aa4d584f09c 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -43,7 +43,7 @@ where if public_key_compressed.to_vec() != identity_public_key.data { return Err(ProtocolError::InvalidSignaturePublicKeyError( - InvalidSignaturePublicKeyError::new(identity_public_key.data.to_owned()), + InvalidSignaturePublicKeyError::new(identity_public_key.data.to_vec()), )); } @@ -55,7 +55,7 @@ where if pub_key_hash != identity_public_key.data { return Err(ProtocolError::InvalidSignaturePublicKeyError( - InvalidSignaturePublicKeyError::new(identity_public_key.data.to_owned()), + InvalidSignaturePublicKeyError::new(identity_public_key.data.to_vec()), )); } self.sign_by_private_key(private_key, identity_public_key.key_type, bls) @@ -65,7 +65,7 @@ where if public_key != identity_public_key.data { return Err(ProtocolError::InvalidSignaturePublicKeyError( - InvalidSignaturePublicKeyError::new(identity_public_key.data.to_owned()), + InvalidSignaturePublicKeyError::new(identity_public_key.data.to_vec()), )); } self.sign_by_private_key(private_key, identity_public_key.key_type, bls) @@ -330,7 +330,7 @@ mod test { key_type: KeyType::ECDSA_SECP256K1, purpose: Purpose::AUTHENTICATION, security_level: SecurityLevel::HIGH, - data: ec_public_compressed_bytes.try_into().unwrap(), + data: BinaryData::new(ec_public_compressed_bytes.try_into().unwrap()), read_only: false, disabled_at: None, }; @@ -442,7 +442,8 @@ mod test { let mut st = get_mock_state_transition(); let mut keys = get_test_keys(); keys.identity_public_key.key_type = KeyType::ECDSA_HASH160; - keys.identity_public_key.data = ripemd160_sha256(&keys.identity_public_key.data); + keys.identity_public_key.data = + BinaryData::new(ripemd160_sha256(keys.identity_public_key.data.as_slice())); st.sign(&keys.identity_public_key, &keys.ec_private, &bls) .unwrap(); @@ -460,7 +461,7 @@ mod test { let mut rng = dashcore::secp256k1::rand::thread_rng(); let (_, public_key) = secp.generate_keypair(&mut rng); - keys.identity_public_key.data = public_key.serialize().to_vec(); + keys.identity_public_key.data = BinaryData::new(public_key.serialize().to_vec()); let sign_result = st.sign(&keys.identity_public_key, &keys.ec_private, &bls); assert_error_contains!(sign_result, "Invalid signature public key"); @@ -514,7 +515,7 @@ mod test { let mut st = get_mock_state_transition(); let mut keys = get_test_keys(); keys.identity_public_key.key_type = KeyType::BLS12_381; - keys.identity_public_key.data = keys.bls_public.clone(); + keys.identity_public_key.data = BinaryData::new(keys.bls_public.clone()); st.sign(&keys.identity_public_key, &keys.bls_private, &bls) .expect("validation should be successful"); @@ -543,7 +544,7 @@ mod test { let st = get_mock_state_transition(); let mut keys = get_test_keys(); keys.identity_public_key.key_type = KeyType::BLS12_381; - keys.identity_public_key.data = keys.bls_public.clone(); + keys.identity_public_key.data = BinaryData::new(keys.bls_public.clone()); let verify_error = st .verify_signature(&keys.identity_public_key, &bls) diff --git a/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs index dd2f4e5e53b..9590f17829d 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs @@ -8,6 +8,8 @@ use crate::{ tests::utils::generate_random_identifier_struct, version::LATEST_VERSION, }; +use platform_value::string_encoding::Encoding; +use platform_value::BinaryData; pub fn get_identity_update_transition_fixture() -> IdentityUpdateTransition { IdentityUpdateTransition { @@ -20,9 +22,13 @@ pub fn get_identity_update_transition_fixture() -> IdentityUpdateTransition { key_type: KeyType::ECDSA_SECP256K1, purpose: Purpose::AUTHENTICATION, read_only: false, - data: base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap(), + data: BinaryData::from_string( + "AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH", + Encoding::Base64, + ) + .unwrap(), security_level: SecurityLevel::MASTER, - signature: vec![0; 65], + signature: BinaryData::new(vec![0; 65]), }], disable_public_keys: vec![0], public_keys_disabled_at: Some(1234567), diff --git a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs index aa35afc01d1..8325315632d 100644 --- a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs +++ b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs @@ -26,7 +26,7 @@ mod from_raw_object { assert_eq!(public_key.security_level, SecurityLevel::MASTER); assert!(!public_key.read_only); assert_eq!( - public_key.data, + public_key.data.to_vec(), [ 2, 234, 242, 34, 227, 45, 70, 185, 127, 86, 248, 144, 187, 34, 195, 214, 94, 39, 155, 24, 189, 162, 3, 243, 11, 210, 211, 238, 215, 105, 163, 71, 98 @@ -97,7 +97,7 @@ mod from_raw_object { assert_eq!(public_key.security_level, SecurityLevel::MASTER); assert!(!public_key.read_only); assert_eq!( - public_key.data, + public_key.data.to_vec(), [ 2, 234, 242, 34, 227, 45, 70, 185, 127, 86, 248, 144, 187, 34, 195, 214, 94, 39, 155, 24, 189, 162, 3, 243, 11, 210, 211, 238, 215, 105, 163, 71, 98 diff --git a/packages/rs-dpp/src/tests/identity/identity_spec.rs b/packages/rs-dpp/src/tests/identity/identity_spec.rs index b3c08e9abdb..1747aa1b02f 100644 --- a/packages/rs-dpp/src/tests/identity/identity_spec.rs +++ b/packages/rs-dpp/src/tests/identity/identity_spec.rs @@ -170,6 +170,7 @@ mod api { prelude::IdentityPublicKey, tests::fixtures::identity_fixture, }; + use platform_value::BinaryData; #[test] fn should_get_biggest_public_key_id() { @@ -178,7 +179,7 @@ mod api { let identity_public_key_1 = IdentityPublicKey { id: 99, key_type: crate::identity::KeyType::ECDSA_SECP256K1, - data: vec![97_u8, 36], + data: BinaryData::new(vec![97_u8, 36]), purpose: Purpose::AUTHENTICATION, security_level: SecurityLevel::MASTER, read_only: false, @@ -187,7 +188,7 @@ mod api { let identity_public_key_2 = IdentityPublicKey { id: 50, key_type: crate::identity::KeyType::ECDSA_SECP256K1, - data: vec![97_u8, 36], + data: BinaryData::new(vec![97_u8, 36]), purpose: Purpose::AUTHENTICATION, security_level: SecurityLevel::MASTER, read_only: false, diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index ddb2d4b0a32..c3e69b983ec 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -82,7 +82,7 @@ fn set_public_keys_to_add() { purpose: Purpose::AUTHENTICATION, security_level : SecurityLevel::CRITICAL, read_only: true, - data: hex::decode("01fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694").unwrap(), + data: BinaryData::new(hex::decode("01fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694").unwrap()), signature : Default::default(), }; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs index 0b8f1a4e4ac..04c1f419cdd 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs @@ -25,7 +25,7 @@ use crate::{ NativeBlsModule, NonConsensusError, }; use jsonschema::error::ValidationErrorKind; -use platform_value::{platform_value, Value}; +use platform_value::{platform_value, BinaryData, Value}; use serde_json::Value as JsonValue; use std::{convert::TryInto, sync::Arc}; use test_case::test_case; @@ -72,7 +72,7 @@ fn setup_test() -> TestData { key_type: KeyType::ECDSA_SECP256K1, purpose: Purpose::AUTHENTICATION, security_level: SecurityLevel::MASTER, - data: ec_public_key.try_into().unwrap(), + data: BinaryData::new(ec_public_key.try_into().unwrap()), read_only: false, disabled_at: None, }; diff --git a/packages/rs-platform-value/src/types/binary_data.rs b/packages/rs-platform-value/src/types/binary_data.rs index 76fc000922f..04780205a05 100644 --- a/packages/rs-platform-value/src/types/binary_data.rs +++ b/packages/rs-platform-value/src/types/binary_data.rs @@ -1,8 +1,11 @@ use std::fmt; use serde::{Deserialize, Serialize}; use serde::de::Visitor; +use crate::{Error, string_encoding, Value}; +use crate::string_encoding::Encoding; +use crate::types::encoding_string_to_encoding; -#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)] +#[derive(Default, Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] pub struct BinaryData(pub Vec); impl Serialize for BinaryData { @@ -83,6 +86,35 @@ impl BinaryData { pub fn is_empty(&self) -> bool { self.0.is_empty() } + + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn from_string(encoded_value: &str, encoding: Encoding) -> Result { + let vec = string_encoding::decode(encoded_value, encoding)?; + + Ok(BinaryData::new(vec)) + } + + pub fn from_string_with_encoding_string( + encoded_value: &str, + encoding_string: Option<&str>, + ) -> Result { + let encoding = encoding_string_to_encoding(encoding_string); + + BinaryData::from_string(encoded_value, encoding) + } + + pub fn to_string(&self, encoding: Encoding) -> String { + string_encoding::encode(&self.0, encoding) + } + + pub fn to_string_with_encoding_string(&self, encoding_string: Option<&str>) -> String { + let encoding = encoding_string_to_encoding(encoding_string); + + self.to_string(encoding) + } } impl From> for BinaryData { @@ -91,6 +123,55 @@ impl From> for BinaryData { } } + +impl TryFrom for BinaryData { + type Error = Error; + + fn try_from(value: Value) -> Result { + value.into_binary_data() + } +} + +impl TryFrom<&Value> for BinaryData { + type Error = Error; + + fn try_from(value: &Value) -> Result { + value.to_binary_data() + } +} + +impl From for Value { + fn from(value: BinaryData) -> Self { + Value::Bytes(value.0) + } +} + +impl From<&BinaryData> for Value { + fn from(value: &BinaryData) -> Self { + Value::Bytes(value.to_vec()) + } +} + +impl TryFrom for BinaryData { + type Error = Error; + + fn try_from(data: String) -> Result { + Self::from_string(&data, Encoding::Base64) + } +} + +impl Into for BinaryData { + fn into(self) -> String { + self.to_string(Encoding::Base64) + } +} + +impl Into for &BinaryData { + fn into(self) -> String { + self.to_string(Encoding::Base64) + } +} + impl PartialEq<&[u8]> for BinaryData { fn eq(&self, other: &&[u8]) -> bool { self.as_slice() == *other @@ -109,6 +190,12 @@ impl PartialEq> for BinaryData { } } +impl PartialEq for Vec { + fn eq(&self, other: &BinaryData) -> bool { + other.as_slice() == self + } +} + #[cfg(test)] mod tests { use std::collections::HashMap; diff --git a/packages/rs-platform-value/src/types/bytes_32.rs b/packages/rs-platform-value/src/types/bytes_32.rs index 98795d4f503..1fe18657022 100644 --- a/packages/rs-platform-value/src/types/bytes_32.rs +++ b/packages/rs-platform-value/src/types/bytes_32.rs @@ -6,7 +6,7 @@ use crate::{Error, string_encoding, Value}; use crate::string_encoding::Encoding; use crate::types::encoding_string_to_encoding; -#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy)] +#[derive(Default, Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Copy)] pub struct Bytes32(pub [u8; 32]); impl Bytes32 { diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 0cc9a6b0c4d..3fd8180d45e 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -13,10 +13,10 @@ use crate::types::encoding_string_to_encoding; pub const IDENTIFIER_MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; -#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy)] +#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Copy)] pub struct IdentifierBytes32(pub [u8; 32]); -#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Copy, Serialize, Deserialize)] +#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Copy, Serialize, Deserialize)] pub struct Identifier(pub IdentifierBytes32); impl Serialize for IdentifierBytes32 { From b32c0229ba135abe7591e268462f21de688fbd1c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 18:55:17 +0700 Subject: [PATCH 135/228] more fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 4 +-- .../src/data_contract/extra/drive_api.rs | 5 ++++ .../src/data_contract/serialization/cbor.rs | 12 ++++---- .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- .../validate_data_contract_max_depth.rs | 11 +++++-- .../rs-dpp/src/document/document_factory.rs | 4 +-- .../rs-dpp/src/document/document_validator.rs | 11 ++++++- .../rs-dpp/src/document/extended_document.rs | 29 +++++++------------ .../document_create_transition.rs | 4 +-- .../document_replace_transition.rs | 4 +-- .../documents_batch_transition/mod.rs | 3 +- .../src/identity/identity_public_key/mod.rs | 9 +++--- ...ty_credit_withdrawal_transition_factory.rs | 4 +-- .../identity_public_key_transitions.rs | 25 +++++----------- .../identity_update_transition.rs | 2 +- .../abstract_state_transition.rs | 2 -- .../src/tests/fixtures/identity_fixture.rs | 5 ++-- .../identity_update_transition_spec.rs | 18 ++++++------ .../validation/public_keys_validator_spec.rs | 2 +- .../btreemap_field_replacement.rs | 16 ++++++++-- packages/rs-platform-value/src/inner_value.rs | 11 +++++++ packages/rs-platform-value/src/macros.rs | 1 - .../src/value_serialization/ser.rs | 4 --- 24 files changed, 105 insertions(+), 85 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index dd4caad6526..5c68dc86e3b 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -414,7 +414,7 @@ impl DataContract { None => (HashSet::new(), HashSet::new()), Some(binary_properties) => binary_properties.iter().partition_map(|(path, v)| { if let Some(JsonValue::String(content_type)) = v.get("contentMediaType") { - if content_type == identifier::MEDIA_TYPE { + if content_type == platform_value::IDENTIFIER_MEDIA_TYPE { Either::Right(path.clone()) } else { Either::Left(path.clone()) @@ -865,6 +865,6 @@ mod test { let serialized = data_contract.to_buffer().unwrap(); - assert_eq!(data_contract_cbor, serialized); + assert_eq!(hex::encode(data_contract_cbor), hex::encode(serialized)); } } diff --git a/packages/rs-dpp/src/data_contract/extra/drive_api.rs b/packages/rs-dpp/src/data_contract/extra/drive_api.rs index 46f76da7b8e..26bbb7c23bf 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -58,6 +58,7 @@ pub trait DriveContractExt { &self, document_type_name: &str, ) -> Result<&DocumentType, ProtocolError>; + fn has_document_type_for_name(&self, document_type_name: &str) -> bool; } impl DriveContractExt for DataContract { @@ -181,6 +182,10 @@ impl DriveContractExt for DataContract { )) }) } + + fn has_document_type_for_name(&self, document_type_name: &str) -> bool { + self.document_types.get(document_type_name).is_some() + } } #[cfg(test)] diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index 22839a77ed3..f352c370a96 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -101,11 +101,13 @@ impl DataContract { contract_cbor_map.insert(property_names::DOCUMENTS, docs); - contract_cbor_map.insert( - property_names::DEFINITIONS, - CborValue::serialized(&self.defs) - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?, - ); + if !self.defs.is_empty() { + contract_cbor_map.insert( + property_names::DEFINITIONS, + CborValue::serialized(&self.defs) + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?, + ); + } Ok(contract_cbor_map) } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 690c716ab92..357609143ca 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -16,7 +16,6 @@ use crate::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::json_value::JsonValueExt, ProtocolError, }; @@ -223,6 +222,7 @@ mod test { use integer_encoding::VarInt; use crate::tests::fixtures::get_data_contract_fixture; + use crate::util::json_value::JsonValueExt; use crate::version; use super::*; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index e8a907231dd..158ad6e5a60 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -15,7 +15,6 @@ use crate::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::json_value::JsonValueExt, ProtocolError, }; @@ -205,6 +204,7 @@ impl StateTransitionConvert for DataContractUpdateTransition { #[cfg(test)] mod test { + use crate::util::json_value::JsonValueExt; use integer_encoding::VarInt; use std::convert::TryInto; diff --git a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs index fd28ec30fde..dae02556bd0 100644 --- a/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs +++ b/packages/rs-dpp/src/data_contract/validation/validate_data_contract_max_depth.rs @@ -196,7 +196,11 @@ mod test { let result = calc_max_depth(&schema); let err = get_ref_error(result); - assert!(err.ref_error().starts_with("invalid ref '#/$defs/object'")); + assert_eq!( + err.ref_error(), + "invalid ref for max depth '#/$defs/object': value error: structure error: unable to get property $defs in $defs.object" + .to_string() + ); } #[test] @@ -224,7 +228,7 @@ mod test { let err = get_ref_error(result); assert_eq!( err.ref_error(), - "invalid ref 'https://json-schema.org/some': only local references are allowed" + "invalid ref for max depth 'https://json-schema.org/some': Generic Error: only local references are allowed" .to_string() ); } @@ -254,7 +258,8 @@ mod test { let err = get_ref_error(result); assert_eq!( err.ref_error(), - "invalid ref '': only local references are allowed".to_string() + "invalid ref for max depth '': Generic Error: only local references are allowed" + .to_string() ); } diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 55acf9b5329..8003c084e73 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -4,7 +4,7 @@ use std::collections::BTreeMap; use itertools::Itertools; -use platform_value::Value; +use platform_value::{Bytes32, Value}; use rand::rngs::StdRng; use rand::SeedableRng; use serde::{Deserialize, Serialize}; @@ -172,7 +172,7 @@ where document, data_contract, metadata: None, - entropy: document_entropy, + entropy: Bytes32::new(document_entropy), }; // if !validation_result.is_valid() { diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 7404cf36e7d..ebe21bd49b9 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -5,6 +5,7 @@ use lazy_static::lazy_static; use platform_value::Value; use serde_json::Value as JsonValue; +use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::data_contract::document_type::DocumentType; use crate::data_contract::DriveContractExt; use crate::{ @@ -94,7 +95,15 @@ impl DocumentValidator { }; // check if there is a document type - data_contract.document_type_for_name(document_type_name)?; + if !data_contract.has_document_type_for_name(document_type_name) { + result.add_error(BasicError::InvalidDocumentTypeError( + InvalidDocumentTypeError::new( + document_type_name.to_owned(), + data_contract.id.to_owned(), + ), + )); + return Ok(result); + } let enriched_data_contract = enrich_data_contract_with_base_schema( data_contract, diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 40d1ead714f..1c8f4cb3cfb 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -18,7 +18,7 @@ use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::converter::serde_json::BTreeValueJsonConverter; -use platform_value::{ReplacementType, Value}; +use platform_value::{Bytes32, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; use std::collections::{BTreeMap, HashSet}; @@ -58,7 +58,7 @@ pub struct ExtendedDocument { pub metadata: Option, #[serde(skip)] //todo: make entropy optional - pub entropy: [u8; 32], + pub entropy: Bytes32, } impl ExtendedDocument { @@ -192,11 +192,9 @@ impl ExtendedDocument { .remove_optional_integer(property_names::PROTOCOL_VERSION) .map_err(ProtocolError::ValueError)? .unwrap_or(PROTOCOL_VERSION); - extended_document.data_contract_id = Identifier::new( - properties - .remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? - .unwrap_or(extended_document.data_contract.id.to_buffer()), - ); + extended_document.data_contract_id = properties + .remove_optional_identifier(property_names::DATA_CONTRACT_ID)? + .unwrap_or(extended_document.data_contract.id); extended_document.document = Document::from_map(properties, None, None)?; extended_document @@ -377,11 +375,6 @@ impl ExtendedDocument { self.properties().get_optional_at_path(path).ok().flatten() } - /// Get entropy - pub fn get_entropy(&self) -> &[u8] { - &self.entropy - } - pub fn get_identifiers_and_binary_paths( &self, ) -> Result<(HashSet<&str>, HashSet<&str>), ProtocolError> { @@ -475,15 +468,15 @@ mod test { let test_document_properties_alpha_identifier = Value::from([ ("type", Value::Text("array".to_string())), ("byteArray", Value::Bool(true)), - ]); - let test_document_properties_alpha_binary = Value::from([ - ("type", Value::Text("array".to_string())), - ("byteArray", Value::Bool(true)), ( "contentMediaType", Value::Text("application/x.dash.dpp.identifier".to_string()), ), ]); + let test_document_properties_alpha_binary = Value::from([ + ("type", Value::Text("array".to_string())), + ("byteArray", Value::Bool(true)), + ]); let test_document_properties = Value::from([ ("alphaIdentifier", test_document_properties_alpha_identifier), ("alphaBinary", test_document_properties_alpha_binary), @@ -495,7 +488,7 @@ mod test { ("$id", Value::Identifier([0_u8; 32])), ("$schema", Value::Text("schema".to_string())), ("version", Value::U32(0)), - ("$ownerId", Value::Identifier([0_u8; 32])), + ("ownerId", Value::Identifier([0_u8; 32])), ("documents", documents), ]) .try_into() @@ -670,7 +663,7 @@ mod test { "$ownerId" : owner_id, "$type" : "test", "$dataContractId" : data_contract_id, - "revision" : 1, + "$revision" : 1, "alphaBinary" : alpha_value, "alphaIdentifier" : alpha_value, }); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index e377bcf0a4c..f991db49300 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,7 +1,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::{ReplacementType, Value}; +use platform_value::{Bytes32, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; @@ -88,7 +88,7 @@ impl DocumentCreateTransition { document: self.to_document(owner_id)?, data_contract: self.base.data_contract.clone(), metadata: None, - entropy: self.entropy, + entropy: Bytes32::new(self.entropy), }) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 574f6bbe4bd..9e04d5c2483 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -1,6 +1,6 @@ use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; -use platform_value::{ReplacementType, Value}; +use platform_value::{Bytes32, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; @@ -63,7 +63,7 @@ impl DocumentReplaceTransition { document: self.to_document_for_dry_run(owner_id)?, data_contract: self.base.data_contract.clone(), metadata: None, - entropy: [0; 32], + entropy: Bytes32::default(), }) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 972f80f4415..140294b87db 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -497,6 +497,7 @@ pub fn get_security_level_requirement(v: &JsonValue, default: SecurityLevel) -> mod test { use std::sync::Arc; + use platform_value::Bytes32; use serde_json::json; use crate::tests::fixtures::get_extended_documents_fixture; @@ -612,7 +613,7 @@ mod test { let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); let mut document = documents.first().unwrap().to_owned(); - document.entropy = entropy_bytes; + document.entropy = Bytes32::new(entropy_bytes); let transitions = get_document_transitions_fixture([(Action::Create, vec![document])]); let mut transition = transitions.first().unwrap().to_owned(); diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index 58f8e2524d2..de58e5c0bde 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -11,7 +11,7 @@ use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; use ciborium::value::Value as CborValue; use dashcore::PublicKey as ECDSAPublicKey; -use platform_value::{BinaryData, Value}; +use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; @@ -120,10 +120,9 @@ impl IdentityPublicKey { } pub fn from_json_object(mut raw_object: JsonValue) -> Result { - raw_object.replace_binary_paths(BINARY_DATA_FIELDS, ReplaceWith::Bytes)?; - let identity_public_key: IdentityPublicKey = serde_json::from_value(raw_object)?; - - Ok(identity_public_key) + let mut value: Value = raw_object.into(); + value.replace_at_paths(BINARY_DATA_FIELDS, ReplacementType::BinaryBytes)?; + Self::from_value(value) } /// Return raw data, with all binary fields represented as arrays diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs index 3db89412adc..e45394649e8 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs @@ -4,7 +4,7 @@ use lazy_static::__Deref; use std::collections::BTreeMap; use std::convert::TryInto; -use platform_value::Value; +use platform_value::{Bytes32, Value}; use serde_json::json; use crate::contracts::withdrawals_contract::property_names; @@ -135,7 +135,7 @@ where document: withdrawal_document, data_contract: withdrawals_data_contract, metadata: None, - entropy: [0; 32], + entropy: Bytes32::default(), }; self.state_repository diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 0522ad257f6..d6f83f3c0bb 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -125,26 +125,15 @@ impl IdentityPublicKeyWithWitness { /// Return raw data, with all binary fields represented as arrays pub fn to_raw_object(&self, skip_signature: bool) -> Result { - let mut map = BTreeMap::from([ - ("id".to_string(), Value::U32(self.id)), - ("purpose".to_string(), Value::U8(self.purpose as u8)), - ( - "securityLevel".to_string(), - Value::U8(self.security_level as u8), - ), - ("keyType".to_string(), Value::U8(self.key_type as u8)), - ("data".to_string(), Value::Bytes(self.data.to_vec())), - ("readOnly".to_string(), Value::Bool(self.read_only)), - ]); - - if !skip_signature && !self.signature.is_empty() { - map.insert( - "signature".to_string(), - Value::Bytes(self.signature.to_vec()), - ); + let mut value = platform_value::to_value(self)?; + + if skip_signature || self.signature.is_empty() { + value + .remove("signature") + .map_err(ProtocolError::ValueError)?; } - Ok(map.into()) + Ok(value) } /// Return raw data, with all binary fields represented as arrays diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 8bf9c594db8..ef7b724cecc 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -258,7 +258,7 @@ impl StateTransitionConvert for IdentityUpdateTransition { let mut raw_object: Value = state_transition_helpers::to_object(self, skip_signature_paths)?; - raw_object.insert( + raw_object.insert_at_end( property_names::ADD_PUBLIC_KEYS.to_owned(), Value::Array(add_public_keys), )?; diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 814788ea059..0be451d4ff9 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -212,8 +212,6 @@ pub trait StateTransitionConvert: Serialize { let mut value = self.to_object(skip_signature)?; let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; - value.as_map_mut_ref().unwrap().sort_by_keys(); - serializer::serializable_value_to_cbor(&value, Some(protocol_version)) } diff --git a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs index 0451e10e6c7..7987dddd34b 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs @@ -1,5 +1,6 @@ use platform_value::platform_value; use platform_value::string_encoding::{decode, Encoding}; +use platform_value::BinaryData; use serde_json::json; use crate::prelude::{Identifier, Identity}; @@ -17,7 +18,7 @@ pub fn identity_fixture_raw_object() -> platform_value::Value { "type": 0u8, "purpose": 0u8, "securityLevel": 0u8, - "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), + "data": BinaryData::from_string("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), "readOnly": false }, { @@ -25,7 +26,7 @@ pub fn identity_fixture_raw_object() -> platform_value::Value { "type": 0u8, "purpose": 1u8, "securityLevel": 3u8, - "data": decode("A8AK95PYMVX5VQKzOhcVQRCUbc9pyg3RiL7jttEMDU+L", Encoding::Base64).unwrap(), + "data": BinaryData::from_string("A8AK95PYMVX5VQKzOhcVQRCUbc9pyg3RiL7jttEMDU+L", Encoding::Base64).unwrap(), "readOnly": false } ], diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index c3e69b983ec..a0ccec06d39 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -137,10 +137,10 @@ fn to_object() { let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1u32, "type" : 5u8, - "signature" : [], + "signature" : BinaryData::default(), "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id, - "revision": 0u8, + "revision": 0 as Revision, "disablePublicKeys" : [0u32], "publicKeysDisabledAt" : 1234567u64, "addPublicKeys" : [ @@ -148,11 +148,11 @@ fn to_object() { "id" : 3u32, "purpose" : 0u8, - "type": 0u8, "securityLevel" : 0u8, - "data" :base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap(), + "type": 0u8, + "data" :BinaryData::new(base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap()), "readOnly" : false, - "signature" : vec![0u8;65] + "signature" : BinaryData::new(vec![0u8;65]) } ] }); @@ -180,9 +180,9 @@ fn to_object_with_signature_skipped() { "id" : 3u32, "purpose" : 0u8, - "type": 0u8, "securityLevel" : 0u8, - "data" :BinaryData(base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap()), + "type": 0u8, + "data" :BinaryData::new(base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap()), "readOnly" : false, } ] @@ -201,7 +201,7 @@ fn to_json() { let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1u32, "type" : 5u8, - "signature" : Vec::::new(), + "signature" : BinaryData::default(), "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id, "revision": 0 as Revision, @@ -212,8 +212,8 @@ fn to_json() { "id" : 3u32, "purpose" : 0u8, - "type": 0u8, "securityLevel" : 0u8, + "type": 0u8, "data" : BinaryData::new(base64::decode("AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH").unwrap()), "readOnly" : false, "signature" : BinaryData::new(vec![0;65]), diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index b53b3e746c6..12db8fc54cf 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -387,7 +387,7 @@ pub fn should_return_invalid_result_if_key_data_is_not_a_valid_der() { raw_public_keys .get_mut(1) .unwrap() - .set_into_value("data", vec![0; 33]) + .set_into_binary_data("data", vec![0; 33]) .expect("expected to set data"); let result = validator.validate_keys(&raw_public_keys).unwrap(); diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs index 245b218655b..5f3773c9377 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs @@ -80,7 +80,13 @@ fn replace_down( *new_value = replacement_type.replace_for_bytes_32(*bytes)?; } _ => { - let bytes = new_value.to_identifier_bytes()?; + let bytes = match replacement_type { + ReplacementType::Identifier + | ReplacementType::IdentifierBytes + | ReplacementType::TextBase58 => new_value.to_identifier_bytes(), + ReplacementType::BinaryBytes + | ReplacementType::TextBase64 => new_value.to_binary_bytes(), + }?; *new_value = replacement_type.replace_for_bytes(bytes)?; } } @@ -127,7 +133,13 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { *current_value = replacement_type.replace_for_bytes_32(*bytes)?; } _ => { - let bytes = current_value.to_identifier_bytes()?; + let bytes = match replacement_type { + ReplacementType::Identifier + | ReplacementType::IdentifierBytes + | ReplacementType::TextBase58 => current_value.to_identifier_bytes(), + ReplacementType::BinaryBytes + | ReplacementType::TextBase64 => current_value.to_binary_bytes(), + }?; *current_value = replacement_type.replace_for_bytes(bytes)?; } } diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 3bb5c94586d..283a73ed03f 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -48,6 +48,12 @@ impl Value { Ok(Self::insert_in_map(map, key, value.into())) } + pub fn set_into_binary_data(&mut self, key: &str, value: Vec) -> Result<(), Error> + { + let map = self.as_map_mut_ref()?; + Ok(Self::insert_in_map(map, key, Value::Bytes(value))) + } + pub fn set_value(&mut self, key: &str, value: Value) -> Result<(), Error> { let map = self.as_map_mut_ref()?; Ok(Self::insert_in_map(map, key, value)) @@ -58,6 +64,11 @@ impl Value { Ok(Self::insert_in_map_string_value(map, key, value)) } + pub fn insert_at_end(&mut self, key: String, value: Value) -> Result<(), Error> { + let map = self.as_map_mut_ref()?; + Ok(Self::push_to_map_string_value(map, key, value)) + } + pub fn remove(&mut self, key: &str) -> Result { let map = self.as_map_mut_ref()?; map.remove_key(key) diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index a0243a4e384..c4002f7d54e 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -264,7 +264,6 @@ macro_rules! platform_value_internal { use platform_value::ValueMapHelper; let mut object = $crate::ValueMap::new(); platform_value_internal!(@object object () ($($tt)+) ($($tt)+)); - object.sort_by_keys(); object }) }; diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index 4481dce5c69..5d17d7c5cbe 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -248,10 +248,6 @@ impl serde::Serializer for Serializer { fn serialize_tuple(self, len: usize) -> Result { self.serialize_seq(Some(len)) - // Ok(SerializeSizedVec { - // size: len, - // vec: Vec::with_capacity(len), - // }) } fn serialize_tuple_struct( From a87a8c621ea39b87e41da5a53ed55dcfca05aade Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 19:26:09 +0700 Subject: [PATCH 136/228] more fixes --- ...ed_purpose_and_security_level_validator.rs | 4 +- .../abstract_state_transition.rs | 50 ++++++++++--------- ...stract_state_transition_identity_signed.rs | 2 +- .../identity_create_transition_fixture.rs | 46 +++++++---------- ..._create_transition_basic_validator_spec.rs | 1 - 5 files changed, 48 insertions(+), 55 deletions(-) diff --git a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs index 774fc06280e..510fbc2c4ae 100644 --- a/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs +++ b/packages/rs-dpp/src/identity/validation/required_purpose_and_security_level_validator.rs @@ -32,8 +32,8 @@ impl TPublicKeysValidator for RequiredPurposeAndSecurityLevelValidator { .get_optional_integer::("disabledAt") .map_err(NonConsensusError::ValueError) { - Ok(Some(_)) => Some(Ok(pk)), - Ok(None) => None, + Ok(Some(_)) => None, + Ok(None) => Some(Ok(pk)), Err(e) => Some(Err(e)), } }) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 0be451d4ff9..9b4f035dcbe 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -195,21 +195,35 @@ pub trait StateTransitionConvert: Serialize { state_transition_helpers::to_object(self, skip_signature_paths) } + /// Returns the [`platform_value::Value`] instance that preserves the `Vec` representation + /// for Identifiers and binary data + fn to_canonical_object(&self, skip_signature: bool) -> Result { + let skip_signature_paths = if skip_signature { + Self::signature_property_paths() + } else { + vec![] + }; + let mut object = state_transition_helpers::to_object(self, skip_signature_paths)?; + + object.as_map_mut_ref().unwrap().sort_by_keys(); + Ok(object) + } + /// Returns the [`serde_json::Value`] instance that encodes: /// - Identifiers - with base58 /// - Binary data - with base64 fn to_json(&self, skip_signature: bool) -> Result { - state_transition_helpers::to_json( - self, - Self::binary_property_paths(), - Self::signature_property_paths(), - skip_signature, - ) + let skip_signature_paths = if skip_signature { + Self::signature_property_paths() + } else { + vec![] + }; + state_transition_helpers::to_json(self, skip_signature_paths) } // Returns the cibor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { - let mut value = self.to_object(skip_signature)?; + let mut value = self.to_canonical_object(skip_signature)?; let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; serializer::serializable_value_to_cbor(&value, Some(protocol_version)) @@ -223,26 +237,14 @@ pub trait StateTransitionConvert: Serialize { pub mod state_transition_helpers { use super::*; + use std::convert::TryInto; - pub fn to_json<'a>( + pub fn to_json<'a, I: IntoIterator>( serializable: impl Serialize, - binary_property_paths: impl IntoIterator, - signature_property_paths: impl IntoIterator, - skip_signature: bool, + skip_signature_paths: I, ) -> Result { - let mut json_value: JsonValue = serde_json::to_value(serializable)?; - - if skip_signature { - if let JsonValue::Object(ref mut o) = json_value { - for path in signature_property_paths { - o.remove(path); - } - } - } - - json_value.replace_binary_paths(binary_property_paths, ReplaceWith::Base64)?; - - Ok(json_value) + to_object(serializable, skip_signature_paths) + .and_then(|v| v.try_into().map_err(ProtocolError::ValueError)) } pub fn to_object<'a, I: IntoIterator>( diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index aa4d584f09c..6ce30527690 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -405,7 +405,7 @@ mod test { let hash = st.to_buffer(false).unwrap(); let result = hex::encode(hash); - assert_eq!("01a4676f776e6572496458208d6e06cac6cd2c4b9020806a3f1a4ec48fc90defd314330a5ce7d8548dfc2524697369676e617475726580747369676e61747572655075626c69634b65794964016e7472616e736974696f6e5479706501", result.as_str()); + assert_eq!("01a4676f776e6572496458208d6e06cac6cd2c4b9020806a3f1a4ec48fc90defd314330a5ce7d8548dfc2524697369676e617475726540747369676e61747572655075626c69634b65794964016e7472616e736974696f6e5479706501", result.as_str()); } #[test] diff --git a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs index 7e45ee31314..e86430dcf1e 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs @@ -1,7 +1,8 @@ use std::convert::TryInto; use dashcore::PrivateKey; -use platform_value::Value; +use platform_value::BinaryData; +use platform_value::{platform_value, Value}; use crate::identity::{KeyType, Purpose, SecurityLevel}; use crate::tests::fixtures::instant_asset_lock_proof_fixture; @@ -13,31 +14,22 @@ use platform_value::string_encoding::{decode, Encoding}; pub fn identity_create_transition_fixture_json(one_time_private_key: Option) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); - let public_keys = vec![Value::from([ - ("id", Value::U32(0)), - ("type", Value::U8(2)), - ( - "data", - Value::Bytes( - decode( - "AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", - Encoding::Base64, - ) - .unwrap(), - ), - ), - ("purpose", Value::U8(Purpose::AUTHENTICATION as u8)), - ("keyType", Value::U8(KeyType::ECDSA_SECP256K1 as u8)), - ("securityLevel", Value::U8(SecurityLevel::MASTER as u8)), - ("readOnly", Value::Bool(false)), - ("signature", Value::Bytes(vec![0_u8; 65])), - ])]; - Value::from([ - ("protocolVersion", Value::U32(version::LATEST_VERSION)), - ("type", Value::U8(2)), - ("assetLockProof", asset_lock_proof.try_into().unwrap()), - ("publicKeys", Value::Array(public_keys)), - ("signature", Value::Bytes(vec![0_u8; 65])), - ]) + platform_value!({ + "protocolVersion": version::LATEST_VERSION as u32, + "type": 2u8, + "assetLockProof": asset_lock_proof, + "publicKeys": [ + { + "id": 0u32, + "type": KeyType::ECDSA_SECP256K1 as u8, + "data": BinaryData::new(decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap()), + "purpose": Purpose::AUTHENTICATION as u8, + "securityLevel": SecurityLevel::MASTER as u8, + "readOnly": false, + "signature": BinaryData::new(vec![0_u8; 65]) + }, + ], + "signature": BinaryData::new(vec![0_u8; 65]) + }) } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index 0b923adab31..cc83a7d0465 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -339,7 +339,6 @@ mod validate_identity_create_transition_basic_factory { .validate(&raw_state_transition, &Default::default()) .await .unwrap(); - let errors = assert_consensus_errors!(result, ConsensusError::JsonSchemaError, 1); let error = errors.first().unwrap(); From 822ab2392d547637e8d0e4d8d8624f96a967a7de Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 19:54:47 +0700 Subject: [PATCH 137/228] more work --- .../document_type/document_factory.rs | 4 +-- .../document_type/random_document.rs | 9 ++--- packages/rs-dpp/src/document/document.rs | 36 ++++++++----------- .../rs-dpp/src/document/document_factory.rs | 16 ++++----- .../rs-dpp/src/document/extended_document.rs | 18 ++++++---- packages/rs-dpp/src/document/serialize.rs | 18 +++++----- ...pply_documents_batch_transition_factory.rs | 8 ++--- .../document_create_transition.rs | 12 +++---- .../document_replace_transition.rs | 4 +-- ...ty_credit_withdrawal_transition_factory.rs | 4 +-- .../identity_update_transition.rs | 15 ++++---- ...e_documents_batch_transition_state_spec.rs | 6 ++-- ..._documents_batch_transitions_basic_spec.rs | 5 +-- packages/rs-dpp/src/tests/utils/utils.rs | 6 ---- 14 files changed, 77 insertions(+), 84 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs index 618a6cf34ff..8cb5df87a82 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_factory.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_factory.rs @@ -38,8 +38,8 @@ impl DocumentType { }; Ok(Document { - id: id.to_buffer(), - owner_id: owner_id.to_buffer(), + id, + owner_id, properties, revision, created_at, diff --git a/packages/rs-dpp/src/data_contract/document_type/random_document.rs b/packages/rs-dpp/src/data_contract/document_type/random_document.rs index a42f79db18a..dd67f17d7b3 100644 --- a/packages/rs-dpp/src/data_contract/document_type/random_document.rs +++ b/packages/rs-dpp/src/data_contract/document_type/random_document.rs @@ -37,6 +37,7 @@ use crate::data_contract::document_type::property_names::{CREATED_AT, UPDATED_AT use crate::data_contract::document_type::DocumentType; use crate::document::Document; use crate::ProtocolError; +use platform_value::Identifier; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; @@ -96,8 +97,8 @@ impl CreateRandomDocument for DocumentType { /// Creates a document with a random id, owner id, and properties using StdRng. fn random_document_with_rng(&self, rng: &mut StdRng) -> Document { - let id = rng.gen::<[u8; 32]>(); - let owner_id = rng.gen::<[u8; 32]>(); + let id = Identifier::random(rng); + let owner_id = Identifier::random(rng); let mut created_at = None; let mut updated_at = None; let properties = self @@ -166,8 +167,8 @@ impl CreateRandomDocument for DocumentType { /// Creates a Document with properties filled to max size with random data, along with /// a random id and owner id. fn random_filled_document_with_rng(&self, rng: &mut StdRng) -> Document { - let id = rng.gen::<[u8; 32]>(); - let owner_id = rng.gen::<[u8; 32]>(); + let id = Identifier::random(rng); + let owner_id = Identifier::random(rng); let properties = self .properties .iter() diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 19caa7e0aa2..0dfa42d2906 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -77,12 +77,10 @@ pub struct Document { //todo: add an optional version /// The unique document ID. #[serde(rename = "$id")] - //todo: change to identifier once identifier serialized to bytes - pub id: [u8; 32], + pub id: Identifier, /// The ID of the document's owner. #[serde(rename = "$ownerId")] - //todo: change to identifier once identifier serialized to bytes - pub owner_id: [u8; 32], + pub owner_id: Identifier, /// The document's properties (data). #[serde(flatten)] pub properties: BTreeMap, @@ -109,8 +107,8 @@ impl Document { } else { match key_path { // returns self.id or self.owner_id if key path is $id or $ownerId - "$id" => return Ok(Some(Vec::from(self.id))), - "$ownerId" => return Ok(Some(Vec::from(self.owner_id))), + "$id" => return Ok(Some(self.id.to_buffer_vec())), + "$ownerId" => return Ok(Some(self.owner_id.to_buffer_vec())), "$createdAt" => { return Ok(self .created_at @@ -325,11 +323,8 @@ impl Document { pub fn to_map_value(&self) -> Result, ProtocolError> { let mut map: BTreeMap = BTreeMap::new(); - map.insert(property_names::ID.to_string(), Value::Identifier(self.id)); - map.insert( - property_names::OWNER_ID.to_string(), - Value::Identifier(self.owner_id), - ); + map.insert(property_names::ID.to_string(), self.id.into()); + map.insert(property_names::OWNER_ID.to_string(), self.owner_id.into()); if let Some(created_at) = self.created_at { map.insert( @@ -354,11 +349,8 @@ impl Document { pub fn into_map_value(self) -> Result, ProtocolError> { let mut map: BTreeMap = BTreeMap::new(); - map.insert(property_names::ID.to_string(), Value::Identifier(self.id)); - map.insert( - property_names::OWNER_ID.to_string(), - Value::Identifier(self.owner_id), - ); + map.insert(property_names::ID.to_string(), self.id.into()); + map.insert(property_names::OWNER_ID.to_string(), self.owner_id.into()); if let Some(created_at) = self.created_at { map.insert( @@ -452,11 +444,11 @@ impl Document { if let Ok(value) = document_value.remove(property_names::ID) { let data: S = serde_json::from_value(value)?; - document.id = data.try_into()?.to_buffer(); + document.id = data.try_into()?; } if let Ok(value) = document_value.remove(property_names::OWNER_ID) { let data: S = serde_json::from_value(value)?; - document.owner_id = data.try_into()?.to_buffer(); + document.owner_id = data.try_into()?; } if let Ok(value) = document_value.remove(property_names::REVISION) { document.revision = serde_json::from_value(value)? @@ -484,8 +476,8 @@ impl Document { ..Default::default() }; - document.id = properties.remove_hash256_bytes(property_names::ID)?; - document.owner_id = properties.remove_hash256_bytes(property_names::OWNER_ID)?; + document.id = properties.remove_identifier(property_names::ID)?; + document.owner_id = properties.remove_identifier(property_names::OWNER_ID)?; document.revision = properties.remove_optional_integer(property_names::REVISION)?; document.created_at = properties.remove_optional_integer(property_names::CREATED_AT)?; document.updated_at = properties.remove_optional_integer(property_names::UPDATED_AT)?; @@ -497,8 +489,8 @@ impl Document { impl fmt::Display for Document { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "id:{} ", bs58::encode(self.id).into_string())?; - write!(f, "owner_id:{} ", bs58::encode(self.owner_id).into_string())?; + write!(f, "id:{} ", self.id)?; + write!(f, "owner_id:{} ", self.owner_id)?; if let Some(created_at) = self.created_at { let naive = NaiveDateTime::from_timestamp_millis(created_at as i64).unwrap_or_default(); let datetime: DateTime = DateTime::from_utc(naive, Utc); diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 8003c084e73..04dda4d9f9f 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -150,8 +150,8 @@ where }; let document = Document { - id: document_id.to_buffer(), - owner_id: owner_id.to_buffer(), + id: document_id, + owner_id, properties: data .into_btree_string_map() .map_err(ProtocolError::ValueError)?, @@ -401,17 +401,14 @@ where .map(|document| { let mut map: BTreeMap = BTreeMap::new(); map.insert(PROPERTY_ACTION.to_string(), Value::U8(Action::Delete as u8)); - map.insert( - PROPERTY_ID.to_string(), - Value::Identifier(document.document.id), - ); + map.insert(PROPERTY_ID.to_string(), document.document.id.into()); map.insert( PROPERTY_TYPE.to_string(), Value::Text(document.document_type_name), ); map.insert( PROPERTY_DATA_CONTRACT_ID.to_string(), - Value::Identifier(document.data_contract_id.to_buffer()), + document.data_contract_id.into(), ); map.into() }) @@ -422,7 +419,7 @@ where data.into_iter().next().is_none() } - fn is_ownership_the_same<'a>(ids: impl IntoIterator) -> bool { + fn is_ownership_the_same<'a>(ids: impl IntoIterator) -> bool { ids.into_iter().all_equal() } } @@ -521,7 +518,8 @@ mod test { DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())), None, ); - documents[0].document.owner_id = generate_random_identifier_struct().to_buffer(); + + documents[0].document.owner_id = generate_random_identifier_struct(); let result = factory.create_state_transition(vec![(Action::Create, documents)]); assert_error_contains!(result, "Documents have mixed owner ids") diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 1c8f4cb3cfb..fd72bf465c0 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -82,11 +82,11 @@ impl ExtendedDocument { } pub fn id(&self) -> Identifier { - Identifier::new(self.document.id) + self.document.id } pub fn owner_id(&self) -> Identifier { - Identifier::new(self.document.owner_id) + self.document.owner_id } pub fn document_type(&self) -> Result<&DocumentType, ProtocolError> { @@ -532,7 +532,13 @@ mod test { doc.properties() .get_at_path("records.dashUniqueIdentityId") .expect("expected to get value"), - &Value::Text("HBNMY5QWuBVKNFLhgBTC1VmpEnscrmqKPMXpnYSHwhfn".to_string()) + &Value::Identifier( + bs58::decode("HBNMY5QWuBVKNFLhgBTC1VmpEnscrmqKPMXpnYSHwhfn") + .into_vec() + .unwrap() + .try_into() + .unwrap() + ) ); assert_eq!( doc.properties() @@ -701,13 +707,13 @@ mod test { fn new_example_document() -> ExtendedDocument { ExtendedDocument { document: Document { - id: generate_random_identifier(), - owner_id: generate_random_identifier(), + id: generate_random_identifier_struct(), + owner_id: generate_random_identifier_struct(), created_at: Some(1648013404492), updated_at: Some(1648013404492), ..Default::default() }, - data_contract_id: Identifier::from_bytes(&generate_random_identifier()).unwrap(), + data_contract_id: generate_random_identifier_struct(), ..Default::default() } } diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 8a645054b9a..350e5a51f94 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -17,7 +17,7 @@ use byteorder::{BigEndian, ReadBytesExt}; use ciborium::Value as CborValue; use integer_encoding::VarIntWriter; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::Value; +use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; use std::convert::TryFrom; @@ -61,10 +61,10 @@ impl TryFrom for DocumentForCbor { updated_at, } = value; Ok(DocumentForCbor { - id, + id: id.to_buffer(), properties: Value::convert_to_cbor_map(properties) .map_err(ProtocolError::ValueError)?, - owner_id, + owner_id: owner_id.to_buffer(), revision, created_at, updated_at, @@ -145,8 +145,8 @@ impl Document { mut self, document_type: &DocumentType, ) -> Result, ProtocolError> { - let mut buffer: Vec = Vec::try_from(self.id).unwrap(); - let mut owner_id = Vec::try_from(self.owner_id).unwrap(); + let mut buffer: Vec = self.id.to_buffer_vec(); + let mut owner_id = self.owner_id.to_buffer_vec(); buffer.append(&mut owner_id); if let Some(revision) = self.revision { @@ -314,9 +314,9 @@ impl Document { }) .collect::, ProtocolError>>()?; Ok(Document { - id, + id: Identifier::new(id), properties, - owner_id, + owner_id: Identifier::new(owner_id), revision, created_at, updated_at, @@ -378,8 +378,8 @@ impl Document { // dev-note: properties is everything other than the id and owner id Ok(Document { properties: document_map, - owner_id, - id, + owner_id: Identifier::new(owner_id), + id: Identifier::new(id), revision, created_at, updated_at, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 88a97697f47..2aebcdb712d 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -65,8 +65,8 @@ pub async fn apply_documents_batch_transition( for document_transition in state_transition.get_transitions() { match document_transition { DocumentTransition::Create(document_create_transition) => { - let document = document_create_transition - .to_extended_document(state_transition.owner_id.to_buffer())?; + let document = + document_create_transition.to_extended_document(state_transition.owner_id)?; //todo: eventually we should use Cow instead state_repository .create_document(&document, state_transition.get_execution_context()) @@ -124,8 +124,8 @@ fn document_from_transition_replace( data_contract: Default::default(), entropy: Default::default(), document: Document { - id: document_replace_transition.base.id.to_buffer(), - owner_id: state_transition.owner_id.to_buffer(), + id: document_replace_transition.base.id, + owner_id: state_transition.owner_id, properties: document_replace_transition.data.clone().unwrap_or_default(), revision: Some(document_replace_transition.revision), created_at: Some(created_at), diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index f991db49300..4aee23f804b 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -1,7 +1,7 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::{Bytes32, ReplacementType, Value}; +use platform_value::{Bytes32, Identifier, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; @@ -65,10 +65,10 @@ impl DocumentCreateTransition { Ok(()) } - pub(crate) fn to_document(&self, owner_id: [u8; 32]) -> Result { + pub(crate) fn to_document(&self, owner_id: Identifier) -> Result { let properties = self.data.clone().unwrap_or_default(); Ok(Document { - id: self.base.id.to_buffer(), + id: self.base.id, owner_id, properties, created_at: self.created_at, @@ -79,7 +79,7 @@ impl DocumentCreateTransition { pub(crate) fn to_extended_document( &self, - owner_id: [u8; 32], + owner_id: Identifier, ) -> Result { Ok(ExtendedDocument { protocol_version: PROTOCOL_VERSION, @@ -92,8 +92,8 @@ impl DocumentCreateTransition { }) } - pub(crate) fn into_document(self, owner_id: [u8; 32]) -> Result { - let id = self.base.id.to_buffer(); + pub(crate) fn into_document(self, owner_id: Identifier) -> Result { + let id = self.base.id; let revision = self.get_revision(); let created_at = self.created_at; let updated_at = self.updated_at; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 9e04d5c2483..26380fbdd6a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -43,8 +43,8 @@ impl DocumentReplaceTransition { ) -> Result { let properties = self.data.clone().unwrap_or_default(); Ok(Document { - id: self.base.id.to_buffer(), - owner_id: owner_id.to_buffer(), + id: self.base.id, + owner_id, properties, created_at: self.updated_at, // we can use the same time, as it can't be worse updated_at: self.updated_at, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs index e45394649e8..033c00518b9 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/apply_identity_credit_withdrawal_transition_factory.rs @@ -120,9 +120,9 @@ where } let withdrawal_document = Document { - id: document_id.to_buffer(), + id: document_id, revision: None, - owner_id: state_transition.identity_id.to_buffer(), + owner_id: state_transition.identity_id, created_at: Some(document_created_at_millis), updated_at: Some(document_created_at_millis), properties: document_properties, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index ef7b724cecc..b2bfed9e9a5 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -326,21 +326,20 @@ impl StateTransitionIdentitySigned for IdentityUpdateTransition { #[cfg(test)] mod test { - - use crate::tests::{ - fixtures::identity_fixture, - utils::{generate_random_identifier, generate_random_identifier_struct}, - }; + use crate::tests::{fixtures::identity_fixture, utils::generate_random_identifier_struct}; + use getrandom::getrandom; use super::*; #[test] fn conversion_to_json_object() { let public_key = identity_fixture().get_public_keys()[&0].to_owned(); + let mut buffer = [0u8; 33]; + let _ = getrandom(&mut buffer); let transition = IdentityUpdateTransition { identity_id: generate_random_identifier_struct(), add_public_keys: vec![(&public_key).into()], - signature: BinaryData::new(generate_random_identifier().to_vec()), + signature: BinaryData::new(buffer.to_vec()), ..Default::default() }; @@ -365,10 +364,12 @@ mod test { #[test] fn conversion_to_raw_object() { let public_key = identity_fixture().get_public_keys()[&0].to_owned(); + let mut buffer = [0u8; 33]; + let _ = getrandom(&mut buffer); let transition = IdentityUpdateTransition { identity_id: generate_random_identifier_struct(), add_public_keys: vec![(&public_key).into()], - signature: BinaryData::new(generate_random_identifier().to_vec()), + signature: BinaryData::new(buffer.to_vec()), ..Default::default() }; diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index d6e611a3240..95c8bfc7b6e 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -302,7 +302,7 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace ) .expect("document should be created"); let another_owner_id = generate_random_identifier_struct(); - fetched_document.document.owner_id = another_owner_id.to_buffer(); + fetched_document.document.owner_id = another_owner_id; let document_transitions = get_document_transitions_fixture([ (Action::Create, vec![]), @@ -613,8 +613,8 @@ async fn should_return_valid_result_if_document_transitions_are_valid() { let mut fetched_document_2 = extended_documents[2].clone(); fetched_document_1.document.revision = Some(1); fetched_document_2.document.revision = Some(1); - fetched_document_1.document.owner_id = owner_id.to_buffer(); - fetched_document_2.document.owner_id = owner_id.to_buffer(); + fetched_document_1.document.owner_id = owner_id; + fetched_document_2.document.owner_id = owner_id; state_repository_mock .expect_fetch_extended_documents() diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index e9ab0a850b2..0cf25d65329 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -15,7 +15,6 @@ use crate::{ get_protocol_version_validator_fixture, }, utils::{ - generate_random_identifier, get_schema_error, }, }, @@ -23,6 +22,7 @@ use crate::{ }; use crate::document::document_transition::document_base_transition::JsonValue; +use crate::tests::utils::generate_random_identifier_struct; use jsonschema::error::ValidationErrorKind; use platform_value::{platform_value, Value}; use test_case::test_case; @@ -671,7 +671,8 @@ async fn id_should_be_valid_generated_id() { .. } = setup_test(Action::Create); - raw_state_transition["transitions"][0]["$id"] = platform_value!(generate_random_identifier()); + raw_state_transition["transitions"][0]["$id"] = + platform_value!(generate_random_identifier_struct()); let result = validate_documents_batch_transition_basic( &protocol_version_validator, diff --git a/packages/rs-dpp/src/tests/utils/utils.rs b/packages/rs-dpp/src/tests/utils/utils.rs index e29b5b3de26..b84deb38fb5 100644 --- a/packages/rs-dpp/src/tests/utils/utils.rs +++ b/packages/rs-dpp/src/tests/utils/utils.rs @@ -27,12 +27,6 @@ macro_rules! assert_error_contains { }; } -pub fn generate_random_identifier() -> [u8; 32] { - let mut buffer = [0u8; 32]; - let _ = getrandom(&mut buffer); - buffer -} - /// Sets a key value pair in serde_json object, returns the modified object pub fn serde_set(mut object: serde_json::Value, key: T, value: S) -> serde_json::Value where From a4f318bef64802f2e70e0160ca6efd2fb7236d22 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 20:41:58 +0700 Subject: [PATCH 138/228] more fixes --- .../rs-dpp/src/document/extended_document.rs | 6 ++-- .../identity_create_transition.rs | 1 + .../identity_topup_transition.rs | 30 +++---------------- .../abstract_state_transition.rs | 3 +- .../src/value_serialization/de.rs | 25 ++++++++++++++-- .../src/value_serialization/ser.rs | 24 +++++++++++++-- 6 files changed, 53 insertions(+), 36 deletions(-) diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index fd72bf465c0..d36d51863c0 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -590,10 +590,10 @@ mod test { let dpns_contract = load_system_data_contract(SystemDataContract::DPNS)?; let document_json = get_data_from_file("src/tests/payloads/document_dpns.json")?; let document = ExtendedDocument::from_json_string(&document_json, dpns_contract)?; - let string = serde_json::to_string(&document)?; - //added this, not sure if we want this check - assert_eq!(document_json, string); + + assert_eq!("{\"$protocolVersion\":0,\"$type\":\"domain\",\"$dataContractId\":\"566vcJkmebVCAb2Dkj2yVMSgGFcsshupnQqtsz1RFbcy\",\"$id\":\"4veLBZPHDkaCPF9LfZ8fX3JZiS5q5iUVGhdBbaa9ga5E\",\"$ownerId\":\"HBNMY5QWuBVKNFLhgBTC1VmpEnscrmqKPMXpnYSHwhfn\",\"label\":\"user-9999\",\"normalizedLabel\":\"user-9999\",\"normalizedParentDomainName\":\"dash\",\"preorderSalt\":\"BzQi567XVqc8wYiVHS887sJtL6MDbxLHNnp+UpTFSB0=\",\"records\":{\"dashUniqueIdentityId\":\"HBNMY5QWuBVKNFLhgBTC1VmpEnscrmqKPMXpnYSHwhfn\"},\"subdomainRules\":{\"allowSubdomains\":false},\"$revision\":1,\"$createdAt\":null,\"$updatedAt\":null}", string); + Ok(()) } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 861f4a109cd..0600c81c907 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -31,6 +31,7 @@ pub struct SerializationOptions { } #[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] pub struct IdentityCreateTransition { // Own ST fields pub public_keys: Vec, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 71c3e823f2d..99a49a4b5c7 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -3,7 +3,7 @@ use std::convert::{TryFrom, TryInto}; use platform_value::{BinaryData, Value}; use serde::de::Error as DeError; use serde::ser::Error as SerError; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; @@ -23,7 +23,8 @@ mod property_names { pub const IDENTITY_ID: &str = "identityId"; } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] pub struct IdentityTopUpTransition { // Own ST fields pub asset_lock_proof: AssetLockProof, @@ -32,6 +33,7 @@ pub struct IdentityTopUpTransition { pub protocol_version: u32, pub transition_type: StateTransitionType, pub signature: BinaryData, + #[serde(skip)] pub execution_context: StateTransitionExecutionContext, } @@ -54,30 +56,6 @@ impl From for StateTransition { } } -impl Serialize for IdentityTopUpTransition { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - let raw = self - .to_object(Default::default()) - .map_err(|e| S::Error::custom(e.to_string()))?; - - raw.serialize(serializer) - } -} - -impl<'de> Deserialize<'de> for IdentityTopUpTransition { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let value = platform_value::Value::deserialize(deserializer)?; - - Self::new(value).map_err(|e| D::Error::custom(e.to_string())) - } -} - /// Main state transition functionality implementation impl IdentityTopUpTransition { pub fn new(raw_state_transition: Value) -> Result { diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 9b4f035dcbe..6d6f0fd57d3 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -221,9 +221,10 @@ pub trait StateTransitionConvert: Serialize { state_transition_helpers::to_json(self, skip_signature_paths) } - // Returns the cibor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version + // Returns the cbor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { let mut value = self.to_canonical_object(skip_signature)?; + dbg!(&value); let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; serializer::serializable_value_to_cbor(&value, Some(protocol_version)) diff --git a/packages/rs-platform-value/src/value_serialization/de.rs b/packages/rs-platform-value/src/value_serialization/de.rs index 4cc9ddbe558..b75ee37e10e 100644 --- a/packages/rs-platform-value/src/value_serialization/de.rs +++ b/packages/rs-platform-value/src/value_serialization/de.rs @@ -164,8 +164,15 @@ impl<'de> de::Deserializer<'de> for Deserializer { type Error = Error; fn deserialize_any>(self, visitor: V) -> Result { + let human_readable = self.is_human_readable(); match self.0 { - Value::Bytes(x) => visitor.visit_bytes(&x), + Value::Bytes(x) => { + if human_readable { + visitor.visit_str(base64::encode(x).as_str()) + } else { + visitor.visit_bytes(&x) + } + }, Value::Text(x) => visitor.visit_str(&x), Value::Array(x) => visitor.visit_seq(ArrayDeserializer(x.iter())), Value::Map(x) => visitor.visit_map(ValueMapDeserializer(x.iter().peekable())), @@ -182,10 +189,22 @@ impl<'de> de::Deserializer<'de> for Deserializer { Value::I16(x) => visitor.visit_i16(x), Value::U8(x) => visitor.visit_u8(x), Value::I8(x) => visitor.visit_i8(x), - Value::Bytes32(x) => visitor.visit_bytes(&x), + Value::Bytes32(x) => { + if human_readable { + visitor.visit_str(base64::encode(x).as_str()) + } else { + visitor.visit_bytes(&x) + } + }, Value::EnumU8(_x) => todo!(), Value::EnumString(_x) => todo!(), - Value::Identifier(x) => visitor.visit_bytes(&x), + Value::Identifier(x) => { + if human_readable { + visitor.visit_str(bs58::encode(x).into_string().as_str()) + } else { + visitor.visit_bytes(&x) + } + }, } } diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index 5d17d7c5cbe..880dd56c995 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -43,9 +43,27 @@ impl Serialize for Value { Value::I16(i) => serializer.serialize_i16(*i), Value::U8(i) => serializer.serialize_u8(*i), Value::I8(i) => serializer.serialize_i8(*i), - Value::Bytes(bytes) => serializer.serialize_bytes(bytes), - Value::Bytes32(bytes) => serializer.serialize_bytes(bytes), - Value::Identifier(bytes) => serializer.serialize_bytes(bytes), + Value::Bytes(bytes) => { + if serializer.is_human_readable() { + serializer.serialize_str(base64::encode(bytes).as_str()) + } else { + serializer.serialize_bytes(bytes) + } + }, + Value::Bytes32(bytes) => { + if serializer.is_human_readable() { + serializer.serialize_str(base64::encode(bytes).as_str()) + } else { + serializer.serialize_bytes(bytes) + } + }, + Value::Identifier(bytes) => { + if serializer.is_human_readable() { + serializer.serialize_str(bs58::encode(bytes).into_string().as_str()) + } else { + serializer.serialize_bytes(bytes) + } + }, Value::Float(f64) => serializer.serialize_f64(*f64), Value::Text(string) => serializer.serialize_str(string), Value::EnumU8(_x) => todo!(), From afdd8cd7b5f7a352d7245eaa19e77662ef0d3db3 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 20:45:00 +0700 Subject: [PATCH 139/228] more fixes --- .../rs-dpp/src/state_transition/abstract_state_transition.rs | 1 - .../abstract_state_transition_identity_signed.rs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 6d6f0fd57d3..9b626515014 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -224,7 +224,6 @@ pub trait StateTransitionConvert: Serialize { // Returns the cbor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { let mut value = self.to_canonical_object(skip_signature)?; - dbg!(&value); let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; serializer::serializable_value_to_cbor(&value, Some(protocol_version)) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index 6ce30527690..8e0cb763bca 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -359,7 +359,7 @@ mod test { .unwrap(), 1 ); - assert!(st_object["signature"].as_array().unwrap().is_empty()); + assert!(st_object["signature"].as_bytes().unwrap().is_empty()); } #[test] @@ -394,7 +394,7 @@ mod test { let st = get_mock_state_transition(); let hash = st.hash(false).unwrap(); assert_eq!( - "bb9f19724ffe1be08e6f9d111c8930a3a6de59a6653ad983f922a3523d75d33b", + "208afc16722df887c6e2935d1a0c13c56c5a91318beec4089cad6919be18debc", hex::encode(hash) ) } From b581135037e7888145953ea0b3109afaf78c3ad0 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 21:39:50 +0700 Subject: [PATCH 140/228] more fixes --- .../src/data_contract/serialization/cbor.rs | 8 +++--- .../data_contract_create_transition/mod.rs | 2 -- .../src/data_trigger/dpns_triggers/mod.rs | 8 ++---- .../document_create_transition.rs | 21 +++++++-------- .../documents_batch_transition/mod.rs | 5 ++-- ...lidate_documents_batch_transition_basic.rs | 26 +++++++++---------- .../identity_update_transition.rs | 6 ++--- .../validation/validator_transaction_basic.rs | 2 +- ..._documents_batch_transitions_basic_spec.rs | 2 +- packages/rs-dpp/src/tests/identifier_spec.rs | 2 +- ..._create_transition_basic_validator_spec.rs | 6 ++--- .../src/btreemap_extensions/mod.rs | 12 ++++----- .../rs-platform-value/src/types/identifier.rs | 19 ++++++++++++++ 13 files changed, 64 insertions(+), 55 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index f352c370a96..01e5388a922 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -30,8 +30,8 @@ impl DataContract { let data_contract_map: BTreeMap = Value::convert_from_cbor_map(data_contract_cbor_map)?; - let contract_id: [u8; 32] = data_contract_map.get_identifier(property_names::ID)?; - let owner_id: [u8; 32] = data_contract_map.get_identifier(property_names::OWNER_ID)?; + let contract_id: Identifier = data_contract_map.get_identifier(property_names::ID)?; + let owner_id: Identifier = data_contract_map.get_identifier(property_names::OWNER_ID)?; let schema = data_contract_map.get_string(property_names::SCHEMA)?; let version = data_contract_map.get_integer(property_names::VERSION)?; @@ -58,10 +58,10 @@ impl DataContract { let mut data_contract = Self { protocol_version, - id: Identifier::new(contract_id), + id: contract_id, schema, version, - owner_id: Identifier::new(owner_id), + owner_id, documents, defs, metadata: None, diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 357609143ca..11eabd09d8e 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -30,8 +30,6 @@ pub struct DataContractCreateTransition { pub protocol_version: u32, #[serde(rename = "type")] pub transition_type: StateTransitionType, - // we want to skip serialization of transitions, as we does it manually in `to_object()` and `to_json()` - #[serde(skip_serializing)] pub data_contract: DataContract, pub entropy: Bytes32, pub signature_public_key_id: KeyID, diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index cb6481fd739..43d2fda79a2 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -112,9 +112,7 @@ where dt_create, format!( "ownerId {} doesn't match {} {}", - owner_id, - PROPERTY_DASH_UNIQUE_IDENTITY_ID, - Identifier::new(id) + owner_id, PROPERTY_DASH_UNIQUE_IDENTITY_ID, id ), ); result.add_error(err.into()) @@ -131,9 +129,7 @@ where dt_create, format!( "ownerId {} doesn't match {} {}", - owner_id, - PROPERTY_DASH_ALIAS_IDENTITY_ID, - Identifier::new(id) + owner_id, PROPERTY_DASH_ALIAS_IDENTITY_ID, id ), ); result.add_error(err.into()); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 4aee23f804b..ab1decaf01a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -209,7 +209,7 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { #[cfg(test)] mod test { use platform_value::string_encoding::Encoding; - use platform_value::{platform_value, Identifier}; + use platform_value::{platform_value, BinaryData, Identifier}; use serde_json::json; use super::*; @@ -267,7 +267,7 @@ mod test { ("$id", Value::Identifier([0_u8; 32])), ("$schema", Value::Text("schema".to_string())), ("version", Value::U32(0)), - ("$ownerId", Value::Identifier([0_u8; 32])), + ("ownerId", Value::Identifier([0_u8; 32])), ("documents", documents), ]) .try_into() @@ -277,11 +277,11 @@ mod test { #[test] fn convert_to_json_with_dynamic_binary_paths() { let data_contract = data_contract_with_dynamic_properties(); - let alpha_binary = vec![10_u8; 32]; + let alpha_binary = BinaryData::new(vec![10_u8; 32]); let alpha_identifier = Identifier::from([10_u8; 32]); let id = Identifier::from([11_u8; 32]); let data_contract_id = Identifier::from([13_u8; 32]); - let entropy = vec![14_u8; 32]; + let entropy = Bytes32::new([14_u8; 32]); let raw_document = platform_value!({ "$protocolVersion" : 0u32, @@ -299,25 +299,22 @@ mod test { DocumentCreateTransition::from_raw_object(raw_document, data_contract).unwrap(); let json_transition = transition.to_json().expect("no errors"); - assert_eq!( - json_transition["$id"], - JsonValue::String(id.to_string(Encoding::Base58)) - ); + assert_eq!(json_transition["$id"], JsonValue::String(id.into())); assert_eq!( json_transition["$dataContractId"], - JsonValue::String(data_contract_id.to_string(Encoding::Base58)) + JsonValue::String(data_contract_id.into()) ); assert_eq!( json_transition["alphaBinary"], - JsonValue::String(base64::encode(&alpha_binary)) + JsonValue::String(alpha_binary.into()) ); assert_eq!( json_transition["alphaIdentifier"], - JsonValue::String(alpha_identifier.to_string(Encoding::Base58)) + JsonValue::String(alpha_identifier.into()) ); assert_eq!( json_transition["$entropy"], - JsonValue::String(base64::encode(&entropy)) + JsonValue::String(entropy.into()) ); } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 140294b87db..fa0483091cc 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -378,7 +378,7 @@ impl StateTransitionConvert for DocumentsBatchTransition { fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { let mut result_buf = self.protocol_version.encode_var_vec(); - let value = self.to_object(skip_signature)?; + let value: CborValue = self.to_object(skip_signature)?.try_into()?; let map = CborValue::serialized(&value) .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; @@ -637,7 +637,6 @@ mod test { let bytes = state_transition.to_buffer(false).unwrap(); - pretty_assertions::assert_eq!(expected_bytes.len(), bytes.len()); - pretty_assertions::assert_eq!(expected_bytes, bytes); + assert_eq!(hex::encode(expected_bytes), hex::encode(bytes)); } } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 4df4dcbac92..ad0203d0b50 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -9,6 +9,7 @@ use crate::consensus::basic::document::{ InvalidDocumentTransitionActionError, InvalidDocumentTransitionIdError, InvalidDocumentTypeError, }; +use crate::consensus::ConsensusError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; use crate::document::state_transition::documents_batch_transition::property_names; use crate::document::validation::basic::find_duplicates_by_id::find_duplicates_by_id; @@ -92,11 +93,9 @@ pub async fn validate_documents_batch_transition_basic( .to_btree_ref_string_map() .map_err(ProtocolError::ValueError)?; - let owner_id = Identifier::from( - state_transition_map - .get_hash256_bytes(property_names::OWNER_ID) - .map_err(ProtocolError::ValueError)?, - ); + let owner_id = state_transition_map + .get_identifier(property_names::OWNER_ID) + .map_err(ProtocolError::ValueError)?; let protocol_version = state_transition_map.get_integer(property_names::PROTOCOL_VERSION)?; let validation_result = protocol_version_validator.validate(protocol_version)?; @@ -112,20 +111,22 @@ pub async fn validate_documents_batch_transition_basic( HashMap::new(); for raw_document_transition in raw_document_transitions { - let data_contract_id_bytes = match raw_document_transition - .get_optional_hash256_bytes(property_names::DATA_CONTRACT_ID)? + let identifier = match raw_document_transition + .get_optional_identifier(property_names::DATA_CONTRACT_ID) { - None => { + Ok(None) => { result.add_error(BasicError::MissingDataContractIdError( MissingDataContractIdError::new(raw_document_transition.into()), )); continue; } - Some(id) => id, + Ok(Some(id)) => id, + Err(err) => { + result.add_error(ConsensusError::ValueError(err)); + continue; + } }; - let identifier = Identifier::from(data_contract_id_bytes); - match document_transitions_by_contracts.entry(identifier) { Entry::Vacant(vacant) => { vacant.insert(vec![raw_document_transition]); @@ -273,8 +274,7 @@ fn validate_raw_transitions<'a>( } if action == Action::Create { - let document_id = - Identifier::from_bytes(&raw_document_transition.get_identifier("$id")?)?; + let document_id = raw_document_transition.get_identifier("$id")?; let entropy = raw_document_transition.get_bytes("$entropy")?; // validate the id generation let generated_document_id = diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index b2bfed9e9a5..1a13e3505ad 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -380,12 +380,12 @@ mod test { assert!(matches!( result[property_names::IDENTITY_ID], - Value::Array(_) + Value::Identifier(_) )); - assert!(matches!(result[property_names::SIGNATURE], Value::Array(_))); + assert!(matches!(result[property_names::SIGNATURE], Value::Bytes(_))); assert!(matches!( result[property_names::ADD_PUBLIC_KEYS][0]["data"], - Value::Array(_) + Value::Bytes(_) )); } } diff --git a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs b/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs index b47c9e4b6b8..7e187bd00e4 100644 --- a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs +++ b/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs @@ -261,7 +261,7 @@ mod test { ) .await .expect("the validation result should be returned"); - + dbg!(&result); let basic_error = get_basic_error_from_result(&result, 0); match basic_error { diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 0cf25d65329..9e84c406985 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -519,7 +519,7 @@ async fn data_contract_id_should_be_byte_array() { .expect("validation result should be returned"); let error = &result.errors()[0]; - assert_eq!(1025, error.code()); + assert_eq!(5000, error.code()); } #[test_case("$id")] diff --git a/packages/rs-dpp/src/tests/identifier_spec.rs b/packages/rs-dpp/src/tests/identifier_spec.rs index 3f80d6e7999..dee179ef987 100644 --- a/packages/rs-dpp/src/tests/identifier_spec.rs +++ b/packages/rs-dpp/src/tests/identifier_spec.rs @@ -28,7 +28,7 @@ pub fn from_string_fails_for_strings_encoding_more_than_32_bytes() { match res { Err(err) => assert_eq!( err.to_string(), - "Identifier Error: Identifier must be 32 bytes long" + "byte length not 32 bytes error: Identifier must be 32 bytes long" ), Ok(_) => panic!("Expected from_string to return error"), } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index cc83a7d0465..27144b2100f 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -172,11 +172,11 @@ mod validate_identity_create_transition_basic_factory { panic!("Expected error"); } Err(e) => match e { - NonConsensusError::SerdeParsingError(e) => { - assert_eq!(e.message(), "Expected protocolVersion to be a uint"); + NonConsensusError::ValueError(e) => { + assert_eq!(e.to_string(), "integer out of bounds"); } _ => { - panic!("Expected version parsing error"); + panic!("Expected value error"); } }, } diff --git a/packages/rs-platform-value/src/btreemap_extensions/mod.rs b/packages/rs-platform-value/src/btreemap_extensions/mod.rs index cccaab0610f..f0eadc3aee2 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/mod.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/mod.rs @@ -4,7 +4,7 @@ use std::convert::TryFrom; use std::iter::FromIterator; use std::{collections::BTreeMap, convert::TryInto}; -use crate::{BinaryData, Error, Value, ValueMap}; +use crate::{BinaryData, Error, Identifier, Value, ValueMap}; pub(crate) mod btreemap_field_replacement; mod btreemap_mut_value_extensions; @@ -21,8 +21,8 @@ pub use btreemap_removal_extensions::BTreeValueRemoveFromMapHelper; pub use btreemap_removal_inner_value_extensions::BTreeValueRemoveInnerValueFromMapHelper; pub trait BTreeValueMapHelper { - fn get_optional_identifier(&self, key: &str) -> Result, Error>; - fn get_identifier(&self, key: &str) -> Result<[u8; 32], Error>; + fn get_optional_identifier(&self, key: &str) -> Result, Error>; + fn get_identifier(&self, key: &str) -> Result; fn get_optional_string(&self, key: &str) -> Result, Error>; fn get_string(&self, key: &str) -> Result; fn get_optional_str(&self, key: &str) -> Result, Error>; @@ -116,11 +116,11 @@ impl BTreeValueMapHelper for BTreeMap where V: Borrow, { - fn get_optional_identifier(&self, key: &str) -> Result, Error> { - self.get(key).map(|v| v.borrow().to_hash256()).transpose() + fn get_optional_identifier(&self, key: &str) -> Result, Error> { + self.get(key).map(|v| v.borrow().to_identifier()).transpose() } - fn get_identifier(&self, key: &str) -> Result<[u8; 32], Error> { + fn get_identifier(&self, key: &str) -> Result { self.get_optional_identifier(key)?.ok_or_else(|| { Error::StructureError(format!("unable to get identifier property {key}")) }) diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 3fd8180d45e..172e455e061 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -220,6 +220,12 @@ impl std::fmt::Display for Identifier { } } +impl PartialEq<&Identifier> for Identifier { + fn eq(&self, other: &&Identifier) -> bool { + &self.0.0 == &other.0.0 + } +} + impl PartialEq<[u8; 32]> for Identifier { fn eq(&self, other: &[u8; 32]) -> bool { &self.0.0 == other @@ -272,6 +278,19 @@ impl From<&Identifier> for Value { } } +impl Into for Identifier { + fn into(self) -> String { + self.to_string(Encoding::Base58) + } +} + +impl Into for &Identifier { + fn into(self) -> String { + self.to_string(Encoding::Base58) + } +} + + #[cfg(test)] mod tests { use std::collections::HashMap; From cc9cb588cd1bfbf443ab88c2bd57c6bec6b582bf Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 21:51:10 +0700 Subject: [PATCH 141/228] more work --- packages/rs-dpp/src/identity/identity.rs | 23 +++++++++++-------- packages/rs-platform-value/src/inner_value.rs | 13 +++++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index e003ee9bcb5..5a67533a8d4 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -3,7 +3,7 @@ use std::convert::TryFrom; use ciborium::value::Value as CborValue; use integer_encoding::VarInt; -use platform_value::Value; +use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -281,18 +281,21 @@ impl Identity { /// Creates an identity from a json structure pub fn from_json(mut json_object: JsonValue) -> Result { - if let Some(public_keys_value) = json_object.get_mut("publicKeys") { - if let Some(public_keys_array) = public_keys_value.as_array_mut() { - for public_key in public_keys_array.iter_mut() { - public_key.replace_binary_paths( - identity_public_key::BINARY_DATA_FIELDS, - ReplaceWith::Bytes, - )?; - } + let mut platform_value: Value = json_object.into(); + + platform_value + .replace_at_paths(IDENTIFIER_FIELDS_RAW_OBJECT, ReplacementType::Identifier)?; + + if let Some(public_keys_array) = platform_value.get_optional_array_mut_ref("publicKeys")? { + for public_key in public_keys_array.iter_mut() { + public_key.replace_at_paths( + identity_public_key::BINARY_DATA_FIELDS, + ReplacementType::BinaryBytes, + )?; } } - let identity: Identity = serde_json::from_value(json_object)?; + let identity: Identity = platform_value::from_value(platform_value)?; Ok(identity) } diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 283a73ed03f..c454beec1af 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -319,6 +319,11 @@ impl Value { Self::inner_array_ref(map, key) } + pub fn get_optional_array_mut_ref<'a>(&'a mut self, key: &'a str) -> Result>, Error> { + let map = self.to_map_mut()?; + Self::inner_optional_array_mut_ref(map, key) + } + pub fn get_array_mut_ref<'a>(&'a mut self, key: &'a str) -> Result<&'a mut Vec, Error> { let map = self.to_map_mut()?; Self::inner_array_mut_ref(map, key) @@ -449,6 +454,14 @@ impl Value { Self::get_mut_from_map(document_type, key).map(|value| value.to_array_mut())? } + /// Retrieves the value of a key from a map if it's an array of strings. + pub fn inner_optional_array_mut_ref<'a>( + document_type: &'a mut [(Value, Value)], + key: &'a str, + ) -> Result>, Error> { + Self::get_optional_mut_from_map(document_type, key).map(|value| value.to_array_mut()).transpose() + } + /// Retrieves the value of a key from a map if it's an array of strings. pub fn inner_array_ref<'a>( document_type: &'a [(Value, Value)], From ef16f86e4fe9138103a289a0c29c2b23eca0bd25 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 22:00:12 +0700 Subject: [PATCH 142/228] more fixes --- ...e_identity_update_transition_basic_spec.rs | 2 +- packages/rs-platform-value/src/inner_value.rs | 29 ++++++++++++++++--- packages/rs-platform-value/src/lib.rs | 2 +- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs index 04c1f419cdd..b3fc7f9d313 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs @@ -302,7 +302,7 @@ fn protocol_version_should_be_valid() { .validate(&raw_state_transition) .expect_err("error should be returned"); - assert!(matches!(result, NonConsensusError::SerdeJsonError(_))); + assert!(matches!(result, NonConsensusError::ValueError(_))); } #[test] diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index c454beec1af..c246da48ead 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -118,7 +118,13 @@ impl Value { { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) - .map(|v| v.into_integer()) + .map(|v| + if v.is_null() { + None + } else { + Some(v.into_integer()) + } + ).flatten() .transpose() } @@ -131,7 +137,12 @@ impl Value { pub fn remove_optional_identifier(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) - .map(|v| v.into_identifier()) + .map(|v| if v.is_null() { + None + } else { + Some(v.into_identifier()) + }) + .flatten() .transpose() } @@ -557,7 +568,12 @@ impl Value { key: &str, ) -> Result, Error> { Self::get_optional_from_map(document_type, key) - .map(|value| value.to_bool()) + .map(|value| if value.is_null() { + None + } else { + Some(value.to_bool()) + }) + .flatten() .transpose() } @@ -584,7 +600,12 @@ impl Value { + TryFrom, { Self::get_optional_from_map(document_type, key) - .map(|key_value| key_value.to_integer()) + .map(|key_value| if key_value.is_null() { + None + } else { + Some(key_value.to_integer()) + }) + .flatten() .transpose() } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index efb4a47b176..7ccb2cd5c1d 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -255,7 +255,7 @@ impl Value { Value::I16(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), Value::U8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), Value::I8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), - _other => Err(Error::StructureError("value is not an integer".to_string())), + other => Err(Error::StructureError(format!("value is not an integer, found {}", other))), } } From d19a63a83bb7364b404bc309c153ca5795703894 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 17 Mar 2023 22:08:19 +0700 Subject: [PATCH 143/228] more fixes --- .../tests/identity/validation/identity_validator_spec.rs | 2 +- .../identity/validation/public_keys_validator_spec.rs | 5 +++-- ...required_purpose_and_security_level_validator_spec.rs | 9 +++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs index becbb2c1657..445ecec9f6b 100644 --- a/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/identity_validator_spec.rs @@ -396,7 +396,7 @@ pub mod revision { match error.kind() { ValidationErrorKind::Required { property } => { - assert_eq!(property.to_string(), "\"revision\""); + assert_eq!(property.to_string(), "\"protocolVersion\""); } _ => panic!("Expected to be missing property"), } diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index 12db8fc54cf..bf560f366a8 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -5,6 +5,7 @@ use crate::identity::{KeyID, KeyType, Purpose, SecurityLevel}; use crate::tests::fixtures::get_public_keys_validator; use crate::tests::utils::platform_value_set_ref; use crate::{assert_consensus_errors, NativeBlsModule}; +use platform_value::BinaryData; use platform_value::{platform_value, Value}; fn setup_test() -> (Vec, PublicKeysValidator) { @@ -494,7 +495,7 @@ pub fn should_pass_valid_ecdsa_hash160_public_key() { "purpose": 0u8, "securityLevel": 0u8, "readOnly": true, - "data": hex::decode("6086389d3fa4773aa950b8de18c5bd6d8f2b73bc").unwrap(), + "data": BinaryData::new(hex::decode("6086389d3fa4773aa950b8de18c5bd6d8f2b73bc").unwrap()), }]); let raw_public_keys = raw_public_keys_json.as_array().unwrap(); @@ -512,7 +513,7 @@ pub fn should_return_invalid_result_if_bls12_381_public_key_is_invalid() { "purpose": 0u8, "securityLevel": 0u8, "readOnly": true, - "data": hex::decode("11fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694").unwrap(), + "data": BinaryData::new(hex::decode("11fac99ca2c8f39c286717c213e190aba4b7af76db320ec43f479b7d9a2012313a0ae59ca576edf801444bc694686694").unwrap()), }]); let raw_public_keys = raw_public_keys_json.as_array().unwrap(); diff --git a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs index 9b7040f3060..42b451260b9 100644 --- a/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/required_purpose_and_security_level_validator_spec.rs @@ -4,6 +4,7 @@ use crate::identity::{ }; use platform_value::platform_value; use platform_value::string_encoding::{decode, Encoding}; +use platform_value::BinaryData; #[test] fn should_return_invalid_result_if_state_transition_does_not_contain_master_key() { @@ -14,7 +15,7 @@ fn should_return_invalid_result_if_state_transition_does_not_contain_master_key( "type" : KeyType::ECDSA_SECP256K1 as u8, "purpose" : Purpose::AUTHENTICATION as u8, "securityLevel" : SecurityLevel::CRITICAL as u8, - "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), + "data": BinaryData::new(decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap()), "readOnly" : false, }), // this key must be filtered out @@ -24,7 +25,7 @@ fn should_return_invalid_result_if_state_transition_does_not_contain_master_key( "purpose": Purpose::AUTHENTICATION as u8, "securityLevel" : SecurityLevel::CRITICAL as u8, "disabledAt" : 42, - "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), + "data": BinaryData::new(decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap()), "readOnly" : false, }), ]; @@ -49,7 +50,7 @@ fn should_return_valid_result() { "type" : KeyType::ECDSA_SECP256K1 as u8, "purpose" : Purpose::AUTHENTICATION as u8, "securityLevel" : SecurityLevel::MASTER as u8, - "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), + "data": BinaryData::new(decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap()), "readOnly" : false, }), // this key must be filtered out @@ -59,7 +60,7 @@ fn should_return_valid_result() { "purpose": Purpose::AUTHENTICATION as u8, "securityLevel" : SecurityLevel::CRITICAL as u8, "disabledAt" : 42u64, - "data": decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap(), + "data": BinaryData::new(decode("AuryIuMtRrl/VviQuyLD1l4nmxi9ogPzC9LT7tdpo0di", Encoding::Base64).unwrap()), "readOnly" : false, }), ]; From 0b120111e1f3d515c51abd244ba69c1797185bae Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:09:17 +0700 Subject: [PATCH 144/228] dpp tests all passing --- packages/rs-dpp/src/identity/core_script.rs | 41 +++++++++++++++++-- .../src/identity/identity_public_key/mod.rs | 11 +++++ .../mod.rs | 4 +- ...ty_credit_withdrawal_transition_fixture.rs | 9 ++-- .../identity/identity_public_key_spec.rs | 8 ++-- ...credit_withdrawal_transition_basic_spec.rs | 8 ++-- ..._top_up_transition_basic_validator_spec.rs | 4 +- .../validation/public_keys_validator_spec.rs | 13 ++---- packages/rs-platform-value/src/error.rs | 14 +++++-- 9 files changed, 80 insertions(+), 32 deletions(-) diff --git a/packages/rs-dpp/src/identity/core_script.rs b/packages/rs-dpp/src/identity/core_script.rs index 893ec8144cb..a2602d2d9e4 100644 --- a/packages/rs-dpp/src/identity/core_script.rs +++ b/packages/rs-dpp/src/identity/core_script.rs @@ -1,7 +1,11 @@ +use std::fmt; +use std::fmt::Write; use std::ops::Deref; use dashcore::Script as DashcoreScript; use platform_value::string_encoding::{self, Encoding}; +use platform_value::BinaryData; +use serde::de::Visitor; use serde::{Deserialize, Serialize}; use crate::ProtocolError; @@ -10,6 +14,10 @@ use crate::ProtocolError; pub struct CoreScript(DashcoreScript); impl CoreScript { + pub fn new(script: DashcoreScript) -> Self { + CoreScript(script) + } + pub fn to_string(&self, encoding: Encoding) -> String { string_encoding::encode(&self.0.to_bytes(), encoding) } @@ -44,7 +52,11 @@ impl Serialize for CoreScript { where S: serde::Serializer, { - serializer.serialize_str(&self.to_string(Encoding::Base64)) + if serializer.is_human_readable() { + serializer.serialize_str(&self.to_string(Encoding::Base64)) + } else { + serializer.serialize_bytes(self.as_bytes()) + } } } @@ -53,10 +65,31 @@ impl<'de> Deserialize<'de> for CoreScript { where D: serde::Deserializer<'de>, { - let data: String = Deserialize::deserialize(deserializer)?; + if deserializer.is_human_readable() { + let data: String = Deserialize::deserialize(deserializer)?; + + Self::from_string(&data, Encoding::Base64) + .map_err(|e| serde::de::Error::custom(e.to_string())) + } else { + struct BytesVisitor; + + impl<'de> Visitor<'de> for BytesVisitor { + type Value = CoreScript; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + Ok(CoreScript::from_bytes(v.to_vec())) + } + } - Self::from_string(&data, Encoding::Base64) - .map_err(|e| serde::de::Error::custom(e.to_string())) + deserializer.deserialize_bytes(BytesVisitor) + } } } diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index de58e5c0bde..999199dc2e9 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -225,6 +225,17 @@ impl TryFrom for IdentityPublicKey { } } +impl TryFrom<&str> for IdentityPublicKey { + type Error = ProtocolError; + + fn try_from(value: &str) -> Result { + let mut platform_value: Value = serde_json::from_str::(value).map_err(|e| ProtocolError::StringDecodeError(e.to_string()))?.into(); + platform_value.replace_at_paths(BINARY_DATA_FIELDS, ReplacementType::BinaryBytes)?; + platform_value.try_into().map_err(ProtocolError::ValueError) + } +} + + pub fn de_base64_to_vec<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { let data: String = Deserialize::deserialize(d)?; base64::decode(data) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index d2b995b0123..ed266eb2ba7 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -4,6 +4,7 @@ use serde_json::Value as JsonValue; use serde_repr::{Deserialize_repr, Serialize_repr}; use std::convert::TryInto; +use crate::contracts::withdrawals_contract::property_names::OUTPUT_SCRIPT; use crate::version::LATEST_VERSION; use crate::{ identity::{core_script::CoreScript, KeyID}, @@ -91,7 +92,6 @@ impl IdentityCreditWithdrawalTransition { ReplacementType::Identifier, ) .map_err(ProtocolError::ValueError)?; - Self::from_value(value) } @@ -177,7 +177,7 @@ impl StateTransitionConvert for IdentityCreditWithdrawalTransition { } fn binary_property_paths() -> Vec<&'static str> { - vec![PROPERTY_SIGNATURE] + vec![PROPERTY_SIGNATURE, OUTPUT_SCRIPT] } fn to_object(&self, skip_signature: bool) -> Result { diff --git a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs index 4e476d8da23..36c431071c0 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs @@ -1,6 +1,9 @@ use crate::prelude::Identifier; +use crate::prelude::Revision; +use crate::identity::core_script::CoreScript; use dashcore::{hashes::hex::FromHex, PubkeyHash, Script}; use platform_value::string_encoding::{encode, Encoding}; +use platform_value::BinaryData; use platform_value::{platform_value, Value}; use serde_json::{json, Value as JsonValue}; @@ -17,10 +20,10 @@ pub fn identity_credit_withdrawal_transition_fixture_raw_object() -> Value { "amount": 1042u64, "coreFeePerByte": 3u32, "pooling": Pooling::Never as u8, - "outputScript": Script::new_p2pkh(&PubkeyHash::from_hex("0000000000000000000000000000000000000000").unwrap()).to_bytes(), - "signature": vec![0_u8; 65], + "outputScript": CoreScript::new(Script::new_p2pkh(&PubkeyHash::from_hex("0000000000000000000000000000000000000000").unwrap())), + "revision": 1 as Revision, "signaturePublicKeyId": 0u32, - "revision": 1u32, + "signature": BinaryData::new(vec![0_u8; 65]), }) } diff --git a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs index 8325315632d..0848d9df9f4 100644 --- a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs +++ b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs @@ -1,8 +1,10 @@ mod from_raw_object { + use std::convert::TryInto; use bls_signatures::Serialize; use dashcore::PublicKey; use platform_value::platform_value; use serde_json::json; + use platform_value::BinaryData; use crate::identity::{KeyType, Purpose, SecurityLevel}; use crate::prelude::IdentityPublicKey; @@ -87,7 +89,7 @@ mod from_raw_object { \"securityLevel\":0, \ \"readOnly\":false \ }"; - let public_key: IdentityPublicKey = serde_json::from_str(pk_str).unwrap(); + let public_key: IdentityPublicKey = pk_str.try_into().expect("expected to convert to IdentityPublicKey"); // let public_key = IdentityPublicKey::from_raw_object(public_key_json).unwrap(); @@ -155,7 +157,7 @@ mod from_raw_object { "type": KeyType::ECDSA_SECP256K1 as u8, "purpose": Purpose::AUTHENTICATION as u8, "securityLevel": SecurityLevel::MASTER as u8, - "data": public_key, + "data": BinaryData::new(public_key), "readOnly": false }); @@ -183,7 +185,7 @@ mod from_raw_object { "type": KeyType::BLS12_381 as u8, "purpose": Purpose::AUTHENTICATION as u8, "securityLevel": SecurityLevel::MASTER as u8, - "data": bls_public_key, + "data": BinaryData::new(bls_public_key), "readOnly": false }); diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs index 9e59421ad52..60655cd53bf 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_credit_withdrawal_transition/validation/basic/validate_identity_credit_withdrawal_transition_basic_spec.rs @@ -82,11 +82,11 @@ mod validate_identity_credit_withdrawal_transition_basic_factory { panic!("Expected error"); } Err(e) => match e { - NonConsensusError::SerdeParsingError(e) => { - assert_eq!(e.message(), "Expected protocolVersion to be a uint"); + NonConsensusError::ValueError(e) => { + assert_eq!(e.to_string(), "integer out of bounds"); } - _ => { - panic!("Expected version parsing error"); + other => { + panic!("Expected version parsing error, got {}", other); } }, } diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs index 402d234298c..60f8250e8e1 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_topup_transition/validation/basic/identity_top_up_transition_basic_validator_spec.rs @@ -116,8 +116,8 @@ mod validate_identity_topup_transition_basic { panic!("Expected error"); } Err(e) => match e { - NonConsensusError::SerdeParsingError(e) => { - assert_eq!(e.message(), "Expected protocolVersion to be a uint"); + NonConsensusError::ValueError(e) => { + assert_eq!(e.to_string(), "integer out of bounds"); } _ => { panic!("Expected version parsing error"); diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index bf560f366a8..6deaf45ac66 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -416,16 +416,9 @@ pub fn should_return_invalid_result_if_key_data_is_not_a_valid_der() { pub fn should_return_invalid_result_if_key_has_an_invalid_combination_of_purpose_and_security_level( ) { let (mut raw_public_keys, validator) = setup_test(); - platform_value_set_ref( - raw_public_keys.get_mut(1).unwrap(), - "purpose", - Purpose::ENCRYPTION as u64, - ); - platform_value_set_ref( - raw_public_keys.get_mut(1).unwrap(), - "securityLevel", - SecurityLevel::MASTER as u64, - ); + + raw_public_keys.get_mut(1).unwrap().set_into_value("purpose", Purpose::ENCRYPTION as u8).unwrap(); + raw_public_keys.get_mut(1).unwrap().set_into_value("securityLevel", SecurityLevel::MASTER as u8).unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!( diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index eec07f95373..fe2fce456e2 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -1,6 +1,8 @@ use std::fmt::Display; +use serde::Deserialize; use thiserror::Error; +use crate::value_serialization; #[derive(Error, Clone, Eq, PartialEq, Debug)] pub enum Error { @@ -24,6 +26,12 @@ pub enum Error { #[error("byte length not 32 bytes error: {0}")] ByteLengthNot32BytesError(String), + + #[error("serde serialization error: {0}")] + SerdeSerializationError(String), + + #[error("serde deserialization error: {0}")] + SerdeDeserializationError(String), } impl serde::ser::Error for Error { @@ -31,8 +39,7 @@ impl serde::ser::Error for Error { where T: Display, { - println!("{msg}"); - todo!() + Error::SerdeSerializationError(msg.to_string()) } } @@ -41,7 +48,6 @@ impl serde::de::Error for Error { where T: Display, { - println!("{msg}"); - todo!() + Error::SerdeDeserializationError(msg.to_string()) } } From b8173e318db4b833e4a7359d36adb776b344c89e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:09:28 +0700 Subject: [PATCH 145/228] fmt --- .../rs-dpp/src/identity/identity_public_key/mod.rs | 5 +++-- .../identity_credit_withdrawal_transition_fixture.rs | 2 +- .../src/tests/identity/identity_public_key_spec.rs | 8 +++++--- .../validation/public_keys_validator_spec.rs | 12 ++++++++++-- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index 999199dc2e9..5ab1b8c0bd0 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -229,13 +229,14 @@ impl TryFrom<&str> for IdentityPublicKey { type Error = ProtocolError; fn try_from(value: &str) -> Result { - let mut platform_value: Value = serde_json::from_str::(value).map_err(|e| ProtocolError::StringDecodeError(e.to_string()))?.into(); + let mut platform_value: Value = serde_json::from_str::(value) + .map_err(|e| ProtocolError::StringDecodeError(e.to_string()))? + .into(); platform_value.replace_at_paths(BINARY_DATA_FIELDS, ReplacementType::BinaryBytes)?; platform_value.try_into().map_err(ProtocolError::ValueError) } } - pub fn de_base64_to_vec<'de, D: Deserializer<'de>>(d: D) -> Result, D::Error> { let data: String = Deserialize::deserialize(d)?; base64::decode(data) diff --git a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs index 36c431071c0..0b6ed7c5d4b 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs @@ -1,6 +1,6 @@ +use crate::identity::core_script::CoreScript; use crate::prelude::Identifier; use crate::prelude::Revision; -use crate::identity::core_script::CoreScript; use dashcore::{hashes::hex::FromHex, PubkeyHash, Script}; use platform_value::string_encoding::{encode, Encoding}; use platform_value::BinaryData; diff --git a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs index 0848d9df9f4..23612972009 100644 --- a/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs +++ b/packages/rs-dpp/src/tests/identity/identity_public_key_spec.rs @@ -1,10 +1,10 @@ mod from_raw_object { - use std::convert::TryInto; use bls_signatures::Serialize; use dashcore::PublicKey; use platform_value::platform_value; - use serde_json::json; use platform_value::BinaryData; + use serde_json::json; + use std::convert::TryInto; use crate::identity::{KeyType, Purpose, SecurityLevel}; use crate::prelude::IdentityPublicKey; @@ -89,7 +89,9 @@ mod from_raw_object { \"securityLevel\":0, \ \"readOnly\":false \ }"; - let public_key: IdentityPublicKey = pk_str.try_into().expect("expected to convert to IdentityPublicKey"); + let public_key: IdentityPublicKey = pk_str + .try_into() + .expect("expected to convert to IdentityPublicKey"); // let public_key = IdentityPublicKey::from_raw_object(public_key_json).unwrap(); diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index 6deaf45ac66..67f9ce24d91 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -417,8 +417,16 @@ pub fn should_return_invalid_result_if_key_has_an_invalid_combination_of_purpose ) { let (mut raw_public_keys, validator) = setup_test(); - raw_public_keys.get_mut(1).unwrap().set_into_value("purpose", Purpose::ENCRYPTION as u8).unwrap(); - raw_public_keys.get_mut(1).unwrap().set_into_value("securityLevel", SecurityLevel::MASTER as u8).unwrap(); + raw_public_keys + .get_mut(1) + .unwrap() + .set_into_value("purpose", Purpose::ENCRYPTION as u8) + .unwrap(); + raw_public_keys + .get_mut(1) + .unwrap() + .set_into_value("securityLevel", SecurityLevel::MASTER as u8) + .unwrap(); let result = validator.validate_keys(&raw_public_keys).unwrap(); let errors = assert_consensus_errors!( From 892a9d804eeec9c097ed9a436826b6706c3154a5 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:14:23 +0700 Subject: [PATCH 146/228] fixes --- packages/rs-dpp/src/data_contract/data_contract.rs | 6 +++--- .../rs-dpp/src/data_contract/data_contract_facade.rs | 2 +- .../rs-dpp/src/data_contract/data_contract_factory.rs | 7 ++++--- .../document_transition/document_create_transition.rs | 2 +- .../state_transition/documents_batch_transition/mod.rs | 2 +- packages/rs-dpp/src/identity/core_script.rs | 3 +-- packages/rs-dpp/src/identity/identity.rs | 4 ++-- packages/rs-dpp/src/identity/identity_public_key/mod.rs | 2 +- .../identity_credit_withdrawal_transition/mod.rs | 2 +- .../identity_topup_transition.rs | 3 +-- .../src/state_transition/abstract_state_transition.rs | 6 +----- packages/rs-dpp/src/tests/fixtures/get_data_contract.rs | 1 - .../rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs | 1 - .../tests/fixtures/identity_create_transition_fixture.rs | 2 -- packages/rs-dpp/src/tests/fixtures/identity_fixture.rs | 2 +- .../identity/validation/public_keys_validator_spec.rs | 2 +- packages/rs-platform-value/src/error.rs | 2 -- packages/rs-platform-value/src/types/bytes_32.rs | 1 - packages/rs-platform-value/src/types/identifier.rs | 2 +- .../rs-platform-value/src/value_serialization/ser.rs | 9 ++------- 20 files changed, 22 insertions(+), 39 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 5c68dc86e3b..1b89a0e738e 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -6,7 +6,7 @@ use anyhow::anyhow; use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; use platform_value::Value; -use platform_value::{BinaryData, Bytes32, Identifier}; +use platform_value::{Bytes32, Identifier}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -468,7 +468,7 @@ impl TryInto for &DataContract { impl TryFrom<&str> for DataContract { type Error = ProtocolError; fn try_from(v: &str) -> Result { - let mut data_contract: DataContract = serde_json::from_str(v)?; + let data_contract: DataContract = serde_json::from_str(v)?; //todo: there's a better to do this, find it let value = data_contract.to_object()?; DataContract::from_raw_object(value) @@ -750,7 +750,7 @@ mod test { let contract = DataContract::try_from(string_contract.as_str())?; let serialized_contract = serde_json::to_string(&contract.to_json()?)?; - ///they will be out of order so won't be exactly the same + // they will be out of order so won't be exactly the same assert_eq!(serialized_contract, string_contract); Ok(()) } diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index ffef6971bea..3289613b6ac 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -4,7 +4,7 @@ use crate::data_contract::state_transition::{ }; use crate::data_contract::validation::data_contract_validator::DataContractValidator; use crate::data_contract::{DataContract, DataContractFactory}; -use crate::document::document_transition::document_base_transition::JsonValue; + use crate::prelude::{Identifier, ValidationResult}; use crate::version::ProtocolVersionValidator; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index cde4c121118..dc1ff01892e 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -1,4 +1,4 @@ -use serde_json::{Map, Value as JsonValue}; +use serde_json::Value as JsonValue; use std::collections::BTreeMap; use std::convert::TryInto; use std::sync::Arc; @@ -8,9 +8,9 @@ use platform_value::{Bytes32, Value}; use crate::data_contract::contract_config::ContractConfig; use crate::data_contract::errors::InvalidDataContractError; -use crate::data_contract::property_names; + use crate::data_contract::property_names::PROTOCOL_VERSION; -use crate::util::serializer::serializable_value_to_cbor; + use crate::{ data_contract::{self, generate_data_contract_id}, decode_protocol_entity_factory::DecodeProtocolEntity, @@ -222,6 +222,7 @@ impl DataContractFactory { #[cfg(test)] mod tests { use super::*; + use crate::data_contract::property_names; use crate::tests::fixtures::get_data_contract_fixture; use crate::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; use std::sync::Arc; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index ab1decaf01a..061b8bba99c 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -208,7 +208,7 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { #[cfg(test)] mod test { - use platform_value::string_encoding::Encoding; + use platform_value::{platform_value, BinaryData, Identifier}; use serde_json::json; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index fa0483091cc..34e82d6e499 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -18,7 +18,7 @@ use crate::document::document_transition::DocumentTransitionObjectLike; use crate::prelude::{DocumentTransition, Identifier}; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::util::cbor_value::{CborCanonicalMap, FieldType, ReplacePaths, ValuesCollection}; -use crate::util::json_value::{JsonValueExt, ReplaceWith}; +use crate::util::json_value::JsonValueExt; use crate::version::LATEST_VERSION; use crate::ProtocolError; use crate::{ diff --git a/packages/rs-dpp/src/identity/core_script.rs b/packages/rs-dpp/src/identity/core_script.rs index a2602d2d9e4..169cf73b280 100644 --- a/packages/rs-dpp/src/identity/core_script.rs +++ b/packages/rs-dpp/src/identity/core_script.rs @@ -1,10 +1,9 @@ use std::fmt; -use std::fmt::Write; use std::ops::Deref; use dashcore::Script as DashcoreScript; use platform_value::string_encoding::{self, Encoding}; -use platform_value::BinaryData; + use serde::de::Visitor; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 5a67533a8d4..ce957d8a539 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -13,7 +13,7 @@ use crate::prelude::Revision; use crate::util::cbor_value::{CborBTreeMapHelper, CborCanonicalMap}; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; -use crate::util::json_value::{JsonValueExt, ReplaceWith}; +use crate::util::json_value::JsonValueExt; use crate::{errors::ProtocolError, identifier::Identifier, metadata::Metadata, util::hash}; use super::{IdentityPublicKey, KeyID}; @@ -280,7 +280,7 @@ impl Identity { } /// Creates an identity from a json structure - pub fn from_json(mut json_object: JsonValue) -> Result { + pub fn from_json(json_object: JsonValue) -> Result { let mut platform_value: Value = json_object.into(); platform_value diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index 5ab1b8c0bd0..f42c9b4e026 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -119,7 +119,7 @@ impl IdentityPublicKey { value.try_into().map_err(ProtocolError::ValueError) } - pub fn from_json_object(mut raw_object: JsonValue) -> Result { + pub fn from_json_object(raw_object: JsonValue) -> Result { let mut value: Value = raw_object.into(); value.replace_at_paths(BINARY_DATA_FIELDS, ReplacementType::BinaryBytes)?; Self::from_value(value) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index ed266eb2ba7..53c70e20b7f 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -81,7 +81,7 @@ impl IdentityCreditWithdrawalTransition { Ok(transition) } - pub fn from_json(mut value: JsonValue) -> Result { + pub fn from_json(value: JsonValue) -> Result { let mut value: Value = value.into(); value .replace_at_paths(Self::binary_property_paths(), ReplacementType::BinaryBytes) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 99a49a4b5c7..06fa1d7c20a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -1,8 +1,7 @@ use std::convert::{TryFrom, TryInto}; use platform_value::{BinaryData, Value}; -use serde::de::Error as DeError; -use serde::ser::Error as SerError; + use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 9b626515014..b38902bef84 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -12,11 +12,7 @@ use crate::state_transition::errors::{ use crate::{ identity::KeyType, prelude::ProtocolError, - util::{ - hash, - json_value::{JsonValueExt, ReplaceWith}, - serializer, - }, + util::{hash, serializer}, BlsModule, }; diff --git a/packages/rs-dpp/src/tests/fixtures/get_data_contract.rs b/packages/rs-dpp/src/tests/fixtures/get_data_contract.rs index 94b53ca9fc9..2dc80352921 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_data_contract.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_data_contract.rs @@ -1,7 +1,6 @@ use std::sync::Arc; use platform_value::platform_value; -use serde_json::json; use crate::prelude::*; use crate::{ diff --git a/packages/rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs b/packages/rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs index e8a01442d40..004b1d5e5d7 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dpns_data_contract.rs @@ -4,7 +4,6 @@ use data_contracts::{DataContractSource, SystemDataContract}; use platform_value::platform_value; use serde_json::json; -use crate::data_contract::contract_config::ContractConfig; use crate::prelude::*; use crate::{ data_contract::validation::data_contract_validator::DataContractValidator, diff --git a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs index e86430dcf1e..778dad06ef2 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs @@ -1,5 +1,3 @@ -use std::convert::TryInto; - use dashcore::PrivateKey; use platform_value::BinaryData; use platform_value::{platform_value, Value}; diff --git a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs index 7987dddd34b..de75cc522ca 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs @@ -1,5 +1,5 @@ use platform_value::platform_value; -use platform_value::string_encoding::{decode, Encoding}; +use platform_value::string_encoding::Encoding; use platform_value::BinaryData; use serde_json::json; diff --git a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs index 67f9ce24d91..80624d87e31 100644 --- a/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/validation/public_keys_validator_spec.rs @@ -3,7 +3,7 @@ use crate::identity::validation::PublicKeysValidator; use crate::identity::validation::TPublicKeysValidator; use crate::identity::{KeyID, KeyType, Purpose, SecurityLevel}; use crate::tests::fixtures::get_public_keys_validator; -use crate::tests::utils::platform_value_set_ref; + use crate::{assert_consensus_errors, NativeBlsModule}; use platform_value::BinaryData; use platform_value::{platform_value, Value}; diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index fe2fce456e2..696f4fac38d 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -1,8 +1,6 @@ use std::fmt::Display; -use serde::Deserialize; use thiserror::Error; -use crate::value_serialization; #[derive(Error, Clone, Eq, PartialEq, Debug)] pub enum Error { diff --git a/packages/rs-platform-value/src/types/bytes_32.rs b/packages/rs-platform-value/src/types/bytes_32.rs index 1fe18657022..5bb9782e914 100644 --- a/packages/rs-platform-value/src/types/bytes_32.rs +++ b/packages/rs-platform-value/src/types/bytes_32.rs @@ -1,5 +1,4 @@ use std::fmt; -use std::fmt::Write; use serde::{Deserialize, Serialize}; use serde::de::Visitor; use crate::{Error, string_encoding, Value}; diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 172e455e061..e9739d9306e 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -4,7 +4,7 @@ use std::convert::{TryFrom, TryInto}; use std::fmt; use serde::de::Visitor; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::string_encoding::Encoding; diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index 880dd56c995..19b4e5581ad 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -1,6 +1,6 @@ use crate::error::Error; use crate::value_map::ValueMap; -use crate::{to_value, Value, ValueMapHelper}; +use crate::{to_value, Value}; use serde::ser::{Impossible, Serialize}; use std::fmt::Display; @@ -331,11 +331,6 @@ impl serde::Serializer for Serializer { } } -pub struct SerializeSizedVec { - size: usize, - vec: Vec, -} - pub struct SerializeVec { vec: Vec, } @@ -481,7 +476,7 @@ impl serde::ser::SerializeMap for SerializeMap { fn end(self) -> Result { match self { - SerializeMap::Map { mut map, .. } => { + SerializeMap::Map { map, .. } => { Ok(Value::Map(map)) }, } From 1638c049102eed7095b9d3f81e4f148b2ac1db1f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:15:55 +0700 Subject: [PATCH 147/228] fixes --- packages/rs-dpp/src/identity/identity.rs | 1 - .../identity_update_transition/identity_update_transition.rs | 1 - packages/rs-dpp/src/tests/utils/utils.rs | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index ce957d8a539..a6a90d8fadb 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -13,7 +13,6 @@ use crate::prelude::Revision; use crate::util::cbor_value::{CborBTreeMapHelper, CborCanonicalMap}; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; -use crate::util::json_value::JsonValueExt; use crate::{errors::ProtocolError, identifier::Identifier, metadata::Metadata, util::hash}; use super::{IdentityPublicKey, KeyID}; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 1a13e3505ad..0bae2073267 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -12,7 +12,6 @@ use crate::{ state_transition_helpers, StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - util::json_value::JsonValueExt, version::LATEST_VERSION, ProtocolError, }; diff --git a/packages/rs-dpp/src/tests/utils/utils.rs b/packages/rs-dpp/src/tests/utils/utils.rs index b84deb38fb5..d48bd7a6e65 100644 --- a/packages/rs-dpp/src/tests/utils/utils.rs +++ b/packages/rs-dpp/src/tests/utils/utils.rs @@ -2,6 +2,7 @@ use anyhow::Result; use dashcore::{Block, BlockHeader}; use getrandom::getrandom; use platform_value::Value; +#[cfg(test)] use serde_json::Value as JsonValue; use crate::prelude::Identifier; From 8a3981cf4e795d7d6d85678d4568bdee0e61960a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:25:28 +0700 Subject: [PATCH 148/228] fixes --- .../src/data_contract/validation/multi_validator.rs | 7 ++----- .../validation/state/mod.rs | 4 ++-- .../fee/calculate_state_transition_fee.rs | 4 ++-- .../validate_state_transition_identity_signature.rs | 10 +++++----- .../validate_state_transition_key_signature.rs | 6 +++--- .../validation/data_contract_validator_spec.rs | 12 ++++++------ ...validate_documents_batch_transition_state_spec.rs | 4 ---- .../src/tests/fixtures/get_documents_fixture.rs | 2 +- .../fixtures/identity_create_transition_fixture.rs | 4 ++-- .../identity_credit_withdrawal_transition_fixture.rs | 2 +- .../fixtures/identity_topup_transition_fixture.rs | 2 +- ...dentity_create_transition_basic_validator_spec.rs | 2 +- 12 files changed, 26 insertions(+), 33 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 31e57e33af6..69f0acf4fee 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -147,8 +147,7 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ) - .into(); + ); let mut result = validate(&schema, &[byte_array_has_no_items_as_parent_validator]); assert_eq!(2, result.errors().len()); let first_error = get_basic_error(result.errors.pop().unwrap()); @@ -199,8 +198,7 @@ mod test { "required": ["foo"], "additionalProperties": false, - }) - .into(); + }); let result = validate(&schema, &[pattern_is_valid_regex_validator]); let consensus_error = result.errors.get(0).expect("the error should be returned"); @@ -351,7 +349,6 @@ mod test { } } }) - .into() } fn get_basic_error(error: ConsensusError) -> BasicError { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs index de412a90ad6..265622ba52c 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs @@ -40,7 +40,7 @@ mod test { use crate::{ identity::state_transition::identity_create_transition::IdentityCreateTransition, state_repository::MockStateRepositoryLike, state_transition::StateTransitionLike, - tests::fixtures::identity_create_transition_fixture_json, + tests::fixtures::identity_create_transition_fixture, }; use super::validate_identity_create_transition_state; @@ -48,7 +48,7 @@ mod test { #[tokio::test] async fn should_not_verify_signature_on_dry_run() { let mut state_repository = MockStateRepositoryLike::new(); - let raw_transition = identity_create_transition_fixture_json(None); + let raw_transition = identity_create_transition_fixture(None); let transition = IdentityCreateTransition::new(raw_transition).unwrap(); transition.get_execution_context().enable_dry_run(); diff --git a/packages/rs-dpp/src/state_transition/fee/calculate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/fee/calculate_state_transition_fee.rs index 28f34992cd6..02c908fb8d8 100644 --- a/packages/rs-dpp/src/state_transition/fee/calculate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/fee/calculate_state_transition_fee.rs @@ -25,7 +25,7 @@ mod test { state_transition_execution_context::StateTransitionExecutionContext, StateTransitionLike, }, - tests::fixtures::identity_create_transition_fixture_json, + tests::fixtures::identity_create_transition_fixture, NativeBlsModule, }; @@ -39,7 +39,7 @@ mod test { hex::decode("af432c476f65211f45f48f1d42c9c0b497e56696aa1736b40544ef1a496af837") .unwrap(); let mut state_transition = - IdentityCreateTransition::new(identity_create_transition_fixture_json(None)).unwrap(); + IdentityCreateTransition::new(identity_create_transition_fixture(None)).unwrap(); state_transition .sign_by_private_key(&private_key, KeyType::ECDSA_SECP256K1, &bls) .expect("signing should be successful"); diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs index e87c3f7a8db..1142249db08 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs @@ -401,7 +401,7 @@ mod test { let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); - state_transition.owner_id = owner_id.clone(); + state_transition.owner_id = *owner_id; state_repository_mock .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); @@ -434,7 +434,7 @@ mod test { let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); - state_transition.owner_id = owner_id.clone(); + state_transition.owner_id = *owner_id; state_repository_mock .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); @@ -464,7 +464,7 @@ mod test { let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); - state_transition.owner_id = owner_id.clone(); + state_transition.owner_id = *owner_id; state_repository_mock .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); @@ -492,7 +492,7 @@ mod test { let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); - state_transition.owner_id = owner_id.clone(); + state_transition.owner_id = *owner_id; state_repository_mock .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); @@ -523,7 +523,7 @@ mod test { let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); - state_transition.owner_id = owner_id.clone(); + state_transition.owner_id = *owner_id; state_repository_mock .expect_fetch_identity() .returning(move |_, _| Ok(Some(identity.clone()))); diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs index b12b6b6137b..d995f342fac 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs @@ -154,7 +154,7 @@ mod test { state_transition::{StateTransition, StateTransitionLike}, tests::{ fixtures::{ - identity_create_transition_fixture_json, identity_topup_transition_fixture, + identity_create_transition_fixture, identity_topup_transition_fixture, }, utils::get_signature_error_from_result, }, @@ -219,7 +219,7 @@ mod test { let private_key = PrivateKey::new(secret_key, Network::Testnet); let mut state_transition: StateTransition = IdentityCreateTransition::new( - identity_create_transition_fixture_json(Some(private_key)).into(), + identity_create_transition_fixture(Some(private_key)), ) .unwrap() .into(); @@ -256,7 +256,7 @@ mod test { let private_key = PrivateKey::new(secret_key, Network::Testnet); let mut state_transition: StateTransition = IdentityCreateTransition::new( - identity_create_transition_fixture_json(Some(private_key)).into(), + identity_create_transition_fixture(Some(private_key)), ) .unwrap() .into(); diff --git a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs index b571a744848..291904e0f6d 100644 --- a/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/validation/data_contract_validator_spec.rs @@ -335,7 +335,7 @@ mod defs { .set_value_at_path( "$defs", format!("def_{}", i).as_str(), - platform_value!({"type" : "string"}).into(), + platform_value!({"type" : "string"}), ) .expect("expected to set value"); } @@ -408,7 +408,7 @@ fn owner_id_should_be_byte_array(property_name: &str) { let array = ["string"; 32]; raw_data_contract - .set_value(property_name, platform_value!(array).into()) + .set_value(property_name, platform_value!(array)) .expect("expected to set value"); let result = data_contract_validator @@ -440,7 +440,7 @@ fn owner_id_should_be_no_less_32_bytes(property_name: &str) { let array = [0u8; 31]; raw_data_contract - .set_value(property_name, platform_value!(array).into()) + .set_value(property_name, platform_value!(array)) .expect("expected to set value"); let result = data_contract_validator @@ -467,7 +467,7 @@ fn owner_id_should_be_no_longer_32_bytes(property_name: &str) { let mut too_long_id = Vec::new(); too_long_id.resize(33, 0u8); raw_data_contract - .set_value(property_name, platform_value!(too_long_id).into()) + .set_value(property_name, platform_value!(too_long_id)) .expect("expected to set value"); let result = data_contract_validator @@ -494,7 +494,7 @@ mod documents { } = setup_test(); raw_data_contract - .set_value("documents", platform_value!(1).into()) + .set_value("documents", platform_value!(1)) .expect("expected to set value"); let result = data_contract_validator @@ -516,7 +516,7 @@ mod documents { } = setup_test(); raw_data_contract - .set_value("documents", platform_value!({}).into()) + .set_value("documents", platform_value!({})) .expect("expected to set value"); raw_data_contract["documents"] = platform_value!({}); diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 95c8bfc7b6e..873d40ead51 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -284,8 +284,6 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let mut replace_document = ExtendedDocument::from_raw_json_document( extended_documents[0] .to_json_object_for_validation() - .unwrap() - .try_into() .unwrap(), data_contract.clone(), ) @@ -295,8 +293,6 @@ async fn should_return_invalid_result_if_document_transition_with_action_replace let mut fetched_document = ExtendedDocument::from_raw_json_document( extended_documents[0] .to_json_object_for_validation() - .unwrap() - .try_into() .unwrap(), data_contract.clone(), ) diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 0d9ec8befaf..a005a865d93 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -119,7 +119,7 @@ fn get_extended_documents( data_contract, owner_id, "optionalUniqueIndexedDocument".to_string(), - platform_value!({ "firstName": "Jacques-Yves", "lastName": "Cousteau" }).into() + platform_value!({ "firstName": "Jacques-Yves", "lastName": "Cousteau" }) )?, ]; diff --git a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs index 778dad06ef2..48beb6f6f38 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_create_transition_fixture.rs @@ -10,11 +10,11 @@ use platform_value::string_encoding::{decode, Encoding}; //3bufpwQjL5qsvuP4fmCKgXJrKG852DDMYfi9J6XKqPAT //[198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237] -pub fn identity_create_transition_fixture_json(one_time_private_key: Option) -> Value { +pub fn identity_create_transition_fixture(one_time_private_key: Option) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); platform_value!({ - "protocolVersion": version::LATEST_VERSION as u32, + "protocolVersion": version::LATEST_VERSION, "type": 2u8, "assetLockProof": asset_lock_proof, "publicKeys": [ diff --git a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs index 0b6ed7c5d4b..6ccefd47fc0 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_credit_withdrawal_transition_fixture.rs @@ -14,7 +14,7 @@ use crate::{ pub fn identity_credit_withdrawal_transition_fixture_raw_object() -> Value { platform_value!({ - "protocolVersion": version::LATEST_VERSION as u32, + "protocolVersion": version::LATEST_VERSION, "type": StateTransitionType::IdentityCreditWithdrawal as u8, "identityId": Identifier::from([1_u8; 32]), "amount": 1042u64, diff --git a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs index c2f882b15d6..2535df9ec30 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_topup_transition_fixture.rs @@ -11,7 +11,7 @@ use crate::version; pub fn identity_topup_transition_fixture(one_time_private_key: Option) -> Value { let asset_lock_proof = instant_asset_lock_proof_fixture(one_time_private_key); platform_value!({ - "protocolVersion": version::LATEST_VERSION as u32, + "protocolVersion": version::LATEST_VERSION, "type": StateTransitionType::IdentityTopUp as u8, "assetLockProof": asset_lock_proof, "identityId": Identifier::new([198, 23, 40, 120, 58, 93, 0, 165, 27, 49, 4, 117, 107, 204, 67, 46, 164, 216, 230, 135, 201, 92, 31, 155, 62, 131, 211, 177, 139, 175, 163, 237]), diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index 27144b2100f..5611ad8d77e 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -63,7 +63,7 @@ pub fn setup_test( let protocol_version_validator = ProtocolVersionValidator::default(); ( - crate::tests::fixtures::identity_create_transition_fixture_json(None), + crate::tests::fixtures::identity_create_transition_fixture(None), IdentityCreateTransitionBasicValidator::new( protocol_version_validator, public_keys_validator, From f6624aed27449cd7dcb595887b2672ef8d0686f4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:27:30 +0700 Subject: [PATCH 149/228] more fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 6 +++--- .../src/data_contract/document_type/index.rs | 2 +- .../errors/data_contract_not_present_error.rs | 2 +- .../errors/identity_not_present_error.rs | 2 +- ...te_data_contract_update_transition_basic.rs | 2 +- .../validation/multi_validator.rs | 3 +-- ...apply_documents_batch_transition_factory.rs | 2 +- ...alidate_documents_batch_transition_basic.rs | 2 +- ...alidate_documents_batch_transition_state.rs | 12 ++++++------ .../incompatible_data_contract_schema_error.rs | 2 +- .../invalid_document_transition_id_error.rs | 4 ++-- .../document/invalid_document_type_error.rs | 2 +- .../invalid_identity_key_signature_error.rs | 2 +- .../signature/identity_not_found_error.rs | 2 +- .../invalid_identity_public_key_type_error.rs | 2 +- ...ignature_public_key_security_level_error.rs | 4 ++-- .../signature/public_key_is_disabled_error.rs | 2 +- .../public_key_security_level_not_met_error.rs | 4 ++-- .../wrong_public_key_purpose_error.rs | 4 ++-- .../invalid_identity_public_key_type_error.rs | 2 +- .../public_key_security_level_not_met_error.rs | 4 ++-- .../errors/wrong_public_key_purpose_error.rs | 4 ++-- .../state_transition_factory.rs | 2 +- .../validate_state_transition_fee.rs | 4 ++-- .../tests/fixtures/get_documents_fixture.rs | 18 +++++++++--------- 25 files changed, 47 insertions(+), 48 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 1b89a0e738e..cde8799fc18 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -298,7 +298,7 @@ impl DataContract { .ok_or(ProtocolError::DataContractError( DataContractError::InvalidDocumentTypeError(InvalidDocumentTypeError::new( doc_type.to_owned(), - self.id.clone(), + self.id, )), ))?; Ok(document) @@ -309,7 +309,7 @@ impl DataContract { return Err(ProtocolError::DataContractError( DataContractError::InvalidDocumentTypeError(InvalidDocumentTypeError::new( doc_type.to_owned(), - self.id.clone(), + self.id, )), )); }; @@ -333,7 +333,7 @@ impl DataContract { .ok_or(ProtocolError::DataContractError( DataContractError::InvalidDocumentTypeError(InvalidDocumentTypeError::new( doc_type.to_owned(), - self.id.clone(), + self.id, )), )) } diff --git a/packages/rs-dpp/src/data_contract/document_type/index.rs b/packages/rs-dpp/src/data_contract/document_type/index.rs index 5c7b7bb1874..047f76114b7 100644 --- a/packages/rs-dpp/src/data_contract/document_type/index.rs +++ b/packages/rs-dpp/src/data_contract/document_type/index.rs @@ -18,7 +18,7 @@ pub struct Index { impl Index { /// Check to see if two objects are conflicting pub fn objects_are_conflicting(&self, object1: &ValueMap, object2: &ValueMap) -> bool { - if self.unique == false { + if !self.unique { return false; } self.properties.iter().all(|property| { diff --git a/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs b/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs index 440cf3f79eb..77860f7ce1e 100644 --- a/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs +++ b/packages/rs-dpp/src/data_contract/errors/data_contract_not_present_error.rs @@ -15,7 +15,7 @@ impl DataContractNotPresentError { } pub fn data_contract_id(&self) -> Identifier { - self.data_contract_id.clone() + self.data_contract_id } } diff --git a/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs b/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs index 82d3fdf1f78..2cbed031790 100644 --- a/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs +++ b/packages/rs-dpp/src/data_contract/errors/identity_not_present_error.rs @@ -15,7 +15,7 @@ impl IdentityNotPresentError { } pub fn id(&self) -> Identifier { - self.id.clone() + self.id } } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 7cc0bda57cc..b717341adf4 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -192,7 +192,7 @@ where get_operation_and_property_name_json(&diffs[0]); validation_result.add_error(BasicError::IncompatibleDataContractSchemaError( IncompatibleDataContractSchemaError::new( - existing_data_contract.id.clone(), + existing_data_contract.id, operation_name.to_owned(), property_name.to_owned(), document_schema.clone(), diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 69f0acf4fee..8b409faca04 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -178,8 +178,7 @@ mod test { "required": ["foo"], "additionalProperties": false, } - ) - .into(); + ); assert!(validate(&schema, &[pattern_is_valid_regex_validator]).is_valid()) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs index 2aebcdb712d..88730fafa1a 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/apply_documents_batch_transition_factory.rs @@ -87,7 +87,7 @@ pub async fn apply_documents_batch_transition( })?; document_replace_transition.replace_extended_document(document)?; state_repository - .update_document(&document, state_transition.get_execution_context()) + .update_document(document, state_transition.get_execution_context()) .await?; }; } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index ad0203d0b50..c0e5e259b22 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -228,7 +228,7 @@ fn validate_raw_transitions<'a>( if !data_contract.is_document_defined(document_type) { result.add_error(BasicError::InvalidDocumentTypeError( - InvalidDocumentTypeError::new(document_type.to_string(), data_contract.id.clone()), + InvalidDocumentTypeError::new(document_type.to_string(), data_contract.id), )); return Ok(result); } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index 02c5a75784c..65c3d70efe6 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -82,7 +82,7 @@ pub async fn validate_document_transitions( .map_err(Into::into)? .ok_or_else(|| { ProtocolError::DataContractNotPresentError(DataContractNotPresentError::new( - data_contract_id.clone(), + *data_contract_id, )) })?; @@ -277,7 +277,7 @@ fn check_if_document_is_already_present( if maybe_fetched_document.is_some() { result.add_error(ConsensusError::StateError(Box::new( StateError::DocumentAlreadyPresentError { - document_id: document_transition.base().id.clone(), + document_id: document_transition.base().id, }, ))) } @@ -296,7 +296,7 @@ fn check_if_document_can_be_found( if maybe_fetched_document.is_none() { result.add_error(ConsensusError::StateError(Box::new( StateError::DocumentNotFoundError { - document_id: document_transition.base().id.clone(), + document_id: document_transition.base().id, }, ))) } @@ -311,7 +311,7 @@ fn check_if_timestamps_are_equal(document_transition: &DocumentTransition) -> Va if created_at.is_some() && updated_at.is_some() && updated_at.unwrap() != created_at.unwrap() { result.add_error(ConsensusError::StateError(Box::new( StateError::DocumentTimestampsMismatchError { - document_id: document_transition.base().id.clone(), + document_id: document_transition.base().id, }, ))); } @@ -334,7 +334,7 @@ fn check_created_inside_time_window( result.add_error(ConsensusError::StateError(Box::new( StateError::DocumentTimestampWindowViolationError { timestamp_name: String::from("createdAt"), - document_id: document_transition.base().id.clone(), + document_id: document_transition.base().id, timestamp: created_at as i64, time_window_start: window_validation.time_window_start as i64, time_window_end: window_validation.time_window_end as i64, @@ -359,7 +359,7 @@ fn check_updated_inside_time_window( result.add_error(ConsensusError::StateError(Box::new( StateError::DocumentTimestampWindowViolationError { timestamp_name: String::from("updatedAt"), - document_id: document_transition.base().id.clone(), + document_id: document_transition.base().id, timestamp: updated_at as i64, time_window_start: window_validation.time_window_start as i64, time_window_end: window_validation.time_window_end as i64, diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/incompatible_data_contract_schema_error.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/incompatible_data_contract_schema_error.rs index c7d425dabf4..428600507f0 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/data_contract/incompatible_data_contract_schema_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/incompatible_data_contract_schema_error.rs @@ -34,7 +34,7 @@ impl IncompatibleDataContractSchemaError { } pub fn data_contract_id(&self) -> Identifier { - self.data_contract_id.clone() + self.data_contract_id } pub fn operation(&self) -> String { self.operation.clone() diff --git a/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_transition_id_error.rs b/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_transition_id_error.rs index 53b29f79cae..a34a81c2cd2 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_transition_id_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_transition_id_error.rs @@ -22,11 +22,11 @@ impl InvalidDocumentTransitionIdError { } pub fn expected_id(&self) -> Identifier { - self.expected_id.clone() + self.expected_id } pub fn invalid_id(&self) -> Identifier { - self.invalid_id.clone() + self.invalid_id } } diff --git a/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_type_error.rs b/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_type_error.rs index 1f9811ea2fd..d78a144f5e1 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_type_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/document/invalid_document_type_error.rs @@ -23,7 +23,7 @@ impl InvalidDocumentTypeError { } pub fn data_contract_id(&self) -> Identifier { - self.data_contract_id.clone() + self.data_contract_id } } diff --git a/packages/rs-dpp/src/errors/consensus/basic/identity/invalid_identity_key_signature_error.rs b/packages/rs-dpp/src/errors/consensus/basic/identity/invalid_identity_key_signature_error.rs index a38e93bd09a..999ed0bb72b 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/identity/invalid_identity_key_signature_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/identity/invalid_identity_key_signature_error.rs @@ -15,7 +15,7 @@ impl InvalidIdentityKeySignatureError { } pub fn public_key_id(&self) -> KeyID { - self.public_key_id.clone() + self.public_key_id } } diff --git a/packages/rs-dpp/src/errors/consensus/signature/identity_not_found_error.rs b/packages/rs-dpp/src/errors/consensus/signature/identity_not_found_error.rs index 1acdcbab98b..4ce82f3b6b1 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/identity_not_found_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/identity_not_found_error.rs @@ -16,7 +16,7 @@ impl IdentityNotFoundError { } pub fn identity_id(&self) -> Identifier { - self.identity_id.clone() + self.identity_id } } diff --git a/packages/rs-dpp/src/errors/consensus/signature/invalid_identity_public_key_type_error.rs b/packages/rs-dpp/src/errors/consensus/signature/invalid_identity_public_key_type_error.rs index cbd77b97495..3fa7a96938a 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/invalid_identity_public_key_type_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/invalid_identity_public_key_type_error.rs @@ -16,7 +16,7 @@ impl InvalidIdentityPublicKeyTypeError { } pub fn public_key_type(&self) -> KeyType { - self.public_key_type.clone() + self.public_key_type } } diff --git a/packages/rs-dpp/src/errors/consensus/signature/invalid_signature_public_key_security_level_error.rs b/packages/rs-dpp/src/errors/consensus/signature/invalid_signature_public_key_security_level_error.rs index cf155a36d76..74d898a663f 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/invalid_signature_public_key_security_level_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/invalid_signature_public_key_security_level_error.rs @@ -23,10 +23,10 @@ impl InvalidSignaturePublicKeySecurityLevelError { } pub fn public_key_security_level(&self) -> SecurityLevel { - self.public_key_security_level.clone() + self.public_key_security_level } pub fn required_key_security_level(&self) -> SecurityLevel { - self.required_key_security_level.clone() + self.required_key_security_level } } diff --git a/packages/rs-dpp/src/errors/consensus/signature/public_key_is_disabled_error.rs b/packages/rs-dpp/src/errors/consensus/signature/public_key_is_disabled_error.rs index 067d3975492..27b64619a96 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/public_key_is_disabled_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/public_key_is_disabled_error.rs @@ -16,7 +16,7 @@ impl PublicKeyIsDisabledError { } pub fn public_key_id(&self) -> KeyID { - self.public_key_id.clone() + self.public_key_id } } diff --git a/packages/rs-dpp/src/errors/consensus/signature/public_key_security_level_not_met_error.rs b/packages/rs-dpp/src/errors/consensus/signature/public_key_security_level_not_met_error.rs index d959065038f..b3bed276c8b 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/public_key_security_level_not_met_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/public_key_security_level_not_met_error.rs @@ -23,10 +23,10 @@ impl PublicKeySecurityLevelNotMetError { } pub fn public_key_security_level(&self) -> SecurityLevel { - self.public_key_security_level.clone() + self.public_key_security_level } pub fn required_security_level(&self) -> SecurityLevel { - self.required_security_level.clone() + self.required_security_level } } diff --git a/packages/rs-dpp/src/errors/consensus/signature/wrong_public_key_purpose_error.rs b/packages/rs-dpp/src/errors/consensus/signature/wrong_public_key_purpose_error.rs index c825fcb31ca..622195ec5e5 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/wrong_public_key_purpose_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/wrong_public_key_purpose_error.rs @@ -20,10 +20,10 @@ impl WrongPublicKeyPurposeError { } pub fn public_key_purpose(&self) -> Purpose { - self.public_key_purpose.clone() + self.public_key_purpose } pub fn key_purpose_requirement(&self) -> Purpose { - self.key_purpose_requirement.clone() + self.key_purpose_requirement } } diff --git a/packages/rs-dpp/src/state_transition/errors/invalid_identity_public_key_type_error.rs b/packages/rs-dpp/src/state_transition/errors/invalid_identity_public_key_type_error.rs index 33dd2468da5..7685a719849 100644 --- a/packages/rs-dpp/src/state_transition/errors/invalid_identity_public_key_type_error.rs +++ b/packages/rs-dpp/src/state_transition/errors/invalid_identity_public_key_type_error.rs @@ -15,7 +15,7 @@ impl InvalidIdentityPublicKeyTypeError { } pub fn public_key_type(&self) -> KeyType { - self.public_key_type.clone() + self.public_key_type } } diff --git a/packages/rs-dpp/src/state_transition/errors/public_key_security_level_not_met_error.rs b/packages/rs-dpp/src/state_transition/errors/public_key_security_level_not_met_error.rs index c69caff4026..898c22a30f8 100644 --- a/packages/rs-dpp/src/state_transition/errors/public_key_security_level_not_met_error.rs +++ b/packages/rs-dpp/src/state_transition/errors/public_key_security_level_not_met_error.rs @@ -22,10 +22,10 @@ impl PublicKeySecurityLevelNotMetError { } pub fn public_key_security_level(&self) -> SecurityLevel { - self.public_key_security_level.clone() + self.public_key_security_level } pub fn required_security_level(&self) -> SecurityLevel { - self.required_security_level.clone() + self.required_security_level } } diff --git a/packages/rs-dpp/src/state_transition/errors/wrong_public_key_purpose_error.rs b/packages/rs-dpp/src/state_transition/errors/wrong_public_key_purpose_error.rs index 12f05a3f437..7f1fdb8522e 100644 --- a/packages/rs-dpp/src/state_transition/errors/wrong_public_key_purpose_error.rs +++ b/packages/rs-dpp/src/state_transition/errors/wrong_public_key_purpose_error.rs @@ -19,10 +19,10 @@ impl WrongPublicKeyPurposeError { } pub fn public_key_purpose(&self) -> Purpose { - self.public_key_purpose.clone() + self.public_key_purpose } pub fn key_purpose_requirement(&self) -> Purpose { - self.key_purpose_requirement.clone() + self.key_purpose_requirement } } diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 10713ac03de..c2202e035ac 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -66,7 +66,7 @@ pub async fn create_state_transition( ) .await?; let documents_batch_transition = DocumentsBatchTransition::from_raw_object( - raw_state_transition.into(), + raw_state_transition, data_contracts, )?; Ok(StateTransition::DocumentsBatch(documents_batch_transition)) diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs index dee849c6c1a..f98764ce43e 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs @@ -78,7 +78,7 @@ where .map_err(Into::into)? .ok_or_else(|| { ProtocolError::IdentityNotPresentError(IdentityNotPresentError::new( - identity_id.clone(), + *identity_id, )) })?; @@ -152,7 +152,7 @@ where .map_err(Into::into)? .ok_or_else(|| { ProtocolError::IdentityNotPresentError(IdentityNotPresentError::new( - identity_id.clone(), + *identity_id, )) })?; diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index a005a865d93..715b5952897 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -70,51 +70,51 @@ fn get_extended_documents( data_contract.clone(), owner_id, "niceDocument".to_string(), - platform_value!({ "name": "Cutie" }).into(), + platform_value!({ "name": "Cutie" }), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "prettyDocument".to_string(), - platform_value!({ "lastName": "Shiny" }).into(), + platform_value!({ "lastName": "Shiny" }), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "prettyDocument".to_string(), - platform_value!({ "lastName": "Sweety" }).into(), + platform_value!({ "lastName": "Sweety" }), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - platform_value!( { "firstName": "William", "lastName": "Birkin" }).into(), + platform_value!( { "firstName": "William", "lastName": "Birkin" }), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - platform_value!( { "firstName": "Leon", "lastName": "Kennedy" }).into(), + platform_value!( { "firstName": "Leon", "lastName": "Kennedy" }), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "noTimeDocument".to_string(), - platform_value!({ "name": "ImOutOfTime" }).into(), + platform_value!({ "name": "ImOutOfTime" }), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "uniqueDates".to_string(), - platform_value!({ "firstName": "John" }).into(), + platform_value!({ "firstName": "John" }), )?, factory.create_extended_document_for_state_transition( data_contract.clone(), owner_id, "indexedDocument".to_string(), - platform_value!( { "firstName": "Bill", "lastName": "Gates" }).into(), + platform_value!( { "firstName": "Bill", "lastName": "Gates" }), )?, - factory.create_extended_document_for_state_transition(data_contract.clone(), owner_id, "withByteArrays".to_string(), platform_value!( { "byteArrayField": get_random_10_bytes(), "identifierField": gen_owner_id().to_buffer() }).into())?, + factory.create_extended_document_for_state_transition(data_contract.clone(), owner_id, "withByteArrays".to_string(), platform_value!( { "byteArrayField": get_random_10_bytes(), "identifierField": gen_owner_id().to_buffer() }))?, factory.create_extended_document_for_state_transition( data_contract, owner_id, From 8b711f3e851d9ee0885e450863d652af22c58d21 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:28:08 +0700 Subject: [PATCH 150/228] more fixes --- .../state_transition_factory.rs | 6 ++--- .../validate_state_transition_fee.rs | 4 +--- ...validate_state_transition_key_signature.rs | 22 ++++++++----------- ...e_documents_batch_transition_state_spec.rs | 1 - 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index c2202e035ac..2ccfa1a4b5f 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -65,10 +65,8 @@ pub async fn create_state_transition( &execution_context, ) .await?; - let documents_batch_transition = DocumentsBatchTransition::from_raw_object( - raw_state_transition, - data_contracts, - )?; + let documents_batch_transition = + DocumentsBatchTransition::from_raw_object(raw_state_transition, data_contracts)?; Ok(StateTransition::DocumentsBatch(documents_batch_transition)) } // TODO!! add basic validation diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs index f98764ce43e..765bc0d817d 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs @@ -151,9 +151,7 @@ where .transpose() .map_err(Into::into)? .ok_or_else(|| { - ProtocolError::IdentityNotPresentError(IdentityNotPresentError::new( - *identity_id, - )) + ProtocolError::IdentityNotPresentError(IdentityNotPresentError::new(*identity_id)) })?; Ok(identity.get_balance()) diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs index d995f342fac..17e82fcdda9 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs @@ -153,9 +153,7 @@ mod test { state_repository::MockStateRepositoryLike, state_transition::{StateTransition, StateTransitionLike}, tests::{ - fixtures::{ - identity_create_transition_fixture, identity_topup_transition_fixture, - }, + fixtures::{identity_create_transition_fixture, identity_topup_transition_fixture}, utils::get_signature_error_from_result, }, NativeBlsModule, @@ -218,11 +216,10 @@ mod test { .expect("secret key should be created"); let private_key = PrivateKey::new(secret_key, Network::Testnet); - let mut state_transition: StateTransition = IdentityCreateTransition::new( - identity_create_transition_fixture(Some(private_key)), - ) - .unwrap() - .into(); + let mut state_transition: StateTransition = + IdentityCreateTransition::new(identity_create_transition_fixture(Some(private_key))) + .unwrap() + .into(); state_transition .sign_by_private_key( @@ -255,11 +252,10 @@ mod test { .expect("secret key should be created"); let private_key = PrivateKey::new(secret_key, Network::Testnet); - let mut state_transition: StateTransition = IdentityCreateTransition::new( - identity_create_transition_fixture(Some(private_key)), - ) - .unwrap() - .into(); + let mut state_transition: StateTransition = + IdentityCreateTransition::new(identity_create_transition_fixture(Some(private_key))) + .unwrap() + .into(); state_transition .sign_by_private_key( diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index 873d40ead51..c4cba82b141 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -1,5 +1,4 @@ use std::collections::BTreeMap; -use std::convert::TryInto; use std::time::Duration; use chrono::Utc; From 5da08d51199361640caa561978e38af451404803 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:32:41 +0700 Subject: [PATCH 151/228] more work --- .../state/validate_documents_batch_transition_state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index 65c3d70efe6..1b41e2032d6 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -216,7 +216,7 @@ fn check_ownership( Some(d) => d, None => return result, }; - if &fetched_document.owner_id() != owner_id { + if fetched_document.owner_id() != owner_id { result.add_error(ConsensusError::StateError(Box::new( StateError::DocumentOwnerIdMismatchError { document_id: document_transition.base().id, From 234fdca6efb6d7f8063d27d0ba60293227471b31 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 14:44:26 +0700 Subject: [PATCH 152/228] fixed rs-drive --- packages/rs-dpp/src/document/document.rs | 6 +++--- packages/rs-dpp/src/document/extended_document.rs | 2 +- packages/rs-dpp/src/document/serialize.rs | 4 ++-- packages/rs-dpp/src/util/json_value/mod.rs | 2 +- packages/rs-drive-abci/src/state/genesis.rs | 2 +- packages/rs-drive/src/drive/document/mod.rs | 2 +- packages/rs-drive/src/drive/identity/insert.rs | 2 +- packages/rs-drive/src/query/mod.rs | 4 +++- packages/rs-platform-value/src/types/identifier.rs | 4 ++-- 9 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 0dfa42d2906..4abee2714ba 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -107,8 +107,8 @@ impl Document { } else { match key_path { // returns self.id or self.owner_id if key path is $id or $ownerId - "$id" => return Ok(Some(self.id.to_buffer_vec())), - "$ownerId" => return Ok(Some(self.owner_id.to_buffer_vec())), + "$id" => return Ok(Some(self.id.to_vec())), + "$ownerId" => return Ok(Some(self.owner_id.to_vec())), "$createdAt" => { return Ok(self .created_at @@ -252,7 +252,7 @@ impl Document { contract: &DataContract, document_type: &DocumentType, ) -> Result, ProtocolError> { - let mut buf = contract.id.to_buffer_vec(); + let mut buf = contract.id.to_vec(); buf.extend(document_type.name.as_bytes()); buf.extend(self.serialize(document_type)?); Ok(hash(buf)) diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index d36d51863c0..58567434709 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -345,7 +345,7 @@ impl ExtendedDocument { value_mut.push(( CborValue::Text(property_names::DATA_CONTRACT_ID.to_string()), - CborValue::Bytes(self.data_contract_id.to_buffer_vec()), + CborValue::Bytes(self.data_contract_id.to_vec()), )); let canonical_map: CborCanonicalMap = cbor_value.try_into()?; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 350e5a51f94..50c6a1ecc60 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -145,8 +145,8 @@ impl Document { mut self, document_type: &DocumentType, ) -> Result, ProtocolError> { - let mut buffer: Vec = self.id.to_buffer_vec(); - let mut owner_id = self.owner_id.to_buffer_vec(); + let mut buffer: Vec = self.id.to_vec(); + let mut owner_id = self.owner_id.to_vec(); buffer.append(&mut owner_id); if let Some(revision) = self.revision { diff --git a/packages/rs-dpp/src/util/json_value/mod.rs b/packages/rs-dpp/src/util/json_value/mod.rs index 0ebe99b8ba8..7e9cf2e2522 100644 --- a/packages/rs-dpp/src/util/json_value/mod.rs +++ b/packages/rs-dpp/src/util/json_value/mod.rs @@ -496,7 +496,7 @@ pub fn replace_identifier( } ReplaceWith::Bytes => { let data_string: String = serde_json::from_value(to_replace.clone())?; - let identifier = Identifier::from_string(&data_string, Encoding::Base58)?.to_vec(); + let identifier = Identifier::from_string(&data_string, Encoding::Base58)?.to_json_value_vec(); *to_replace = JsonValue::Array(identifier); } } diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index d0635e90f51..539a96a9223 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -244,7 +244,7 @@ impl Platform { "normalizedParentDomainName" => "", "preorderSalt" => CborValue::Bytes(DPNS_DASH_TLD_PREORDER_SALT.to_vec()), "records" => { - "dashAliasIdentityId" => CborValue::Bytes(contract.owner_id.to_buffer_vec()), + "dashAliasIdentityId" => CborValue::Bytes(contract.owner_id.to_vec()), }, }) .map_err(|_| { diff --git a/packages/rs-drive/src/drive/document/mod.rs b/packages/rs-drive/src/drive/document/mod.rs index 0445350660e..f5292a1cdb4 100644 --- a/packages/rs-drive/src/drive/document/mod.rs +++ b/packages/rs-drive/src/drive/document/mod.rs @@ -147,7 +147,7 @@ fn make_document_reference( // 0 represents document storage // Then we add document id // Then we add 0 if the document type keys history - let mut reference_path = vec![vec![0], Vec::from(document.id)]; + let mut reference_path = vec![vec![0], document.id.to_vec()]; let mut max_reference_hops = 1; if document_type.documents_keep_history { reference_path.push(vec![0]); diff --git a/packages/rs-drive/src/drive/identity/insert.rs b/packages/rs-drive/src/drive/identity/insert.rs index c25b6464d22..a02d307e23f 100644 --- a/packages/rs-drive/src/drive/identity/insert.rs +++ b/packages/rs-drive/src/drive/identity/insert.rs @@ -118,7 +118,7 @@ impl Drive { // We insert the identity tree let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey((identity_tree_path, id.to_buffer_vec())), + PathFixedSizeKey((identity_tree_path, id.to_vec())), Some(&storage_flags), apply_type, transaction, diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index a6fe3f1cc5f..0fd65324c15 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -103,6 +103,7 @@ use dpp::data_contract::extra::common::bytes_for_system_value; use dpp::document::Document; #[cfg(any(feature = "full", feature = "verify"))] use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; +use dpp::platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; #[cfg(any(feature = "full", feature = "verify"))] use dpp::platform_value::Value; #[cfg(any(feature = "full", feature = "verify"))] @@ -317,7 +318,8 @@ impl<'a> DriveQuery<'a> { )) })?; let mut query_document: BTreeMap = - Value::convert_from_cbor_map(query_document_cbor); + Value::convert_from_cbor_map(query_document_cbor) + .map_err(|e| Error::Protocol(ProtocolError::ValueError(e)))?; let maybe_limit: Option = query_document .remove_optional_integer("limit") diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index e9739d9306e..75f2c273484 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -152,7 +152,7 @@ impl Identifier { Ok(Identifier::new(bytes.try_into().unwrap())) } - pub fn to_vec(&self) -> Vec { + pub fn to_json_value_vec(&self) -> Vec { self.to_buffer() .iter() .map(|v| JsonValue::from(*v)) @@ -169,7 +169,7 @@ impl Identifier { } /// Convenience method to get underlying buffer as a vec - pub fn to_buffer_vec(&self) -> Vec { + pub fn to_vec(&self) -> Vec { self.0 .0.to_vec() } From 1544a833ce9a6ae7fab528634f22b90c5dc86ac5 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 17:49:35 +0700 Subject: [PATCH 153/228] fixed compilation issues --- .../document_type/random_document.rs | 8 +- .../state_transition/asset_lock_proof/mod.rs | 12 +++ .../tests/fixtures/get_documents_fixture.rs | 2 +- packages/rs-dpp/src/util/json_value/mod.rs | 10 +- .../src/identity_credit_withdrawal/mod.rs | 99 ++++++++++--------- packages/rs-drive-abci/src/state/genesis.rs | 41 ++++---- .../src/test/helpers/fee_pools.rs | 7 +- .../tests/strategy_tests/main.rs | 6 +- .../btreemap_field_replacement.rs | 24 +++-- .../src/btreemap_extensions/mod.rs | 9 +- .../src/converter/ciborium.rs | 2 +- packages/rs-platform-value/src/inner_value.rs | 69 +++++++------ .../src/inner_value_at_path.rs | 9 +- packages/rs-platform-value/src/lib.rs | 28 +++++- packages/rs-platform-value/src/macros.rs | 3 +- .../rs-platform-value/src/system_bytes.rs | 50 +++++----- .../src/types/binary_data.rs | 28 +++--- .../rs-platform-value/src/types/bytes_32.rs | 31 +++--- .../rs-platform-value/src/types/identifier.rs | 57 +++++------ packages/rs-platform-value/src/types/mod.rs | 4 +- packages/rs-platform-value/src/value_map.rs | 2 +- .../src/value_serialization/de.rs | 6 +- .../src/value_serialization/mod.rs | 4 +- .../src/value_serialization/ser.rs | 10 +- .../src/data_contract/data_contract.rs | 17 ++-- .../src/data_contract/data_contract_facade.rs | 24 +++-- .../errors/data_contract_generic_error.rs | 2 - .../data_contract_create_transition/mod.rs | 16 +-- .../validation.rs | 3 +- .../data_contract_update_transition/mod.rs | 16 +-- .../validation.rs | 3 +- .../data_contract_factory.rs | 19 +++- .../src/document/extended_document.rs | 44 ++++----- packages/wasm-dpp/src/document/factory.rs | 7 +- .../fetch_and_validate_data_contract.rs | 14 +-- packages/wasm-dpp/src/document/mod.rs | 50 +++++----- .../document_create_transition.rs | 6 +- .../document_replace_transition.rs | 6 +- .../document_transition/mod.rs | 4 +- .../document_batch_transition/mod.rs | 56 ++++++----- .../basic/find_duplicates_by_indices.rs | 6 +- .../missing_data_contract_id_error.rs | 6 +- .../wasm-dpp/src/errors/consensus_error.rs | 4 + packages/wasm-dpp/src/errors/from.rs | 1 - packages/wasm-dpp/src/errors/value_error.rs | 1 - packages/wasm-dpp/src/identifier/mod.rs | 22 +++-- .../wasm-dpp/src/identity/factory_utils.rs | 4 +- .../wasm-dpp/src/identity/identity_facade.rs | 2 +- .../wasm-dpp/src/identity/identity_factory.rs | 8 +- .../src/identity/identity_public_key/mod.rs | 5 +- .../chain/chain_asset_lock_proof.rs | 15 +-- ...in_asset_lock_proof_structure_validator.rs | 4 +- .../instant/instant_asset_lock_proof.rs | 4 +- ...nt_asset_lock_proof_structure_validator.rs | 4 +- .../identity_create_transition.rs | 8 +- ...ntity_create_transition_basic_validator.rs | 4 +- .../identity_create_transition/to_object.rs | 2 +- .../identity_public_key_transitions.rs | 11 ++- .../identity_topup_transition.rs | 6 +- ...entity_topup_transition_basic_validator.rs | 4 +- .../identity_topup_transition/to_object.rs | 2 +- .../identity_update_public_keys_validator.rs | 8 +- .../identity_update_transition.rs | 14 +-- ...ntity_update_transition_basic_validator.rs | 2 +- .../identity_update_transition/to_object.rs | 2 +- .../validate_public_key_signatures.rs | 10 +- .../identity/validation/identity_validator.rs | 7 +- .../validation/public_keys_validator.rs | 10 +- packages/wasm-dpp/src/utils.rs | 22 ++--- 69 files changed, 549 insertions(+), 457 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/random_document.rs b/packages/rs-dpp/src/data_contract/document_type/random_document.rs index dd67f17d7b3..cb804bfa90e 100644 --- a/packages/rs-dpp/src/data_contract/document_type/random_document.rs +++ b/packages/rs-dpp/src/data_contract/document_type/random_document.rs @@ -97,8 +97,8 @@ impl CreateRandomDocument for DocumentType { /// Creates a document with a random id, owner id, and properties using StdRng. fn random_document_with_rng(&self, rng: &mut StdRng) -> Document { - let id = Identifier::random(rng); - let owner_id = Identifier::random(rng); + let id = Identifier::random_with_rng(rng); + let owner_id = Identifier::random_with_rng(rng); let mut created_at = None; let mut updated_at = None; let properties = self @@ -167,8 +167,8 @@ impl CreateRandomDocument for DocumentType { /// Creates a Document with properties filled to max size with random data, along with /// a random id and owner id. fn random_filled_document_with_rng(&self, rng: &mut StdRng) -> Document { - let id = Identifier::random(rng); - let owner_id = Identifier::random(rng); + let id = Identifier::random_with_rng(rng); + let owner_id = Identifier::random_with_rng(rng); let properties = self .properties .iter() diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index 346e0f6ee51..d5388ef5ed3 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -94,6 +94,18 @@ impl TryFrom for AssetLockProofType { } } +impl TryFrom for AssetLockProofType { + type Error = SerdeParsingError; + + fn try_from(value: u64) -> Result { + match value { + 0 => Ok(Self::Instant), + 1 => Ok(Self::Chain), + _ => Err(SerdeParsingError::new("Unexpected asset lock proof type")), + } + } +} + impl AssetLockProof { pub fn type_from_raw_value(value: &Value) -> Option { let proof_type_res = value.get_integer::("type"); diff --git a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs index 715b5952897..3e506103f6c 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -143,7 +143,7 @@ pub fn get_withdrawal_document_fixture( .into_btree_string_map() .map_err(ProtocolError::ValueError)?; - let id = Identifier::random(&mut rng); + let id = Identifier::random_with_rng(&mut rng); document_type.create_document_with_valid_properties(id, owner_id, properties) } diff --git a/packages/rs-dpp/src/util/json_value/mod.rs b/packages/rs-dpp/src/util/json_value/mod.rs index 7e9cf2e2522..447abba5b50 100644 --- a/packages/rs-dpp/src/util/json_value/mod.rs +++ b/packages/rs-dpp/src/util/json_value/mod.rs @@ -87,7 +87,7 @@ pub trait JsonValueExt { fn insert_with_path(&mut self, path: &str, value: JsonValue) -> Result<(), anyhow::Error>; /// Removes data from given path and tries deserialize it into provided type - fn remove_path_into( + fn remove_value_at_path_into( &mut self, property_name: &str, ) -> Result; @@ -431,7 +431,10 @@ impl JsonValueExt for JsonValue { } /// Removes the value under given path and tries to deserialize it into provided type - fn remove_path_into(&mut self, path: &str) -> Result { + fn remove_value_at_path_into( + &mut self, + path: &str, + ) -> Result { let path_literal: JsonPathLiteral = path.into(); let json_path: JsonPath = path_literal.try_into().unwrap(); @@ -496,7 +499,8 @@ pub fn replace_identifier( } ReplaceWith::Bytes => { let data_string: String = serde_json::from_value(to_replace.clone())?; - let identifier = Identifier::from_string(&data_string, Encoding::Base58)?.to_json_value_vec(); + let identifier = + Identifier::from_string(&data_string, Encoding::Base58)?.to_json_value_vec(); *to_replace = JsonValue::Array(identifier); } } diff --git a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs index 3ae4293d544..ed88dce9da2 100644 --- a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs @@ -339,9 +339,7 @@ impl Platform { )?; for document in documents.iter_mut() { - let document_id = Identifier::from_bytes(&document.id)?; - - let Some((_, transaction_bytes)) = withdrawal_transactions.get(&document_id) else { + let Some((_, transaction_bytes)) = withdrawal_transactions.get(&document.id) else { return Err(Error::Execution(ExecutionError::CorruptedCodeExecution("transactions must contain a transaction"))) }; @@ -522,7 +520,7 @@ impl Platform { })?; withdrawals.insert( - Identifier::from_bytes(&document.id)?, + document.id, ( transaction_index.to_be_bytes().to_vec(), transaction_buffer.clone(), @@ -556,6 +554,7 @@ mod tests { use crate::block::BlockStateInfo; use crate::test::helpers::setup::setup_platform_with_initial_state_structure; + use dpp::platform_value::platform_value; use dpp::{ data_contract::{DataContract, DriveContractExt}, prelude::Identifier, @@ -637,15 +636,15 @@ mod tests { let document_1 = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::BROADCASTED, - "transactionIndex": 1, - "transactionSignHeight": 93, - "transactionId": vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "outputScript": CoreScript::new((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::BROADCASTED as u8, + "transactionIndex": 1u32, + "transactionSignHeight": 93u64, + "transactionId": Identifier::new([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), }), None, ).expect("expected withdrawal document"); @@ -665,15 +664,15 @@ mod tests { let document_2 = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::BROADCASTED, - "transactionIndex": 2, - "transactionSignHeight": 10, - "transactionId": vec![3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::new((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::BROADCASTED as u8, + "transactionIndex": 2u32, + "transactionSignHeight": 10u64, + "transactionId": Identifier::new([3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), }), None, ).expect("expected withdrawal document"); @@ -745,6 +744,7 @@ mod tests { use dpp::data_contract::DriveContractExt; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; + use dpp::platform_value::platform_value; use dpp::prelude::Identifier; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use drive::dpp::contracts::withdrawals_contract; @@ -771,13 +771,13 @@ mod tests { let document_1 = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::QUEUED, - "transactionIndex": 1, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::new((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::QUEUED as u8, + "transactionIndex": 1u32, }), None, ) @@ -798,13 +798,13 @@ mod tests { let document_2 = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::QUEUED, - "transactionIndex": 2, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::new((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::QUEUED as u8, + "transactionIndex": 2u32, }), None, ) @@ -939,6 +939,7 @@ mod tests { use dpp::data_contract::DriveContractExt; use dpp::document::Document; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; + use dpp::platform_value::platform_value; use dpp::prelude::Identifier; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use drive::drive::block_info::BlockInfo; @@ -964,13 +965,13 @@ mod tests { let document_1 = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::POOLED, - "transactionIndex": 1, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::new((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::POOLED as u8, + "transactionIndex": 1u32, }), None, ) @@ -991,13 +992,13 @@ mod tests { let document_2 = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::POOLED, - "transactionIndex": 2, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::new((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::POOLED as u8, + "transactionIndex": 2u32, }), None, ) diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 539a96a9223..b27c8b6cf90 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -32,7 +32,7 @@ use crate::error::Error; use crate::platform::Platform; use ciborium::{cbor, Value as CborValue}; use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; -use dpp::platform_value::Value; +use dpp::platform_value::{platform_value, BinaryData, Bytes32, Value}; use dpp::ProtocolError; use drive::contract::DataContract; use drive::dpp::data_contract::DriveContractExt; @@ -42,6 +42,7 @@ use drive::dpp::identity::{ Identity, IdentityPublicKey, KeyType, Purpose, SecurityLevel, TimestampMillis, }; +use dpp::platform_value::string_encoding::{encode, Encoding}; use drive::dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use drive::drive::batch::{ ContractOperationType, DocumentOperationType, DriveOperationType, IdentityOperationType, @@ -50,7 +51,6 @@ use drive::drive::block_info::BlockInfo; use drive::drive::defaults::PROTOCOL_VERSION; use drive::drive::object_size_info::{DocumentAndContractInfo, DocumentInfo, OwnedDocumentInfo}; use drive::query::TransactionArg; -use platform_value::string_encoding::{encode, Encoding}; use serde_json::json; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet}; @@ -128,7 +128,7 @@ impl Platform { security_level: SecurityLevel::MASTER, key_type: KeyType::ECDSA_SECP256K1, read_only: false, - data: identity_public_keys_set.master, + data: identity_public_keys_set.master.into(), disabled_at: None, }, IdentityPublicKey { @@ -137,7 +137,7 @@ impl Platform { security_level: SecurityLevel::HIGH, key_type: KeyType::ECDSA_SECP256K1, read_only: false, - data: identity_public_keys_set.high, + data: identity_public_keys_set.high.into(), disabled_at: None, }, ]); @@ -226,11 +226,11 @@ impl Platform { data_contract_id: contract.id, data_contract: contract.clone(), metadata: None, - entropy: [0; 32], + entropy: Bytes32::new([0; 32]), document: Document { - id: DPNS_DASH_TLD_DOCUMENT_ID, + id: DPNS_DASH_TLD_DOCUMENT_ID.into(), revision: None, - owner_id: contract.owner_id.to_buffer(), + owner_id: contract.owner_id, created_at: None, updated_at: None, properties: BTreeMap::from_json_value(properties_json) @@ -238,22 +238,15 @@ impl Platform { }, }; - let document_stub_properties_value: Value = cbor!({ - "label" => domain, - "normalizedLabel" => domain, - "normalizedParentDomainName" => "", - "preorderSalt" => CborValue::Bytes(DPNS_DASH_TLD_PREORDER_SALT.to_vec()), - "records" => { - "dashAliasIdentityId" => CborValue::Bytes(contract.owner_id.to_vec()), + let document_stub_properties_value = platform_value!({ + "label" : domain, + "normalizedLabel" : domain, + "normalizedParentDomainName" : "", + "preorderSalt" : BinaryData::new(DPNS_DASH_TLD_PREORDER_SALT.to_vec()), + "records" : { + "dashAliasIdentityId" : contract.owner_id, }, - }) - .map_err(|_| { - // TODO: Can't pass original error because the error expecting String - Error::Execution(ExecutionError::CorruptedCodeExecution( - "can't create cbor for dpns tld", - )) - })? - .into(); + }); let document_stub_properties = document_stub_properties_value .into_btree_string_map() @@ -262,9 +255,9 @@ impl Platform { let document_cbor = document.to_buffer()?; let document = Document { - id: DPNS_DASH_TLD_DOCUMENT_ID, + id: DPNS_DASH_TLD_DOCUMENT_ID.into(), properties: document_stub_properties, - owner_id: contract.owner_id.to_buffer(), + owner_id: contract.owner_id, revision: None, created_at: None, updated_at: None, diff --git a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs index 12aab9caf46..46ade2004b8 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -37,6 +37,7 @@ use std::collections::BTreeMap; use dpp::document::document_transition::INITIAL_REVISION; use dpp::platform_value::Value; +use dpp::prelude::Identifier; use drive::dpp::identity::Identity; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; @@ -58,12 +59,12 @@ use crate::contracts::reward_shares::MN_REWARD_SHARES_DOCUMENT_TYPE; fn create_test_mn_share_document( drive: &Drive, contract: &Contract, - identity_id: [u8; 32], + identity_id: Identifier, pay_to_identity: &Identity, percentage: u16, transaction: TransactionArg, ) -> Document { - let id = rand::random::<[u8; 32]>(); + let id = Identifier::random(); let mut properties: BTreeMap = BTreeMap::new(); @@ -139,7 +140,7 @@ pub fn create_test_masternode_share_identities_and_documents( let document = create_test_mn_share_document( drive, contract, - *mn_identity, + Identifier::new(*mn_identity), &identity, 5000, transaction, diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 7d0b6326795..9062030ac04 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -233,7 +233,7 @@ impl Strategy { .clone() .into_partial_identity_info(); - document.owner_id = identity.id.to_buffer(); + document.owner_id = identity.id; let storage_flags = StorageFlags::new_single_epoch( block_info.epoch.index, Some(identity.id.to_buffer()), @@ -274,12 +274,12 @@ impl Strategy { .expect("expected to deserialize document"); let identity = platform .drive - .fetch_identity_with_balance(document.owner_id, None) + .fetch_identity_with_balance(document.owner_id.to_buffer(), None) .expect("expected to be able to get identity") .expect("expected to get an identity"); let delete_op = DriveOperationType::DocumentOperation( DocumentOperationType::DeleteDocumentForContract { - document_id: document.id, + document_id: document.id.to_buffer(), contract: &op.contract, document_type: &op.document_type, owner_id: None, diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs index 5f3773c9377..d3c26d4cb15 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs @@ -24,8 +24,9 @@ impl ReplacementType { )) })?)) } - ReplacementType::BinaryBytes - | ReplacementType::IdentifierBytes => Ok(Value::Bytes(bytes)), + ReplacementType::BinaryBytes | ReplacementType::IdentifierBytes => { + Ok(Value::Bytes(bytes)) + } ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), } @@ -34,8 +35,9 @@ impl ReplacementType { pub fn replace_for_bytes_32(&self, bytes: [u8; 32]) -> Result { match self { ReplacementType::Identifier => Ok(Value::Identifier(bytes)), - ReplacementType::BinaryBytes - | ReplacementType::IdentifierBytes => Ok(Value::Bytes32(bytes)), + ReplacementType::BinaryBytes | ReplacementType::IdentifierBytes => { + Ok(Value::Bytes32(bytes)) + } ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), } @@ -83,9 +85,12 @@ fn replace_down( let bytes = match replacement_type { ReplacementType::Identifier | ReplacementType::IdentifierBytes - | ReplacementType::TextBase58 => new_value.to_identifier_bytes(), - ReplacementType::BinaryBytes - | ReplacementType::TextBase64 => new_value.to_binary_bytes(), + | ReplacementType::TextBase58 => { + new_value.to_identifier_bytes() + } + ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { + new_value.to_binary_bytes() + } }?; *new_value = replacement_type.replace_for_bytes(bytes)?; } @@ -137,8 +142,9 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { ReplacementType::Identifier | ReplacementType::IdentifierBytes | ReplacementType::TextBase58 => current_value.to_identifier_bytes(), - ReplacementType::BinaryBytes - | ReplacementType::TextBase64 => current_value.to_binary_bytes(), + ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { + current_value.to_binary_bytes() + } }?; *current_value = replacement_type.replace_for_bytes(bytes)?; } diff --git a/packages/rs-platform-value/src/btreemap_extensions/mod.rs b/packages/rs-platform-value/src/btreemap_extensions/mod.rs index f0eadc3aee2..8858d7bb133 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/mod.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/mod.rs @@ -117,7 +117,9 @@ where V: Borrow, { fn get_optional_identifier(&self, key: &str) -> Result, Error> { - self.get(key).map(|v| v.borrow().to_identifier()).transpose() + self.get(key) + .map(|v| v.borrow().to_identifier()) + .transpose() } fn get_identifier(&self, key: &str) -> Result { @@ -424,8 +426,9 @@ where } fn get_binary_data(&self, key: &str) -> Result { - self.get_optional_binary_data(key)? - .ok_or_else(|| Error::StructureError(format!("unable to get binary data property {key}"))) + self.get_optional_binary_data(key)?.ok_or_else(|| { + Error::StructureError(format!("unable to get binary data property {key}")) + }) } fn get_optional_float(&self, key: &str) -> Result, Error> { diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 9b0d9828ea7..18f6eb53fc1 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -116,7 +116,7 @@ impl TryInto for Value { .map(|(k, v)| Ok((k.try_into()?, v.try_into()?))) .collect::, Error>>()?, ) - }, + } Value::Identifier(bytes) => CborValue::Bytes(bytes.to_vec()), Value::EnumU8(_) => todo!(), Value::EnumString(_) => todo!(), diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index c246da48ead..b40e5eabc53 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -1,7 +1,7 @@ -use std::cmp::Ordering; use crate::value_map::{ValueMap, ValueMapHelper}; use crate::{BinaryData, Bytes32, Identifier}; use crate::{Error, Value}; +use std::cmp::Ordering; use std::collections::BTreeMap; impl Value { @@ -48,8 +48,7 @@ impl Value { Ok(Self::insert_in_map(map, key, value.into())) } - pub fn set_into_binary_data(&mut self, key: &str, value: Vec) -> Result<(), Error> - { + pub fn set_into_binary_data(&mut self, key: &str, value: Vec) -> Result<(), Error> { let map = self.as_map_mut_ref()?; Ok(Self::insert_in_map(map, key, Value::Bytes(value))) } @@ -118,13 +117,14 @@ impl Value { { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) - .map(|v| - if v.is_null() { - None - } else { - Some(v.into_integer()) - } - ).flatten() + .map(|v| { + if v.is_null() { + None + } else { + Some(v.into_integer()) + } + }) + .flatten() .transpose() } @@ -137,10 +137,12 @@ impl Value { pub fn remove_optional_identifier(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) - .map(|v| if v.is_null() { - None - } else { - Some(v.into_identifier()) + .map(|v| { + if v.is_null() { + None + } else { + Some(v.into_identifier()) + } }) .flatten() .transpose() @@ -330,7 +332,10 @@ impl Value { Self::inner_array_ref(map, key) } - pub fn get_optional_array_mut_ref<'a>(&'a mut self, key: &'a str) -> Result>, Error> { + pub fn get_optional_array_mut_ref<'a>( + &'a mut self, + key: &'a str, + ) -> Result>, Error> { let map = self.to_map_mut()?; Self::inner_optional_array_mut_ref(map, key) } @@ -345,7 +350,10 @@ impl Value { Self::inner_array_slice(map, key) } - pub fn get_optional_binary_data<'a>(&'a self, key: &'a str) -> Result, Error> { + pub fn get_optional_binary_data<'a>( + &'a self, + key: &'a str, + ) -> Result, Error> { let map = self.to_map()?; Self::inner_optional_binary_data_value(map, key) } @@ -470,7 +478,9 @@ impl Value { document_type: &'a mut [(Value, Value)], key: &'a str, ) -> Result>, Error> { - Self::get_optional_mut_from_map(document_type, key).map(|value| value.to_array_mut()).transpose() + Self::get_optional_mut_from_map(document_type, key) + .map(|value| value.to_array_mut()) + .transpose() } /// Retrieves the value of a key from a map if it's an array of strings. @@ -568,10 +578,12 @@ impl Value { key: &str, ) -> Result, Error> { Self::get_optional_from_map(document_type, key) - .map(|value| if value.is_null() { - None - } else { - Some(value.to_bool()) + .map(|value| { + if value.is_null() { + None + } else { + Some(value.to_bool()) + } }) .flatten() .transpose() @@ -600,10 +612,12 @@ impl Value { + TryFrom, { Self::get_optional_from_map(document_type, key) - .map(|key_value| if key_value.is_null() { - None - } else { - Some(key_value.to_integer()) + .map(|key_value| { + if key_value.is_null() { + None + } else { + Some(key_value.to_integer()) + } }) .flatten() .transpose() @@ -812,8 +826,7 @@ impl Value { for (key, value) in map.iter_mut() { if let Value::Text(text) = key { match inserting_key.cmp(text) { - Ordering::Less => { - } + Ordering::Less => {} Ordering::Equal => { found_value = Some(value); break; @@ -827,7 +840,7 @@ impl Value { if let Some(value) = found_value { *value = inserting_value; } else { - map.insert(pos,(Value::Text(inserting_key), inserting_value)) + map.insert(pos, (Value::Text(inserting_key), inserting_value)) } } diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index b90568964e8..c56ac950d2b 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -1,5 +1,5 @@ use crate::value_map::ValueMapHelper; -use crate::{Error, Value, ValueMap}; +use crate::{error, Error, Value, ValueMap}; use lazy_static::lazy_static; use regex::Regex; use std::collections::BTreeMap; @@ -40,6 +40,13 @@ impl Value { map.remove_key(last_path_component) } + pub fn remove_value_at_path_into>( + &mut self, + path: &str, + ) -> Result { + self.remove_value_at_path(path)?.try_into() + } + pub fn remove_values_at_paths<'a>( &'a mut self, paths: Vec<&'a str>, diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 7ccb2cd5c1d..72be1895e00 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -31,9 +31,9 @@ use std::collections::{BTreeMap, HashMap}; pub type Hash256 = [u8; 32]; pub use btreemap_extensions::btreemap_field_replacement::ReplacementType; -pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; pub use types::binary_data::BinaryData; pub use types::bytes_32::Bytes32; +pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; pub use value_serialization::{from_value, to_value}; @@ -255,7 +255,10 @@ impl Value { Value::I16(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), Value::U8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), Value::I8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), - other => Err(Error::StructureError(format!("value is not an integer, found {}", other))), + other => Err(Error::StructureError(format!( + "value is not an integer, found {}", + other + ))), } } @@ -1114,8 +1117,9 @@ impl Value { ReplacementType::Identifier | ReplacementType::IdentifierBytes | ReplacementType::TextBase58 => new_value.to_identifier_bytes(), - ReplacementType::BinaryBytes - | ReplacementType::TextBase64 => new_value.to_binary_bytes(), + ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { + new_value.to_binary_bytes() + } }?; *new_value = replacement_type.replace_for_bytes(bytes)?; return Ok(true); @@ -1298,3 +1302,19 @@ impl From<&[&str]> for Value { ) } } + +impl TryInto> for Value { + type Error = Error; + + fn try_into(self) -> Result, Self::Error> { + self.to_bytes() + } +} + +impl TryInto for Value { + type Error = Error; + + fn try_into(self) -> Result { + self.into_text() + } +} diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index c4002f7d54e..447851f349d 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -261,7 +261,6 @@ macro_rules! platform_value_internal { ({ $($tt:tt)+ }) => { $crate::Value::Map({ - use platform_value::ValueMapHelper; let mut object = $crate::ValueMap::new(); platform_value_internal!(@object object () ($($tt)+) ($($tt)+)); object @@ -300,8 +299,8 @@ macro_rules! platform_value_expect_expr_comma { #[cfg(test)] mod test { - use crate::{platform_value, to_value, Identifier, Value}; use crate::types::binary_data::BinaryData; + use crate::{platform_value, to_value, Identifier, Value}; #[test] fn test_identity_is_kept() { diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index 5516263b718..8e00aa2704e 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -355,21 +355,24 @@ impl Value { /// ``` pub fn into_bytes_32(self) -> Result { match self { - Value::Text(text) => { - Bytes32::from_vec(base64::decode(text).map_err(|_| Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))?) - }, - Value::Array(array) => { - Bytes32::from_vec(array + Value::Text(text) => Bytes32::from_vec(base64::decode(text).map_err(|_| { + Error::StructureError( + "value was a string, but could not be decoded from base 64".to_string(), + ) + })?), + Value::Array(array) => Bytes32::from_vec( + array .iter() .map(|byte| byte.to_integer()) - .collect::, Error>>()?) - }, + .collect::, Error>>()?, + ), Value::Bytes32(bytes) => Ok(Bytes32::new(bytes)), - Value::Bytes(vec) => { - Bytes32::from_vec(vec) - }, + Value::Bytes(vec) => Bytes32::from_vec(vec), Value::Identifier(identifier) => Ok(Bytes32::new(identifier)), - _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), + _other => Err(Error::StructureError( + "value are not bytes, a string, or an array of values representing bytes" + .to_string(), + )), } } @@ -403,21 +406,24 @@ impl Value { /// ``` pub fn to_bytes_32(&self) -> Result { match self { - Value::Text(text) => { - Bytes32::from_vec(base64::decode(text).map_err(|_| Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))?) - }, - Value::Array(array) => { - Bytes32::from_vec(array + Value::Text(text) => Bytes32::from_vec(base64::decode(text).map_err(|_| { + Error::StructureError( + "value was a string, but could not be decoded from base 64".to_string(), + ) + })?), + Value::Array(array) => Bytes32::from_vec( + array .iter() .map(|byte| byte.to_integer()) - .collect::, Error>>()?) - }, + .collect::, Error>>()?, + ), Value::Bytes32(bytes) => Ok(Bytes32::new(*bytes)), - Value::Bytes(vec) => { - Bytes32::from_vec(vec.clone()) - }, + Value::Bytes(vec) => Bytes32::from_vec(vec.clone()), Value::Identifier(identifier) => Ok(Bytes32::new(*identifier)), - _other => Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string())), + _other => Err(Error::StructureError( + "value are not bytes, a string, or an array of values representing bytes" + .to_string(), + )), } } diff --git a/packages/rs-platform-value/src/types/binary_data.rs b/packages/rs-platform-value/src/types/binary_data.rs index 04780205a05..ff25d24bba9 100644 --- a/packages/rs-platform-value/src/types/binary_data.rs +++ b/packages/rs-platform-value/src/types/binary_data.rs @@ -1,17 +1,17 @@ -use std::fmt; -use serde::{Deserialize, Serialize}; -use serde::de::Visitor; -use crate::{Error, string_encoding, Value}; use crate::string_encoding::Encoding; use crate::types::encoding_string_to_encoding; +use crate::{string_encoding, Error, Value}; +use serde::de::Visitor; +use serde::{Deserialize, Serialize}; +use std::fmt; #[derive(Default, Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] pub struct BinaryData(pub Vec); impl Serialize for BinaryData { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, + where + S: serde::Serializer, { if serializer.is_human_readable() { serializer.serialize_str(&base64::encode(self.0.as_slice())) @@ -23,11 +23,10 @@ impl Serialize for BinaryData { impl<'de> Deserialize<'de> for BinaryData { fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, + where + D: serde::Deserializer<'de>, { if deserializer.is_human_readable() { - struct StringVisitor; impl<'de> Visitor<'de> for StringVisitor { @@ -38,8 +37,8 @@ impl<'de> Deserialize<'de> for BinaryData { } fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, + where + E: serde::de::Error, { let bytes = base64::decode(v).map_err(|e| E::custom(format!("{}", e)))?; Ok(BinaryData(bytes)) @@ -58,8 +57,8 @@ impl<'de> Deserialize<'de> for BinaryData { } fn visit_bytes(self, v: &[u8]) -> Result - where - E: serde::de::Error, + where + E: serde::de::Error, { Ok(BinaryData(v.to_vec())) } @@ -123,7 +122,6 @@ impl From> for BinaryData { } } - impl TryFrom for BinaryData { type Error = Error; @@ -200,7 +198,7 @@ impl PartialEq for Vec { mod tests { use std::collections::HashMap; - use crate::{from_value, Identifier, to_value, Value}; + use crate::{from_value, to_value, Identifier, Value}; use serde::{Deserialize, Serialize}; use super::*; diff --git a/packages/rs-platform-value/src/types/bytes_32.rs b/packages/rs-platform-value/src/types/bytes_32.rs index 5bb9782e914..7cefaf94b8a 100644 --- a/packages/rs-platform-value/src/types/bytes_32.rs +++ b/packages/rs-platform-value/src/types/bytes_32.rs @@ -1,9 +1,9 @@ -use std::fmt; -use serde::{Deserialize, Serialize}; -use serde::de::Visitor; -use crate::{Error, string_encoding, Value}; use crate::string_encoding::Encoding; use crate::types::encoding_string_to_encoding; +use crate::{string_encoding, Error, Value}; +use serde::de::Visitor; +use serde::{Deserialize, Serialize}; +use std::fmt; #[derive(Default, Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Copy)] pub struct Bytes32(pub [u8; 32]); @@ -14,7 +14,9 @@ impl Bytes32 { } pub fn from_vec(buffer: Vec) -> Result { - let buffer : [u8; 32] = buffer.try_into().map_err(|_| Error::ByteLengthNot32BytesError("buffer was not 32 bytes long".to_string()))?; + let buffer: [u8; 32] = buffer.try_into().map_err(|_| { + Error::ByteLengthNot32BytesError("buffer was not 32 bytes long".to_string()) + })?; Ok(Bytes32::new(buffer)) } @@ -58,8 +60,8 @@ impl Bytes32 { impl Serialize for Bytes32 { fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, + where + S: serde::Serializer, { if serializer.is_human_readable() { serializer.serialize_str(&base64::encode(self.0)) @@ -71,11 +73,10 @@ impl Serialize for Bytes32 { impl<'de> Deserialize<'de> for Bytes32 { fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, + where + D: serde::Deserializer<'de>, { if deserializer.is_human_readable() { - struct StringVisitor; impl<'de> Visitor<'de> for StringVisitor { @@ -86,8 +87,8 @@ impl<'de> Deserialize<'de> for Bytes32 { } fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, + where + E: serde::de::Error, { let bytes = base64::decode(v).map_err(|e| E::custom(format!("{}", e)))?; if bytes.len() != 32 { @@ -111,8 +112,8 @@ impl<'de> Deserialize<'de> for Bytes32 { } fn visit_bytes(self, v: &[u8]) -> Result - where - E: serde::de::Error, + where + E: serde::de::Error, { let mut bytes = [0u8; 32]; if v.len() != 32 { @@ -174,4 +175,4 @@ impl Into for &Bytes32 { fn into(self) -> String { self.to_string(Encoding::Base64) } -} \ No newline at end of file +} diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 75f2c273484..aea0d2780d2 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -8,15 +8,17 @@ use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::string_encoding::Encoding; -use crate::{string_encoding, Error, Value}; use crate::types::encoding_string_to_encoding; +use crate::{string_encoding, Error, Value}; pub const IDENTIFIER_MEDIA_TYPE: &str = "application/x.dash.dpp.identifier"; #[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Copy)] pub struct IdentifierBytes32(pub [u8; 32]); -#[derive(Default, Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Copy, Serialize, Deserialize)] +#[derive( + Default, Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Copy, Serialize, Deserialize, +)] pub struct Identifier(pub IdentifierBytes32); impl Serialize for IdentifierBytes32 { @@ -38,7 +40,6 @@ impl<'de> Deserialize<'de> for IdentifierBytes32 { D: serde::Deserializer<'de>, { if deserializer.is_human_readable() { - struct StringVisitor; impl<'de> Visitor<'de> for StringVisitor { @@ -49,10 +50,12 @@ impl<'de> Deserialize<'de> for IdentifierBytes32 { } fn visit_str(self, v: &str) -> Result - where - E: serde::de::Error, + where + E: serde::de::Error, { - let bytes = bs58::decode(v).into_vec().map_err(|e| E::custom(format!("{}", e)))?; + let bytes = bs58::decode(v) + .into_vec() + .map_err(|e| E::custom(format!("{}", e)))?; if bytes.len() != 32 { return Err(E::invalid_length(bytes.len(), &self)); } @@ -74,8 +77,8 @@ impl<'de> Deserialize<'de> for IdentifierBytes32 { } fn visit_bytes(self, v: &[u8]) -> Result - where - E: serde::de::Error, + where + E: serde::de::Error, { let mut bytes = [0u8; 32]; if v.len() != 32 { @@ -91,29 +94,16 @@ impl<'de> Deserialize<'de> for IdentifierBytes32 { } } -// impl<'de> Deserialize<'de> for Identifier { -// fn deserialize(deserializer: D) -> Result -// where -// D: serde::Deserializer<'de>, -// { -// let data: DocumentValue = Deserialize::deserialize(deserializer)?; -// if let DocumentValue::Bytes(bytes) = data { -// return Ok(Identifier::from(bytes.0)); -// } -// Err(serde::de::Error::custom(format!( -// "expected bytes, got: {:?}", -// data -// ))) -// } -// } - - impl Identifier { pub fn new(buffer: [u8; 32]) -> Identifier { Identifier(IdentifierBytes32(buffer)) } - pub fn random(rng: &mut StdRng) -> Identifier { + pub fn random() -> Identifier { + Identifier(IdentifierBytes32(rand::random::<[u8; 32]>())) + } + + pub fn random_with_rng(rng: &mut StdRng) -> Identifier { Identifier(IdentifierBytes32(rng.gen())) } @@ -165,7 +155,7 @@ impl Identifier { // TODO - consider to change the name to 'asBuffer` pub fn to_buffer(&self) -> [u8; 32] { - self.0.0 + self.0 .0 } /// Convenience method to get underlying buffer as a vec @@ -222,31 +212,31 @@ impl std::fmt::Display for Identifier { impl PartialEq<&Identifier> for Identifier { fn eq(&self, other: &&Identifier) -> bool { - &self.0.0 == &other.0.0 + &self.0 .0 == &other.0 .0 } } impl PartialEq<[u8; 32]> for Identifier { fn eq(&self, other: &[u8; 32]) -> bool { - &self.0.0 == other + &self.0 .0 == other } } impl PartialEq<[u8; 32]> for &Identifier { fn eq(&self, other: &[u8; 32]) -> bool { - &self.0.0 == other + &self.0 .0 == other } } impl PartialEq for [u8; 32] { fn eq(&self, other: &Identifier) -> bool { - self == &other.0.0 + self == &other.0 .0 } } impl PartialEq<&Identifier> for [u8; 32] { fn eq(&self, other: &&Identifier) -> bool { - self == &other.0.0 + self == &other.0 .0 } } @@ -290,12 +280,11 @@ impl Into for &Identifier { } } - #[cfg(test)] mod tests { use std::collections::HashMap; - use crate::{from_value, Identifier, to_value}; + use crate::{from_value, to_value, Identifier}; use serde::{Deserialize, Serialize}; use super::*; diff --git a/packages/rs-platform-value/src/types/mod.rs b/packages/rs-platform-value/src/types/mod.rs index 68c1d791fd6..a3623b191d9 100644 --- a/packages/rs-platform-value/src/types/mod.rs +++ b/packages/rs-platform-value/src/types/mod.rs @@ -1,8 +1,8 @@ use crate::string_encoding::Encoding; -pub(crate) mod identifier; -pub(crate) mod bytes_32; pub(crate) mod binary_data; +pub(crate) mod bytes_32; +pub(crate) mod identifier; fn encoding_string_to_encoding(encoding_string: Option<&str>) -> Encoding { match encoding_string { diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 12cf8f3e738..4f0ecd6381e 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -1,5 +1,5 @@ -use std::cmp::Ordering; use crate::{Error, Value}; +use std::cmp::Ordering; use std::collections::BTreeMap; pub type ValueMap = Vec<(Value, Value)>; diff --git a/packages/rs-platform-value/src/value_serialization/de.rs b/packages/rs-platform-value/src/value_serialization/de.rs index b75ee37e10e..499bce4873c 100644 --- a/packages/rs-platform-value/src/value_serialization/de.rs +++ b/packages/rs-platform-value/src/value_serialization/de.rs @@ -172,7 +172,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { } else { visitor.visit_bytes(&x) } - }, + } Value::Text(x) => visitor.visit_str(&x), Value::Array(x) => visitor.visit_seq(ArrayDeserializer(x.iter())), Value::Map(x) => visitor.visit_map(ValueMapDeserializer(x.iter().peekable())), @@ -195,7 +195,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { } else { visitor.visit_bytes(&x) } - }, + } Value::EnumU8(_x) => todo!(), Value::EnumString(_x) => todo!(), Value::Identifier(x) => { @@ -204,7 +204,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { } else { visitor.visit_bytes(&x) } - }, + } } } diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index 5a9db9c6949..a17599e18ae 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -111,10 +111,8 @@ where #[cfg(test)] mod tests { - use std::collections::HashMap; - - use crate::Identifier; use serde::{Deserialize, Serialize}; + use std::collections::HashMap; use super::*; diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index 19b4e5581ad..f7d64063464 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -49,21 +49,21 @@ impl Serialize for Value { } else { serializer.serialize_bytes(bytes) } - }, + } Value::Bytes32(bytes) => { if serializer.is_human_readable() { serializer.serialize_str(base64::encode(bytes).as_str()) } else { serializer.serialize_bytes(bytes) } - }, + } Value::Identifier(bytes) => { if serializer.is_human_readable() { serializer.serialize_str(bs58::encode(bytes).into_string().as_str()) } else { serializer.serialize_bytes(bytes) } - }, + } Value::Float(f64) => serializer.serialize_f64(*f64), Value::Text(string) => serializer.serialize_str(string), Value::EnumU8(_x) => todo!(), @@ -476,9 +476,7 @@ impl serde::ser::SerializeMap for SerializeMap { fn end(self) -> Result { match self { - SerializeMap::Map { map, .. } => { - Ok(Value::Map(map)) - }, + SerializeMap::Map { map, .. } => Ok(Value::Map(map)), } } } diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index eb371168181..cb4898d02ff 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -8,8 +8,9 @@ use serde_json::Value as JsonValue; use wasm_bindgen::prelude::*; use dpp::data_contract::{DataContract, SCHEMA_URI}; -use dpp::platform_value::Value; -use platform_value::string_encoding::Encoding; +use dpp::platform_value; +use dpp::platform_value::string_encoding::Encoding; +use dpp::platform_value::{Bytes32, Value}; use crate::errors::{from_dpp_err, RustConversionError}; use crate::identifier::identifier_from_js_value; @@ -88,8 +89,8 @@ impl DataContractWasm { let parameters: DataContractParameters = with_js_error!(serde_wasm_bindgen::from_value(raw_parameters))?; - DataContract::from_json_raw_object( - serde_json::to_value(parameters).expect("Implements Serialize"), + DataContract::from_raw_object( + platform_value::to_value(parameters).expect("Implements Serialize"), ) .map_err(from_dpp_err) .map(Into::into) @@ -217,9 +218,9 @@ impl DataContractWasm { definitions.insert(k, v); } if definitions.is_empty() { - bail_js!("`defitions` cannot be empty"); + bail_js!("`definitions` cannot be empty"); } - self.0.defs = Some(definitions); + self.0.defs = definitions; } else { bail_js!("the parameter 'definitions' is not an JS object"); } @@ -240,13 +241,13 @@ impl DataContractWasm { )) .to_js_value() })?; - self.0.entropy = entropy; + self.0.entropy = Bytes32::new(entropy); Ok(()) } #[wasm_bindgen(js_name=getEntropy)] pub fn get_entropy(&mut self) -> Buffer { - Buffer::from_bytes(&self.0.entropy) + Buffer::from_bytes_owned(self.0.entropy.to_vec()) } #[wasm_bindgen(js_name=getBinaryProperties)] diff --git a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs index 2d9d4f132eb..d2118d700e2 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs @@ -1,15 +1,17 @@ use crate::errors::protocol_error::from_protocol_error; use crate::{ - js_value_to_platform_value, js_value_to_serde_value, DataContractCreateTransitionWasm, - DataContractUpdateTransitionWasm, DataContractWasm, + js_value_to_platform_value, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, + DataContractWasm, }; use dpp::data_contract::DataContractFacade; use dpp::identifier::Identifier; use dpp::version::ProtocolVersionValidator; -use crate::utils::{get_bool_from_options, SKIP_VALIDATION_PROPERTY_NAME}; +use crate::utils::{get_bool_from_options, WithJsError, SKIP_VALIDATION_PROPERTY_NAME}; use crate::validation::ValidationResultWasm; +use dpp::platform_value::Value; +use dpp::ProtocolError; use std::sync::Arc; use wasm_bindgen::prelude::*; @@ -38,16 +40,24 @@ impl DataContractFacadeWasm { documents: JsValue, definitions: JsValue, ) -> Result { - let id = Identifier::from_bytes(&owner_id).map_err(from_protocol_error)?; + let id = Identifier::from_bytes(&owner_id) + .map_err(ProtocolError::ValueError) + .with_js_error()?; - let definitions: Option = if definitions.is_object() { + let definitions: Option = if definitions.is_object() { Some(serde_wasm_bindgen::from_value(definitions)?) } else { None }; + //todo: contract config self.0 - .create(id, serde_wasm_bindgen::from_value(documents)?, definitions) + .create( + id, + serde_wasm_bindgen::from_value(documents)?, + None, + definitions, + ) .map(Into::into) .map_err(from_protocol_error) } @@ -116,7 +126,7 @@ impl DataContractFacadeWasm { &self, js_raw_data_contract: JsValue, ) -> Result { - let raw_data_contract = js_value_to_serde_value(js_raw_data_contract)?; + let raw_data_contract = js_value_to_platform_value(js_raw_data_contract)?; self.0 .validate(raw_data_contract) diff --git a/packages/wasm-dpp/src/data_contract/errors/data_contract_generic_error.rs b/packages/wasm-dpp/src/data_contract/errors/data_contract_generic_error.rs index 73abfcd0b8a..d28b90ac779 100644 --- a/packages/wasm-dpp/src/data_contract/errors/data_contract_generic_error.rs +++ b/packages/wasm-dpp/src/data_contract/errors/data_contract_generic_error.rs @@ -1,5 +1,3 @@ -use crate::errors::consensus_error::from_consensus_error_ref; -use dpp::consensus::ConsensusError; use wasm_bindgen::prelude::*; #[wasm_bindgen(js_name=DataContractGenericError)] diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 098d78aca41..e1144ba44bc 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -8,14 +8,17 @@ pub use validation::*; use dpp::{ data_contract::state_transition::DataContractCreateTransition, + platform_value, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, }, + ProtocolError, }; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; use crate::errors::protocol_error::from_protocol_error; +use crate::utils::WithJsError; use crate::{ buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper, with_js_error, DataContractParameters, DataContractWasm, StateTransitionExecutionContextWasm, @@ -56,11 +59,12 @@ impl DataContractCreateTransitionWasm { pub fn new(raw_parameters: JsValue) -> Result { let parameters: DataContractCreateTransitionParameters = with_js_error!(serde_wasm_bindgen::from_value(raw_parameters))?; - DataContractCreateTransition::from_raw_object( - serde_json::to_value(parameters).expect("the struct will be a valid json"), - ) - .map(Into::into) - .map_err(from_dpp_err) + let transition_object = platform_value::to_value(parameters) + .map_err(ProtocolError::ValueError) + .with_js_error()?; + DataContractCreateTransition::from_raw_object(transition_object) + .map(Into::into) + .map_err(from_dpp_err) } #[wasm_bindgen(js_name=getDataContract)] @@ -75,7 +79,7 @@ impl DataContractCreateTransitionWasm { #[wasm_bindgen(js_name=getEntropy)] pub fn get_entropy(&self) -> Buffer { - Buffer::from_bytes(&self.0.entropy) + Buffer::from_bytes_owned(self.0.entropy.to_vec()) } #[wasm_bindgen(js_name=getOwnerId)] diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs index 943650f59ba..90d08ed2fc6 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs @@ -5,6 +5,7 @@ use dpp::{ validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, validate_data_contract_create_transition_state::validate_data_contract_create_transition_state as dpp_validate_data_contract_create_transition_state, }, + platform_value, state_transition::state_transition_execution_context::StateTransitionExecutionContext, validation::DataValidatorWithContext, version::ProtocolVersionValidator, @@ -47,7 +48,7 @@ pub async fn validate_data_contract_create_transition_basic( ))?; let validation_result = validator.validate( - &serde_json::to_value(¶meters)?, + &platform_value::to_value(¶meters)?, &StateTransitionExecutionContext::default(), )?; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 976092f8742..5ef6c74b9ba 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -8,13 +8,16 @@ pub use validation::*; use dpp::{ data_contract::state_transition::DataContractUpdateTransition, + platform_value, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, }, + ProtocolError, }; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; +use crate::utils::WithJsError; use crate::{ buffer::Buffer, errors::{from_dpp_err, protocol_error::from_protocol_error}, @@ -57,11 +60,12 @@ impl DataContractUpdateTransitionWasm { pub fn new(raw_parameters: JsValue) -> Result { let parameters: DataContractUpdateTransitionParameters = with_js_error!(serde_wasm_bindgen::from_value(raw_parameters))?; - DataContractUpdateTransition::from_raw_object( - serde_json::to_value(parameters).expect("the struct will be a valid json"), - ) - .map(Into::into) - .map_err(from_dpp_err) + let raw_data_contract_update_transition = platform_value::to_value(parameters) + .map_err(ProtocolError::ValueError) + .with_js_error()?; + DataContractUpdateTransition::from_raw_object(raw_data_contract_update_transition) + .map(Into::into) + .map_err(from_dpp_err) } #[wasm_bindgen(js_name=getDataContract)] @@ -76,7 +80,7 @@ impl DataContractUpdateTransitionWasm { #[wasm_bindgen(js_name=getEntropy)] pub fn get_entropy(&self) -> Buffer { - Buffer::from_bytes(&self.0.data_contract.entropy) + Buffer::from_bytes_owned(self.0.data_contract.entropy.to_vec()) } #[wasm_bindgen(js_name=getOwnerId)] diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index dd342daf273..41d61e05213 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -8,6 +8,7 @@ use dpp::{ }, state::validate_data_contract_update_transition_state::validate_data_contract_update_transition_state as dpp_validate_data_contract_update_transition_state, }, + platform_value, version::ProtocolVersionValidator, }; use wasm_bindgen::prelude::*; @@ -72,7 +73,7 @@ pub async fn validate_data_contract_update_transition_basic( let validation_result = validator .validate( - &serde_json::to_value(¶meters)?, + &platform_value::to_value(¶meters)?, &execution_context.into(), ) .await?; diff --git a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs index 9fc1122bb37..06d04fc924d 100644 --- a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs +++ b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs @@ -6,11 +6,14 @@ use dpp::{ validation::data_contract_validator::DataContractValidator, DataContractFactory, EntropyGenerator, }, + platform_value, prelude::Identifier, version::ProtocolVersionValidator, + ProtocolError, }; use wasm_bindgen::prelude::*; +use crate::utils::WithJsError; use crate::{ data_contract::errors::InvalidDataContractError, errors::{from_dpp_err, protocol_error::from_protocol_error}, @@ -51,9 +54,12 @@ impl DataContractValidatorWasm { pub fn validate(&self, raw_data_contract: JsValue) -> Result { let parameters: DataContractParameters = with_js_error!(serde_wasm_bindgen::from_value(raw_data_contract))?; - let json_object = serde_json::to_value(parameters).expect("Implements Serialize"); + let platform_object = platform_value::to_value(parameters).expect("Implements Serialize"); - let validation_result = self.0.validate(&json_object).map_err(from_protocol_error)?; + let validation_result = self + .0 + .validate(&platform_object) + .map_err(from_protocol_error)?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } } @@ -116,11 +122,14 @@ impl DataContractFactoryWasm { owner_id: Vec, documents: JsValue, ) -> Result { - let documents_json: serde_json::Value = + let documents_object: platform_value::Value = with_js_error!(serde_wasm_bindgen::from_value(documents))?; - let identifier = Identifier::from_bytes(&owner_id).map_err(from_dpp_err)?; + let identifier = Identifier::from_bytes(&owner_id) + .map_err(ProtocolError::ValueError) + .with_js_error()?; + //todo: contract config self.0 - .create(identifier, documents_json, None) + .create(identifier, documents_object, None, None) .map(Into::into) .map_err(from_dpp_err) } diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 09d200d6da0..2d3359e9b74 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -1,7 +1,7 @@ use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::document::{ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS}; -use dpp::platform_value::{ReplacementType, Value}; +use dpp::platform_value::{Bytes32, ReplacementType, Value}; use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::JsonValueExt; @@ -77,7 +77,7 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=setId)] pub fn set_id(&mut self, js_id: IdentifierWrapper) { - self.0.document.id = js_id.inner().buffer; + self.0.document.id = js_id.into_inner(); } #[wasm_bindgen(js_name=getType)] @@ -104,7 +104,7 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=setOwnerId)] pub fn set_owner_id(&mut self, owner_id: IdentifierWrapper) { - self.0.document.owner_id = owner_id.into_inner().buffer; + self.0.document.owner_id = owner_id.into_inner(); } #[wasm_bindgen(js_name=getOwnerId)] @@ -132,13 +132,13 @@ impl ExtendedDocumentWasm { )) .to_js_value() })?; - self.0.entropy = entropy; + self.0.entropy = Bytes32::new(entropy); Ok(()) } #[wasm_bindgen(js_name=getEntropy)] pub fn get_entropy(&mut self) -> Buffer { - Buffer::from_bytes(&self.0.entropy) + Buffer::from_bytes_owned(self.0.entropy.to_vec()) } #[wasm_bindgen(js_name=setData)] @@ -170,7 +170,7 @@ impl ExtendedDocumentWasm { let (identifier_paths, _) = self.0.get_identifiers_and_binary_paths().with_js_error()?; let mut value: Value = js_value_to_set.with_serde_to_json_value()?.into(); if identifier_paths.contains(path.as_str()) { - let identifier_value = ReplacementType::Bytes + let identifier_value = ReplacementType::IdentifierBytes .replace_consume_value(value) .map_err(ProtocolError::ValueError) .with_js_error()?; @@ -182,7 +182,7 @@ impl ExtendedDocumentWasm { if identifier_path.starts_with(path.as_str()) { let (_, suffix) = identifier_path.split_at(path.len() + 1); value - .replace_at_path(suffix, ReplacementType::Bytes) + .replace_at_path(suffix, ReplacementType::IdentifierBytes) .map_err(ProtocolError::ValueError) .map(|_| ()) .with_js_error() @@ -196,24 +196,22 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=get)] pub fn get(&mut self, path: String) -> JsValue { - let binary_type = self.get_binary_type_of_path(&path); - if let Some(value) = self.0.get(&path) { - match binary_type { - BinaryType::Identifier => { - if let Ok(bytes) = value.to_identifier_bytes() { - let id: IdentifierWrapper = Identifier::from_bytes(&bytes).unwrap().into(); - - return id.into(); - } + match value { + Value::Bytes(bytes) => { + return Buffer::from_bytes(bytes).into(); } - BinaryType::Buffer => { - if let Ok(bytes) = value.to_identifier_bytes() { - return Buffer::from_bytes(&bytes).into(); - } + Value::Bytes32(bytes) => { + return Buffer::from_bytes(bytes.as_slice()).into(); + } + Value::Identifier(bytes) => { + let id: IdentifierWrapper = Identifier::new(*bytes).into(); + + return id.into(); } - BinaryType::None => { + _ => { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + //todo: maybe go directly from value let json_value: Option = value.clone().try_into().ok(); if let Some(json_value) = json_value { if let Ok(js_value) = json_value.serialize(&serializer) { @@ -276,7 +274,7 @@ impl ExtendedDocumentWasm { .into_iter() .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS) { - if let Ok(bytes) = value.remove_path_into::>(path) { + if let Ok(bytes) = value.remove_value_at_path_into::>(path) { if !options.skip_identifiers_conversion { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, path, buffer.into()); @@ -288,7 +286,7 @@ impl ExtendedDocumentWasm { } for path in binary_paths { - if let Ok(bytes) = value.remove_path_into::>(path) { + if let Ok(bytes) = value.remove_value_at_path_into::>(path) { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, path, buffer.into()); } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index decb2bc9687..11dcf314948 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -2,7 +2,6 @@ use anyhow::anyhow; use std::collections::HashMap; use std::sync::Arc; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; use dpp::platform_value::ReplacementType; use dpp::{ document::{ @@ -11,11 +10,11 @@ use dpp::{ extended_document, fetch_and_validate_data_contract::DataContractFetcherAndValidator, }, - util::json_value::{JsonValueExt, ReplaceWith}, ProtocolError, }; use wasm_bindgen::prelude::*; +use dpp::platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use dpp::prelude::ExtendedDocument; use std::convert::TryFrom; @@ -169,11 +168,11 @@ impl DocumentFactoryWASM { // When data contract is available, replace remaining dynamic paths let document_data = document.properties_as_mut(); document_data - .replace_at_paths(identifier_paths, ReplacementType::Bytes) + .replace_at_paths(identifier_paths, ReplacementType::IdentifierBytes) .map_err(ProtocolError::ValueError) .with_js_error()?; document_data - .replace_at_paths(binary_paths, ReplacementType::Bytes) + .replace_at_paths(binary_paths, ReplacementType::BinaryBytes) .map_err(ProtocolError::ValueError) .with_js_error()?; Ok(document.into()) diff --git a/packages/wasm-dpp/src/document/fetch_and_validate_data_contract.rs b/packages/wasm-dpp/src/document/fetch_and_validate_data_contract.rs index 5fd1fc9cee1..1caefd3c1bf 100644 --- a/packages/wasm-dpp/src/document/fetch_and_validate_data_contract.rs +++ b/packages/wasm-dpp/src/document/fetch_and_validate_data_contract.rs @@ -1,14 +1,16 @@ +use dpp::platform_value::ReplacementType; use dpp::{ document::{self, fetch_and_validate_data_contract::fetch_and_validate_data_contract}, prelude::DataContract, state_transition::state_transition_execution_context::StateTransitionExecutionContext, validation::ValidationResult, + ProtocolError, }; use wasm_bindgen::prelude::*; use crate::{ state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - utils::{replace_identifiers_with_bytes_without_failing, ToSerdeJSONExt, WithJsError}, + utils::{ToSerdeJSONExt, WithJsError}, validation::ValidationResultWasm, DataContractWasm, }; @@ -58,11 +60,11 @@ async fn fetch_and_validate_data_contract_inner( state_repository: &ExternalStateRepositoryLikeWrapper, js_raw_document: &JsValue, ) -> Result { - let mut document_value = js_raw_document.with_serde_to_json_value()?; - replace_identifiers_with_bytes_without_failing( - &mut document_value, - document::IDENTIFIER_FIELDS, - ); + let mut document_value = js_raw_document.with_serde_to_platform_value()?; + document_value + .replace_at_paths(document::IDENTIFIER_FIELDS, ReplacementType::Identifier) + .map_err(ProtocolError::ValueError) + .with_js_error()?; // TODO! remove the context. The the providing the context in state repository should be optional let ctx = StateTransitionExecutionContext::default(); diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 7f1469726b7..a87b010ce08 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -12,10 +12,8 @@ use crate::buffer::Buffer; use crate::identifier::IdentifierWrapper; use crate::lodash::lodash_set; -use crate::utils::{ - replace_identifiers_with_bytes_without_failing, with_serde_to_json_value, Inner, ToSerdeJSONExt, -}; use crate::utils::{try_to_u64, WithJsError}; +use crate::utils::{with_serde_to_json_value, Inner, ToSerdeJSONExt}; use crate::with_js_error; use crate::DataContractWasm; @@ -31,12 +29,12 @@ mod validator; pub use document_batch_transition::DocumentsBatchTransitionWASM; use dpp::data_contract::DriveContractExt; -use dpp::document::{Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, IDENTIFIER_FIELDS}; +use dpp::document::{Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS}; pub use extended_document::ExtendedDocumentWasm; use dpp::document::extended_document::property_names; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; +use dpp::platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; use dpp::platform_value::ReplacementType; use dpp::platform_value::Value; @@ -91,7 +89,7 @@ impl DocumentWasm { identifier_paths .into_iter() .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS), - ReplacementType::Bytes, + ReplacementType::IdentifierBytes, ) .map_err(ProtocolError::ValueError) .with_js_error()?; @@ -109,12 +107,12 @@ impl DocumentWasm { #[wasm_bindgen(js_name=setId)] pub fn set_id(&mut self, js_id: IdentifierWrapper) { - self.0.id = js_id.into_inner().buffer; + self.0.id = js_id.into_inner(); } #[wasm_bindgen(js_name=setOwnerId)] pub fn set_owner_id(&mut self, owner_id: IdentifierWrapper) { - self.0.owner_id = owner_id.into_inner().buffer; + self.0.owner_id = owner_id.into_inner(); } #[wasm_bindgen(js_name=getOwnerId)] @@ -175,7 +173,7 @@ impl DocumentWasm { return Ok(Buffer::from_bytes(bytes.as_slice()).into()); } Value::Identifier(identifier) => { - let id: IdentifierWrapper = Identifier::from(*identifier).into(); + let id: IdentifierWrapper = Identifier::new(*identifier).into(); return Ok(id.into()); } _ => { @@ -247,7 +245,7 @@ impl DocumentWasm { let js_value = value.serialize(&serializer)?; for path in identifiers_paths.into_iter() { - if let Ok(bytes) = value.remove_path_into::>(path) { + if let Ok(bytes) = value.remove_value_at_path_into::>(path) { if !options.skip_identifiers_conversion { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, path, buffer.into()); @@ -259,7 +257,7 @@ impl DocumentWasm { } for path in binary_paths { - if let Ok(bytes) = value.remove_path_into::>(path) { + if let Ok(bytes) = value.remove_value_at_path_into::>(path) { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, path, buffer.into()); } @@ -341,12 +339,12 @@ pub(crate) fn document_data_to_bytes( .with_js_error()?; document .properties - .replace_at_paths(identifier_paths, ReplacementType::Bytes) + .replace_at_paths(identifier_paths, ReplacementType::IdentifierBytes) .map_err(ProtocolError::ValueError) .with_js_error()?; document .properties - .replace_at_paths(binary_paths, ReplacementType::Bytes) + .replace_at_paths(binary_paths, ReplacementType::BinaryBytes) .map_err(ProtocolError::ValueError) .with_js_error()?; Ok(()) @@ -355,23 +353,27 @@ pub(crate) fn document_data_to_bytes( pub(crate) fn raw_document_from_js_value( js_raw_document: &JsValue, data_contract: &DataContract, -) -> Result { - let mut raw_document = js_raw_document.with_serde_to_json_value()?; +) -> Result { + let mut raw_document = js_raw_document.with_serde_to_platform_value()?; - let document_type = raw_document - .get_string(property_names::DOCUMENT_TYPE) + let document_type_name = raw_document + .get_str(property_names::DOCUMENT_TYPE) + .map_err(ProtocolError::ValueError) .with_js_error()?; - let (identifier_paths, _) = data_contract - .get_identifiers_and_binary_paths(document_type) + let (identifier_paths, binary_paths) = data_contract + .get_identifiers_and_binary_paths(document_type_name) .with_js_error()?; - replace_identifiers_with_bytes_without_failing( - &mut raw_document, - identifier_paths.into_iter().chain(IDENTIFIER_FIELDS), - ); + raw_document + .replace_at_paths(identifier_paths, ReplacementType::Identifier) + .map_err(ProtocolError::ValueError) + .with_js_error()?; + raw_document + .replace_at_paths(binary_paths, ReplacementType::BinaryBytes) + .map_err(ProtocolError::ValueError) + .with_js_error()?; - // The binary paths are not being converted, because they always should be a `Buffer`. `Buffer` is always an Array Ok(raw_document) } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 07a14c7b779..5778a475c0b 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -3,9 +3,9 @@ use std::convert::TryInto; use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::identity::TimestampMillis; -use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; -use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use dpp::platform_value::btreemap_extensions::{ + BTreeValueMapHelper, BTreeValueMapPathHelper, BTreeValueMapReplacementPathHelper, +}; use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; use dpp::platform_value::ReplacementType; use dpp::prelude::Revision; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 9435aa42e70..48cfbd2a3fc 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -3,9 +3,9 @@ use std::convert::TryInto; use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::identity::TimestampMillis; -use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; -use dpp::platform_value::btreemap_path_extensions::BTreeValueMapPathHelper; +use dpp::platform_value::btreemap_extensions::{ + BTreeValueMapHelper, BTreeValueMapPathHelper, BTreeValueMapReplacementPathHelper, +}; use dpp::platform_value::ReplacementType; use dpp::prelude::Revision; use dpp::{ diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index 1973606f3c2..b29ba3da196 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -305,7 +305,7 @@ pub(crate) fn to_object<'a>( let js_value = value.serialize(&serializer)?; for path in identifiers_paths.into_iter() { - if let Ok(bytes) = value.remove_path_into::>(path) { + if let Ok(bytes) = value.remove_value_at_path_into::>(path) { if !options.skip_identifiers_conversion { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, path, buffer.into()); @@ -317,7 +317,7 @@ pub(crate) fn to_object<'a>( } for path in binary_paths.into_iter() { - if let Ok(bytes) = value.remove_path_into::>(path) { + if let Ok(bytes) = value.remove_value_at_path_into::>(path) { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, path, buffer.into()); } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 30df03254b8..b057b8218d2 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -15,8 +15,8 @@ use dpp::{ use js_sys::{Array, Reflect}; use serde::{Deserialize, Serialize}; -use dpp::platform_value::btreemap_field_replacement::BTreeValueMapReplacementPathHelper; -use dpp::platform_value::ReplacementType; +use dpp::platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; +use dpp::platform_value::{BinaryData, ReplacementType}; use wasm_bindgen::prelude::*; use crate::{ @@ -25,10 +25,7 @@ use crate::{ document_batch_transition::document_transition::DocumentTransitionWasm, identifier::IdentifierWrapper, lodash::lodash_set, - utils::{ - replace_identifiers_with_bytes_without_failing, Inner, IntoWasm, ToSerdeJSONExt, - WithJsError, - }, + utils::{Inner, IntoWasm, ToSerdeJSONExt, WithJsError}, IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, }; pub mod apply_document_batch_transition; @@ -165,7 +162,11 @@ impl DocumentsBatchTransitionWASM { let mut value = self.0.to_object(options.skip_signature).with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_value = value.serialize(&serializer)?; - let is_signature_present = value.get(property_names::SIGNATURE).is_some(); + let is_signature_present = value + .get(property_names::SIGNATURE) + .map_err(ProtocolError::ValueError) + .with_js_error()? + .is_some(); // Transform every transition individually let transitions = Array::new(); @@ -183,20 +184,26 @@ impl DocumentsBatchTransitionWASM { // Transform paths that are specific to the DocumentsBatchTransition for path in DocumentsBatchTransition::binary_property_paths() { - if let Ok(bytes) = value.remove_path_into::>(path) { - let buffer = Buffer::from_bytes(&bytes); - lodash_set(&js_value, path, buffer.into()); - } + let bytes = value + .remove_value_at_path(path) + .and_then(|value| value.to_binary_bytes()) + .map_err(ProtocolError::ValueError) + .with_js_error()?; + let buffer = Buffer::from_bytes_owned(bytes); + lodash_set(&js_value, path, buffer.into()); } for path in DocumentsBatchTransition::identifiers_property_paths() { - if let Ok(bytes) = value.remove_path_into::>(path) { - if !options.skip_identifiers_conversion { - let buffer = Buffer::from_bytes(&bytes); - lodash_set(&js_value, path, buffer.into()); - } else { - let id = IdentifierWrapper::new(bytes)?; - lodash_set(&js_value, path, id.into()); - } + let bytes = value + .remove_value_at_path(path) + .and_then(|value| value.to_identifier_bytes()) + .map_err(ProtocolError::ValueError) + .with_js_error()?; + if !options.skip_identifiers_conversion { + let buffer = Buffer::from_bytes_owned(bytes); + lodash_set(&js_value, path, buffer.into()); + } else { + let id = IdentifierWrapper::new(bytes)?; + lodash_set(&js_value, path, id.into()); } } @@ -207,7 +214,12 @@ impl DocumentsBatchTransitionWASM { &JsValue::undefined(), )?; } - if value.get(property_names::SIGNATURE_PUBLIC_KEY_ID).is_none() { + if value + .get(property_names::SIGNATURE_PUBLIC_KEY_ID) + .map_err(ProtocolError::ValueError) + .with_js_error()? + .is_none() + { js_sys::Reflect::set( &js_value, &property_names::SIGNATURE_PUBLIC_KEY_ID.into(), @@ -297,12 +309,12 @@ impl DocumentsBatchTransitionWASM { #[wasm_bindgen(js_name=getSignature)] pub fn get_signature(&self) -> Vec { - self.0.get_signature().to_owned() + self.0.get_signature().to_vec() } #[wasm_bindgen(js_name=setSignature)] pub fn set_signature(&mut self, signature: Vec) { - self.0.set_signature(signature) + self.0.set_signature(BinaryData::new(signature)) } #[wasm_bindgen(js_name=calculateFee)] diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index ed08c591bac..c49078ecb4e 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -9,7 +9,7 @@ use js_sys::Array; use wasm_bindgen::prelude::*; use crate::identifier::IdentifierWrapper; -use crate::utils::{with_serde_to_platform_value, Inner}; +use crate::utils::Inner; use crate::{ document_batch_transition::document_transition::to_object, utils::{ToSerdeJSONExt, WithJsError}, @@ -22,7 +22,7 @@ pub fn find_duplicates_by_indices_wasm( data_contract: &DataContractWasm, owner_id: &IdentifierWrapper, ) -> Result, JsValue> { - let mut owner_id_value: Value = Value::Identifier(owner_id.inner().buffer); + let owner_id_value: Value = Value::Identifier(owner_id.inner().to_buffer()); let raw_transitions: Vec = js_raw_transitions .iter() .map(|transition| { @@ -39,7 +39,7 @@ pub fn find_duplicates_by_indices_wasm( }) .collect::, JsValue>>()?; - let mut result = + let result = find_duplicates_by_indices(&raw_transitions, data_contract.inner()).with_js_error()?; let duplicates: Vec = result diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/missing_data_contract_id_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/missing_data_contract_id_error.rs index 8b252552119..1cfc8959bdd 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/document/missing_data_contract_id_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/missing_data_contract_id_error.rs @@ -1,15 +1,15 @@ -use dpp::document::document_transition::document_base_transition::JsonValue; +use dpp::platform_value::Value; use serde::Serialize; use wasm_bindgen::prelude::*; #[wasm_bindgen(js_name=MissingDataContractIdError)] pub struct MissingDataContractIdErrorWasm { - raw_document_transition: JsonValue, + raw_document_transition: Value, code: u32, } impl MissingDataContractIdErrorWasm { - pub fn new(raw_document_transition: JsonValue, code: u32) -> Self { + pub fn new(raw_document_transition: Value, code: u32) -> Self { MissingDataContractIdErrorWasm { raw_document_transition, code, diff --git a/packages/wasm-dpp/src/errors/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus_error.rs index 30863820762..b067c1808e5 100644 --- a/packages/wasm-dpp/src/errors/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus_error.rs @@ -61,6 +61,7 @@ use crate::errors::consensus::state::identity::{ InvalidIdentityPublicKeyIdErrorWasm, InvalidIdentityRevisionErrorWasm, MaxIdentityPublicKeyLimitReachedErrorWasm, }; +use crate::errors::value_error::PlatformValueErrorWasm; use dpp::errors::DataTriggerError; use super::consensus::basic::data_contract::{ @@ -190,6 +191,9 @@ pub fn from_consensus_error_ref(e: &DPPConsensusError) -> JsValue { DPPConsensusError::SignatureError(e) => from_signature_error(e), DPPConsensusError::StateError(state_error) => from_state_error(state_error), DPPConsensusError::BasicError(basic_error) => from_basic_error(basic_error), + DPPConsensusError::ValueError(value_error) => { + PlatformValueErrorWasm::new(value_error.clone()).into() + } } } diff --git a/packages/wasm-dpp/src/errors/from.rs b/packages/wasm-dpp/src/errors/from.rs index 0db35a10730..9b4fed8ccb4 100644 --- a/packages/wasm-dpp/src/errors/from.rs +++ b/packages/wasm-dpp/src/errors/from.rs @@ -1,4 +1,3 @@ -use dpp::data_contract::errors::DataContractNotPresentError; use wasm_bindgen::JsValue; use dpp::errors::ProtocolError; diff --git a/packages/wasm-dpp/src/errors/value_error.rs b/packages/wasm-dpp/src/errors/value_error.rs index 54286d17736..b90c4f3ad0a 100644 --- a/packages/wasm-dpp/src/errors/value_error.rs +++ b/packages/wasm-dpp/src/errors/value_error.rs @@ -1,6 +1,5 @@ use dpp::platform_value::Error as PlatformValueError; use wasm_bindgen::prelude::*; -use wasm_bindgen::JsValue; #[wasm_bindgen(js_name=PlatformValueError)] pub struct PlatformValueErrorWasm { diff --git a/packages/wasm-dpp/src/identifier/mod.rs b/packages/wasm-dpp/src/identifier/mod.rs index 7ac160c9ca9..bd657984d49 100644 --- a/packages/wasm-dpp/src/identifier/mod.rs +++ b/packages/wasm-dpp/src/identifier/mod.rs @@ -1,6 +1,5 @@ use dpp::prelude::Identifier; use itertools::Itertools; -use platform_value::string_encoding::Encoding; pub use serde::{Deserialize, Serialize}; use serde_json::Value; use wasm_bindgen::prelude::*; @@ -8,12 +7,11 @@ use wasm_bindgen::JsCast; use crate::bail_js; use crate::buffer::Buffer; -use crate::errors::from_dpp_err; use crate::utils::Inner; use crate::utils::ToSerdeJSONExt; use crate::utils::WithJsError; -use dpp::identifier; use dpp::platform_value::string_encoding::Encoding; +use dpp::{identifier, ProtocolError}; #[derive(Serialize, Deserialize, PartialEq, Eq)] enum IdentifierSource { @@ -65,7 +63,9 @@ impl std::convert::From for Identifier { impl IdentifierWrapper { #[wasm_bindgen(constructor)] pub fn new(buffer: Vec) -> Result { - let identifier = identifier::Identifier::from_bytes(&buffer).map_err(from_dpp_err)?; + let identifier = identifier::Identifier::from_bytes(&buffer) + .map_err(ProtocolError::ValueError) + .with_js_error()?; Ok(IdentifierWrapper { wrapped: identifier, @@ -102,7 +102,7 @@ impl IdentifierWrapper { #[wasm_bindgen(js_name=toBuffer)] pub fn to_buffer(&self) -> Buffer { - Buffer::from_bytes(&self.wrapped.buffer) + Buffer::from_bytes_owned(self.wrapped.to_vec()) } #[wasm_bindgen(js_name=toJSON)] @@ -123,12 +123,12 @@ impl IdentifierWrapper { #[wasm_bindgen(getter)] pub fn length(&self) -> usize { - self.wrapped.buffer.len() + self.wrapped.to_buffer().len() } #[wasm_bindgen(js_name=toBytes)] pub fn to_bytes(&self) -> Vec { - self.wrapped.buffer.to_vec() + self.wrapped.to_vec() } #[wasm_bindgen(js_name=clone)] @@ -165,9 +165,13 @@ pub(crate) fn identifier_from_js_value(js_value: &JsValue) -> Result { let bytes: Vec = arr.into_iter().map(value_to_u8).try_collect()?; - Identifier::from_bytes(&bytes).with_js_error() + Identifier::from_bytes(&bytes) + .map_err(ProtocolError::ValueError) + .with_js_error() } - Value::String(string) => Identifier::from_string(&string, Encoding::Base58).with_js_error(), + Value::String(string) => Identifier::from_string(&string, Encoding::Base58) + .map_err(ProtocolError::ValueError) + .with_js_error(), _ => { bail_js!("Invalid ID. Expected array or string") } diff --git a/packages/wasm-dpp/src/identity/factory_utils.rs b/packages/wasm-dpp/src/identity/factory_utils.rs index 0f2d77b998c..50ee7267a8f 100644 --- a/packages/wasm-dpp/src/identity/factory_utils.rs +++ b/packages/wasm-dpp/src/identity/factory_utils.rs @@ -1,6 +1,6 @@ use crate::errors::RustConversionError; use crate::identity::identity_public_key_transitions::IdentityPublicKeyCreateTransitionWasm; -use crate::utils::{generic_of_js_val, to_vec_of_serde_values}; +use crate::utils::{generic_of_js_val, to_vec_of_platform_values}; use crate::{create_asset_lock_proof_from_wasm_instance, IdentityPublicKeyWasm}; use dpp::identity::state_transition::asset_lock_proof::AssetLockProof; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; @@ -15,7 +15,7 @@ pub fn parse_create_args( ) -> Result<(AssetLockProof, BTreeMap), JsValue> { let asset_lock_proof = create_asset_lock_proof_from_wasm_instance(&asset_lock_proof)?; - let raw_public_keys = to_vec_of_serde_values(public_keys.iter())?; + let raw_public_keys = to_vec_of_platform_values(public_keys.iter())?; let public_keys = raw_public_keys .into_iter() diff --git a/packages/wasm-dpp/src/identity/identity_facade.rs b/packages/wasm-dpp/src/identity/identity_facade.rs index 8d89c60995a..b68fee7ee0f 100644 --- a/packages/wasm-dpp/src/identity/identity_facade.rs +++ b/packages/wasm-dpp/src/identity/identity_facade.rs @@ -75,7 +75,7 @@ impl IdentityFacadeWasm { Default::default() }; - let raw_identity = identity_object.with_serde_to_json_value()?; + let raw_identity = identity_object.with_serde_to_platform_value()?; let result = self .0 diff --git a/packages/wasm-dpp/src/identity/identity_factory.rs b/packages/wasm-dpp/src/identity/identity_factory.rs index 7b467552f05..6f2b9b0fe0d 100644 --- a/packages/wasm-dpp/src/identity/identity_factory.rs +++ b/packages/wasm-dpp/src/identity/identity_factory.rs @@ -6,7 +6,7 @@ use crate::identity::errors::InvalidIdentityError; use crate::identity::validation::IdentityValidatorWasm; use crate::{ - create_asset_lock_proof_from_wasm_instance, utils, with_js_error, ChainAssetLockProofWasm, + create_asset_lock_proof_from_wasm_instance, with_js_error, ChainAssetLockProofWasm, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, IdentityUpdateTransitionWasm, IdentityWasm, InstantAssetLockProofWasm, }; @@ -16,11 +16,11 @@ use dpp::identity::factory::IdentityFactory; use dpp::prelude::Identity; use serde::Deserialize; -use serde_json::Value; use std::convert::TryInto; use std::sync::Arc; +use crate::utils::with_serde_to_platform_value; use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; @@ -71,9 +71,7 @@ impl IdentityFactoryWasm { Default::default() }; - let identity_json = utils::stringify(&identity_object)?; - let raw_identity: Value = - serde_json::from_str(&identity_json).map_err(|e| e.to_string())?; + let raw_identity = with_serde_to_platform_value(&identity_object)?; let result = self .0 diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index 263b9d599e4..d84751fb6c8 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -7,6 +7,7 @@ use crate::errors::from_dpp_err; use crate::utils::Inner; use crate::{buffer::Buffer, utils}; use dpp::identity::{IdentityPublicKey, KeyID}; +use dpp::platform_value::BinaryData; mod purpose; pub use purpose::*; @@ -58,13 +59,13 @@ impl IdentityPublicKeyWasm { #[wasm_bindgen(js_name=setData)] pub fn set_data(&mut self, data: Vec) -> Result<(), JsValue> { - self.0.data = data; + self.0.data = BinaryData::new(data); Ok(()) } #[wasm_bindgen(js_name=getData)] pub fn get_data(&self) -> Vec { - self.0.data.clone() + self.0.data.to_vec() } #[wasm_bindgen(js_name=setPurpose)] diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index 87770ec15dc..09f84dec020 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -9,8 +9,8 @@ use crate::{ with_js_error, }; use dpp::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; -use platform_value::string_encoding; -use platform_value::string_encoding::Encoding; +use dpp::platform_value::string_encoding; +use dpp::platform_value::string_encoding::Encoding; #[wasm_bindgen(js_name=ChainAssetLockProof)] #[derive(Clone)] @@ -62,17 +62,17 @@ impl ChainAssetLockProofWasm { #[wasm_bindgen(js_name=getCoreChainLockedHeight)] pub fn get_core_chain_locked_height(&self) -> u32 { - self.0.core_chain_locked_height() + self.0.core_chain_locked_height } #[wasm_bindgen(js_name=setCoreChainLockedHeight)] pub fn set_core_chain_locked_height(&mut self, value: u32) { - self.0.set_core_chain_locked_height(value); + self.0.core_chain_locked_height = value; } #[wasm_bindgen(js_name=getOutPoint)] pub fn get_out_point(&self) -> Buffer { - Buffer::from_bytes(self.0.out_point()) + Buffer::from_bytes_owned(self.0.out_point.to_vec()) } #[wasm_bindgen(js_name=setOutPoint)] @@ -81,7 +81,7 @@ impl ChainAssetLockProofWasm { RustConversionError::Error(String::from("outPoint must be a 36 byte array")) .to_js_value() })?; - self.0.set_out_point(out_point); + self.0.out_point = out_point; Ok(()) } @@ -90,7 +90,8 @@ impl ChainAssetLockProofWasm { pub fn to_json(&self) -> Result { let js_object = self.to_object()?; - let out_point_base64 = string_encoding::encode(self.0.out_point(), Encoding::Base64); + let out_point_base64 = + string_encoding::encode(self.0.out_point.as_slice(), Encoding::Base64); js_sys::Reflect::set( &js_object, diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs index 9393008cbd8..62cd368c064 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs @@ -56,12 +56,12 @@ impl ChainAssetLockProofStructureValidatorWasm { raw_asset_lock_proof: JsValue, execution_context: &StateTransitionExecutionContextWasm, ) -> Result { - let asset_lock_proof_json = raw_asset_lock_proof.with_serde_to_json_value()?; + let asset_lock_proof_object = raw_asset_lock_proof.with_serde_to_platform_value()?; let context: &StateTransitionExecutionContext = execution_context.into(); let validation_result = self .0 - .validate(&asset_lock_proof_json, context) + .validate(&asset_lock_proof_object, context) .await .map_err(|e| from_dpp_err(e.into()))?; diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs index 1815c96a21d..3fbcc104756 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs @@ -16,8 +16,8 @@ use crate::{ use dpp::identity::state_transition::asset_lock_proof::instant::{ InstantAssetLockProof, RawInstantLock, }; -use platform_value::string_encoding; -use platform_value::string_encoding::Encoding; +use dpp::platform_value::string_encoding; +use dpp::platform_value::string_encoding::Encoding; #[derive(Serialize, Deserialize)] #[serde(remote = "TxOut")] diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs index c63068a14b7..bdfed684b13 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs @@ -56,12 +56,12 @@ impl InstantAssetLockProofStructureValidatorWasm { raw_asset_lock_proof: JsValue, execution_context: &StateTransitionExecutionContextWasm, ) -> Result { - let asset_lock_proof_json = raw_asset_lock_proof.with_serde_to_json_value()?; + let asset_lock_proof_object = raw_asset_lock_proof.with_serde_to_platform_value()?; let context: &StateTransitionExecutionContext = execution_context.into(); let validation_result = self .0 - .validate(&asset_lock_proof_json, context) + .validate(&asset_lock_proof_object, context) .await .map_err(|e| from_dpp_err(e.into()))?; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 3c84e7b0386..b665564f82e 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -21,6 +21,8 @@ use crate::{ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; use crate::utils::{generic_of_js_val, ToSerdeJSONExt}; +use dpp::platform_value::string_encoding; +use dpp::platform_value::string_encoding::Encoding; use dpp::{ identifier::Identifier, identity::state_transition::{ @@ -29,8 +31,6 @@ use dpp::{ }, state_transition::StateTransitionLike, }; -use platform_value::string_encoding; -use platform_value::string_encoding::Encoding; #[wasm_bindgen(js_name=IdentityCreateTransition)] #[derive(Clone)] @@ -52,7 +52,7 @@ impl From for IdentityCreateTransition { impl IdentityCreateTransitionWasm { #[wasm_bindgen(constructor)] pub fn new(raw_parameters: JsValue) -> Result { - let raw_state_transition = raw_parameters.with_serde_to_json_value()?; + let raw_state_transition = raw_parameters.with_serde_to_platform_value()?; let identity_create_transition = IdentityCreateTransition::new(raw_state_transition) .map_err(|e| RustConversionError::Error(e.to_string()).to_js_value())?; @@ -332,6 +332,6 @@ impl IdentityCreateTransitionWasm { #[wasm_bindgen(js_name=getSignature)] pub fn get_signature(&self) -> Buffer { - Buffer::from_bytes(self.0.get_signature()) + Buffer::from_bytes_owned(self.0.get_signature().to_vec()) } } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs index 9d276588d5d..33562ccc43b 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs @@ -140,11 +140,11 @@ impl IdentityCreateTransitionBasicValidatorWasm { .protocol_version_validator() .set_current_protocol_version(current_protocol_version); - let state_transition_json = raw_state_transition.with_serde_to_json_value()?; + let state_transition_object = raw_state_transition.with_serde_to_platform_value()?; let validation_result = self .0 - .validate(&state_transition_json, execution_context) + .validate(&state_transition_object, execution_context) .await .map_err(|e| from_dpp_err(e.into()))?; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/to_object.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/to_object.rs index 06c8ba4b46a..a34b87ad2db 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/to_object.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/to_object.rs @@ -38,7 +38,7 @@ pub fn to_object_struct( }; if !options.skip_signature.unwrap_or(false) { - to_object.signature = Some(transition.get_signature().to_owned()); + to_object.signature = Some(transition.get_signature().to_vec()); } to_object diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 4a5c2cae8ac..7b27fe2f6c7 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -1,6 +1,7 @@ //todo: move this file to transition use dpp::dashcore::anyhow; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; +use dpp::platform_value::BinaryData; pub use serde::{Deserialize, Serialize}; use std::convert::{TryFrom, TryInto}; use wasm_bindgen::prelude::*; @@ -54,13 +55,13 @@ impl IdentityPublicKeyCreateTransitionWasm { #[wasm_bindgen(js_name=setData)] pub fn set_data(&mut self, data: Vec) -> Result<(), JsValue> { - self.0.data = data; + self.0.data = BinaryData::new(data); Ok(()) } #[wasm_bindgen(js_name=getData)] pub fn get_data(&self) -> Vec { - self.0.data.clone() + self.0.data.to_vec() } #[wasm_bindgen(js_name=setPurpose)] @@ -101,12 +102,12 @@ impl IdentityPublicKeyCreateTransitionWasm { #[wasm_bindgen(js_name=setSignature)] pub fn set_signature(&mut self, signature: Vec) { - self.0.signature = signature + self.0.signature = BinaryData::new(signature) } #[wasm_bindgen(js_name=getSignature)] pub fn get_signature(&self) -> Vec { - self.0.signature.clone() + self.0.signature.to_vec() } #[wasm_bindgen(js_name=hash)] @@ -160,7 +161,7 @@ impl IdentityPublicKeyCreateTransitionWasm { js_sys::Reflect::set( &js_object, &JsValue::from_str("signature"), - &JsValue::from(Buffer::from_bytes(&self.0.signature)), + &JsValue::from(Buffer::from_bytes_owned(self.0.signature.to_vec())), )?; } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 44702a346a9..bc233b9d435 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -21,6 +21,8 @@ use crate::{ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; +use dpp::platform_value::string_encoding; +use dpp::platform_value::string_encoding::Encoding; use dpp::{ identifier::Identifier, identity::state_transition::{ @@ -28,8 +30,6 @@ use dpp::{ }, state_transition::StateTransitionLike, }; -use platform_value::string_encoding; -use platform_value::string_encoding::Encoding; #[wasm_bindgen(js_name=IdentityTopUpTransition)] #[derive(Clone)] @@ -51,7 +51,7 @@ impl From for IdentityTopUpTransition { impl IdentityTopUpTransitionWasm { #[wasm_bindgen(constructor)] pub fn new(raw_parameters: JsValue) -> Result { - let raw_state_transition = raw_parameters.with_serde_to_json_value()?; + let raw_state_transition = raw_parameters.with_serde_to_platform_value()?; let identity_topup_transition = IdentityTopUpTransition::from_raw_object(raw_state_transition) diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition_basic_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition_basic_validator.rs index ae9066e30e2..5d50c92910d 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition_basic_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition_basic_validator.rs @@ -100,11 +100,11 @@ impl IdentityTopUpTransitionBasicValidatorWasm { .protocol_version_validator() .set_current_protocol_version(current_protocol_version); - let state_transition_json = raw_state_transition.with_serde_to_json_value()?; + let state_transition_object = raw_state_transition.with_serde_to_platform_value()?; let validation_result = self .0 - .validate(&state_transition_json, execution_context) + .validate(&state_transition_object, execution_context) .await .map_err(|e| from_dpp_err(e.into()))?; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/to_object.rs b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/to_object.rs index 0cb4c0bd0a2..67f59a7f8ec 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/to_object.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/to_object.rs @@ -35,7 +35,7 @@ pub fn to_object_struct( }; if !options.skip_signature.unwrap_or(false) { - to_object.signature = Some(transition.get_signature().to_owned()); + to_object.signature = Some(transition.get_signature().to_vec()); } to_object diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs index 514b1ab47aa..cc224dfcf6f 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs @@ -1,10 +1,10 @@ use crate::errors::from_dpp_err; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransitionWasm; use crate::validation::ValidationResultWasm; -use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::state_transition::identity_update_transition::validate_public_keys::IdentityUpdatePublicKeysValidator; use dpp::identity::validation::TPublicKeysValidator; +use dpp::platform_value::Value; use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; @@ -34,14 +34,14 @@ impl IdentityUpdatePublicKeysValidatorWasm { IdentityPublicKeyCreateTransitionWasm::new(raw_key)?.into(); parsed_key - .to_raw_json_object(false) + .to_raw_object(false) .map_err(|e| from_dpp_err(e.into())) }) - .collect::, JsValue>>()?; + .collect::, JsValue>>()?; let result = self .0 - .validate_keys(&public_keys) + .validate_keys(public_keys.as_slice()) .map_err(|e| from_dpp_err(e.into()))?; Ok(result.map(|_| JsValue::undefined()).into()) diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index f118b3497e3..8a12d8036f4 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -16,18 +16,18 @@ use crate::{ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; -use crate::utils::generic_of_js_val; +use crate::utils::{generic_of_js_val, WithJsError}; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::{KeyID, TimestampMillis}; +use dpp::platform_value::string_encoding; +use dpp::platform_value::string_encoding::Encoding; use dpp::prelude::Revision; use dpp::state_transition::StateTransitionIdentitySigned; use dpp::{ identifier::Identifier, identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition, - state_transition::StateTransitionLike, + platform_value, state_transition::StateTransitionLike, ProtocolError, }; -use platform_value::string_encoding; -use platform_value::string_encoding::Encoding; #[wasm_bindgen(js_name=IdentityUpdateTransition)] #[derive(Clone)] @@ -64,7 +64,9 @@ impl IdentityUpdateTransitionWasm { let parameters: IdentityUpdateTransitionParams = with_js_error!(serde_wasm_bindgen::from_value(raw_parameters))?; - let raw_state_transition = with_js_error!(serde_json::to_value(parameters))?; + let raw_state_transition = platform_value::to_value(parameters) + .map_err(ProtocolError::ValueError) + .with_js_error()?; let identity_update_transition = IdentityUpdateTransition::new(raw_state_transition) .map_err(|e| RustConversionError::Error(e.to_string()).to_js_value())?; @@ -418,7 +420,7 @@ impl IdentityUpdateTransitionWasm { #[wasm_bindgen(js_name=getSignature)] pub fn get_signature(&self) -> Buffer { - Buffer::from_bytes(self.0.get_signature()) + Buffer::from_bytes_owned(self.0.get_signature().to_vec()) } #[wasm_bindgen(js_name=getRevision)] diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs index 68c865298d8..d113b85443c 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs @@ -82,7 +82,7 @@ impl IdentityUpdateTransitionBasicValidatorWasm { .protocol_version_validator() .set_current_protocol_version(current_protocol_version); - let state_transition_json = raw_state_transition.with_serde_to_json_value()?; + let state_transition_json = raw_state_transition.with_serde_to_platform_value()?; let validation_result = self .0 diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/to_object.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/to_object.rs index a49dd019f9b..066d130d570 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/to_object.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/to_object.rs @@ -41,7 +41,7 @@ pub fn to_object_struct( }; if !options.skip_signature.unwrap_or(false) { - let signature = Some(transition.get_signature().to_owned()); + let signature = Some(transition.get_signature().to_vec()); if let Some(signature) = &signature { if !signature.is_empty() { to_object.signature_public_key_id = transition.get_signature_public_key_id() diff --git a/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 9dea396f180..088794a54b0 100644 --- a/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -12,7 +12,7 @@ use dpp::identity::state_transition::validate_public_key_signatures::{ use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; -use serde_json::Value as JsonValue; +use dpp::platform_value::Value; use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; @@ -38,7 +38,7 @@ impl PublicKeysSignaturesValidatorWasm { raw_state_transition: JsValue, raw_public_keys: Vec, ) -> Result { - let state_transition_json = raw_state_transition.with_serde_to_json_value()?; + let state_transition_object = raw_state_transition.with_serde_to_platform_value()?; let public_keys = raw_public_keys .into_iter() @@ -46,14 +46,14 @@ impl PublicKeysSignaturesValidatorWasm { let parsed_key: IdentityPublicKeyWithWitness = IdentityPublicKeyCreateTransitionWasm::new(raw_key)?.into(); parsed_key - .to_raw_json_object(false) + .to_raw_object(false) .map_err(|e| from_dpp_err(e.into())) }) - .collect::, JsValue>>()?; + .collect::, JsValue>>()?; let result = self .0 - .validate_public_key_signatures(&state_transition_json, &public_keys) + .validate_public_key_signatures(&state_transition_object, &public_keys) .map_err(|e| from_dpp_err(e.into()))?; Ok(result.map(|_| JsValue::undefined()).into()) diff --git a/packages/wasm-dpp/src/identity/validation/identity_validator.rs b/packages/wasm-dpp/src/identity/validation/identity_validator.rs index 8a75891f4ca..35ab49e1b95 100644 --- a/packages/wasm-dpp/src/identity/validation/identity_validator.rs +++ b/packages/wasm-dpp/src/identity/validation/identity_validator.rs @@ -1,10 +1,9 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; -use crate::utils; +use crate::utils::with_serde_to_platform_value; use crate::validation::ValidationResultWasm; use dpp::identity::validation::{IdentityValidator, PublicKeysValidator}; use dpp::version::ProtocolVersionValidator; -use serde_json::Value; use std::sync::Arc; use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::{JsError, JsValue}; @@ -37,9 +36,7 @@ impl IdentityValidatorWasm { #[wasm_bindgen] pub fn validate(&self, raw_identity: JsValue) -> Result { - let identity_json = utils::stringify(&raw_identity)?; - let raw_identity: Value = - serde_json::from_str(&identity_json).map_err(|e| e.to_string())?; + let raw_identity = with_serde_to_platform_value(&raw_identity)?; let result = self .0 .validate_identity_object(&raw_identity) diff --git a/packages/wasm-dpp/src/identity/validation/public_keys_validator.rs b/packages/wasm-dpp/src/identity/validation/public_keys_validator.rs index 2d284c89f45..fe7aa6075fd 100644 --- a/packages/wasm-dpp/src/identity/validation/public_keys_validator.rs +++ b/packages/wasm-dpp/src/identity/validation/public_keys_validator.rs @@ -1,6 +1,6 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; -use crate::utils::{to_vec_of_serde_values, ToSerdeJSONExt}; +use crate::utils::{to_vec_of_platform_values, ToSerdeJSONExt}; use crate::validation::ValidationResultWasm; use dpp::identity::validation::{ PublicKeysValidator, TPublicKeysValidator, PUBLIC_KEY_SCHEMA_FOR_TRANSITION, @@ -32,7 +32,7 @@ impl PublicKeysValidatorWasm { &self, public_keys: js_sys::Array, ) -> Result { - let raw_public_keys = to_vec_of_serde_values(public_keys.iter())?; + let raw_public_keys = to_vec_of_platform_values(public_keys.iter())?; let validation_result = self .public_key_validator @@ -46,11 +46,11 @@ impl PublicKeysValidatorWasm { &self, public_key: JsValue, ) -> Result { - let pk_serde_json = public_key.with_serde_to_json_value()?; + let pk_object = public_key.with_serde_to_platform_value()?; let validation_result = self .public_key_validator - .validate_public_key_structure(&pk_serde_json) + .validate_public_key_structure(&pk_object) .map_err(|e| JsValue::from(e.to_string()))?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } @@ -60,7 +60,7 @@ impl PublicKeysValidatorWasm { &self, public_keys: js_sys::Array, ) -> Result { - let raw_public_keys = to_vec_of_serde_values(public_keys.iter())?; + let raw_public_keys = to_vec_of_platform_values(public_keys.iter())?; let validation_result = self .public_key_in_state_transition_validator diff --git a/packages/wasm-dpp/src/utils.rs b/packages/wasm-dpp/src/utils.rs index e6328b0c94b..4a7b90061af 100644 --- a/packages/wasm-dpp/src/utils.rs +++ b/packages/wasm-dpp/src/utils.rs @@ -4,7 +4,6 @@ use std::convert::TryInto; use anyhow::{anyhow, bail}; use dpp::{ dashcore::{anyhow, anyhow::Context}, - util::json_value::{JsonValueExt, ReplaceWith}, ProtocolError, }; @@ -75,6 +74,15 @@ pub fn to_vec_of_serde_values( .collect() } +pub fn to_vec_of_platform_values( + values: impl IntoIterator>, +) -> Result, JsValue> { + values + .into_iter() + .map(|v| v.as_ref().with_serde_to_platform_value()) + .collect() +} + pub fn into_vec_of(iter: &[JsValue]) -> Vec where T: for<'de> serde::de::Deserialize<'de>, @@ -263,18 +271,6 @@ pub fn convert_number_to_u64(js_number: js_sys::Number) -> Result( - value: &mut JsonValue, - paths: impl IntoIterator, -) { - // Errors are ignored. When `Buffer` crosses the WASM boundary it becomes an Array. - // When `Identifier` crosses the WASM boundary it becomes a String. From perspective of JS - // `Identifier` and `Buffer` are used interchangeably, so we we can expect the replacing may fail when `Buffer` is provided - let _ = value - .replace_identifier_paths(paths, ReplaceWith::Bytes) - .with_js_error(); -} - // The trait `Inner` provides better flexibility and visibility when you need to switch // between WASM structure and original structure. pub(crate) trait Inner { From 25113b03249d51ce91a8525dfa22d2c5e8a36103 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 18:33:04 +0700 Subject: [PATCH 154/228] more fixes --- .../document_type/array_field.rs | 2 +- .../document_type/document_field.rs | 37 ++----------- .../withdrawals_data_triggers/mod.rs | 2 +- packages/rs-drive-abci/src/abci/handlers.rs | 20 +++---- .../src/identity_credit_withdrawal/mod.rs | 27 +++++----- packages/rs-drive-nodejs/src/converter.rs | 3 +- .../rs-drive/src/drive/document/delete.rs | 4 +- .../rs-drive/src/drive/document/update.rs | 8 +-- .../drive/identity/withdrawals/documents.rs | 53 ++++++++++--------- packages/rs-drive/tests/query_tests.rs | 34 ++++++------ .../rs-drive/tests/query_tests_history.rs | 8 +-- .../src/types/binary_data.rs | 3 -- .../rs-platform-value/src/types/identifier.rs | 5 +- 13 files changed, 90 insertions(+), 116 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/array_field.rs b/packages/rs-dpp/src/data_contract/document_type/array_field.rs index 687b543469c..468419732ab 100644 --- a/packages/rs-dpp/src/data_contract/document_type/array_field.rs +++ b/packages/rs-dpp/src/data_contract/document_type/array_field.rs @@ -135,6 +135,6 @@ impl ArrayFieldType { fn get_field_type_matching_error() -> ProtocolError { ProtocolError::DataContractError(DataContractError::ValueWrongType( - "document field type doesn't match document value", + "document field type doesn't match document value for array", )) } diff --git a/packages/rs-dpp/src/data_contract/document_type/document_field.rs b/packages/rs-dpp/src/data_contract/document_type/document_field.rs index e76628f302e..a6e838352b7 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_field.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_field.rs @@ -574,23 +574,7 @@ impl DocumentFieldType { } } DocumentFieldType::ByteArray(_, _) => { - let mut bytes = match value { - Value::Bytes(bytes) => Ok(bytes.clone()), - Value::Text(text) => { - let value_as_bytes = base64::decode(text).map_err(|_| { - ProtocolError::DataContractError(DataContractError::ValueDecodingError( - "bytearray: invalid base64 value", - )) - })?; - Ok(value_as_bytes) - } - Value::Array(array) => array - .iter() - .map(|byte| byte.to_integer().map_err(ProtocolError::ValueError)) - .collect::, ProtocolError>>(), - _ => Err(get_field_type_matching_error()), - }?; - + let mut bytes = value.to_binary_bytes()?; let mut r_vec = bytes.len().encode_var_vec(); r_vec.append(&mut bytes); Ok(r_vec) @@ -680,22 +664,9 @@ impl DocumentFieldType { DocumentFieldType::Number => { encode_float(value.to_float().map_err(ProtocolError::ValueError)?) } - DocumentFieldType::ByteArray(_, _) => match value { - Value::Bytes(bytes) => Ok(bytes.clone()), - Value::Text(text) => { - let value_as_bytes = base64::decode(text).map_err(|_| { - ProtocolError::DataContractError(DataContractError::ValueDecodingError( - "bytearray: invalid base64 value", - )) - })?; - Ok(value_as_bytes) - } - Value::Array(array) => array - .iter() - .map(|byte| byte.to_integer().map_err(ProtocolError::ValueError)) - .collect::, ProtocolError>>(), - _ => Err(get_field_type_matching_error()), - }, + DocumentFieldType::ByteArray(_, _) => { + value.to_binary_bytes().map_err(ProtocolError::ValueError) + } DocumentFieldType::Boolean => { let value_as_boolean = value.as_bool().ok_or_else(get_field_type_matching_error)?; if value_as_boolean { diff --git a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs index bfc737bf823..1b3ce88bd7e 100644 --- a/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/withdrawals_data_triggers/mod.rs @@ -145,7 +145,7 @@ mod tests { "pooling": Pooling::Never as u8, "outputScript": (0..23).collect::>(), "status": withdrawals_contract::WithdrawalStatus::BROADCASTED as u8, - "transactionIndex": 1u32, + "transactionIndex": 1u64, "transactionSignHeight": 93u64, "transactionId": vec![1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], }), diff --git a/packages/rs-drive-abci/src/abci/handlers.rs b/packages/rs-drive-abci/src/abci/handlers.rs index f2e0da0bf96..46634a6ad37 100644 --- a/packages/rs-drive-abci/src/abci/handlers.rs +++ b/packages/rs-drive-abci/src/abci/handlers.rs @@ -251,7 +251,9 @@ mod tests { use dashcore::BlockHash; use dpp::contracts::withdrawals_contract; use dpp::data_contract::DriveContractExt; + use dpp::identity::core_script::CoreScript; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; + use dpp::platform_value::{platform_value, BinaryData}; use dpp::prelude::Identifier; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use dpp::tests::fixtures::get_withdrawal_document_fixture; @@ -310,15 +312,15 @@ mod tests { let document = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::POOLED, - "transactionIndex": 1, - "transactionSignHeight": 93, - "transactionId": tx_id, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::from_bytes((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::POOLED as u8, + "transactionIndex": 1u64, + "transactionSignHeight": 93u64, + "transactionId": BinaryData::new(tx_id), }), None, ) diff --git a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs index ed88dce9da2..f75aca1a301 100644 --- a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs @@ -554,6 +554,7 @@ mod tests { use crate::block::BlockStateInfo; use crate::test::helpers::setup::setup_platform_with_initial_state_structure; + use dpp::identity::core_script::CoreScript; use dpp::platform_value::platform_value; use dpp::{ data_contract::{DataContract, DriveContractExt}, @@ -640,9 +641,9 @@ mod tests { "amount": 1000u64, "coreFeePerByte": 1u32, "pooling": Pooling::Never, - "outputScript": CoreScript::new((0..23).collect::>()), + "outputScript": CoreScript::from_bytes((0..23).collect::>()), "status": withdrawals_contract::WithdrawalStatus::BROADCASTED as u8, - "transactionIndex": 1u32, + "transactionIndex": 1u64, "transactionSignHeight": 93u64, "transactionId": Identifier::new([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), }), @@ -668,9 +669,9 @@ mod tests { "amount": 1000u64, "coreFeePerByte": 1u32, "pooling": Pooling::Never as u8, - "outputScript": CoreScript::new((0..23).collect::>()), + "outputScript": CoreScript::from_bytes((0..23).collect::>()), "status": withdrawals_contract::WithdrawalStatus::BROADCASTED as u8, - "transactionIndex": 2u32, + "transactionIndex": 2u64, "transactionSignHeight": 10u64, "transactionId": Identifier::new([3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), }), @@ -742,6 +743,7 @@ mod tests { use std::cell::RefCell; use dpp::data_contract::DriveContractExt; + use dpp::identity::core_script::CoreScript; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::platform_value; @@ -775,9 +777,9 @@ mod tests { "amount": 1000u64, "coreFeePerByte": 1u32, "pooling": Pooling::Never as u8, - "outputScript": CoreScript::new((0..23).collect::>()), + "outputScript": CoreScript::from_bytes((0..23).collect::>()), "status": withdrawals_contract::WithdrawalStatus::QUEUED as u8, - "transactionIndex": 1u32, + "transactionIndex": 1u64, }), None, ) @@ -802,9 +804,9 @@ mod tests { "amount": 1000u64, "coreFeePerByte": 1u32, "pooling": Pooling::Never as u8, - "outputScript": CoreScript::new((0..23).collect::>()), + "outputScript": CoreScript::from_bytes((0..23).collect::>()), "status": withdrawals_contract::WithdrawalStatus::QUEUED as u8, - "transactionIndex": 2u32, + "transactionIndex": 2u64, }), None, ) @@ -938,6 +940,7 @@ mod tests { use crate::test::helpers::setup::setup_platform_with_initial_state_structure; use dpp::data_contract::DriveContractExt; use dpp::document::Document; + use dpp::identity::core_script::CoreScript; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; use dpp::platform_value::platform_value; use dpp::prelude::Identifier; @@ -969,9 +972,9 @@ mod tests { "amount": 1000u64, "coreFeePerByte": 1u32, "pooling": Pooling::Never as u8, - "outputScript": CoreScript::new((0..23).collect::>()), + "outputScript": CoreScript::from_bytes((0..23).collect::>()), "status": withdrawals_contract::WithdrawalStatus::POOLED as u8, - "transactionIndex": 1u32, + "transactionIndex": 1u64, }), None, ) @@ -996,9 +999,9 @@ mod tests { "amount": 1000u64, "coreFeePerByte": 1u32, "pooling": Pooling::Never as u8, - "outputScript": CoreScript::new((0..23).collect::>()), + "outputScript": CoreScript::from_bytes((0..23).collect::>()), "status": withdrawals_contract::WithdrawalStatus::POOLED as u8, - "transactionIndex": 2u32, + "transactionIndex": 2u64, }), None, ) diff --git a/packages/rs-drive-nodejs/src/converter.rs b/packages/rs-drive-nodejs/src/converter.rs index fcd40a5283f..e6874d4e4a1 100644 --- a/packages/rs-drive-nodejs/src/converter.rs +++ b/packages/rs-drive-nodejs/src/converter.rs @@ -1,4 +1,5 @@ use drive::dpp::identity::{IdentityPublicKey, KeyID, KeyType, Purpose, SecurityLevel}; +use drive::dpp::platform_value::BinaryData; use drive::drive::block_info::BlockInfo; use drive::drive::flags::StorageFlags; use drive::fee::credits::Credits; @@ -485,7 +486,7 @@ pub fn js_object_to_identity_public_key<'a, C: Context<'a>>( security_level, key_type, read_only, - data, + data: BinaryData::new(data), disabled_at, }) } diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 19384bbc81e..dea1203505e 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -1716,10 +1716,10 @@ mod tests { drive .delete_document_for_contract( - documents.get(0).unwrap().id, + documents.get(0).unwrap().id.to_buffer(), &contract, "niceDocument", - Some(documents.get(0).unwrap().owner_id), + Some(documents.get(0).unwrap().owner_id.to_buffer()), BlockInfo::default(), true, Some(&db_transaction), diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 772b728061e..5ddfd117c79 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -684,7 +684,7 @@ mod tests { use dpp::document::document_factory::DocumentFactory; use dpp::document::document_validator::DocumentValidator; - use dpp::platform_value::Value; + use dpp::platform_value::{platform_value, Value}; use dpp::prelude::DataContract; use dpp::util::serializer; use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; @@ -1054,7 +1054,7 @@ mod tests { drive .delete_document_for_contract( - alice_profile.id, + alice_profile.id.to_buffer(), &contract, "profile", None, @@ -2351,7 +2351,7 @@ mod tests { let block_info = BlockInfo::default(); let owner_id = dpp::identifier::Identifier::new([2u8; 32]); - let documents = json!({ + let documents = platform_value!({ "niceDocument": { "type": "object", "properties": { @@ -2382,7 +2382,7 @@ mod tests { ); let contract = factory - .create(owner_id, documents, None) + .create(owner_id, documents, None, None) .expect("data in fixture should be correct"); let contract_cbor = contract.to_cbor().expect("should encode contract to cbor"); diff --git a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs index 9701e9b1d8c..5ce3324d815 100644 --- a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs +++ b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; use dpp::data_contract::document_type::random_document::CreateRandomDocument; use dpp::document::Document; +use dpp::identity::core_script::CoreScript; use dpp::platform_value::Value; use dpp::{contracts::withdrawals_contract, data_contract::DriveContractExt}; use grovedb::TransactionArg; @@ -176,8 +177,8 @@ impl Drive { let document = documents .get(0) - .ok_or(Error::Drive(DriveError::CorruptedCodeExecution( - "document was not found by transactionId", + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "document was not found by transactionId".to_string(), )))? .clone(); @@ -197,7 +198,9 @@ mod tests { mod fetch_withdrawal_documents_by_status { use dpp::data_contract::DriveContractExt; + use dpp::identity::core_script::CoreScript; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; + use dpp::platform_value::platform_value; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use super::*; @@ -227,13 +230,13 @@ mod tests { let document = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::QUEUED, - "transactionIndex": 1, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::from_bytes((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::QUEUED as u8, + "transactionIndex": 1u64, }), None, ) @@ -254,13 +257,13 @@ mod tests { let document = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::from_bytes((0..23).collect::>()), "status": withdrawals_contract::WithdrawalStatus::POOLED, - "transactionIndex": 2, + "transactionIndex": 2u64, }), None, ) @@ -296,7 +299,9 @@ mod tests { mod find_document_by_transaction_id { use dpp::data_contract::DriveContractExt; + use dpp::identity::core_script::CoreScript; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; + use dpp::platform_value::{platform_value, Bytes32}; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use super::*; @@ -317,14 +322,14 @@ mod tests { let document = get_withdrawal_document_fixture( &data_contract, owner_id, - json!({ - "amount": 1000, - "coreFeePerByte": 1, - "pooling": Pooling::Never, - "outputScript": (0..23).collect::>(), - "status": withdrawals_contract::WithdrawalStatus::POOLED, - "transactionIndex": 1, - "transactionId": (0..32).collect::>(), + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": CoreScript::from_bytes((0..23).collect::>()), + "status": withdrawals_contract::WithdrawalStatus::POOLED as u8, + "transactionIndex": 1u64, + "transactionId": Bytes32::default(), }), None, ) @@ -344,7 +349,7 @@ mod tests { let found_document = drive .find_withdrawal_document_by_transaction_id( - &(0..32).collect::>(), + Bytes32::default().as_slice(), Some(&transaction), ) .expect("to find document by it's transaction id"); diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 8c7ccabca4e..2c488eae388 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -88,6 +88,7 @@ use drive::tests::helpers::setup::setup_drive; use dpp::data_contract::validation::data_contract_validator::DataContractValidator; #[cfg(feature = "full")] use dpp::document::Document; +use dpp::platform_value::platform_value; #[cfg(feature = "full")] use dpp::platform_value::Value; @@ -1750,12 +1751,11 @@ fn test_family_basic_queries() { .expect("we should be able to deserialize the cbor"); assert_eq!( - last_person.id, + last_person.id.to_vec(), vec![ 76, 161, 17, 201, 152, 232, 129, 48, 168, 13, 49, 10, 218, 53, 118, 136, 165, 198, 189, 116, 116, 22, 133, 92, 104, 165, 186, 249, 94, 81, 45, 20, ] - .as_slice() ); // fetching by $id with order by desc @@ -1791,12 +1791,11 @@ fn test_family_basic_queries() { .expect("we should be able to deserialize the cbor"); assert_eq!( - last_person.id, + last_person.id.to_vec(), vec![ 140, 161, 17, 201, 152, 232, 129, 48, 168, 13, 49, 10, 218, 53, 118, 136, 165, 198, 189, 116, 116, 22, 133, 92, 104, 165, 186, 249, 94, 81, 45, 20, ] - .as_slice() ); // @@ -1855,12 +1854,11 @@ fn test_family_basic_queries() { .expect("we should be able to deserialize the cbor"); assert_eq!( - last_person.id, + last_person.id.to_vec(), vec![ 249, 170, 70, 122, 181, 31, 35, 176, 175, 131, 70, 150, 250, 223, 194, 203, 175, 200, 107, 252, 199, 227, 154, 105, 89, 57, 38, 85, 236, 192, 254, 88, ] - .as_slice() ); // @@ -2325,7 +2323,7 @@ fn test_family_sql_query() { // Empty where clause let query_cbor = serializer::serializable_value_to_cbor( - json!({ + &json!({ "where": [], "limit": 100, "orderBy": [ @@ -2345,7 +2343,7 @@ fn test_family_sql_query() { // Equality clause let query_cbor = serializer::serializable_value_to_cbor( - json!({ + &json!({ "where": [ ["firstName", "==", "Chris"] ] @@ -2363,7 +2361,7 @@ fn test_family_sql_query() { // Less than let query_cbor = serializer::serializable_value_to_cbor( - json!({ + &json!({ "where": [ ["firstName", "<", "Chris"] ], @@ -2386,7 +2384,7 @@ fn test_family_sql_query() { // Starts with let query_cbor = serializer::serializable_value_to_cbor( - json!({ + &json!({ "where": [ ["firstName", "StartsWith", "C"] ], @@ -2409,7 +2407,7 @@ fn test_family_sql_query() { // Range combination let query_cbor = serializer::serializable_value_to_cbor( - json!({ + &json!({ "where": [ ["firstName", ">", "Chris"], ["firstName", "<=", "Noellyn"] @@ -2433,7 +2431,7 @@ fn test_family_sql_query() { // In clause let names = vec![String::from("a"), String::from("b")]; let query_cbor = serializer::serializable_value_to_cbor( - json!({ + &json!({ "where": [ ["firstName", "in", names] ], @@ -2543,7 +2541,7 @@ fn test_family_with_nulls_query() { .map(|result| { let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); - base64::encode(document.id) + base64::encode(document.id.as_slice()) }) .collect(); @@ -2768,7 +2766,7 @@ fn test_dpns_query() { .map(|result| { let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); - hex::encode(document.id) + hex::encode(document.id.as_slice()) }) .collect(); @@ -4093,7 +4091,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { .map(|result| { let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); - Vec::from(document.id) + document.id.to_vec() }) .collect(); @@ -4141,7 +4139,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { .map(|result| { let document = Document::from_cbor(result.as_slice(), None, None) .expect("we should be able to deserialize the cbor"); - Vec::from(document.id) + document.id.to_vec() }) .collect(); @@ -4232,7 +4230,7 @@ fn test_query_a_b_c_d_e_contract() { let block_info = BlockInfo::default(); let owner_id = dpp::identifier::Identifier::new([2u8; 32]); - let documents = json!({ + let documents = platform_value!({ "testDocument": { "type": "object", "properties": { @@ -4285,7 +4283,7 @@ fn test_query_a_b_c_d_e_contract() { let factory = DataContractFactory::new(1, Arc::new(data_contract_validator)); let contract = factory - .create(owner_id, documents, None) + .create(owner_id, documents, None, None) .expect("data in fixture should be correct"); let contract_cbor = contract.to_cbor().expect("should encode contract to cbor"); diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index f81ce4c84cb..6b8f4ac103b 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -707,7 +707,7 @@ fn test_query_historical() { .as_text() .expect("the first name should be a string") .to_string(); - (name, Vec::from(document.id)) + (name, document.id.to_vec()) }) .collect(); @@ -1263,7 +1263,7 @@ fn test_query_historical() { .expect("we should be able to deserialize the cbor"); assert_eq!( - last_person.id, + last_person.id.to_vec(), vec![ 76, 161, 17, 201, 152, 232, 129, 48, 168, 13, 49, 10, 218, 53, 118, 136, 165, 198, 189, 116, 116, 22, 133, 92, 104, 165, 186, 249, 94, 81, 45, 20 @@ -1304,7 +1304,7 @@ fn test_query_historical() { .expect("we should be able to deserialize the cbor"); assert_eq!( - last_person.id, + last_person.id.to_vec(), vec![ 140, 161, 17, 201, 152, 232, 129, 48, 168, 13, 49, 10, 218, 53, 118, 136, 165, 198, 189, 116, 116, 22, 133, 92, 104, 165, 186, 249, 94, 81, 45, 20 @@ -1368,7 +1368,7 @@ fn test_query_historical() { .expect("we should be able to deserialize the cbor"); assert_eq!( - last_person.id, + last_person.id.to_vec(), vec![ 249, 170, 70, 122, 181, 31, 35, 176, 175, 131, 70, 150, 250, 223, 194, 203, 175, 200, 107, 252, 199, 227, 154, 105, 89, 57, 38, 85, 236, 192, 254, 88 diff --git a/packages/rs-platform-value/src/types/binary_data.rs b/packages/rs-platform-value/src/types/binary_data.rs index ff25d24bba9..2dd0830b8ef 100644 --- a/packages/rs-platform-value/src/types/binary_data.rs +++ b/packages/rs-platform-value/src/types/binary_data.rs @@ -196,10 +196,7 @@ impl PartialEq for Vec { #[cfg(test)] mod tests { - use std::collections::HashMap; - use crate::{from_value, to_value, Identifier, Value}; - use serde::{Deserialize, Serialize}; use super::*; diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index aea0d2780d2..bf7493f034b 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -282,12 +282,9 @@ impl Into for &Identifier { #[cfg(test)] mod tests { - use std::collections::HashMap; - - use crate::{from_value, to_value, Identifier}; - use serde::{Deserialize, Serialize}; use super::*; + use crate::{from_value, to_value, Identifier}; #[test] fn test_identifier_value_serialization() { From e0a3e9dc3688a35b84a1ffc11cd0a4c34511a7fc Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 20:39:28 +0700 Subject: [PATCH 155/228] more fixes --- packages/rs-platform-value/src/eq.rs | 108 ++++++++++++++++++ packages/rs-platform-value/src/lib.rs | 15 +-- packages/rs-platform-value/src/patch/diff.rs | 2 +- packages/rs-platform-value/src/pointer.rs | 18 ++- .../rs-platform-value/src/system_bytes.rs | 24 ++-- .../src/value_serialization/mod.rs | 7 +- 6 files changed, 149 insertions(+), 25 deletions(-) create mode 100644 packages/rs-platform-value/src/eq.rs diff --git a/packages/rs-platform-value/src/eq.rs b/packages/rs-platform-value/src/eq.rs new file mode 100644 index 00000000000..5b82e58ef3c --- /dev/null +++ b/packages/rs-platform-value/src/eq.rs @@ -0,0 +1,108 @@ +use crate::Value; + +macro_rules! implpartialeq { + ($($t:ty),+ $(,)?) => { + $( + impl PartialEq<$t> for Value { + #[inline] + fn eq(&self, other: &$t) -> bool { + if let Some(i) = self.as_integer::<$t>() { + &i == other + } else { + false + } + } + } + + impl PartialEq<$t> for &Value { + #[inline] + fn eq(&self, other: &$t) -> bool { + if let Some(i) = self.as_integer::<$t>() { + &i == other + } else { + false + } + } + } + )+ + }; +} + +implpartialeq! { + u128, + u64, + u32, + u16, + u8, + i128, + i64, + i32, + i16, + i8, +} + +impl PartialEq for Value { + #[inline] + fn eq(&self, other: &String) -> bool { + if let Some(i) = self.as_text() { + i == other + } else { + false + } + } +} + +impl PartialEq for &Value { + #[inline] + fn eq(&self, other: &String) -> bool { + if let Some(i) = self.as_str() { + i == other + } else { + false + } + } +} + +impl PartialEq<&str> for Value { + #[inline] + fn eq(&self, other: &&str) -> bool { + if let Some(i) = self.as_str() { + &i == other + } else { + false + } + } +} + +impl PartialEq<&str> for &Value { + #[inline] + fn eq(&self, other: &&str) -> bool { + if let Some(i) = self.as_str() { + &i == other + } else { + false + } + } +} + +impl PartialEq for Value { + #[inline] + fn eq(&self, other: &f64) -> bool { + if let Some(i) = self.as_float() { + &i == other + } else { + false + } + } +} + +impl PartialEq for &Value { + #[inline] + fn eq(&self, other: &f64) -> bool { + if let Some(i) = self.as_float() { + &i == other + } else { + false + } + } +} diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 72be1895e00..9616b326d7b 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -10,6 +10,7 @@ extern crate core; pub mod btreemap_extensions; pub mod converter; pub mod display; +mod eq; mod error; mod index; mod inner_array_value; @@ -229,7 +230,7 @@ impl Value { /// /// let value = Value::Bool(true); /// let r_value : Result = value.to_integer(); - /// assert_eq!(r_value, Err(Error::StructureError("value is not an integer".to_string()))); + /// assert_eq!(r_value, Err(Error::StructureError("value is not an integer, found true".to_string()))); /// ``` pub fn to_integer(&self) -> Result where @@ -1194,8 +1195,8 @@ impl From<[(Value, Value); N]> for Value { /// ``` /// use platform_value::Value; /// - /// let map1 = Value::from([(1, 2), (3, 4)]); - /// let map2: Value = [(1, 2), (3, 4)].into(); + /// let map1 = Value::from([(Value::from(1), Value::from(2)), (Value::from(3), Value::from(4))]); + /// let map2: Value = [(Value::from(1), Value::from(2)), (Value::from(3), Value::from(4))].into(); /// assert_eq!(map1, map2); /// ``` fn from(arr: [(Value, Value); N]) -> Self { @@ -1213,8 +1214,8 @@ impl From<[(String, Value); N]> for Value { /// ``` /// use platform_value::Value; /// - /// let map1 = Value::from([("1".to_string(), 2), ("3".to_string(), 4)]); - /// let map2: Value = [("1".to_string(), 2), ("3".to_string(), 4)].into(); + /// let map1 = Value::from([("1".to_string(), Value::from(2)), ("3".to_string(), Value::from(4))]); + /// let map2: Value = [("1".to_string(), Value::from(2)), ("3".to_string(), Value::from(4))].into(); /// assert_eq!(map1, map2); /// ``` fn from(mut arr: [(String, Value); N]) -> Self { @@ -1234,8 +1235,8 @@ impl From<[(&str, Value); N]> for Value { /// ``` /// use platform_value::Value; /// - /// let map1 = Value::from([("1", 2), ("3", 4)]); - /// let map2: Value = [("1", 2), ("3", 4)].into(); + /// let map1 = Value::from([("1", Value::from(2)), ("3", Value::from(4))]); + /// let map2: Value = [("1", Value::from(2)), ("3", Value::from(4))].into(); /// assert_eq!(map1, map2); /// ``` fn from(mut arr: [(&str, Value); N]) -> Self { diff --git a/packages/rs-platform-value/src/patch/diff.rs b/packages/rs-platform-value/src/patch/diff.rs index 471eefac823..9b2ff790bb1 100644 --- a/packages/rs-platform-value/src/patch/diff.rs +++ b/packages/rs-platform-value/src/patch/diff.rs @@ -105,7 +105,7 @@ fn append_path(path: &mut String, key: &str) { /// use platform_value::{from_value, patch, platform_value}; /// /// # pub fn main() { -/// use treediff::diff; +/// use platform_value::patch::diff; /// let left = platform_value!({ /// "title": "Goodbye!", /// "author" : { diff --git a/packages/rs-platform-value/src/pointer.rs b/packages/rs-platform-value/src/pointer.rs index 098e6669541..ab110f28af4 100644 --- a/packages/rs-platform-value/src/pointer.rs +++ b/packages/rs-platform-value/src/pointer.rs @@ -1,4 +1,5 @@ use crate::{Value, ValueMapHelper}; +use std::mem; fn parse_index(s: &str) -> Option { if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) { @@ -71,8 +72,8 @@ impl Value { /// use platform_value::Value; /// /// fn main() { - /// let s = r#"{"x": 1.0, "y": 2.0}"#; - /// let mut value: Value = serde_json::from_str(s).unwrap().into(); + /// use platform_value::platform_value; + /// let mut value: Value = platform_value!({"x": 1.0, "y": 2.0}); /// /// // Check value using read-only pointer /// assert_eq!(value.pointer("/x"), Some(&1.0.into())); @@ -106,4 +107,17 @@ impl Value { _ => None, }) } + + /// Takes the value out of the `Value`, leaving a `Null` in its place. + /// + /// ``` + /// # use platform_value::platform_value; + /// # + /// let mut v = platform_value!({ "x": "y" }); + /// assert_eq!(v["x"].take(), platform_value!("y")); + /// assert_eq!(v, platform_value!({ "x": null })); + /// ``` + pub fn take(&mut self) -> Value { + mem::replace(self, Value::Null) + } } diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index 8e00aa2704e..dc2b551e43e 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -329,20 +329,20 @@ impl Value { /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` - /// # use platform_value::{Error, Value}; - /// use platform_value::Value::Bytes32; + /// # use platform_value::{Bytes32, Error, Value}; + /// /// # /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]); /// assert_eq!(value.into_bytes_32(), Ok(Bytes32([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]))); /// /// - /// let value = Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string()); + /// let value = Value::Text("ViN2Q6crZW1IYSNjAP5smv6avijtGTr2bxMs142MnHU=".to_string()); /// assert_eq!(value.into_bytes_32(), Ok(Bytes32([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); /// /// let value = Value::Text("a811".to_string()); - /// assert_eq!(value.into_bytes_32(), Err(Error::StructureError("buffer was not 32 bytes long".to_string()))); + /// assert_eq!(value.into_bytes_32(), Err(Error::ByteLengthNot32BytesError("buffer was not 32 bytes long".to_string()))); /// /// let value = Value::Text("a811Ii".to_string()); - /// assert_eq!(value.into_bytes_32(), Err(Error::StructureError("value was a string, but could not be decoded from base 58".to_string()))); + /// assert_eq!(value.into_bytes_32(), Err(Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))); /// /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); /// assert_eq!(value.into_bytes_32(), Ok(Bytes32([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); @@ -381,25 +381,25 @@ impl Value { /// Returns `Err(Error::Structure("reason"))` otherwise. /// /// ``` - /// # use platform_value::{Error, Value}; + /// # use platform_value::{Bytes32, Error, Value}; /// # /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]); - /// assert_eq!(value.to_bytes_32(), Ok([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50])); /// + /// assert_eq!(value.to_bytes_32(), Ok(Bytes32::new([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50]))); /// /// - /// let value = Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string()); - /// assert_eq!(value.to_bytes_32(), Ok([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117])); + /// let value = Value::Text("ViN2Q6crZW1IYSNjAP5smv6avijtGTr2bxMs142MnHU=".to_string()); + /// assert_eq!(value.to_bytes_32(), Ok(Bytes32::new([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); /// /// let value = Value::Text("a811".to_string()); - /// assert_eq!(value.to_bytes_32(), Err(Error::StructureError("buffer was not 32 bytes long".to_string()))); + /// assert_eq!(value.to_bytes_32(), Err(Error::ByteLengthNot32BytesError("buffer was not 32 bytes long".to_string()))); /// /// let value = Value::Text("a811Ii".to_string()); /// assert_eq!(value.to_bytes_32(), Err(Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))); /// /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)]); - /// assert_eq!(value.to_bytes_32(), Ok([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101])); + /// assert_eq!(value.to_bytes_32(), Ok(Bytes32::new([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); /// /// let value = Value::Identifier([5u8;32]); - /// assert_eq!(value.to_bytes_32(), Ok([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5])); + /// assert_eq!(value.to_bytes_32(), Ok(Bytes32::new([5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5,5, 5, 5,5,5,5,5,5]))); /// /// let value = Value::Bool(true); /// assert_eq!(value.to_bytes_32(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); diff --git a/packages/rs-platform-value/src/value_serialization/mod.rs b/packages/rs-platform-value/src/value_serialization/mod.rs index a17599e18ae..e3af45fdba9 100644 --- a/packages/rs-platform-value/src/value_serialization/mod.rs +++ b/packages/rs-platform-value/src/value_serialization/mod.rs @@ -23,7 +23,7 @@ pub mod ser; /// location: String, /// } /// -/// fn compare_platform_values() -> Result<(), Box> { +/// fn compare_platform_values() -> Result<(), Box> { /// let u = User { /// fingerprint: "0xF9BA143B95FF6D82".to_owned(), /// location: "Menlo Park, CA".to_owned(), @@ -123,7 +123,8 @@ mod tests { arr: Vec, map: HashMap, number: i32, - static_string: &'static str, + //todo: manage static strings + //static_string: &'static str, } let mut hm = HashMap::new(); @@ -134,7 +135,7 @@ mod tests { arr: vec!["kek".to_owned(), "top".to_owned()], map: hm, number: 420, - static_string: "pizza", + //static_string: "pizza", }; let platform_value = to_value(yeet.clone()).expect("please"); From bff7b09facbae7c4bf078a06104784ded9428cdb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 21:08:13 +0700 Subject: [PATCH 156/228] fixes --- .../rs-drive/src/drive/identity/withdrawals/documents.rs | 1 - packages/rs-drive/src/query/mod.rs | 1 - packages/rs-platform-value/src/macros.rs | 6 ++++++ packages/rs-platform-value/src/patch/mod.rs | 4 +++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs index 5ce3324d815..02c16823f90 100644 --- a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs +++ b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs @@ -2,7 +2,6 @@ use std::collections::BTreeMap; use dpp::data_contract::document_type::random_document::CreateRandomDocument; use dpp::document::Document; -use dpp::identity::core_script::CoreScript; use dpp::platform_value::Value; use dpp::{contracts::withdrawals_contract, data_contract::DriveContractExt}; use grovedb::TransactionArg; diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 0fd65324c15..c8036c1dd83 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -102,7 +102,6 @@ use dpp::data_contract::extra::common::bytes_for_system_value; #[cfg(any(feature = "full", feature = "verify"))] use dpp::document::Document; #[cfg(any(feature = "full", feature = "verify"))] -use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; #[cfg(any(feature = "full", feature = "verify"))] use dpp::platform_value::Value; diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index 447851f349d..31c521ea938 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -302,6 +302,12 @@ mod test { use crate::types::binary_data::BinaryData; use crate::{platform_value, to_value, Identifier, Value}; + #[test] + fn test_null() { + let value = platform_value!(null); + assert_eq!(value, Value::Null) + } + #[test] fn test_identity_is_kept() { let id = Identifier::new([0; 32]); diff --git a/packages/rs-platform-value/src/patch/mod.rs b/packages/rs-platform-value/src/patch/mod.rs index 8502fa8d370..adc19bf74d4 100644 --- a/packages/rs-platform-value/src/patch/mod.rs +++ b/packages/rs-platform-value/src/patch/mod.rs @@ -443,6 +443,8 @@ fn apply_patches( /// "tags": [ "example" ] /// }); /// +/// merge(&mut doc, &patch); +/// /// assert_eq!(doc, platform_value!({ /// "title": "Hello!", /// "author" : { @@ -466,7 +468,7 @@ pub fn merge(doc: &mut Value, patch: &Value) { let map = doc.as_map_mut().unwrap(); for (key, value) in patch.as_map().unwrap() { if value.is_null() { - map.remove_optional_key_value(value); + map.remove_optional_key_value(key); } else { merge(map.get_key_by_value_mut_or_insert(key, Value::Null), value); } From 5efa74f92a1f2ad21daae6658174171f28a394bd Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 18 Mar 2023 21:40:17 +0700 Subject: [PATCH 157/228] small change --- packages/rs-dpp/src/bls.rs | 1 + packages/wasm-dpp/src/data_contract/data_contract.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/bls.rs b/packages/rs-dpp/src/bls.rs index 32fbc71c15b..e60d474e260 100644 --- a/packages/rs-dpp/src/bls.rs +++ b/packages/rs-dpp/src/bls.rs @@ -1,4 +1,5 @@ use crate::{ProtocolError, PublicKeyValidationError}; +#[cfg(not(target_arch = "wasm32"))] use anyhow::anyhow; use bls_signatures::{verify_messages, PrivateKey, PublicKey, Serialize}; use std::convert::TryInto; diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index cb4898d02ff..25d8866972d 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -278,13 +278,13 @@ impl DataContractWasm { js_sys::Reflect::set( &object, &Into::::into("$id".to_owned()), - &Into::::into(Buffer::from_bytes(&self.0.id.to_buffer())), + &Into::::into(Buffer::from_bytes_owned(self.0.id.to_vec())), ) .expect("target is an object"); js_sys::Reflect::set( &object, &Into::::into("ownerId".to_owned()), - &Into::::into(Buffer::from_bytes(&self.0.owner_id.to_buffer())), + &Into::::into(Buffer::from_bytes_owned(&self.0.owner_id.to_vec())), ) .expect("target is an object"); Ok(object) From 361bfc10ed31a580c9a1ae34de23a26343396553 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 19 Mar 2023 00:29:34 +0700 Subject: [PATCH 158/228] fixes --- .../src/data_contract/data_contract_facade.rs | 3 --- .../data_contract_create_transition/mod.rs | 8 ++----- ...e_data_contract_update_transition_basic.rs | 2 +- packages/rs-dpp/src/errors/errors.rs | 1 - .../abstract_state_transition.rs | 24 +++++++++---------- .../errors/state_transition_error.rs | 4 ++-- .../state_transition_facade.rs | 2 +- .../state_transition_factory.rs | 11 +++++---- .../validate_state_transition_basic.rs | 3 +-- ..._documents_batch_transitions_basic_spec.rs | 6 ++--- .../identity_update_transition_spec.rs | 1 - .../src/data_contract/data_contract.rs | 5 +++- .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- .../wasm-dpp/src/document/document_facade.rs | 4 ++-- packages/wasm-dpp/src/document/factory.rs | 4 +--- packages/wasm-dpp/src/document/mod.rs | 3 +-- .../state_transition_facade.rs | 10 ++++---- .../state_transition_factory.rs | 3 ++- 19 files changed, 44 insertions(+), 54 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index 28430f2fa7b..69ed645115e 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -1,7 +1,4 @@ use crate::data_contract::contract_config::ContractConfig; -use crate::data_contract::state_transition::{ - DataContractCreateTransition, DataContractUpdateTransition, -}; use crate::data_contract::validation::data_contract_validator::DataContractValidator; use crate::data_contract::{DataContract, DataContractFactory}; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index caf524a4674..464c84959c7 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -126,12 +126,8 @@ impl DataContractCreateTransition { } /// Returns ID of the created contract - pub fn get_modified_data_ids(&self) -> Vec<&Identifier> { - vec![&self.data_contract.id] - } - - pub fn get_entropy(&self) -> &[u8; 32] { - &self.entropy.to_buffer() + pub fn get_modified_data_ids(&self) -> Vec { + vec![self.data_contract.id] } } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 07e16b3b27d..6e672b0102b 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -74,7 +74,7 @@ impl AsyncDataValidatorWithContext for DataContractUpdateTransitionBasicVali where SR: StateRepositoryLike, { - type Item = JsonValue; + type Item = Value; async fn validate( &self, diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index a99e99407cb..a0a0eaac2a6 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -17,7 +17,6 @@ use crate::{ SerdeParsingError, }; -use crate::{CompatibleProtocolVersionIsNotDefinedError, NonConsensusError, SerdeParsingError}; use platform_value::{Error as ValueError, Value}; #[derive(Error, Debug)] diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 85d8b0c6228..37ecadb18f7 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -14,10 +14,7 @@ use crate::state_transition::errors::{ use crate::{ identity::KeyType, prelude::{Identifier, ProtocolError}, - util::{ - hash, - serializer, - }, + util::{hash, serializer}, BlsModule, }; @@ -121,13 +118,12 @@ pub trait StateTransitionLike: )); } let data_hash = self.hash(true)?; - signer::verify_hash_signature(&data_hash, self.get_signature().as_slice(), public_key_hash).or_else( - |_| { + signer::verify_hash_signature(&data_hash, self.get_signature().as_slice(), public_key_hash) + .or_else(|_| { Err(ProtocolError::from(ConsensusError::SignatureError( SignatureError::InvalidStateTransitionSignatureError, ))) - }, - ) + }) } /// Verifies an ECDSA signature with the public key @@ -139,11 +135,13 @@ pub trait StateTransitionLike: } let data = self.to_buffer(true)?; - signer::verify_data_signature(&data, self.get_signature().as_slice(), public_key).or_else(|_| { - Err(ProtocolError::from(ConsensusError::SignatureError( - SignatureError::InvalidStateTransitionSignatureError, - ))) - }) + signer::verify_data_signature(&data, self.get_signature().as_slice(), public_key).or_else( + |_| { + Err(ProtocolError::from(ConsensusError::SignatureError( + SignatureError::InvalidStateTransitionSignatureError, + ))) + }, + ) } /// Verifies a BLS signature with the public key diff --git a/packages/rs-dpp/src/state_transition/errors/state_transition_error.rs b/packages/rs-dpp/src/state_transition/errors/state_transition_error.rs index b8c3dfe3804..2937d3c2507 100644 --- a/packages/rs-dpp/src/state_transition/errors/state_transition_error.rs +++ b/packages/rs-dpp/src/state_transition/errors/state_transition_error.rs @@ -1,4 +1,4 @@ -use serde_json::Value as JsonValue; +use platform_value::Value; use thiserror::Error; use crate::consensus::ConsensusError; @@ -8,6 +8,6 @@ pub enum StateTransitionError { #[error("Invalid State Transition: {errors:?}")] InvalidStateTransitionError { errors: Vec, - raw_state_transition: JsonValue, + raw_state_transition: Value, }, } diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index f1d1bc031a7..1a37204ad71 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -1,7 +1,7 @@ use std::ops::Deref; use std::sync::Arc; -use serde_json::Value; +use platform_value::Value; use crate::{BlsModule, ProtocolError}; use crate::data_contract::state_transition::data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator; use crate::data_contract::state_transition::data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator; diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index e3f1b810a03..a2ea5c3d1dd 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -1,3 +1,4 @@ +use anyhow::anyhow; use std::{ convert::{TryFrom, TryInto}, sync::Arc, @@ -27,7 +28,7 @@ use crate::{ validation::AsyncDataValidatorWithContext, BlsModule, ProtocolError, }; -use platform_value::Value; +use platform_value::{Value, ValueMapHelper}; use super::{ state_transition_execution_context::StateTransitionExecutionContext, @@ -69,7 +70,7 @@ where pub async fn create_from_object( &self, - raw_state_transition: JsonValue, + raw_state_transition: Value, options: Option, ) -> Result { let options = options.unwrap_or_default(); @@ -104,9 +105,9 @@ where DecodeProtocolEntity::decode_protocol_entity(state_transition_buffer)?; match raw_state_transition { - JsonValue::Object(ref mut m) => m.insert( - String::from("protocolVersion"), - JsonValue::Number(Number::from(protocol_version)), + Value::Map(ref mut m) => m.insert_string_key_value( + "protocolVersion".to_string(), + Value::U32(protocol_version), ), _ => { return Err(ConsensusError::SerializedObjectParsingError { diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs index acff2a2a263..4a6b90e02b0 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs @@ -19,7 +19,6 @@ use crate::{ ProtocolError, }; - use super::validate_state_transition_by_type::ValidatorByStateTransitionType; pub struct StateTransitionBasicValidator @@ -59,7 +58,7 @@ where ) -> Result { let mut result = SimpleValidationResult::default(); - let Ok(state_transition_type) = raw_state_transition.get_u8("type") else { + let Ok(state_transition_type) = raw_state_transition.get_integer("type") else { result.add_error( ConsensusError::BasicError( Box::new(BasicError::MissingStateTransitionTypeError) diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 6c878e35141..60691a72c2f 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -1,5 +1,3 @@ -use std::collections::BTreeMap; -use std::sync::Arc; use crate::{ data_contract::DataContract, document::{ @@ -17,10 +15,12 @@ use crate::{ get_documents_fixture_with_owner_id_from_contract, get_protocol_version_validator_fixture, }, - utils::{generate_random_identifier, get_schema_error}, + utils::get_schema_error, }, version::{ProtocolVersionValidator, LATEST_VERSION}, }; +use std::collections::BTreeMap; +use std::sync::Arc; use crate::document::document_transition::document_base_transition::JsonValue; use crate::tests::utils::generate_random_identifier_struct; diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index a0ccec06d39..e95fb139be8 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -170,7 +170,6 @@ fn to_object_with_signature_skipped() { let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1u32, "type" : 5u8, - "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id, "revision": 0 as Revision, "disablePublicKeys" : [0u32], diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index 25d8866972d..f127792998e 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -284,7 +284,7 @@ impl DataContractWasm { js_sys::Reflect::set( &object, &Into::::into("ownerId".to_owned()), - &Into::::into(Buffer::from_bytes_owned(&self.0.owner_id.to_vec())), + &Into::::into(Buffer::from_bytes_owned(self.0.owner_id.to_vec())), ) .expect("target is an object"); Ok(object) @@ -343,3 +343,6 @@ impl DataContractWasm { &self.0 } } + +#[test] +fn test_query_many() {} diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 6e730b86027..bcdbcfe458f 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -7,7 +7,7 @@ pub use apply::*; pub use validation::*; use dpp::{ - data_contract::state_transition::DataContractCreateTransition, + data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition, platform_value, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 09976f58063..52203c4d428 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -7,7 +7,7 @@ pub use apply::*; pub use validation::*; use dpp::{ - data_contract::state_transition::DataContractUpdateTransition, + data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition, platform_value, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index b191ea7ac90..731c9c05ffa 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -6,8 +6,8 @@ use crate::{ fetch_and_validate_data_contract::DataContractFetcherAndValidatorWasm, utils::{get_class_name, IntoWasm}, validation::ValidationResultWasm, - DataContractWasm, DocumentFactoryWASM, DocumentValidatorWasm, ExtendedDocumentWasm, - DocumentsBatchTransitionWasm, + DataContractWasm, DocumentFactoryWASM, DocumentValidatorWasm, DocumentsBatchTransitionWasm, + ExtendedDocumentWasm, }; #[derive(Clone)] diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 12c1fde7c36..ab497ea6cd9 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -21,9 +21,7 @@ use std::convert::TryFrom; use crate::{ identifier::identifier_from_js_value, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - utils::{ - replace_identifiers_with_bytes_without_failing, IntoWasm, ToSerdeJSONExt, WithJsError, - }, + utils::{IntoWasm, ToSerdeJSONExt, WithJsError}, DataContractWasm, DocumentsBatchTransitionWasm, ExtendedDocumentWasm, }; diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 02421e99dd4..8b102feb9b4 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -27,7 +27,7 @@ pub mod generate_document_id; pub mod state_transition; mod validator; -pub use document_batch_transition::DocumentsBatchTransitionWASM; +pub use document_batch_transition::DocumentsBatchTransitionWasm; use dpp::data_contract::DriveContractExt; use dpp::document::{Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS}; @@ -39,7 +39,6 @@ use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; use dpp::platform_value::ReplacementType; use dpp::platform_value::Value; use dpp::ProtocolError; -pub use document_batch_transition::DocumentsBatchTransitionWasm; pub use factory::DocumentFactoryWASM; use serde_json::Value as JsonValue; pub use validator::DocumentValidatorWasm; diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index c28ab38385e..e3080e31b39 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -55,7 +55,7 @@ impl StateTransitionFacadeWasm { Default::default() }; - let raw_state_transition = raw_state_transition.with_serde_to_json_value()?; + let raw_state_transition = raw_state_transition.with_serde_to_platform_value()?; let result = self .0 @@ -117,10 +117,10 @@ impl StateTransitionFacadeWasm { super::super::conversion::state_transition_wasm_to_object( &raw_state_transition, )? - .with_serde_to_json_value()?; + .with_serde_to_platform_value()?; (state_transition, state_transition_json, execution_context) } else { - let state_transition_json = raw_state_transition.with_serde_to_json_value()?; + let state_transition_json = raw_state_transition.with_serde_to_platform_value()?; let execution_context = StateTransitionExecutionContext::default(); let state_transition = self .0 @@ -163,9 +163,9 @@ impl StateTransitionFacadeWasm { // state_transition.to_object() returns value that does not pass basic validation state_transition_json = super::super::conversion::state_transition_wasm_to_object(&raw_state_transition)? - .with_serde_to_json_value()?; + .with_serde_to_platform_value()?; } else { - state_transition_json = raw_state_transition.with_serde_to_json_value()?; + state_transition_json = raw_state_transition.with_serde_to_platform_value()?; execution_context = StateTransitionExecutionContext::default(); } diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index 4da5f6d42e4..f1c74b89dfa 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -10,6 +10,7 @@ use dpp::{state_transition::{ StateTransitionFactory, StateTransitionFactoryOptions, StateTransition, errors::StateTransitionError, }, version::ProtocolVersionValidator, data_contract::state_transition::{data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator}, identity::{state_transition::{identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, validate_public_key_signatures::{PublicKeysSignaturesValidator}, asset_lock_proof::{AssetLockProofValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator, AssetLockTransactionValidator}, identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic}, validation::PublicKeysValidator}, document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, ProtocolError}; use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; +use dpp::platform_value::Value; use crate::utils::ToSerdeJSONExt; use crate::{ @@ -174,7 +175,7 @@ impl StateTransitionFactoryWasm { Default::default() }; - let raw_state_transition: JsonValue = state_transition_object.with_serde_to_json_value()?; + let raw_state_transition: Value = state_transition_object.with_serde_to_platform_value()?; let result = self .0 From 112ca720d5e8f83e9d396aab028e5f14f9b0dacb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 19 Mar 2023 00:54:50 +0700 Subject: [PATCH 159/228] fixes --- packages/rs-drive-abci/src/platform.rs | 2 +- packages/rs-drive-abci/src/state/genesis.rs | 6 +-- .../drive/identity/withdrawals/documents.rs | 1 - .../src/converter/serde_json.rs | 9 +--- packages/rs-platform-value/src/inner_value.rs | 32 ++++++------ .../src/inner_value_at_path.rs | 49 ++++++++++--------- packages/rs-platform-value/src/lib.rs | 9 +--- packages/rs-platform-value/src/macros.rs | 4 +- .../src/types/binary_data.rs | 12 ++--- .../rs-platform-value/src/types/bytes_32.rs | 12 ++--- .../rs-platform-value/src/types/identifier.rs | 12 ++--- .../src/value_serialization/ser.rs | 10 ++-- .../wasm-dpp/src/data_contract/errors/mod.rs | 5 +- packages/wasm-dpp/src/document/factory.rs | 2 +- ...ate_document_transitions_with_ids_error.rs | 2 +- ...document_transitions_with_indices_error.rs | 2 +- .../identity_update_public_keys_validator.rs | 4 +- .../validate_public_key_signatures.rs | 4 +- .../state_transition_factory.rs | 2 - 19 files changed, 78 insertions(+), 101 deletions(-) diff --git a/packages/rs-drive-abci/src/platform.rs b/packages/rs-drive-abci/src/platform.rs index b0bbac3e4ef..bd6c5ac22ce 100644 --- a/packages/rs-drive-abci/src/platform.rs +++ b/packages/rs-drive-abci/src/platform.rs @@ -83,7 +83,7 @@ impl Platform { config.core.rpc.username.clone(), config.core.rpc.password.clone(), ) - .map_err(|e| { + .map_err(|_e| { Error::Execution(ExecutionError::CorruptedCodeExecution( "Could not setup Dash Core RPC client", )) diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index b27c8b6cf90..a6b37effd0c 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -27,12 +27,12 @@ // DEALINGS IN THE SOFTWARE. use crate::abci::messages::SystemIdentityPublicKeys; -use crate::error::execution::ExecutionError; + use crate::error::Error; use crate::platform::Platform; -use ciborium::{cbor, Value as CborValue}; + use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; -use dpp::platform_value::{platform_value, BinaryData, Bytes32, Value}; +use dpp::platform_value::{platform_value, BinaryData, Bytes32}; use dpp::ProtocolError; use drive::contract::DataContract; use drive::dpp::data_contract::DriveContractExt; diff --git a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs index 02c16823f90..04e4865a7e9 100644 --- a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs +++ b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs @@ -190,7 +190,6 @@ mod tests { use dpp::contracts::withdrawals_contract; use dpp::prelude::Identifier; use dpp::tests::fixtures::get_withdrawal_document_fixture; - use serde_json::json; use crate::tests::helpers::setup::setup_drive_with_initial_state_structure; use crate::tests::helpers::setup::{setup_document, setup_system_data_contract}; diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 09859568f9e..c6f56e290e7 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -231,14 +231,9 @@ impl From<&JsonValue> for Value { }) { //this is an array of bytes - Self::Bytes( - array - .into_iter() - .map(|v| v.as_u64().unwrap() as u8) - .collect(), - ) + Self::Bytes(array.iter().map(|v| v.as_u64().unwrap() as u8).collect()) } else { - Self::Array(array.into_iter().map(|v| v.into()).collect()) + Self::Array(array.iter().map(|v| v.into()).collect()) } } JsonValue::Object(map) => Self::Map( diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index b40e5eabc53..b167b6a010f 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -45,27 +45,32 @@ impl Value { T: Into, { let map = self.as_map_mut_ref()?; - Ok(Self::insert_in_map(map, key, value.into())) + Self::insert_in_map(map, key, value.into()); + Ok(()) } pub fn set_into_binary_data(&mut self, key: &str, value: Vec) -> Result<(), Error> { let map = self.as_map_mut_ref()?; - Ok(Self::insert_in_map(map, key, Value::Bytes(value))) + Self::insert_in_map(map, key, Value::Bytes(value)); + Ok(()) } pub fn set_value(&mut self, key: &str, value: Value) -> Result<(), Error> { let map = self.as_map_mut_ref()?; - Ok(Self::insert_in_map(map, key, value)) + Self::insert_in_map(map, key, value); + Ok(()) } pub fn insert(&mut self, key: String, value: Value) -> Result<(), Error> { let map = self.as_map_mut_ref()?; - Ok(Self::insert_in_map_string_value(map, key, value)) + Self::insert_in_map_string_value(map, key, value); + Ok(()) } pub fn insert_at_end(&mut self, key: String, value: Value) -> Result<(), Error> { let map = self.as_map_mut_ref()?; - Ok(Self::push_to_map_string_value(map, key, value)) + Self::push_to_map_string_value(map, key, value); + Ok(()) } pub fn remove(&mut self, key: &str) -> Result { @@ -75,7 +80,7 @@ impl Value { pub fn remove_many(&mut self, keys: &Vec<&str>) -> Result<(), Error> { let map = self.as_map_mut_ref()?; - keys.into_iter() + keys.iter() .try_for_each(|key| map.remove_key(key).map(|_| ())) } @@ -117,14 +122,13 @@ impl Value { { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) - .map(|v| { + .and_then(|v| { if v.is_null() { None } else { Some(v.into_integer()) } }) - .flatten() .transpose() } @@ -137,14 +141,13 @@ impl Value { pub fn remove_optional_identifier(&mut self, key: &str) -> Result, Error> { let map = self.as_map_mut_ref()?; map.remove_optional_key(key) - .map(|v| { + .and_then(|v| { if v.is_null() { None } else { Some(v.into_identifier()) } }) - .flatten() .transpose() } @@ -416,8 +419,7 @@ impl Value { key: &'a str, ) -> Result, Error> { let map = self.to_map()?; - Ok(Self::inner_optional_hash256_value(map, key)? - .map(|identifier| Identifier::new(identifier))) + Ok(Self::inner_optional_hash256_value(map, key)?.map(Identifier::new)) } pub fn get_hash256<'a>(&'a self, key: &'a str) -> Result<[u8; 32], Error> { @@ -578,14 +580,13 @@ impl Value { key: &str, ) -> Result, Error> { Self::get_optional_from_map(document_type, key) - .map(|value| { + .and_then(|value| { if value.is_null() { None } else { Some(value.to_bool()) } }) - .flatten() .transpose() } @@ -612,14 +613,13 @@ impl Value { + TryFrom, { Self::get_optional_from_map(document_type, key) - .map(|key_value| { + .and_then(|key_value| { if key_value.is_null() { None } else { Some(key_value.to_integer()) } }) - .flatten() .transpose() } diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index c56ac950d2b..ff42f9ac5a2 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -34,7 +34,7 @@ impl Value { }; } let Some(last_path_component) = last_path_component else { - return Err(Error::StructureError(format!("path was empty"))); + return Err(Error::StructureError("path was empty".to_string())); }; let map = current_value.as_map_mut_ref()?; map.remove_key(last_path_component) @@ -120,40 +120,41 @@ impl Value { while let Some(path_component) = split.next() { if split.peek().is_none() { last_path_component = Some(path_component); - } else { - if let Some((string_part, number_part)) = is_array_path(path_component) { - let map = current_value.to_map_mut()?; - let array_value = map.get_key_mut_or_insert(string_part, Value::Array(vec![])); - let array = array_value.to_array_mut()?; - if array.len() < number_part { - //this already exists - current_value = array.get_mut(number_part).unwrap() - } else if array.len() == number_part { - //we should create a new map - array.push(Value::Map(ValueMap::new())); - current_value = array.get_mut(number_part).unwrap(); - } else { - return Err(Error::StructureError(format!( - "trying to insert into an array path higher than current array length" - ))); - } + } else if let Some((string_part, number_part)) = is_array_path(path_component) { + let map = current_value.to_map_mut()?; + let array_value = map.get_key_mut_or_insert(string_part, Value::Array(vec![])); + let array = array_value.to_array_mut()?; + if array.len() < number_part { + //this already exists + current_value = array.get_mut(number_part).unwrap() + } else if array.len() == number_part { + //we should create a new map + array.push(Value::Map(ValueMap::new())); + current_value = array.get_mut(number_part).unwrap(); } else { - let map = current_value.to_map_mut()?; - current_value = - map.get_key_mut_or_insert(path_component, Value::Map(ValueMap::new())); + return Err(Error::StructureError( + "trying to insert into an array path higher than current array length" + .to_string(), + )); } + } else { + let map = current_value.to_map_mut()?; + current_value = + map.get_key_mut_or_insert(path_component, Value::Map(ValueMap::new())); }; } let Some(last_path_component) = last_path_component else { - return Err(Error::StructureError(format!("path was empty"))); + return Err(Error::StructureError("path was empty".to_string())); }; let map = current_value.to_map_mut()?; - Ok(Self::insert_in_map(map, last_path_component, value)) + Self::insert_in_map(map, last_path_component, value); + Ok(()) } pub fn set_value_at_path(&mut self, path: &str, key: &str, value: Value) -> Result<(), Error> { let map = self.get_mut_value_at_path(path)?.as_map_mut_ref()?; - Ok(Self::insert_in_map(map, key, value)) + Self::insert_in_map(map, key, value); + Ok(()) } } #[cfg(test)] diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 9616b326d7b..ca51c262bba 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -1245,7 +1245,7 @@ impl From<[(&str, Value); N]> for Value { } // use stable sort to preserve the insertion order. - arr.sort_by(|a, b| a.0.cmp(&b.0)); + arr.sort_by(|a, b| a.0.cmp(b.0)); Value::Map(arr.into_iter().map(|(k, v)| (k.into(), v)).collect()) } } @@ -1295,12 +1295,7 @@ impl From> for Value { impl From<&[&str]> for Value { fn from(value: &[&str]) -> Self { - Value::Array( - value - .into_iter() - .map(|string| string.clone().into()) - .collect(), - ) + Value::Array(value.iter().map(|string| string.clone().into()).collect()) } } diff --git a/packages/rs-platform-value/src/macros.rs b/packages/rs-platform-value/src/macros.rs index 31c521ea938..c08447a09f5 100644 --- a/packages/rs-platform-value/src/macros.rs +++ b/packages/rs-platform-value/src/macros.rs @@ -321,8 +321,8 @@ mod test { fn test_binary_is_kept() { let id = BinaryData::new([0; 44].to_vec()); let value = to_value(id.clone()).unwrap(); - assert_eq!(value, Value::Bytes(id.clone().to_vec())); - let value = platform_value!(id.clone()); + assert_eq!(value, Value::Bytes(id.to_vec())); + let value = platform_value!(id); assert_eq!(value, Value::Bytes(id.to_vec())); } } diff --git a/packages/rs-platform-value/src/types/binary_data.rs b/packages/rs-platform-value/src/types/binary_data.rs index 2dd0830b8ef..37ae43d56dc 100644 --- a/packages/rs-platform-value/src/types/binary_data.rs +++ b/packages/rs-platform-value/src/types/binary_data.rs @@ -158,15 +158,15 @@ impl TryFrom for BinaryData { } } -impl Into for BinaryData { - fn into(self) -> String { - self.to_string(Encoding::Base64) +impl From for String { + fn from(val: BinaryData) -> Self { + val.to_string(Encoding::Base64) } } -impl Into for &BinaryData { - fn into(self) -> String { - self.to_string(Encoding::Base64) +impl From<&BinaryData> for String { + fn from(val: &BinaryData) -> Self { + val.to_string(Encoding::Base64) } } diff --git a/packages/rs-platform-value/src/types/bytes_32.rs b/packages/rs-platform-value/src/types/bytes_32.rs index 7cefaf94b8a..c9fc51fee68 100644 --- a/packages/rs-platform-value/src/types/bytes_32.rs +++ b/packages/rs-platform-value/src/types/bytes_32.rs @@ -165,14 +165,14 @@ impl TryFrom for Bytes32 { } } -impl Into for Bytes32 { - fn into(self) -> String { - self.to_string(Encoding::Base64) +impl From for String { + fn from(val: Bytes32) -> Self { + val.to_string(Encoding::Base64) } } -impl Into for &Bytes32 { - fn into(self) -> String { - self.to_string(Encoding::Base64) +impl From<&Bytes32> for String { + fn from(val: &Bytes32) -> Self { + val.to_string(Encoding::Base64) } } diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index bf7493f034b..e561326cf53 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -268,15 +268,15 @@ impl From<&Identifier> for Value { } } -impl Into for Identifier { - fn into(self) -> String { - self.to_string(Encoding::Base58) +impl From for String { + fn from(val: Identifier) -> Self { + val.to_string(Encoding::Base58) } } -impl Into for &Identifier { - fn into(self) -> String { - self.to_string(Encoding::Base58) +impl From<&Identifier> for String { + fn from(val: &Identifier) -> Self { + val.to_string(Encoding::Base58) } } diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index f7d64063464..31c3c9ae5f7 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -219,9 +219,7 @@ impl serde::Serializer for Serializer { { match name { "Identifier" => match value.serialize(self)? { - Value::Bytes32(b) => { - return Ok(Value::Identifier(b)); - } + Value::Bytes32(b) => Ok(Value::Identifier(b)), data => { panic!("expected Value::Bytes32, got: {data:#?}") } @@ -298,12 +296,10 @@ impl serde::Serializer for Serializer { fn serialize_struct( self, - name: &'static str, + _name: &'static str, len: usize, ) -> Result { - match name { - _ => self.serialize_map(Some(len)), - } + self.serialize_map(Some(len)) } fn serialize_struct_variant( diff --git a/packages/wasm-dpp/src/data_contract/errors/mod.rs b/packages/wasm-dpp/src/data_contract/errors/mod.rs index ec4864a2726..04745c0924a 100644 --- a/packages/wasm-dpp/src/data_contract/errors/mod.rs +++ b/packages/wasm-dpp/src/data_contract/errors/mod.rs @@ -26,9 +26,6 @@ pub fn from_data_contract_to_js_error(e: DataContractError) -> JsValue { ) .into() } - other => { - DataContractGenericError::new(format!("data contract error: {}", other.to_string())) - .into() - } + other => DataContractGenericError::new(format!("data contract error: {}", other)).into(), } } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index ab497ea6cd9..9b8718b4bf1 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -114,7 +114,7 @@ impl DocumentFactoryWASM { data_contract.to_owned().into(), owner_id, document_type.to_string(), - dynamic_data.into(), + dynamic_data, ) .with_js_error()?; diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs index 531a17865c1..05906d8f62c 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_ids_error.rs @@ -23,7 +23,7 @@ impl DuplicateDocumentTransitionsWithIdsErrorWasm { .map(|v| { js_sys::Array::from_iter(vec![ JsValue::from(v.0.clone()), - JsValue::from(Buffer::from_bytes(&v.1.to_vec())), + JsValue::from(Buffer::from_bytes(v.1.as_ref())), ]) }) .collect() diff --git a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs index 53d99b81162..e498237e363 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/document/duplicate_document_transitions_with_indices_error.rs @@ -23,7 +23,7 @@ impl DuplicateDocumentTransitionsWithIndicesErrorWasm { .map(|v| { js_sys::Array::from_iter(vec![ JsValue::from(v.0.clone()), - JsValue::from(Buffer::from_bytes(&v.1.to_vec())), + JsValue::from(Buffer::from_bytes(v.1.as_ref())), ]) }) .collect() diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs index cc224dfcf6f..4b899a4724c 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs @@ -33,9 +33,7 @@ impl IdentityUpdatePublicKeysValidatorWasm { let parsed_key: IdentityPublicKeyWithWitness = IdentityPublicKeyCreateTransitionWasm::new(raw_key)?.into(); - parsed_key - .to_raw_object(false) - .map_err(|e| from_dpp_err(e.into())) + parsed_key.to_raw_object(false).map_err(from_dpp_err) }) .collect::, JsValue>>()?; diff --git a/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 088794a54b0..2667bba29e0 100644 --- a/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -45,9 +45,7 @@ impl PublicKeysSignaturesValidatorWasm { .map(|raw_key| { let parsed_key: IdentityPublicKeyWithWitness = IdentityPublicKeyCreateTransitionWasm::new(raw_key)?.into(); - parsed_key - .to_raw_object(false) - .map_err(|e| from_dpp_err(e.into())) + parsed_key.to_raw_object(false).map_err(from_dpp_err) }) .collect::, JsValue>>()?; diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index f1c74b89dfa..ca123e3da74 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -1,7 +1,5 @@ use std::{ops::Deref, sync::Arc}; -use serde_json::Value as JsonValue; - use dpp::{state_transition::{ validation::{ validate_state_transition_basic::StateTransitionBasicValidator, From bae60a6054a619b1a2ceb9c2d7ba78cb82d55ba5 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 19 Mar 2023 00:59:34 +0700 Subject: [PATCH 160/228] more clippy fixes --- .../abstract_state_transition.rs | 18 +++++++++--------- .../rs-platform-value/src/types/identifier.rs | 6 +++++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 37ecadb18f7..f7a757818a5 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -119,10 +119,10 @@ pub trait StateTransitionLike: } let data_hash = self.hash(true)?; signer::verify_hash_signature(&data_hash, self.get_signature().as_slice(), public_key_hash) - .or_else(|_| { - Err(ProtocolError::from(ConsensusError::SignatureError( + .map_err(|_| { + ProtocolError::from(ConsensusError::SignatureError( SignatureError::InvalidStateTransitionSignatureError, - ))) + )) }) } @@ -135,11 +135,11 @@ pub trait StateTransitionLike: } let data = self.to_buffer(true)?; - signer::verify_data_signature(&data, self.get_signature().as_slice(), public_key).or_else( + signer::verify_data_signature(&data, self.get_signature().as_slice(), public_key).map_err( |_| { - Err(ProtocolError::from(ConsensusError::SignatureError( + ProtocolError::from(ConsensusError::SignatureError( SignatureError::InvalidStateTransitionSignatureError, - ))) + )) }, ) } @@ -160,10 +160,10 @@ pub trait StateTransitionLike: bls.verify_signature(self.get_signature().as_slice(), &data, public_key) .map(|_| ()) - .or_else(|_| { - Err(ProtocolError::from(ConsensusError::SignatureError( + .map_err(|_| { + ProtocolError::from(ConsensusError::SignatureError( SignatureError::InvalidStateTransitionSignatureError, - ))) + )) }) } diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index e561326cf53..ede5e055442 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -153,6 +153,10 @@ impl Identifier { 32 } + pub fn is_empty(&self) -> bool { + false + } + // TODO - consider to change the name to 'asBuffer` pub fn to_buffer(&self) -> [u8; 32] { self.0 .0 @@ -212,7 +216,7 @@ impl std::fmt::Display for Identifier { impl PartialEq<&Identifier> for Identifier { fn eq(&self, other: &&Identifier) -> bool { - &self.0 .0 == &other.0 .0 + self.0 .0 == other.0 .0 } } From f3258750fbb3dd9862bb4471f5f0b25f2035d0de Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 19 Mar 2023 01:09:06 +0700 Subject: [PATCH 161/228] fix --- .../src/btreemap_extensions/btreemap_path_extensions.rs | 2 +- .../src/btreemap_extensions/btreemap_removal_extensions.rs | 4 ++-- packages/wasm-dpp/test/unit/document/Document.spec.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs index 27cf40aaaa4..7911030fb13 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs @@ -521,7 +521,7 @@ where fn remove_hash256_bytes_at_path(&mut self, path: &str) -> Result<[u8; 32], Error> { self.remove_optional_hash256_bytes_at_path(path)? .ok_or_else(|| { - Error::StructureError(format!("unable to remove system hash256 property {path}")) + Error::StructureError(format!("unable to remove hash256 property {path}")) }) } diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs index a4b1ccfabab..4e9836dbcc0 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_removal_extensions.rs @@ -119,7 +119,7 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { fn remove_bytes_32(&mut self, key: &str) -> Result { self.remove_optional_bytes_32(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to remove hash256 property {key}")) + Error::StructureError(format!("unable to remove binary 32 bytes property {key}")) }) } @@ -291,7 +291,7 @@ impl BTreeValueRemoveFromMapHelper for BTreeMap { fn remove_bytes_32(&mut self, key: &str) -> Result { self.remove_optional_bytes_32(key)?.ok_or_else(|| { - Error::StructureError(format!("unable to remove hash256 property {key}")) + Error::StructureError(format!("unable to remove binary bytes 32 property {key}")) }) } diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index 6c5d824bf34..9c2ac6cba83 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -160,7 +160,7 @@ describe('Document', () => { document = new ExtendedDocument(rawDocument, dataContract); } catch (e) { expect(e).to.be.instanceOf(PlatformValueError); - expect(e.getMessage()).to.equal('structure error: unable to remove system hash256 property $ownerId'); + expect(e.getMessage()).to.equal('structure error: unable to remove hash256 property $ownerId'); } }); @@ -180,7 +180,7 @@ describe('Document', () => { document = new ExtendedDocument(rawDocument, dataContract); } catch (e) { expect(e).to.be.instanceOf(PlatformValueError); - expect(e.getMessage()).to.equal('structure error: unable to remove system hash256 property $id'); + expect(e.getMessage()).to.equal('structure error: unable to remove hash256 property $id'); } }); @@ -220,7 +220,7 @@ describe('Document', () => { document = new ExtendedDocument(rawDocument, dataContract); } catch (e) { expect(e).to.be.instanceOf(PlatformValueError); - expect(e.getMessage()).to.equal('structure error: unable to remove system hash256 property $dataContractId'); + expect(e.getMessage()).to.equal('structure error: unable to remove hash256 property $dataContractId'); } }); From 254850606df41641e36db21e5559689131f13b26 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 19 Mar 2023 01:17:22 +0700 Subject: [PATCH 162/228] more clippy fixes --- .../src/btreemap_extensions/btreemap_field_replacement.rs | 2 +- packages/rs-platform-value/src/lib.rs | 7 ++++++- packages/wasm-dpp/src/document/extended_document.rs | 2 +- .../validation/basic/find_duplicates_by_indices.rs | 5 ++++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs index d3c26d4cb15..c5785e85b72 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs @@ -129,7 +129,7 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { let Some(first_path_component) = first else { return Err(Error::PathError("path was empty".to_string())); }; - let Some(current_value) = self.get_mut(first_path_component.clone()) else { + let Some(current_value) = self.get_mut(first_path_component.to_owned()) else { return Ok(()); }; if split.len() == 1 { diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index ca51c262bba..f01250e1321 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -1295,7 +1295,12 @@ impl From> for Value { impl From<&[&str]> for Value { fn from(value: &[&str]) -> Self { - Value::Array(value.iter().map(|string| string.clone().into()).collect()) + Value::Array( + value + .iter() + .map(|string| string.to_owned().into()) + .collect(), + ) } } diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 2d3359e9b74..3a65b530867 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -252,7 +252,7 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=setMetadata)] pub fn set_metadata(&mut self, metadata: &MetadataWasm) { - self.0.metadata = Some(metadata.clone().into()); + self.0.metadata = Some(metadata.to_owned().into()); } #[wasm_bindgen(js_name=toObject)] diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs index c49078ecb4e..271cf462316 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs @@ -34,7 +34,10 @@ pub fn find_duplicates_by_indices_wasm( ) .map_err(ProtocolError::ValueError) .with_js_error()?; - value.set_value("$ownerId", owner_id_value.clone()); + value + .set_value("$ownerId", owner_id_value.clone()) + .map_err(ProtocolError::ValueError) + .with_js_error()?; Ok(value) }) .collect::, JsValue>>()?; From cd5d373a841872e35d3e040235d4e5b493915e96 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 19 Mar 2023 11:12:38 +0700 Subject: [PATCH 163/228] refactoring of replacement methods --- Cargo.lock | 5 +- .../btreemap_field_replacement.rs | 25 ++-- packages/rs-platform-value/src/lib.rs | 47 +----- packages/rs-platform-value/src/replace.rs | 136 ++++++++++++++++++ packages/wasm-dpp/Cargo.toml | 2 +- .../src/data_contract/data_contract.rs | 11 +- .../src/document/extended_document.rs | 45 ++---- packages/wasm-dpp/src/document/factory.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 4 +- .../test/unit/document/Document.spec.js | 7 +- 10 files changed, 179 insertions(+), 105 deletions(-) create mode 100644 packages/rs-platform-value/src/replace.rs diff --git a/Cargo.lock b/Cargo.lock index 79e2b7eab59..8d1f194c5b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2713,9 +2713,8 @@ dependencies = [ [[package]] name = "serde-wasm-bindgen" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +version = "0.5.0" +source = "git+https://github.com/QuantumExplorer/serde-wasm-bindgen?branch=feat/not_human_readable#2737b68b506cbf87a115917b6b3b4aa852a3ad73" dependencies = [ "js-sys", "serde", diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs index c5785e85b72..dad94479a3b 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs @@ -8,7 +8,6 @@ use std::vec::IntoIter; #[derive(Debug, Clone, Copy)] pub enum ReplacementType { Identifier, - IdentifierBytes, BinaryBytes, TextBase58, TextBase64, @@ -24,9 +23,7 @@ impl ReplacementType { )) })?)) } - ReplacementType::BinaryBytes | ReplacementType::IdentifierBytes => { - Ok(Value::Bytes(bytes)) - } + ReplacementType::BinaryBytes => Ok(Value::Bytes(bytes)), ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), } @@ -35,9 +32,7 @@ impl ReplacementType { pub fn replace_for_bytes_32(&self, bytes: [u8; 32]) -> Result { match self { ReplacementType::Identifier => Ok(Value::Identifier(bytes)), - ReplacementType::BinaryBytes | ReplacementType::IdentifierBytes => { - Ok(Value::Bytes32(bytes)) - } + ReplacementType::BinaryBytes => Ok(Value::Bytes32(bytes)), ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), } @@ -47,6 +42,12 @@ impl ReplacementType { let bytes = value.into_identifier_bytes()?; self.replace_for_bytes(bytes) } + + pub fn replace_value_in_place(&self, value: &mut Value) -> Result<(), Error> { + let bytes = value.take().into_identifier_bytes()?; + *value = self.replace_for_bytes(bytes)?; + Ok(()) + } } pub trait BTreeValueMapReplacementPathHelper { @@ -83,9 +84,7 @@ fn replace_down( } _ => { let bytes = match replacement_type { - ReplacementType::Identifier - | ReplacementType::IdentifierBytes - | ReplacementType::TextBase58 => { + ReplacementType::Identifier | ReplacementType::TextBase58 => { new_value.to_identifier_bytes() } ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { @@ -139,9 +138,9 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { } _ => { let bytes = match replacement_type { - ReplacementType::Identifier - | ReplacementType::IdentifierBytes - | ReplacementType::TextBase58 => current_value.to_identifier_bytes(), + ReplacementType::Identifier | ReplacementType::TextBase58 => { + current_value.to_identifier_bytes() + } ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { current_value.to_binary_bytes() } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index f01250e1321..b9453e27fde 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -19,6 +19,7 @@ mod inner_value_at_path; mod macros; pub mod patch; mod pointer; +mod replace; pub mod string_encoding; pub mod system_bytes; mod types; @@ -27,7 +28,7 @@ mod value_serialization; pub use crate::value_map::{ValueMap, ValueMapHelper}; pub use error::Error; -use std::collections::{BTreeMap, HashMap}; +use std::collections::BTreeMap; pub type Hash256 = [u8; 32]; @@ -1099,50 +1100,6 @@ impl Value { _other => Err(Error::StructureError("value is not a map".to_string())), } } - - pub fn replace_at_path( - &mut self, - path: &str, - replacement_type: ReplacementType, - ) -> Result { - let mut split = path.split('.').peekable(); - let mut current_value = self; - while let Some(path_component) = split.next() { - let map = current_value.as_map_mut_ref()?; - let Some(new_value) = map.get_key_mut(path_component) else { - return Ok(false); - }; - - if split.peek().is_none() { - let bytes = match replacement_type { - ReplacementType::Identifier - | ReplacementType::IdentifierBytes - | ReplacementType::TextBase58 => new_value.to_identifier_bytes(), - ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { - new_value.to_binary_bytes() - } - }?; - *new_value = replacement_type.replace_for_bytes(bytes)?; - return Ok(true); - } - current_value = new_value; - } - Ok(false) - } - - pub fn replace_at_paths<'a, I: IntoIterator>( - &mut self, - paths: I, - replacement_type: ReplacementType, - ) -> Result, Error> { - paths - .into_iter() - .map(|path| { - let success = self.replace_at_path(path, replacement_type)?; - Ok((path, success)) - }) - .collect() - } } macro_rules! implfrom { diff --git a/packages/rs-platform-value/src/replace.rs b/packages/rs-platform-value/src/replace.rs new file mode 100644 index 00000000000..f16f59b17d7 --- /dev/null +++ b/packages/rs-platform-value/src/replace.rs @@ -0,0 +1,136 @@ +use crate::{Error, ReplacementType, Value, ValueMapHelper}; +use std::collections::{HashMap, HashSet}; + +impl Value { + /// If the `Value` is a `Map`, replaces the value at the path inside the map. + /// This is used to set inner values as Identifiers or BinaryData, or from Identifiers or + /// BinaryData to base58 or base64 strings. + /// Either returns `Err(Error::Structure("reason"))` or `Err(Error::ByteLengthNot32BytesError))` + /// if the replacement can not happen. + /// + /// ``` + /// # use platform_value::{Error, Identifier, ReplacementType, Value}; + /// # + /// let mut inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("food_id")), Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string())), + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), inner_value), + /// ] + /// ); + /// + /// value.replace_at_path("foods.food_id", ReplacementType::Identifier).expect("expected to replace at path with identifier"); + /// + /// assert_eq!(value.get_value_at_path("foods.food_id"), Ok(&Value::Identifier([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); + /// + /// ``` + pub fn replace_at_path( + &mut self, + path: &str, + replacement_type: ReplacementType, + ) -> Result { + let mut split = path.split('.').peekable(); + let mut current_value = self; + while let Some(path_component) = split.next() { + let map = current_value.as_map_mut_ref()?; + let Some(new_value) = map.get_key_mut(path_component) else { + return Ok(false); + }; + + if split.peek().is_none() { + let bytes = match replacement_type { + ReplacementType::Identifier | ReplacementType::TextBase58 => { + new_value.to_identifier_bytes() + } + ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { + new_value.to_binary_bytes() + } + }?; + *new_value = replacement_type.replace_for_bytes(bytes)?; + return Ok(true); + } + current_value = new_value; + } + Ok(false) + } + + /// Calls replace_at_path for every path in a given array. + /// Either returns `Err(Error::Structure("reason"))` or `Err(Error::ByteLengthNot32BytesError))` + /// if the replacement can not happen. + /// + /// ``` + /// # use platform_value::{Error, Identifier, ReplacementType, Value}; + /// # + /// let mut inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("grapes")), Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string())), + /// (Value::Text(String::from("oranges")), Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)])), + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), inner_value), + /// ] + /// ); + /// + /// let paths = vec!["foods.grapes", "foods.oranges"]; + /// + /// value.replace_at_paths(paths, ReplacementType::Identifier).expect("expected to replace at paths with identifier"); + /// + /// assert_eq!(value.get_value_at_path("foods.grapes"), Ok(&Value::Identifier([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); + /// assert_eq!(value.get_value_at_path("foods.oranges"), Ok(&Value::Identifier([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); + /// + /// ``` + pub fn replace_at_paths<'a, I: IntoIterator>( + &mut self, + paths: I, + replacement_type: ReplacementType, + ) -> Result, Error> { + paths + .into_iter() + .map(|path| { + let success = self.replace_at_path(path, replacement_type)?; + Ok((path, success)) + }) + .collect() + } + + pub fn replace_to_binary_types_when_setting_with_path( + &mut self, + path: &str, + identifier_paths: HashSet<&str>, + binary_paths: HashSet<&str>, + ) -> Result<(), Error> { + if identifier_paths.contains(path) { + ReplacementType::Identifier.replace_value_in_place(self)?; + } else if binary_paths.contains(path) { + ReplacementType::BinaryBytes.replace_value_in_place(self)?; + } else { + identifier_paths + .into_iter() + .try_for_each(|identifier_path| { + if identifier_path.starts_with(path) { + let (_, suffix) = identifier_path.split_at(path.len() + 1); + self.replace_at_path(suffix, ReplacementType::Identifier) + .map(|_| ()) + } else { + Ok(()) + } + })?; + + binary_paths.into_iter().try_for_each(|binary_path| { + if binary_path.starts_with(path) { + let (_, suffix) = binary_path.split_at(path.len() + 1); + self.replace_at_path(suffix, ReplacementType::BinaryBytes) + .map(|_| ()) + } else { + Ok(()) + } + })?; + } + Ok(()) + } +} diff --git a/packages/wasm-dpp/Cargo.toml b/packages/wasm-dpp/Cargo.toml index 51e7f9dd927..c58f8352690 100644 --- a/packages/wasm-dpp/Cargo.toml +++ b/packages/wasm-dpp/Cargo.toml @@ -14,7 +14,7 @@ wasm-bindgen = { version = "0.2.76" } js-sys = "0.3.53" web-sys = { version = "0.3.6", features = ["console"] } thiserror = { version = "1.0" } -serde-wasm-bindgen = "0.4.3" +serde-wasm-bindgen = { git="https://github.com/QuantumExplorer/serde-wasm-bindgen", branch="feat/not_human_readable"} dpp = { path = "../rs-dpp", default-features = false } itertools = { version="0.10.5"} console_error_panic_hook = { version="0.1.7"} diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index f127792998e..863d6e5315c 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -71,15 +71,11 @@ pub(crate) struct DataContractParameters { _extras: serde_json::Value, // Captures excess fields to trigger validation failure later. } -pub fn js_value_to_serde_value(object: JsValue) -> Result { +pub fn js_value_to_platform_value(object: JsValue) -> Result { let parameters: DataContractParameters = with_js_error!(serde_wasm_bindgen::from_value(object))?; - serde_json::to_value(parameters).map_err(|e| e.to_string().into()) -} - -pub fn js_value_to_platform_value(raw_parameters: JsValue) -> Result { - Ok(js_value_to_serde_value(raw_parameters)?.into()) + platform_value::to_value(parameters).map_err(|e| e.to_string().into()) } #[wasm_bindgen(js_class=DataContract)] @@ -272,7 +268,8 @@ impl DataContractWasm { #[wasm_bindgen(js_name=toObject)] pub fn to_object(&self) -> Result { - let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + let serializer = + serde_wasm_bindgen::Serializer::json_compatible().serialize_bytes_as_arrays(false); let object = with_js_error!(self.0.serialize(&serializer))?; js_sys::Reflect::set( diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 3a65b530867..478353035f4 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -1,7 +1,7 @@ use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::document::{ExtendedDocument, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS}; -use dpp::platform_value::{Bytes32, ReplacementType, Value}; +use dpp::platform_value::{Bytes32, Value}; use dpp::prelude::{Identifier, Revision}; use dpp::util::json_schema::JsonSchemaExt; use dpp::util::json_value::JsonValueExt; @@ -167,30 +167,17 @@ impl ExtendedDocumentWasm { #[wasm_bindgen(js_name=set)] pub fn set(&mut self, path: String, js_value_to_set: JsValue) -> Result<(), JsValue> { - let (identifier_paths, _) = self.0.get_identifiers_and_binary_paths().with_js_error()?; - let mut value: Value = js_value_to_set.with_serde_to_json_value()?.into(); - if identifier_paths.contains(path.as_str()) { - let identifier_value = ReplacementType::IdentifierBytes - .replace_consume_value(value) - .map_err(ProtocolError::ValueError) - .with_js_error()?; - return self.0.set(&path, identifier_value).with_js_error(); - } else { - identifier_paths - .into_iter() - .try_for_each(|identifier_path| { - if identifier_path.starts_with(path.as_str()) { - let (_, suffix) = identifier_path.split_at(path.len() + 1); - value - .replace_at_path(suffix, ReplacementType::IdentifierBytes) - .map_err(ProtocolError::ValueError) - .map(|_| ()) - .with_js_error() - } else { - Ok(()) - } - })?; - } + let (identifier_paths, binary_paths) = + self.0.get_identifiers_and_binary_paths().with_js_error()?; + let mut value: Value = js_value_to_set.with_serde_to_platform_value()?; + value + .replace_to_binary_types_when_setting_with_path( + path.as_str(), + identifier_paths, + binary_paths, + ) + .map_err(ProtocolError::ValueError) + .with_js_error()?; self.0.set(&path, value).with_js_error() } @@ -211,12 +198,8 @@ impl ExtendedDocumentWasm { } _ => { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - //todo: maybe go directly from value - let json_value: Option = value.clone().try_into().ok(); - if let Some(json_value) = json_value { - if let Ok(js_value) = json_value.serialize(&serializer) { - return js_value; - } + if let Ok(js_value) = value.serialize(&serializer) { + return js_value; } } } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 9b8718b4bf1..8089ae6600f 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -167,7 +167,7 @@ impl DocumentFactoryWASM { // When data contract is available, replace remaining dynamic paths let document_data = document.properties_as_mut(); document_data - .replace_at_paths(identifier_paths, ReplacementType::IdentifierBytes) + .replace_at_paths(identifier_paths, ReplacementType::Identifier) .map_err(ProtocolError::ValueError) .with_js_error()?; document_data diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 8b102feb9b4..b72db873b51 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -89,7 +89,7 @@ impl DocumentWasm { identifier_paths .into_iter() .chain(EXTENDED_DOCUMENT_IDENTIFIER_FIELDS), - ReplacementType::IdentifierBytes, + ReplacementType::Identifier, ) .map_err(ProtocolError::ValueError) .with_js_error()?; @@ -339,7 +339,7 @@ pub(crate) fn document_data_to_bytes( .with_js_error()?; document .properties - .replace_at_paths(identifier_paths, ReplacementType::IdentifierBytes) + .replace_at_paths(identifier_paths, ReplacementType::Identifier) .map_err(ProtocolError::ValueError) .with_js_error()?; document diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index 9c2ac6cba83..76b556463f2 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -427,8 +427,11 @@ describe('Document', () => { documentJs.set(path, jsId); document.set(path, id); - expect(documentJs.get(path).toBuffer()).to.deep.equal(jsId); - expect(document.get(path).toBuffer()).to.deep.equal(jsId.toBuffer()); + const documentJsIdBuffer = documentJs.get(path).toBuffer(); + const documentIdBuffer = document.get(path).toBuffer(); + + expect(documentJsIdBuffer).to.deep.equal(jsId); + expect(documentIdBuffer.get(path).toBuffer()).to.deep.equal(jsId.toBuffer()); const jsBuffer = documentJs.toBuffer(); const buffer = document.toBuffer(); From 7d23113b441f8b927637e8b6c414505a124091be Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 19 Mar 2023 20:04:35 +0700 Subject: [PATCH 164/228] work on having better replacement methods that support arrays --- .../identity_create_transition.rs | 5 + .../btreemap_field_replacement.rs | 2 +- .../btreemap_path_extensions.rs | 4 +- .../btreemap_path_insertion_extensions.rs | 2 +- packages/rs-platform-value/src/index.rs | 4 +- .../src/inner_value_at_path.rs | 95 ++++++++--- packages/rs-platform-value/src/pointer.rs | 4 +- packages/rs-platform-value/src/replace.rs | 160 ++++++++++++++---- packages/rs-platform-value/src/value_map.rs | 24 ++- .../identity_create_transition.rs | 19 ++- .../test/unit/document/Document.spec.js | 2 +- 11 files changed, 252 insertions(+), 69 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 8f164ad02bb..edac40c118c 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -15,8 +15,13 @@ use crate::state_transition::{ use crate::{NonConsensusError, ProtocolError}; use platform_value::btreemap_extensions::BTreeValueRemoveInnerValueFromMapHelper; +pub const IDENTIFIER_FIELDS: [&str; 1] = [property_names::IDENTITY_ID]; +pub const BINARY_FIELDS: [&str; 2] = [property_names::PUBLIC_KEYS_DATA, property_names::SIGNATURE]; + mod property_names { pub const PUBLIC_KEYS: &str = "publicKeys"; + pub const PUBLIC_KEYS_DATA: &str = "publicKeys[].data"; + pub const PUBLIC_KEYS_SIGNATURE: &str = "publicKeys[].signature"; pub const ASSET_LOCK_PROOF: &str = "assetLockProof"; pub const SIGNATURE: &str = "signature"; pub const PROTOCOL_VERSION: &str = "protocolVersion"; diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs index dad94479a3b..7222b5680a8 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs @@ -74,7 +74,7 @@ fn replace_down( .map(|current_value| { if current_value.is_map() { let map = current_value.as_map_mut_ref()?; - let Some(new_value) = map.get_key_mut(path_component) else { + let Some(new_value) = map.get_optional_key_mut(path_component) else { return Ok(None); }; if split.peek().is_none() { diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs index 7911030fb13..e039a778965 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs @@ -149,7 +149,7 @@ where .borrow(); for path_component in split { let map = current_value.to_map_ref()?; - current_value = map.get_key(path_component).ok_or_else(|| { + current_value = map.get_optional_key(path_component).ok_or_else(|| { Error::StructureError(format!("unable to get property {path_component} in {path}")) })?; } @@ -167,7 +167,7 @@ where }; for path_component in split { let map = current_value.to_map_ref()?; - let Some(new_value) = map.get_key(path_component) else { + let Some(new_value) = map.get_optional_key(path_component) else { return Ok(None); }; current_value = new_value; diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_insertion_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_insertion_extensions.rs index 154398bed43..e0d39e5c521 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_insertion_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_insertion_extensions.rs @@ -31,7 +31,7 @@ impl BTreeValueMapInsertionPathHelper for BTreeMap { } if let Some(last_path_component) = last_path_component { let map = current_value.as_map_mut_ref()?; - if let Some(new_value) = map.get_key_mut(last_path_component) { + if let Some(new_value) = map.get_optional_key_mut(last_path_component) { *new_value = value; } else { map.push((Value::Text(last_path_component.to_string()), value)); diff --git a/packages/rs-platform-value/src/index.rs b/packages/rs-platform-value/src/index.rs index e1090a57f8c..8a9a61fa77e 100644 --- a/packages/rs-platform-value/src/index.rs +++ b/packages/rs-platform-value/src/index.rs @@ -82,13 +82,13 @@ impl Index for usize { impl Index for str { fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> { match v { - Value::Map(map) => map.get_key(self), + Value::Map(map) => map.get_optional_key(self), _ => None, } } fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> { match v { - Value::Map(map) => map.get_key_mut(self), + Value::Map(map) => map.get_optional_key_mut(self), _ => None, } } diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index ff42f9ac5a2..bd1d1f92e71 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -4,16 +4,25 @@ use lazy_static::lazy_static; use regex::Regex; use std::collections::BTreeMap; -fn is_array_path(text: &str) -> Option<(&str, usize)> { +pub(crate) fn is_array_path(text: &str) -> Result)>, Error> { lazy_static! { - static ref RE: Regex = Regex::new(r"(\w+)\[(\d+)\]").unwrap(); + static ref RE: Regex = Regex::new(r"(\w+)\[(\d+)?\]").unwrap(); } - RE.captures(text).map(|captures| { - ( - captures.get(1).unwrap().as_str(), - captures.get(2).unwrap().as_str().parse::().unwrap(), - ) - }) + RE.captures(text) + .map(|captures| { + Ok(( + captures.get(1).unwrap().as_str(), + captures + .get(2) + .map(|m| { + m.as_str() + .parse::() + .map_err(|_| Error::IntegerSizeError) + }) + .transpose()?, + )) + }) + .transpose() } impl Value { @@ -26,7 +35,7 @@ impl Value { last_path_component = Some(path_component); } else { let map = current_value.to_map_mut()?; - current_value = map.get_key_mut(path_component).ok_or_else(|| { + current_value = map.get_optional_key_mut(path_component).ok_or_else(|| { Error::StructureError(format!( "unable to get property {path_component} in {path}" )) @@ -61,10 +70,30 @@ impl Value { let split = path.split('.'); let mut current_value = self; for path_component in split { - let map = current_value.to_map_ref()?; - current_value = map.get_key(path_component).ok_or_else(|| { - Error::StructureError(format!("unable to get property {path_component} in {path}")) - })?; + if let Some((string_part, number_part)) = is_array_path(path_component)? { + let map = current_value.to_map_ref()?; + let array_value = map.get_key(string_part)?; + let array = array_value.to_array_ref()?; + let Some(number_part) = number_part else { + return Err(Error::Unsupported("getting values of more than 1 member of an array is currently not supported".to_string())) + }; + // We are setting the value of just member of the array + if number_part < array.len() { + //this already exists + current_value = array.get(number_part).unwrap() + } else { + return Err(Error::StructureError( + format!("trying to get the value in an array at an index {} higher than current array length {}", number_part, array.len()), + )); + } + } else { + let map = current_value.to_map_ref()?; + current_value = map.get_optional_key(path_component).ok_or_else(|| { + Error::StructureError(format!( + "unable to get property {path_component} in {path}" + )) + })?; + } } Ok(current_value) } @@ -76,11 +105,29 @@ impl Value { let split = path.split('.'); let mut current_value = self; for path_component in split { - let map = current_value.to_map_ref()?; - let Some(new_value) = map.get_key(path_component) else { - return Ok(None); - }; - current_value = new_value; + if let Some((string_part, number_part)) = is_array_path(path_component)? { + let map = current_value.to_map_ref()?; + let Some(array_value) = map.get_optional_key(string_part) else { + return Ok(None); + }; + let array = array_value.to_array_ref()?; + let Some(number_part) = number_part else { + return Err(Error::Unsupported("setting values of all members in an array is currently not supported".to_string())) + }; + // We are setting the value of just member of the array + if number_part < array.len() { + //this already exists + current_value = array.get(number_part).unwrap() + } else { + return Ok(None); + } + } else { + let map = current_value.to_map_ref()?; + let Some(new_value) = map.get_optional_key(path_component) else { + return Ok(None); + }; + current_value = new_value; + } } Ok(Some(current_value)) } @@ -90,7 +137,7 @@ impl Value { let mut current_value = self; for path_component in split { let map = current_value.to_map_mut()?; - current_value = map.get_key_mut(path_component).ok_or_else(|| { + current_value = map.get_optional_key_mut(path_component).ok_or_else(|| { Error::StructureError(format!("unable to get property {path_component} in {path}")) })?; } @@ -105,7 +152,7 @@ impl Value { let mut current_value = self; for path_component in split { let map = current_value.to_map_mut()?; - let Some(new_value) = map.get_key_mut(path_component) else { + let Some(new_value) = map.get_optional_key_mut(path_component) else { return Ok(None); }; current_value = new_value; @@ -120,11 +167,15 @@ impl Value { while let Some(path_component) = split.next() { if split.peek().is_none() { last_path_component = Some(path_component); - } else if let Some((string_part, number_part)) = is_array_path(path_component) { + } else if let Some((string_part, number_part)) = is_array_path(path_component)? { let map = current_value.to_map_mut()?; let array_value = map.get_key_mut_or_insert(string_part, Value::Array(vec![])); let array = array_value.to_array_mut()?; - if array.len() < number_part { + let Some(number_part) = number_part else { + return Err(Error::Unsupported("setting values of all members in an array is currently not supported".to_string())) + }; + // We are setting the value of just member of the array + if number_part < array.len() { //this already exists current_value = array.get_mut(number_part).unwrap() } else if array.len() == number_part { diff --git a/packages/rs-platform-value/src/pointer.rs b/packages/rs-platform-value/src/pointer.rs index ab110f28af4..79cbd5b2c1f 100644 --- a/packages/rs-platform-value/src/pointer.rs +++ b/packages/rs-platform-value/src/pointer.rs @@ -47,7 +47,7 @@ impl Value { .skip(1) .map(|x| x.replace("~1", "/").replace("~0", "~")) .try_fold(self, |target, token| match target { - Value::Map(map) => map.get_key(&token), + Value::Map(map) => map.get_optional_key(&token), Value::Array(list) => parse_index(&token).and_then(|x| list.get(x)), _ => None, }) @@ -102,7 +102,7 @@ impl Value { .skip(1) .map(|x| x.replace("~1", "/").replace("~0", "~")) .try_fold(self, |target, token| match target { - Value::Map(map) => map.get_key_mut(&token), + Value::Map(map) => map.get_optional_key_mut(&token), Value::Array(list) => parse_index(&token).and_then(move |x| list.get_mut(x)), _ => None, }) diff --git a/packages/rs-platform-value/src/replace.rs b/packages/rs-platform-value/src/replace.rs index f16f59b17d7..5d62af0b195 100644 --- a/packages/rs-platform-value/src/replace.rs +++ b/packages/rs-platform-value/src/replace.rs @@ -1,5 +1,6 @@ +use crate::inner_value_at_path::is_array_path; use crate::{Error, ReplacementType, Value, ValueMapHelper}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; impl Value { /// If the `Value` is a `Map`, replaces the value at the path inside the map. @@ -26,35 +27,103 @@ impl Value { /// /// assert_eq!(value.get_value_at_path("foods.food_id"), Ok(&Value::Identifier([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); /// + /// let mut tangerine_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("food_id")), Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string())), + /// ] + /// ); + /// let mut mandarin_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("food_id")), Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string())), + /// ] + /// ); + /// let mut oranges_value = Value::Array( + /// vec![ + /// tangerine_value, + /// mandarin_value + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), oranges_value), + /// ] + /// ); + /// + /// value.replace_at_path("foods[].food_id", ReplacementType::Identifier).expect("expected to replace at path with identifier"); + /// + /// assert_eq!(value.get_value_at_path("foods[0].food_id"), Ok(&Value::Identifier([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117]))); + /// /// ``` pub fn replace_at_path( &mut self, path: &str, replacement_type: ReplacementType, - ) -> Result { + ) -> Result<(), Error> { let mut split = path.split('.').peekable(); - let mut current_value = self; + let mut current_values = vec![self]; while let Some(path_component) = split.next() { - let map = current_value.as_map_mut_ref()?; - let Some(new_value) = map.get_key_mut(path_component) else { - return Ok(false); - }; + if let Some((string_part, number_part)) = is_array_path(path_component)? { + current_values = current_values + .into_iter() + .map(|current_value| { + let map = current_value.to_map_mut()?; + let array_value = map.get_key_mut(string_part)?; + let array = array_value.to_array_mut()?; + if let Some(number_part) = number_part { + if array.len() < number_part { + //this already exists + Ok(vec![array.get_mut(number_part).unwrap()]) + } else { + return Err(Error::StructureError(format!( + "element at position {number_part} in array does not exist" + ))); + } + } else { + // we are replacing all members in array + Ok(array.into_iter().collect()) + } + }) + .collect::>, Error>>()? + .into_iter() + .flatten() + .collect() + } else { + current_values = current_values + .into_iter() + .filter_map(|current_value| { + let map = match current_value.as_map_mut_ref() { + Ok(map) => map, + Err(err) => return Some(Err(err)), + }; + let Some(new_value) = map.get_optional_key_mut(path_component) else { + return None; + }; - if split.peek().is_none() { - let bytes = match replacement_type { - ReplacementType::Identifier | ReplacementType::TextBase58 => { - new_value.to_identifier_bytes() - } - ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { - new_value.to_binary_bytes() - } - }?; - *new_value = replacement_type.replace_for_bytes(bytes)?; - return Ok(true); + if split.peek().is_none() { + let bytes_result = match replacement_type { + ReplacementType::Identifier | ReplacementType::TextBase58 => { + new_value.to_identifier_bytes() + } + ReplacementType::BinaryBytes | ReplacementType::TextBase64 => { + new_value.to_binary_bytes() + } + }; + let bytes = match bytes_result { + Ok(bytes) => bytes, + Err(err) => return Some(Err(err)), + }; + *new_value = match replacement_type.replace_for_bytes(bytes) { + Ok(value) => value, + Err(err) => return Some(Err(err)), + }; + return None; + } + Some(Ok(new_value)) + }) + .collect::, Error>>()?; } - current_value = new_value; } - Ok(false) + Ok(()) } /// Calls replace_at_path for every path in a given array. @@ -88,16 +157,49 @@ impl Value { &mut self, paths: I, replacement_type: ReplacementType, - ) -> Result, Error> { + ) -> Result<(), Error> { paths .into_iter() - .map(|path| { - let success = self.replace_at_path(path, replacement_type)?; - Ok((path, success)) - }) - .collect() + .try_for_each(|path| self.replace_at_path(path, replacement_type)) } + /// `replace_to_binary_types_when_setting_with_path` will replace a value with a corresponding + /// binary type (Identifier or Binary Data) if that data is in one of the given paths. + /// Paths can either be terminal, or can represent an object or an array (with values) where + /// all subvalues must be set to the bianry type. + /// Either returns `Err(Error::Structure("reason"))` or `Err(Error::ByteLengthNot32BytesError))` + /// if the replacement can not happen. + /// + /// ``` + /// # use std::collections::HashSet; + /// use platform_value::{Error, Identifier, ReplacementType, Value}; + /// # + /// let mut inner_inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("mandarins")), Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string())), + /// (Value::Text(String::from("tangerines")), Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)])), + /// ] + /// ); + /// let mut inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("grapes")), Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string())), + /// (Value::Text(String::from("oranges")), inner_inner_value), + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), inner_value), + /// ] + /// ); + /// + /// + /// let identifier_paths = HashSet::from(["foods.oranges.tangerines"]); + /// + /// value.replace_to_binary_types_when_setting_with_path("foods.oranges", identifier_paths, HashSet::new()).expect("expected to replace at paths with identifier"); + /// + /// assert_eq!(value.get_value_at_path("foods.oranges.tangerines"), Ok(&Value::Identifier([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); + /// + /// ``` pub fn replace_to_binary_types_when_setting_with_path( &mut self, path: &str, @@ -113,8 +215,7 @@ impl Value { .into_iter() .try_for_each(|identifier_path| { if identifier_path.starts_with(path) { - let (_, suffix) = identifier_path.split_at(path.len() + 1); - self.replace_at_path(suffix, ReplacementType::Identifier) + self.replace_at_path(identifier_path, ReplacementType::Identifier) .map(|_| ()) } else { Ok(()) @@ -123,8 +224,7 @@ impl Value { binary_paths.into_iter().try_for_each(|binary_path| { if binary_path.starts_with(path) { - let (_, suffix) = binary_path.split_at(path.len() + 1); - self.replace_at_path(suffix, ReplacementType::BinaryBytes) + self.replace_at_path(binary_path, ReplacementType::BinaryBytes) .map(|_| ()) } else { Ok(()) diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 4f0ecd6381e..42a8bd6ca17 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -6,8 +6,10 @@ pub type ValueMap = Vec<(Value, Value)>; pub trait ValueMapHelper { fn sort_by_keys(&mut self); - fn get_key(&self, key: &str) -> Option<&Value>; - fn get_key_mut(&mut self, key: &str) -> Option<&mut Value>; + fn get_key(&self, search_key: &str) -> Result<&Value, Error>; + fn get_optional_key(&self, key: &str) -> Option<&Value>; + fn get_key_mut(&mut self, search_key: &str) -> Result<&mut Value, Error>; + fn get_optional_key_mut(&mut self, key: &str) -> Option<&mut Value>; fn get_key_mut_or_insert(&mut self, key: &str, value: Value) -> &mut Value; fn get_key_by_value_mut_or_insert(&mut self, search_key: &Value, value: Value) -> &mut Value; fn insert_string_key_value(&mut self, key: String, value: Value); @@ -21,7 +23,14 @@ impl ValueMapHelper for ValueMap { self.sort_by(|(key1, _), (key2, _)| key1.partial_cmp(key2).unwrap_or(Ordering::Less)) } - fn get_key(&self, search_key: &str) -> Option<&Value> { + fn get_key(&self, search_key: &str) -> Result<&Value, Error> { + self.get_optional_key(search_key) + .ok_or(Error::StructureError(format!( + "required property not found {search_key}" + ))) + } + + fn get_optional_key(&self, search_key: &str) -> Option<&Value> { self.iter().find_map(|(key, value)| { if let Value::Text(text) = key { if text == search_key { @@ -35,7 +44,14 @@ impl ValueMapHelper for ValueMap { }) } - fn get_key_mut(&mut self, search_key: &str) -> Option<&mut Value> { + fn get_key_mut(&mut self, search_key: &str) -> Result<&mut Value, Error> { + self.get_optional_key_mut(search_key) + .ok_or(Error::StructureError(format!( + "{search_key} not found, but was required" + ))) + } + + fn get_optional_key_mut(&mut self, search_key: &str) -> Option<&mut Value> { self.iter_mut().find_map(|(key, value)| { if let Value::Text(text) = key { if text == search_key { diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 4dadc8c0da1..fd5301d9d7e 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -20,9 +20,12 @@ use crate::{ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; -use crate::utils::{generic_of_js_val, ToSerdeJSONExt}; -use dpp::platform_value::string_encoding; +use crate::utils::{generic_of_js_val, ToSerdeJSONExt, WithJsError}; +use dpp::identity::state_transition::identity_create_transition::{ + BINARY_FIELDS, IDENTIFIER_FIELDS, +}; use dpp::platform_value::string_encoding::Encoding; +use dpp::platform_value::{string_encoding, ReplacementType}; use dpp::{ identifier::Identifier, identity::state_transition::{ @@ -30,6 +33,7 @@ use dpp::{ identity_public_key_transitions::IdentityPublicKeyWithWitness, }, state_transition::StateTransitionLike, + ProtocolError, }; #[wasm_bindgen(js_name=IdentityCreateTransition)] @@ -52,8 +56,15 @@ impl From for IdentityCreateTransition { impl IdentityCreateTransitionWasm { #[wasm_bindgen(constructor)] pub fn new(raw_parameters: JsValue) -> Result { - let raw_state_transition = raw_parameters.with_serde_to_platform_value()?; - + let mut raw_state_transition = raw_parameters.with_serde_to_platform_value()?; + raw_state_transition + .replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes) + .map_err(ProtocolError::ValueError) + .with_js_error()?; + raw_state_transition + .replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier) + .map_err(ProtocolError::ValueError) + .with_js_error()?; let identity_create_transition = IdentityCreateTransition::new(raw_state_transition) .map_err(|e| RustConversionError::Error(e.to_string()).to_js_value())?; diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index 76b556463f2..d70747dfe1f 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -431,7 +431,7 @@ describe('Document', () => { const documentIdBuffer = document.get(path).toBuffer(); expect(documentJsIdBuffer).to.deep.equal(jsId); - expect(documentIdBuffer.get(path).toBuffer()).to.deep.equal(jsId.toBuffer()); + expect(documentIdBuffer).to.deep.equal(jsId); const jsBuffer = documentJs.toBuffer(); const buffer = document.toBuffer(); From 9618db65aa5ac03612b5512780869f090a261a65 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 00:47:51 +0700 Subject: [PATCH 165/228] more fixes --- packages/rs-dpp/src/convertible.rs | 5 + .../rs-dpp/src/data_contract/data_contract.rs | 181 +++--------- .../data_contract/data_contract_factory.rs | 31 ++- .../src/data_contract/serialization/cbor.rs | 9 +- .../data_contract_create_transition/mod.rs | 6 +- .../data_contract_update_transition/mod.rs | 6 +- ...e_data_contract_update_transition_basic.rs | 2 +- packages/rs-dpp/src/document/document.rs | 50 +--- .../rs-dpp/src/document/document_validator.rs | 8 +- .../document_create_transition.rs | 12 +- ...lidate_documents_batch_transition_basic.rs | 7 +- .../src/identity/identity_public_key/mod.rs | 11 +- .../identity_create_transition.rs | 5 +- .../identity_public_key_transitions.rs | 29 +- .../state_transition_factory.rs | 4 +- .../validate_state_transition_basic.rs | 1 - .../rs-dpp/src/util/cbor_value/canonical.rs | 68 +---- packages/rs-dpp/src/util/json_value/mod.rs | 259 ------------------ packages/rs-platform-value/src/lib.rs | 26 ++ .../rs-platform-value/src/types/identifier.rs | 26 +- packages/rs-platform-value/src/value_map.rs | 39 ++- packages/wasm-dpp/src/document/mod.rs | 6 +- .../identity_create_transition.rs | 4 - 23 files changed, 180 insertions(+), 615 deletions(-) diff --git a/packages/rs-dpp/src/convertible.rs b/packages/rs-dpp/src/convertible.rs index 5c3c494e6e3..f4125729810 100644 --- a/packages/rs-dpp/src/convertible.rs +++ b/packages/rs-dpp/src/convertible.rs @@ -1,8 +1,13 @@ +use platform_value::Value; use serde_json::Value as JsonValue; use crate::ProtocolError; pub trait Convertible { + /// Returns the [`platform_value::Value`] instance on an object + fn to_object(&self) -> Result; + /// Returns the [`platform_value::Value`] instance on an object + fn into_object(self) -> Result; /// Returns the [`serde_json::Value`] instance that preserves the `Vec` representation /// for Identifiers and binary data fn to_json_object(&self) -> Result; diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index cde8799fc18..4bde43c57af 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -1,12 +1,10 @@ use std::collections::{BTreeMap, HashSet}; use std::convert::{TryFrom, TryInto}; -use anyhow::anyhow; - use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; -use platform_value::Value; use platform_value::{Bytes32, Identifier}; +use platform_value::{ReplacementType, Value, ValueMapHelper}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -20,7 +18,6 @@ use crate::data_contract::contract_config::{ use crate::data_contract::get_binary_properties_from_schema::get_binary_properties; -use crate::util::json_value::{JsonValueExt, ReplaceWith}; use crate::{ errors::ProtocolError, metadata::Metadata, @@ -45,32 +42,42 @@ pub const IDENTIFIER_FIELDS: [&str; 2] = [property_names::ID, property_names::OW pub const BINARY_FIELDS: [&str; 1] = [property_names::ENTROPY]; impl Convertible for DataContract { - fn to_json_object(&self) -> Result { - let mut json_object = serde_json::to_value(self)?; - if !json_object.is_object() { - return Err(anyhow!("the Data Contract isn't a JSON Value Object").into()); - } + fn to_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } - json_object.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Bytes)?; - Ok(json_object) + fn into_object(self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + + fn to_json_object(&self) -> Result { + self.to_object()? + .try_into_validating_json() + .map_err(ProtocolError::ValueError) } /// Returns Data Contract as a JSON Value fn to_json(&self) -> Result { - Ok(serde_json::to_value(self)?) + self.to_object()? + .try_into() + .map_err(ProtocolError::ValueError) } /// Returns Data Contract as a Buffer fn to_buffer(&self) -> Result, ProtocolError> { let protocol_version = self.protocol_version; - // what means skip_identifiers_conversion - let mut json_object = self.to_json_object(true)?; - if let JsonValue::Object(ref mut o) = json_object { - o.remove("protocolVersion"); - }; + let mut object = self.to_object()?; + object.remove(property_names::PROTOCOL_VERSION)?; + if self.defs.is_none() { + object.remove(property_names::DEFINITIONS)?; + } + object + .to_map_mut() + .unwrap() + .sort_by_lexicographical_byte_ordering_keys_and_inner_maps(); - serializer::serializable_value_to_cbor(&json_object, Some(protocol_version)) + serializer::serializable_value_to_cbor(&object, Some(protocol_version)) } } @@ -96,7 +103,7 @@ pub struct DataContract { // TODO we may ensure in compile time that defs are not empty if we define a type for it #[serde(rename = "$defs", default)] - pub defs: BTreeMap, + pub defs: Option>, #[serde(skip)] pub entropy: Bytes32, @@ -140,9 +147,8 @@ impl DataContract { .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; // Defs - let defs = data_contract_map - .get_optional_inner_str_json_value_map::>("$defs")? - .unwrap_or_default(); + let defs = + data_contract_map.get_optional_inner_str_json_value_map::>("$defs")?; let binary_properties = documents .iter() @@ -177,99 +183,17 @@ impl DataContract { Ok(data_contract) } - pub fn from_json_object(mut json_value: JsonValue) -> Result { - json_value.replace_binary_paths(BINARY_FIELDS, ReplaceWith::Bytes)?; - - let value: Value = json_value.clone().into(); - let data_contract_map = value - .into_btree_string_map() - .map_err(ProtocolError::ValueError)?; - let mut data_contract: DataContract = serde_json::from_value(json_value)?; - data_contract.generate_binary_properties(); - - let mutability = get_contract_configuration_properties(&data_contract_map) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; - let definition_references = get_definitions(&data_contract_map)?; - let document_types = get_document_types_from_contract( - &data_contract_map, - &definition_references, - mutability.documents_keep_history_contract_default, - mutability.documents_mutable_contract_default, - ) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; - - data_contract.document_types = document_types; - - Ok(data_contract) + pub fn from_json_object(json_value: JsonValue) -> Result { + let mut value: Value = json_value.into(); + value.replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes)?; + value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; + Self::from_raw_object(value) } pub fn from_buffer(b: impl AsRef<[u8]>) -> Result { Self::from_cbor(b) } - pub fn to_object(&self) -> Result { - platform_value::to_value(self).map_err(ProtocolError::ValueError) - // let mut raw_object = BTreeMap::from([ - // (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), - // (property_names::ID.to_string(), Value::Identifier(self.id.to_buffer())), - // (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.to_buffer())), - // (property_names::SCHEMA.to_string(), Value::Text(self.schema.clone())), - // (property_names::VERSION.to_string(), Value::U32(self.version)), - // (property_names::DOCUMENTS.to_string(), self.documents.into()), - // (property_names::ENTROPY.to_string(), Value::Bytes32(self.entropy))]); - // if let Some(defs) = &self.defs { - // raw_object.insert(property_names::DEFINITIONS.to_string(), defs.into()) - // } - // - // Ok(raw_object.into()) - } - - pub fn into_object(self) -> Result { - platform_value::to_value(self).map_err(ProtocolError::ValueError) - // let mut raw_object = BTreeMap::from([ - // (property_names::PROTOCOL_VERSION.to_string(), Value::U32(self.protocol_version)), - // (property_names::ID.to_string(), Value::Identifier(self.id.to_buffer())), - // (property_names::OWNER_ID.to_string(), Value::Identifier(self.owner_id.to_buffer())), - // (property_names::SCHEMA.to_string(), Value::Text(self.schema)), - // (property_names::VERSION.to_string(), Value::U32(self.version)), - // (property_names::DOCUMENTS.to_string(), self.documents.into()), - // (property_names::ENTROPY.to_string(), Value::Bytes32(self.entropy))]); - // if let Some(defs) = &self.defs { - // raw_object.insert(property_names::DEFINITIONS.to_string(), defs.into()) - // } - // - // Ok(raw_object.into()) - } - - pub fn to_json_object( - &self, - skip_identifiers_conversion: bool, - ) -> Result { - let mut json_object = serde_json::to_value(self)?; - if !json_object.is_object() { - return Err(anyhow!("the Data Contract isn't a JSON Value Object").into()); - } - - if !skip_identifiers_conversion { - json_object.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Bytes)?; - } - Ok(json_object) - } - - /// Returns Data Contract as a JSON Value - pub fn to_json(&self) -> Result { - Ok(serde_json::to_value(self)?) - } - - /// Returns Data Contract as a Buffer - pub fn to_buffer(&self) -> Result, ProtocolError> { - self.to_cbor() - } - - pub fn definitions(&self) -> &BTreeMap { - &self.defs - } - // Returns hash from Data Contract pub fn hash(&self) -> Result, ProtocolError> { Ok(hash(self.to_buffer()?)) @@ -431,14 +355,7 @@ impl DataContract { impl TryFrom for DataContract { type Error = ProtocolError; fn try_from(v: JsonValue) -> Result { - let mut v = v; - - v.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Base58)?; - - let mut data_contract: Self = serde_json::from_value(v)?; - data_contract.generate_binary_properties(); - - Ok(data_contract) + DataContract::from_json_object(v) } } @@ -760,7 +677,7 @@ mod test { let string_contract = get_data_from_file("src/tests/payloads/contract_example.json")?; let data_contract: DataContract = serde_json::from_str(&string_contract)?; - let raw_data_contract = data_contract.to_json_object(false)?; + let raw_data_contract = data_contract.to_json_object()?; for path in IDENTIFIER_FIELDS { assert!(raw_data_contract .get(path) @@ -775,14 +692,10 @@ mod test { init(); let string_contract = get_data_from_file("src/tests/payloads/contract_example.json")?; - let mut raw_contract: JsonValue = serde_json::from_str(&string_contract)?; - raw_contract.replace_identifier_paths(IDENTIFIER_FIELDS, ReplaceWith::Bytes)?; + let raw_contract: JsonValue = serde_json::from_str(&string_contract)?; for path in IDENTIFIER_FIELDS { - assert!(raw_contract - .get(path) - .expect("the path should exist") - .is_array()) + raw_contract.get(path).expect("the path should exist"); } let data_contract_from_raw = DataContract::try_from(raw_contract)?; @@ -804,26 +717,6 @@ mod test { Ok(()) } - #[test] - fn conversion_from_invalid_object() -> Result<()> { - init(); - - let string_contract = get_data_from_file("src/tests/payloads/contract_example.json")?; - - let invalid_raw_contract: JsonValue = serde_json::from_str(&string_contract)?; - // The identifiers are strings but they should be arrays of bytes - for path in IDENTIFIER_FIELDS { - assert!(invalid_raw_contract - .get(path) - .expect("the path should exist") - .is_string()) - } - - let result = DataContract::try_from(invalid_raw_contract); - assert_error_contains!(result, "expected a sequence"); - Ok(()) - } - fn get_data_contract_cbor_bytes() -> Vec { let data_contract_cbor_hex = "01a56324696458208efef7338c0d34b2e408411b9473d724cbf9b675ca72b3126f7f8e7deb42ae516724736368656d61783468747470733a2f2f736368656d612e646173682e6f72672f6470702d302d342d302f6d6574612f646174612d636f6e7472616374676f776e657249645820962088aa3812bb3386d0c9130edbde51e4be17bb2d10031d4147c8597facee256776657273696f6e0169646f63756d656e7473a76b756e697175654461746573a56474797065666f626a65637467696e646963657382a3646e616d6566696e6465783166756e69717565f56a70726f7065727469657382a16a2463726561746564417463617363a16a2475706461746564417463617363a2646e616d6566696e646578326a70726f7065727469657381a16a2475706461746564417463617363687265717569726564836966697273744e616d656a246372656174656441746a247570646174656441746a70726f70657274696573a2686c6173744e616d65a1647479706566737472696e676966697273744e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f46c6e696365446f63756d656e74a46474797065666f626a656374687265717569726564816a246372656174656441746a70726f70657274696573a1646e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f46e6e6f54696d65446f63756d656e74a36474797065666f626a6563746a70726f70657274696573a1646e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f46e707265747479446f63756d656e74a46474797065666f626a65637468726571756972656482686c6173744e616d656a247570646174656441746a70726f70657274696573a1686c6173744e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f46e7769746842797465417272617973a56474797065666f626a65637467696e646963657381a2646e616d6566696e646578316a70726f7065727469657381a16e6279746541727261794669656c6463617363687265717569726564816e6279746541727261794669656c646a70726f70657274696573a26e6279746541727261794669656c64a36474797065656172726179686d61784974656d731069627974654172726179f56f6964656e7469666965724669656c64a56474797065656172726179686d61784974656d731820686d696e4974656d73182069627974654172726179f570636f6e74656e744d656469615479706578216170706c69636174696f6e2f782e646173682e6470702e6964656e746966696572746164646974696f6e616c50726f70657274696573f46f696e6465786564446f63756d656e74a56474797065666f626a65637467696e646963657386a3646e616d6566696e6465783166756e69717565f56a70726f7065727469657382a168246f776e6572496463617363a16966697273744e616d656464657363a3646e616d6566696e6465783266756e69717565f56a70726f7065727469657382a168246f776e6572496463617363a1686c6173744e616d656464657363a2646e616d6566696e646578336a70726f7065727469657381a1686c6173744e616d6563617363a2646e616d6566696e646578346a70726f7065727469657382a16a2463726561746564417463617363a16a2475706461746564417463617363a2646e616d6566696e646578356a70726f7065727469657381a16a2475706461746564417463617363a2646e616d6566696e646578366a70726f7065727469657381a16a2463726561746564417463617363687265717569726564846966697273744e616d656a246372656174656441746a24757064617465644174686c6173744e616d656a70726f70657274696573a2686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f6966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f746164646974696f6e616c50726f70657274696573f4781d6f7074696f6e616c556e69717565496e6465786564446f63756d656e74a56474797065666f626a65637467696e646963657383a3646e616d6566696e6465783166756e69717565f56a70726f7065727469657381a16966697273744e616d656464657363a3646e616d6566696e6465783266756e69717565f56a70726f7065727469657383a168246f776e6572496463617363a16966697273744e616d6563617363a1686c6173744e616d6563617363a3646e616d6566696e6465783366756e69717565f56a70726f7065727469657382a167636f756e74727963617363a1646369747963617363687265717569726564826966697273744e616d65686c6173744e616d656a70726f70657274696573a46463697479a2647479706566737472696e67696d61784c656e677468183f67636f756e747279a2647479706566737472696e67696d61784c656e677468183f686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f6966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f746164646974696f6e616c50726f70657274696573f4"; hex::decode(data_contract_cbor_hex).unwrap() diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index 4fb2c9f73e0..fda3110e063 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -102,18 +102,24 @@ impl DataContractFactory { .map(|(key, value)| Ok((key, value.try_into().map_err(ProtocolError::ValueError)?))) .collect::, ProtocolError>>()?; - let json_defs = definition_references - .into_iter() - .map(|(key, value)| { - Ok(( - key, - value - .clone() - .try_into() - .map_err(ProtocolError::ValueError)?, - )) - }) - .collect::, ProtocolError>>()?; + let json_defs = if !definition_references.is_empty() { + Some( + definition_references + .into_iter() + .map(|(key, value)| { + Ok(( + key, + value + .clone() + .try_into() + .map_err(ProtocolError::ValueError)?, + )) + }) + .collect::, ProtocolError>>()?, + ) + } else { + None + }; let mut data_contract = DataContract { protocol_version: self.protocol_version, id: data_contract_id, @@ -223,6 +229,7 @@ mod tests { use crate::data_contract::property_names; use crate::tests::fixtures::get_data_contract_fixture; use crate::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; + use crate::Convertible; use std::sync::Arc; pub struct TestData { diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index 01e5388a922..35f179996ab 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -36,9 +36,8 @@ impl DataContract { let version = data_contract_map.get_integer(property_names::VERSION)?; // Defs - let defs = data_contract_map - .get_optional_inner_str_json_value_map::>("$defs")? - .unwrap_or_default(); + let defs = + data_contract_map.get_optional_inner_str_json_value_map::>("$defs")?; // Documents let documents: BTreeMap = data_contract_map @@ -101,13 +100,13 @@ impl DataContract { contract_cbor_map.insert(property_names::DOCUMENTS, docs); - if !self.defs.is_empty() { + if let Some(defs) = &self.defs { contract_cbor_map.insert( property_names::DEFINITIONS, CborValue::serialized(&self.defs) .map_err(|e| ProtocolError::EncodingError(e.to_string()))?, ); - } + }; Ok(contract_cbor_map) } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 464c84959c7..f8c27ee8f04 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -16,7 +16,7 @@ use crate::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - ProtocolError, + Convertible, ProtocolError, }; use super::property_names::*; @@ -276,10 +276,10 @@ mod test { assert_eq!( data.state_transition .get_data_contract() - .to_json_object(false) + .to_json_object() .expect("conversion to object shouldn't fail"), data.data_contract - .to_json_object(false) + .to_json_object() .expect("conversion to object shouldn't fail") ); } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 68704bacba2..3c38ef47867 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -15,7 +15,7 @@ use crate::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, StateTransitionType, }, - ProtocolError, + Convertible, ProtocolError, }; use super::property_names::*; @@ -266,10 +266,10 @@ mod test { assert_eq!( data.state_transition .get_data_contract() - .to_json_object(false) + .to_json_object() .expect("conversion to object shouldn't fail"), data.data_contract - .to_json_object(false) + .to_json_object() .expect("conversion to object shouldn't fail") ); } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 6e672b0102b..c4b060bed3f 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -18,7 +18,7 @@ use crate::{ util::json_value::JsonValueExt, validation::{JsonSchemaValidator, SimpleValidationResult}, version::ProtocolVersionValidator, - DashPlatformProtocolInitError, ProtocolError, + Convertible, DashPlatformProtocolInitError, ProtocolError, }; use anyhow::anyhow; use anyhow::Context; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 4abee2714ba..adc63f04f0e 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -57,7 +57,6 @@ use crate::prelude::Revision; use crate::util::hash::hash; use crate::util::json_value::JsonValueExt; -use crate::util::json_value::ReplaceWith; use crate::ProtocolError; /// The property names of a document @@ -377,63 +376,20 @@ impl Document { Ok(self.into_map_value()?.into()) } - pub fn to_value(&self) -> Result { + pub fn to_object(&self) -> Result { Ok(self.to_map_value()?.into()) } pub fn to_cbor_value(&self) -> Result { - self.to_value() + self.to_object() .map(|v| v.try_into().map_err(ProtocolError::ValueError))? } pub fn to_json(&self) -> Result { - self.to_value() + self.to_object() .map(|v| v.try_into().map_err(ProtocolError::ValueError))? } - pub fn replace_all_fields( - value: &mut JsonValue, - data_contract: &DataContract, - document_type_name: &str, - ) -> Result<(), ProtocolError> { - let (identifier_paths, binary_paths) = - Self::get_identifiers_and_binary_paths(data_contract, document_type_name)?; - - value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; - value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - Ok(()) - } - - pub fn replace_property_fields( - value: &mut JsonValue, - data_contract: &DataContract, - document_type_name: &str, - ) -> Result<(), ProtocolError> { - let (identifier_paths, binary_paths) = - data_contract.get_identifiers_and_binary_paths(document_type_name)?; - - value.replace_identifier_paths(identifier_paths, ReplaceWith::Base58)?; - value.replace_binary_paths(binary_paths, ReplaceWith::Base64)?; - Ok(()) - } - - // The skipIdentifierConversion option is removed as it doesn't make sense in the case of - // of Rust. Rust doesn't distinguish between `Buffer` and `Identifier` - pub fn to_object( - &self, - data_contract: &DataContract, - document_type_name: &str, - ) -> Result { - let mut json_object = serde_json::to_value(self)?; - - let (identifier_paths, binary_paths) = - Self::get_identifiers_and_binary_paths(data_contract, document_type_name)?; - let _ = json_object.replace_identifier_paths(identifier_paths, ReplaceWith::Bytes); - let _ = json_object.replace_binary_paths(binary_paths, ReplaceWith::Bytes); - - Ok(json_object) - } - pub fn from_json_value(mut document_value: JsonValue) -> Result where for<'de> S: Deserialize<'de> + TryInto, diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index ebe21bd49b9..79a517a7c47 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -64,8 +64,8 @@ impl DocumentValidator { .get_document_schema(document_type.name.as_str())? .to_owned(); - let json_schema_validator = if !data_contract.defs.is_empty() { - JsonSchemaValidator::new_with_definitions(document_schema, data_contract.defs.iter()) + let json_schema_validator = if let Some(defs) = &data_contract.defs { + JsonSchemaValidator::new_with_definitions(document_schema, defs.iter()) } else { JsonSchemaValidator::new(document_schema) } @@ -115,8 +115,8 @@ impl DocumentValidator { .get_document_schema(document_type_name)? .to_owned(); - let json_schema_validator = if !data_contract.defs.is_empty() { - JsonSchemaValidator::new_with_definitions(document_schema, data_contract.defs.iter()) + let json_schema_validator = if let Some(defs) = &data_contract.defs { + JsonSchemaValidator::new_with_definitions(document_schema, defs.iter()) } else { JsonSchemaValidator::new(document_schema) } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 061b8bba99c..0a877b202af 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -13,10 +13,7 @@ use crate::identity::TimestampMillis; use crate::prelude::Revision; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; -use crate::{ - data_contract::DataContract, errors::ProtocolError, util::json_value::JsonValueExt, - util::json_value::ReplaceWith, -}; +use crate::{data_contract::DataContract, errors::ProtocolError}; use super::INITIAL_REVISION; use super::{document_base_transition::DocumentBaseTransition, DocumentTransitionObjectLike}; @@ -58,13 +55,6 @@ impl DocumentCreateTransition { Some(INITIAL_REVISION) } - pub fn bytes_to_strings( - raw_create_document_transition: &mut JsonValue, - ) -> Result<(), ProtocolError> { - raw_create_document_transition.replace_binary_paths(BINARY_FIELDS, ReplaceWith::Base64)?; - Ok(()) - } - pub(crate) fn to_document(&self, owner_id: Identifier) -> Result { let properties = self.data.clone().unwrap_or_default(); Ok(Document { diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index a129fd20d44..9896983b504 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -289,11 +289,8 @@ fn validate_raw_transitions<'a>( let enriched_data_contract = &enriched_contracts_by_action[&action]; let document_schema = enriched_data_contract.get_document_schema(document_type)?; - let schema_validator = if !enriched_data_contract.defs.is_empty() { - JsonSchemaValidator::new_with_definitions( - document_schema.clone(), - enriched_data_contract.defs.iter(), - ) + let schema_validator = if let Some(defs) = &enriched_data_contract.defs { + JsonSchemaValidator::new_with_definitions(document_schema.clone(), defs.iter()) } else { JsonSchemaValidator::new(document_schema.clone()) } diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index f42c9b4e026..7b6a319efdb 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -21,7 +21,7 @@ pub use crate::identity::purpose::Purpose; pub use crate::identity::security_level::SecurityLevel; use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; use crate::util::hash::ripemd160_sha256; -use crate::util::json_value::{JsonValueExt, ReplaceWith}; +use crate::util::json_value::JsonValueExt; use crate::util::vec; use crate::SerdeParsingError; @@ -139,12 +139,9 @@ impl IdentityPublicKey { } /// Return json with all binary data converted to base64 - pub fn to_json(&self) -> Result { - let mut value = self.to_raw_json_object()?; - - value.replace_binary_paths(BINARY_DATA_FIELDS, ReplaceWith::Base64)?; - - Ok(value) + pub fn to_json(&self) -> Result { + let value: Value = self.try_into()?; + value.try_into().map_err(ProtocolError::ValueError) } pub fn from_cbor_value(cbor_value: &CborValue) -> Result { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index edac40c118c..804b88a4e4a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -16,7 +16,10 @@ use crate::{NonConsensusError, ProtocolError}; use platform_value::btreemap_extensions::BTreeValueRemoveInnerValueFromMapHelper; pub const IDENTIFIER_FIELDS: [&str; 1] = [property_names::IDENTITY_ID]; -pub const BINARY_FIELDS: [&str; 2] = [property_names::PUBLIC_KEYS_DATA, property_names::SIGNATURE]; +pub const BINARY_FIELDS: [&str; 2] = [ + property_names::PUBLIC_KEYS_DATA, + property_names::PUBLIC_KEYS_SIGNATURE, +]; mod property_names { pub const PUBLIC_KEYS: &str = "publicKeys"; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index d6f83f3c0bb..f8651ddc6e5 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -5,13 +5,12 @@ use std::convert::{TryFrom, TryInto}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::{BinaryData, Value}; +use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::errors::ProtocolError; use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; -use crate::util::json_value::{JsonValueExt, ReplaceWith}; use crate::SerdeParsingError; pub const BINARY_DATA_FIELDS: [&str; 2] = ["data", "signature"]; @@ -116,11 +115,10 @@ impl IdentityPublicKeyWithWitness { Ok(identity_public_key) } - pub fn from_json_object(mut raw_object: JsonValue) -> Result { - raw_object.replace_binary_paths(BINARY_DATA_FIELDS, ReplaceWith::Bytes)?; - let identity_public_key: Self = serde_json::from_value(raw_object)?; - - Ok(identity_public_key) + pub fn from_json_object(raw_object: JsonValue) -> Result { + let mut value: Value = raw_object.into(); + value.replace_at_paths(BINARY_DATA_FIELDS, ReplacementType::BinaryBytes)?; + value.try_into().map_err(ProtocolError::ValueError) } /// Return raw data, with all binary fields represented as arrays @@ -160,12 +158,9 @@ impl IdentityPublicKeyWithWitness { } /// Return json with all binary data converted to base64 - pub fn to_json(&self) -> Result { - let mut value = self.to_raw_json_object(false)?; - - value.replace_binary_paths(BINARY_DATA_FIELDS, ReplaceWith::Base64)?; - - Ok(value) + pub fn to_json(&self) -> Result { + let value: Value = self.try_into()?; + value.try_into().map_err(ProtocolError::ValueError) } pub fn from_cbor_value(cbor_value: &CborValue) -> Result { @@ -246,3 +241,11 @@ impl TryInto for IdentityPublicKeyWithWitness { platform_value::to_value(self) } } + +impl TryInto for &IdentityPublicKeyWithWitness { + type Error = platform_value::Error; + + fn try_into(self) -> Result { + platform_value::to_value(self) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index a2ea5c3d1dd..19bbdfa4a04 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -5,6 +5,7 @@ use std::{ }; use crate::consensus::basic::state_transition::InvalidStateTransitionTypeError; +use crate::convertible::Convertible; use crate::data_contract::errors::DataContractNotPresentError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; use crate::{ @@ -225,6 +226,7 @@ fn missing_state_transition_error() -> ProtocolError { #[cfg(test)] mod test { + use crate::convertible::Convertible; use dashcore::network::constants::PROTOCOL_VERSION; use platform_value::{platform_value, Value}; use std::collections::BTreeMap; @@ -273,7 +275,7 @@ mod test { assert!( matches!(result, StateTransition::DataContractCreate(transition) if { - transition.get_data_contract().to_json_object(false).unwrap() == data_contract.to_json_object(false).unwrap() + transition.get_data_contract().to_json_object().unwrap() == data_contract.to_json_object().unwrap() }) ) } diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs index 4a6b90e02b0..5ca4d3b2f8f 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs @@ -14,7 +14,6 @@ use crate::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransitionConvert, StateTransitionType, }, - util::json_value::JsonValueExt, validation::{AsyncDataValidatorWithContext, SimpleValidationResult}, ProtocolError, }; diff --git a/packages/rs-dpp/src/util/cbor_value/canonical.rs b/packages/rs-dpp/src/util/cbor_value/canonical.rs index c645f65b14b..347e31d99ec 100644 --- a/packages/rs-dpp/src/util/cbor_value/canonical.rs +++ b/packages/rs-dpp/src/util/cbor_value/canonical.rs @@ -9,7 +9,7 @@ use ciborium::value::Value as CborValue; use platform_value::string_encoding::Encoding; use serde::Serialize; -use crate::{prelude::Identifier, util::json_value::ReplaceWith, ProtocolError}; +use crate::{prelude::Identifier, ProtocolError}; use super::{ convert::convert_to, get_from_cbor_map, to_path_of_cbors, FieldType, ReplacePaths, @@ -74,16 +74,6 @@ impl CborCanonicalMap { } } - pub fn replace_values(&mut self, keys: I, with: ReplaceWith) - where - I: IntoIterator, - C: Into, - { - for key in keys.into_iter() { - self.replace_value(key, with); - } - } - pub fn replace_path(&mut self, path: &str, from: FieldType, to: FieldType) -> Option<()> { let cbor_value = self.get_path_mut(path)?; let replace_with = convert_to(cbor_value, from, to)?; @@ -93,33 +83,6 @@ impl CborCanonicalMap { Some(()) } - pub fn replace_value(&mut self, key: impl Into, with: ReplaceWith) -> Option<()> { - let k = key.into(); - - let cbor_value = self.get_mut(&k)?; - let replace_with = match with { - ReplaceWith::Base58 => { - let data_bytes = cbor_value.as_bytes()?; - CborValue::Text(bs58::encode(data_bytes).into_string()) - } - ReplaceWith::Base64 => { - let data_bytes = cbor_value.as_bytes()?; - CborValue::Text(base64::encode(data_bytes)) - } - ReplaceWith::Bytes => { - let data_string = String::from(cbor_value.as_text()?); - let identifier = Identifier::from_string(&data_string, Encoding::Base58) - .ok()? - .to_buffer(); - CborValue::Bytes(identifier.to_vec()) - } - }; - - self.set(&k, replace_with); - - Some(()) - } - pub fn set(&mut self, key: &CborValue, replace_with: CborValue) -> Option<()> { if let Some(index) = self.inner.iter().position(|(el_key, _)| el_key == key) { if let Some(key_value) = self.inner.get_mut(index) { @@ -335,35 +298,6 @@ fn recursively_sort_canonical_cbor_map(cbor_map: &mut [(CborValue, CborValue)]) }); } -pub fn replace_binary(to_replace: &mut CborValue, with: ReplaceWith) -> Result<(), anyhow::Error> { - let mut cbor_value = CborValue::Null; - std::mem::swap(to_replace, &mut cbor_value); - match with { - ReplaceWith::Base58 => { - let data_bytes = cbor_value - .as_bytes() - .ok_or_else(|| anyhow!("expect value to be bytes"))?; - *to_replace = CborValue::Text(bs58::encode(data_bytes).into_string()); - } - ReplaceWith::Base64 => { - let data_bytes = cbor_value - .as_bytes() - .ok_or_else(|| anyhow!("expect value to be bytes"))?; - *to_replace = CborValue::Text(base64::encode(data_bytes)); - } - ReplaceWith::Bytes => { - let data_string = String::from( - cbor_value - .as_text() - .ok_or_else(|| anyhow!("expect value to be string"))?, - ); - let identifier = Identifier::from_string(&data_string, Encoding::Base58)?.to_buffer(); - *to_replace = CborValue::Bytes(identifier.to_vec()); - } - } - Ok(()) -} - //todo: explain why this returns an option? pub fn value_to_bytes(value: &CborValue) -> Result>, ProtocolError> { match value { diff --git a/packages/rs-dpp/src/util/json_value/mod.rs b/packages/rs-dpp/src/util/json_value/mod.rs index 447abba5b50..b105ac4de61 100644 --- a/packages/rs-dpp/src/util/json_value/mod.rs +++ b/packages/rs-dpp/src/util/json_value/mod.rs @@ -22,13 +22,6 @@ use remove_path::*; const PROPERTY_CONTENT_MEDIA_TYPE: &str = "contentMediaType"; const PROPERTY_PROTOCOL_VERSION: &str = "protocolVersion"; -#[derive(Debug, Clone, Copy)] -pub enum ReplaceWith { - Bytes, - Base58, - Base64, -} - /// JsonValueExt contains a set of helper methods that simplify work with JsonValue pub trait JsonValueExt { /// assumes the Json Value is a map and tries to remove the given property @@ -62,20 +55,6 @@ pub trait JsonValueExt { /// assumes that the JsonValue is a Map and tries to remove the u32 fn remove_u32(&mut self, property_name: &str) -> Result; - /// replaces Identifiers specified by path with either the Bytes format or string format (base58 or base64) - fn replace_identifier_paths<'a>( - &mut self, - paths: impl IntoIterator, - with: ReplaceWith, - ) -> Result<(), anyhow::Error>; - - /// replaces binary data specified by path with either the Bytes format or string format (base58 or base64) - fn replace_binary_paths<'a>( - &mut self, - paths: impl IntoIterator, - with: ReplaceWith, - ) -> Result<(), anyhow::Error>; - fn add_protocol_version( &mut self, property_name: &str, @@ -325,68 +304,6 @@ impl JsonValueExt for JsonValue { .ok_or_else(|| anyhow!("the property '{:?}' not found", path)) } - fn replace_identifier_paths<'a>( - &mut self, - paths: impl IntoIterator, - with: ReplaceWith, - ) -> Result<(), anyhow::Error> { - let mut results = vec![]; - - for raw_path in paths { - let mut to_replace = get_value_mut(raw_path, self); - match to_replace { - Some(ref mut v) => { - results.push(replace_identifier(v, with).map_err(|err| { - anyhow!( - "unable replace the {:?} with {:?}: '{}'", - raw_path, - with, - err - ) - })); - } - None => { - trace!( - "path '{}' is not found, when replacing to {:?} ", - raw_path, - with - ) - } - } - } - results.into_iter().collect::>() - } - - /// replaces binary data specified by path with either the Bytes format or string format (base58 or base64) - fn replace_binary_paths<'a>( - &mut self, - paths: impl IntoIterator, - with: ReplaceWith, - ) -> Result<(), anyhow::Error> { - let mut results = vec![]; - - for raw_path in paths { - let mut to_replace = get_value_mut(raw_path, self); - match to_replace { - Some(ref mut value) => { - results.push(replace_binary(value, with).map_err(|err| { - anyhow!( - "unable replace {:?} with {:?}: '{}' input data: '{}'", - raw_path, - with, - err, - value - ) - })); - } - None => { - trace!("path '{}' is not found, replacing to {:?} ", raw_path, with) - } - } - } - results.into_iter().collect::>() - } - fn add_protocol_version<'a>( &mut self, property_name: &str, @@ -464,68 +381,6 @@ impl JsonValueExt for JsonValue { } } -/// replaces the Identifiers specified in binary_properties with Bytes or Base58 -pub fn identifiers_to( - binary_properties: &BTreeMap, - dynamic_data: &mut JsonValue, - to: ReplaceWith, -) -> Result<(), ProtocolError> { - let identifier_paths = binary_properties - .iter() - .filter(|(_, p)| identifier_filter(p)) - .map(|(name, _)| name.as_str()); - - dynamic_data.replace_identifier_paths(identifier_paths, to)?; - Ok(()) -} - -/// replaces the Identifier wrapped in Json Value to either the Bytes or Base58 form -pub fn replace_identifier( - to_replace: &mut JsonValue, - with: ReplaceWith, -) -> Result<(), ProtocolError> { - // TODO: remove the clone(). If replace fails, the original value should be untouched - match with { - ReplaceWith::Base58 => { - let data_bytes: Vec = serde_json::from_value(to_replace.clone())?; - let identifier = Identifier::from_bytes(&data_bytes)?; - - *to_replace = JsonValue::String(identifier.to_string(Encoding::Base58)); - } - ReplaceWith::Base64 => { - let data_bytes: Vec = serde_json::from_value(to_replace.clone())?; - let identifier = Identifier::from_bytes(&data_bytes)?; - *to_replace = JsonValue::String(identifier.to_string(Encoding::Base64)); - } - ReplaceWith::Bytes => { - let data_string: String = serde_json::from_value(to_replace.clone())?; - let identifier = - Identifier::from_string(&data_string, Encoding::Base58)?.to_json_value_vec(); - *to_replace = JsonValue::Array(identifier); - } - } - Ok(()) -} - -pub fn replace_binary(to_replace: &mut JsonValue, with: ReplaceWith) -> Result<(), anyhow::Error> { - // TODO: remove the clone(). If replace fails, the original value should be untouched - match with { - ReplaceWith::Base58 => { - let data_bytes: Vec = serde_json::from_value(to_replace.clone())?; - *to_replace = JsonValue::String(bs58::encode(data_bytes).into_string()); - } - ReplaceWith::Base64 => { - let data_bytes: Vec = serde_json::from_value(to_replace.clone())?; - *to_replace = JsonValue::String(base64::encode(data_bytes)); - } - ReplaceWith::Bytes => { - let base64: String = serde_json::from_value(to_replace.clone())?; - *to_replace = JsonValue::from(base64::decode(base64)?); - } - } - Ok(()) -} - fn identifier_filter(value: &JsonValue) -> bool { if let JsonValue::Object(object) = value { if let Some(JsonValue::String(media_type)) = object.get(PROPERTY_CONTENT_MEDIA_TYPE) { @@ -591,94 +446,6 @@ mod test { use super::*; - #[test] - fn test_replace_identifier_paths_happy_path() { - let mut document = json!({ - "root" : { - "from" : { - "id": "6oCKUeLVgjr7VZCyn1LdGbrepqKLmoabaff5WQqyTKYP", - "message": "text_message", - }, - "to" : { - "id": "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8", - "message": "text_message", - }, - "transactions" : [ - { - "message": "text_message", - }, - { - "id": "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8", - "message": "text_message", - "inner": { - "document_id" : "5wpZAEWndYcTeuwZpkmSa8s49cHXU5q2DhdibesxFSu8", - } - } - ] - } - }); - - assert!(document["root"]["from"]["id"].is_string()); - assert!(document["root"]["from"]["message"].is_string()); - assert!(document["root"]["to"]["id"].is_string()); - assert!(document["root"]["to"]["message"].is_string()); - assert!(document["root"]["transactions"][1]["id"].is_string()); - assert!(document["root"]["transactions"][1]["inner"]["document_id"].is_string()); - - let mut binary_properties: BTreeMap = Default::default(); - let paths = vec![ - "root.from.id", - "root.to.id", - "root.transactions[1].id", - "root.transactions[1].inner.document_id", - ]; - - for p in paths { - binary_properties.insert( - p.to_string(), - json!({ "contentMediaType": "application/x.dash.dpp.identifier"}), - ); - } - - identifiers_to(&binary_properties, &mut document, ReplaceWith::Bytes).unwrap(); - assert!(document["root"]["from"]["id"].is_array()); - assert!(document["root"]["from"]["message"].is_string()); - assert!(document["root"]["to"]["id"].is_array()); - assert!(document["root"]["to"]["message"].is_string()); - assert!(document["root"]["transactions"][1]["id"].is_array()); - assert!(document["root"]["transactions"][1]["inner"]["document_id"].is_array()); - - identifiers_to(&binary_properties, &mut document, ReplaceWith::Base58).unwrap(); - assert!(document["root"]["from"]["id"].is_string()); - assert!(document["root"]["from"]["message"].is_string()); - assert!(document["root"]["to"]["id"].is_string()); - assert!(document["root"]["to"]["message"].is_string()); - assert!(document["root"]["transactions"][1]["id"].is_string()); - assert!(document["root"]["transactions"][1]["inner"]["document_id"].is_string()); - } - - #[test] - fn test_replace_identifier_path_with_bytes_wrong_identifier() { - let mut document = json!({ - "root" : { - "from" : { - "id": "123", - "message": "text_message", - }, - } - }); - - assert!(document["root"]["from"]["id"].is_string()); - - let mut binary_properties: BTreeMap = BTreeMap::new(); - binary_properties.insert( - "root.from.id".to_string(), - json!({ "contentMediaType": "application/x.dash.dpp.identifier"}), - ); - let result = identifiers_to(&binary_properties, &mut document, ReplaceWith::Bytes); - assert_error_contains!(result, "Identifier must be 32 bytes long"); - } - #[test] fn insert_with_parents() { let mut document = json!({ @@ -705,30 +472,4 @@ mod test { json!("new_value") ); } - - #[test] - fn failed_replace_should_leave_original_data_untouched() { - let mut document = json!({ - "root" : { - "from" : { - "id": "123", - "message": "text_message", - }, - } - }); - - assert!(document["root"]["from"]["id"].is_string()); - - let mut binary_properties: BTreeMap = BTreeMap::new(); - binary_properties.insert( - "root.from.id".to_string(), - json!({ "contentMediaType": "application/x.dash.dpp.identifier"}), - ); - let result = identifiers_to(&binary_properties, &mut document, ReplaceWith::Bytes); - assert_error_contains!(result, "Identifier must be 32 bytes long"); - assert_eq!( - document["root"]["from"]["id"], - JsonValue::String(String::from("123")) - ); - } } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index b9453e27fde..dda24cae066 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -277,6 +277,32 @@ impl Value { self.as_bytes().is_some() } + /// Returns true if the `Value` is a `Bytes`. Returns false otherwise. + /// + /// ``` + /// # use platform_value::Value; + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111]); + /// + /// assert!(value.is_any_bytes_type()); + /// + /// let value = Value::Identifier([1u8;32]); + /// + /// assert!(value.is_any_bytes_type()); + /// + /// let value = Value::Bytes32([1u8;32]); + /// + /// assert!(value.is_any_bytes_type()); + /// ``` + pub fn is_any_bytes_type(&self) -> bool { + match self { + Value::Bytes(_) + | Value::Bytes32(_) + | Value::Identifier(_) => true, + _ => false, + } + } + /// If the `Value` is a `Bytes`, returns a reference to the associated bytes vector. /// Returns None otherwise. /// diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index ede5e055442..157564f7136 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -3,7 +3,7 @@ use rand::Rng; use std::convert::{TryFrom, TryInto}; use std::fmt; -use serde::de::Visitor; +use serde::de::{Error as SerdeDeError, Visitor}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -67,29 +67,9 @@ impl<'de> Deserialize<'de> for IdentifierBytes32 { deserializer.deserialize_string(StringVisitor) } else { - struct BytesVisitor; + let value = Value::deserialize(deserializer).map_err(|err| err.into())?; - impl<'de> Visitor<'de> for BytesVisitor { - type Value = IdentifierBytes32; - - fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a byte array with length 32") - } - - fn visit_bytes(self, v: &[u8]) -> Result - where - E: serde::de::Error, - { - let mut bytes = [0u8; 32]; - if v.len() != 32 { - return Err(E::invalid_length(v.len(), &self)); - } - bytes.copy_from_slice(v); - Ok(IdentifierBytes32(bytes)) - } - } - - deserializer.deserialize_bytes(BytesVisitor) + Ok(IdentifierBytes32(value.into_hash256().map_err(|_| D::Error::custom("hello"))?)) } } } diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 42a8bd6ca17..a9c4b4551c3 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -6,6 +6,9 @@ pub type ValueMap = Vec<(Value, Value)>; pub trait ValueMapHelper { fn sort_by_keys(&mut self); + fn sort_by_keys_and_inner_maps(&mut self); + fn sort_by_lexicographical_byte_ordering_keys(&mut self); + fn sort_by_lexicographical_byte_ordering_keys_and_inner_maps(&mut self); fn get_key(&self, search_key: &str) -> Result<&Value, Error>; fn get_optional_key(&self, key: &str) -> Option<&Value>; fn get_key_mut(&mut self, search_key: &str) -> Result<&mut Value, Error>; @@ -20,7 +23,41 @@ pub trait ValueMapHelper { impl ValueMapHelper for ValueMap { fn sort_by_keys(&mut self) { - self.sort_by(|(key1, _), (key2, _)| key1.partial_cmp(key2).unwrap_or(Ordering::Less)) + self.sort_by(|(key1, _), (key2, _)| key1.partial_cmp(key2).unwrap_or(Ordering::Less)); + } + + fn sort_by_keys_and_inner_maps(&mut self) { + self.sort_by_keys(); + self.iter_mut().for_each(|(_, v)| { + if let Value::Map(m) = v { + m.sort_by_keys_and_inner_maps() + } + }); + } + + fn sort_by_lexicographical_byte_ordering_keys(&mut self) { + self.sort_by(|(key1, _), (key2, _)| { + if key1.is_text() && key2.is_text() { + let key1 = key1.to_text().unwrap(); + let key2 = key2.to_text().unwrap(); + match key1.len().cmp(&key2.len()) { + Ordering::Less => Ordering::Less, + Ordering::Equal => { key1.cmp(&key2) }, + Ordering::Greater => Ordering::Greater, + } + } else { + key1.partial_cmp(key2).unwrap_or(Ordering::Less) + } + }) + } + + fn sort_by_lexicographical_byte_ordering_keys_and_inner_maps(&mut self) { + self.sort_by_lexicographical_byte_ordering_keys(); + self.iter_mut().for_each(|(_, v)| { + if let Value::Map(m) = v { + m.sort_by_lexicographical_byte_ordering_keys_and_inner_maps() + } + }); } fn get_key(&self, search_key: &str) -> Result<&Value, Error> { diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index b72db873b51..4ed34b7011f 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -38,7 +38,7 @@ use dpp::platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper use dpp::platform_value::converter::serde_json::BTreeValueJsonConverter; use dpp::platform_value::ReplacementType; use dpp::platform_value::Value; -use dpp::ProtocolError; +use dpp::{platform_value, ProtocolError}; pub use factory::DocumentFactoryWASM; use serde_json::Value as JsonValue; pub use validator::DocumentValidatorWasm; @@ -228,8 +228,8 @@ impl DocumentWasm { document_type_name: &str, ) -> Result { let options: ConversionOptions = if !options.is_undefined() && options.is_object() { - let raw_options = options.with_serde_to_json_value()?; - serde_json::from_value(raw_options).with_js_error()? + let raw_options = options.with_serde_to_platform_value()?; + platform_value::from_value(raw_options).with_js_error()? } else { Default::default() }; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index fd5301d9d7e..c2e9b0680fc 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -61,10 +61,6 @@ impl IdentityCreateTransitionWasm { .replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes) .map_err(ProtocolError::ValueError) .with_js_error()?; - raw_state_transition - .replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier) - .map_err(ProtocolError::ValueError) - .with_js_error()?; let identity_create_transition = IdentityCreateTransition::new(raw_state_transition) .map_err(|e| RustConversionError::Error(e.to_string()).to_js_value())?; From 1605125bf1acb7650a4e492d841ae5a2a866d20c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 00:49:12 +0700 Subject: [PATCH 166/228] more fixes --- packages/rs-dpp/src/data_contract/data_contract.rs | 1 - .../rs-dpp/src/data_contract/serialization/cbor.rs | 2 +- .../src/state_transition/state_transition_factory.rs | 2 +- packages/rs-dpp/src/util/cbor_value/canonical.rs | 6 +++--- packages/rs-dpp/src/util/json_value/mod.rs | 10 +++++----- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 4bde43c57af..dae0c81493e 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -519,7 +519,6 @@ mod test { use integer_encoding::VarInt; use crate::{ - assert_error_contains, tests::{fixtures::get_data_contract_fixture, utils::*}, }; diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index 35f179996ab..6f01aed9b91 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -100,7 +100,7 @@ impl DataContract { contract_cbor_map.insert(property_names::DOCUMENTS, docs); - if let Some(defs) = &self.defs { + if let Some(_defs) = &self.defs { contract_cbor_map.insert( property_names::DEFINITIONS, CborValue::serialized(&self.defs) diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 19bbdfa4a04..b7caf3a589f 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -5,7 +5,7 @@ use std::{ }; use crate::consensus::basic::state_transition::InvalidStateTransitionTypeError; -use crate::convertible::Convertible; + use crate::data_contract::errors::DataContractNotPresentError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; use crate::{ diff --git a/packages/rs-dpp/src/util/cbor_value/canonical.rs b/packages/rs-dpp/src/util/cbor_value/canonical.rs index 347e31d99ec..de2a8936c6c 100644 --- a/packages/rs-dpp/src/util/cbor_value/canonical.rs +++ b/packages/rs-dpp/src/util/cbor_value/canonical.rs @@ -4,12 +4,12 @@ use std::{ convert::{TryFrom, TryInto}, }; -use anyhow::anyhow; + use ciborium::value::Value as CborValue; -use platform_value::string_encoding::Encoding; + use serde::Serialize; -use crate::{prelude::Identifier, ProtocolError}; +use crate::{ProtocolError}; use super::{ convert::convert_to, get_from_cbor_map, to_path_of_cbors, FieldType, ReplacePaths, diff --git a/packages/rs-dpp/src/util/json_value/mod.rs b/packages/rs-dpp/src/util/json_value/mod.rs index b105ac4de61..f6abb0b3914 100644 --- a/packages/rs-dpp/src/util/json_value/mod.rs +++ b/packages/rs-dpp/src/util/json_value/mod.rs @@ -1,20 +1,20 @@ -use std::{collections::BTreeMap, convert::TryInto}; +use std::{convert::TryInto}; use anyhow::{anyhow, bail}; -use log::trace; + use serde::de::DeserializeOwned; use serde_json::{Number, Value as JsonValue}; use crate::{ errors::ProtocolError, - identifier::{self, Identifier}, + identifier::{self}, }; use super::json_path::{JsonPath, JsonPathLiteral, JsonPathStep}; mod insert_with_path; use insert_with_path::*; -use platform_value::string_encoding::Encoding; + mod remove_path; use remove_path::*; @@ -442,7 +442,7 @@ pub fn get_value_from_json_path<'a>( mod test { use serde_json::json; - use crate::assert_error_contains; + use super::*; From f605bc31b38214b077bf51ca90559fb188af8a07 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 01:15:07 +0700 Subject: [PATCH 167/228] more clean up --- .../rs-dpp/src/data_contract/data_contract.rs | 4 +--- packages/rs-dpp/src/util/cbor_value/canonical.rs | 3 +-- packages/rs-dpp/src/util/json_value/mod.rs | 5 +---- packages/rs-drive-nodejs/src/lib.rs | 1 + packages/rs-drive/src/drive/contract/mod.rs | 1 + .../rs-platform-value/src/inner_value_at_path.rs | 4 ++++ packages/rs-platform-value/src/lib.rs | 4 +--- .../rs-platform-value/src/types/identifier.rs | 6 +++++- packages/rs-platform-value/src/value_map.rs | 8 ++++---- .../wasm-dpp/src/data_contract/data_contract.rs | 4 ++-- packages/wasm-dpp/src/document/mod.rs | 15 +++++++-------- packages/wasm-dpp/src/identity/mod.rs | 6 +++--- 12 files changed, 31 insertions(+), 30 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index dae0c81493e..e3f3f07d0d5 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -518,9 +518,7 @@ mod test { use anyhow::Result; use integer_encoding::VarInt; - use crate::{ - tests::{fixtures::get_data_contract_fixture, utils::*}, - }; + use crate::tests::{fixtures::get_data_contract_fixture, utils::*}; use super::*; diff --git a/packages/rs-dpp/src/util/cbor_value/canonical.rs b/packages/rs-dpp/src/util/cbor_value/canonical.rs index de2a8936c6c..99ca93f0abb 100644 --- a/packages/rs-dpp/src/util/cbor_value/canonical.rs +++ b/packages/rs-dpp/src/util/cbor_value/canonical.rs @@ -4,12 +4,11 @@ use std::{ convert::{TryFrom, TryInto}, }; - use ciborium::value::Value as CborValue; use serde::Serialize; -use crate::{ProtocolError}; +use crate::ProtocolError; use super::{ convert::convert_to, get_from_cbor_map, to_path_of_cbors, FieldType, ReplacePaths, diff --git a/packages/rs-dpp/src/util/json_value/mod.rs b/packages/rs-dpp/src/util/json_value/mod.rs index f6abb0b3914..35edc64a316 100644 --- a/packages/rs-dpp/src/util/json_value/mod.rs +++ b/packages/rs-dpp/src/util/json_value/mod.rs @@ -1,4 +1,4 @@ -use std::{convert::TryInto}; +use std::convert::TryInto; use anyhow::{anyhow, bail}; @@ -15,7 +15,6 @@ use super::json_path::{JsonPath, JsonPathLiteral, JsonPathStep}; mod insert_with_path; use insert_with_path::*; - mod remove_path; use remove_path::*; @@ -442,8 +441,6 @@ pub fn get_value_from_json_path<'a>( mod test { use serde_json::json; - - use super::*; #[test] diff --git a/packages/rs-drive-nodejs/src/lib.rs b/packages/rs-drive-nodejs/src/lib.rs index 07bc33ef6b0..f623819ae19 100644 --- a/packages/rs-drive-nodejs/src/lib.rs +++ b/packages/rs-drive-nodejs/src/lib.rs @@ -12,6 +12,7 @@ use crate::fee::result::FeeResultWrapper; use drive::dpp::identity::{KeyID, TimestampMillis}; use drive::dpp::prelude::Revision; +use drive::dpp::Convertible; use drive::drive::flags::StorageFlags; use drive::drive::query::QueryDocumentsOutcome; use drive::error::Error; diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 385d0930234..3e253b68ead 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -1385,6 +1385,7 @@ mod tests { mod get_contract_with_fetch_info { use super::*; use dpp::prelude::Identifier; + use dpp::Convertible; #[test] fn should_get_contract_from_global_and_block_cache() { diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index bd1d1f92e71..62111924a1f 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -56,6 +56,10 @@ impl Value { self.remove_value_at_path(path)?.try_into() } + pub fn remove_value_at_path_as_bytes(&mut self, path: &str) -> Result, Error> { + self.remove_value_at_path(path)?.try_into() + } + pub fn remove_values_at_paths<'a>( &'a mut self, paths: Vec<&'a str>, diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index dda24cae066..7e0781a7a6a 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -296,9 +296,7 @@ impl Value { /// ``` pub fn is_any_bytes_type(&self) -> bool { match self { - Value::Bytes(_) - | Value::Bytes32(_) - | Value::Identifier(_) => true, + Value::Bytes(_) | Value::Bytes32(_) | Value::Identifier(_) => true, _ => false, } } diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 157564f7136..127153bde9f 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -69,7 +69,11 @@ impl<'de> Deserialize<'de> for IdentifierBytes32 { } else { let value = Value::deserialize(deserializer).map_err(|err| err.into())?; - Ok(IdentifierBytes32(value.into_hash256().map_err(|_| D::Error::custom("hello"))?)) + Ok(IdentifierBytes32( + value + .into_hash256() + .map_err(|_| D::Error::custom("hello"))?, + )) } } } diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index a9c4b4551c3..57310eb0738 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -29,9 +29,9 @@ impl ValueMapHelper for ValueMap { fn sort_by_keys_and_inner_maps(&mut self) { self.sort_by_keys(); self.iter_mut().for_each(|(_, v)| { - if let Value::Map(m) = v { - m.sort_by_keys_and_inner_maps() - } + if let Value::Map(m) = v { + m.sort_by_keys_and_inner_maps() + } }); } @@ -42,7 +42,7 @@ impl ValueMapHelper for ValueMap { let key2 = key2.to_text().unwrap(); match key1.len().cmp(&key2.len()) { Ordering::Less => Ordering::Less, - Ordering::Equal => { key1.cmp(&key2) }, + Ordering::Equal => key1.cmp(&key2), Ordering::Greater => Ordering::Greater, } } else { diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index 863d6e5315c..ef3fea8b686 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -8,9 +8,9 @@ use serde_json::Value as JsonValue; use wasm_bindgen::prelude::*; use dpp::data_contract::{DataContract, SCHEMA_URI}; -use dpp::platform_value; use dpp::platform_value::string_encoding::Encoding; use dpp::platform_value::{Bytes32, Value}; +use dpp::{platform_value, Convertible}; use crate::errors::{from_dpp_err, RustConversionError}; use crate::identifier::identifier_from_js_value; @@ -216,7 +216,7 @@ impl DataContractWasm { if definitions.is_empty() { bail_js!("`definitions` cannot be empty"); } - self.0.defs = definitions; + self.0.defs = Some(definitions); } else { bail_js!("the parameter 'definitions' is not an JS object"); } diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 4ed34b7011f..438330d34b6 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -229,14 +229,13 @@ impl DocumentWasm { ) -> Result { let options: ConversionOptions = if !options.is_undefined() && options.is_object() { let raw_options = options.with_serde_to_platform_value()?; - platform_value::from_value(raw_options).with_js_error()? + platform_value::from_value(raw_options) + .map_err(ProtocolError::ValueError) + .with_js_error()? } else { Default::default() }; - let mut value = self - .0 - .to_object(&data_contract.0, document_type_name) - .with_js_error()?; + let mut value = self.0.to_object().with_js_error()?; let (identifiers_paths, binary_paths) = Document::get_identifiers_and_binary_paths(&data_contract.0, document_type_name) @@ -245,7 +244,7 @@ impl DocumentWasm { let js_value = value.serialize(&serializer)?; for path in identifiers_paths.into_iter() { - if let Ok(bytes) = value.remove_value_at_path_into::>(path) { + if let Ok(bytes) = value.remove_value_at_path_as_bytes(path) { if !options.skip_identifiers_conversion { let buffer = Buffer::from_bytes(&bytes); lodash_set(&js_value, path, buffer.into()); @@ -257,8 +256,8 @@ impl DocumentWasm { } for path in binary_paths { - if let Ok(bytes) = value.remove_value_at_path_into::>(path) { - let buffer = Buffer::from_bytes(&bytes); + if let Ok(bytes) = value.remove_value_at_path_as_bytes(path) { + let buffer = Buffer::from_bytes_owned(bytes); lodash_set(&js_value, path, buffer.into()); } } diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index 5574a9aef7b..6dfe787651e 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -17,7 +17,7 @@ use dpp::{ProtocolError, SerdeParsingError}; use crate::errors::from_dpp_err; use crate::identifier::IdentifierWrapper; use crate::utils; -use crate::utils::to_vec_of_serde_values; +use crate::utils::{to_vec_of_serde_values, WithJsError}; use crate::MetadataWasm; pub use identity_public_key::*; @@ -173,8 +173,8 @@ impl IdentityWasm { .public_keys .values() .map(|pk| pk.to_json()) - .collect::, SerdeParsingError>>() - .map_err(|e| from_dpp_err(e.into()))?; + .collect::, ProtocolError>>() + .with_js_error()?; let mut identity_json = serde_json::to_value(self.0.clone()).map_err(|e| from_dpp_err(e.into()))?; From 21b925eeddd535e3cedb3ac39259aef0c66aaf70 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 01:23:31 +0700 Subject: [PATCH 168/228] more fixes --- packages/rs-dpp/src/identity/factory.rs | 2 +- packages/rs-dpp/src/identity/identity.rs | 20 +++++-------------- ...ate_state_transition_identity_signature.rs | 16 +++++++-------- .../src/tests/fixtures/identity_fixture.rs | 2 +- .../src/tests/identity/identity_spec.rs | 2 +- 5 files changed, 16 insertions(+), 26 deletions(-) diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index 9d1cd8205b2..c3ec708ed6e 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -134,7 +134,7 @@ where } } - Identity::from_raw_object(raw_identity) + Identity::from_object(raw_identity) } pub fn create_from_buffer( diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index a6a90d8fadb..e416b98cea7 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -1,5 +1,5 @@ use std::collections::BTreeMap; -use std::convert::TryFrom; +use std::convert::{TryFrom, TryInto}; use ciborium::value::Value as CborValue; use integer_encoding::VarInt; @@ -300,24 +300,14 @@ impl Identity { } /// Creates an identity from a raw object - pub fn from_raw_object(raw_object: Value) -> Result { - let identity: Identity = platform_value::from_value(raw_object)?; - - Ok(identity) + pub fn from_object(raw_object: Value) -> Result { + raw_object.try_into() } /// Creates an identity from a json object pub fn from_json_object(raw_object: JsonValue) -> Result { - let pks = raw_object.get("publicKeys").unwrap().as_array().unwrap(); - - for pk in pks { - let _pkd: IdentityPublicKey = serde_json::from_value(pk.clone()) - .map_err(|_e| ProtocolError::Generic(format!("Can't parse public key: {}", pk)))?; - } - - let identity: Identity = serde_json::from_value(raw_object)?; - - Ok(identity) + let value: Value = raw_object.into(); + value.try_into() } /// Computes the hash of an identity diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs index 623f874c220..d05ae3e99f5 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs @@ -313,7 +313,7 @@ mod test { let bls = NativeBlsModule::default(); let mut state_repository_mock = MockStateRepositoryLike::new(); let raw_identity = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(raw_identity).unwrap(); + let identity = Identity::from_object(raw_identity).unwrap(); let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); @@ -338,7 +338,7 @@ mod test { let bls = NativeBlsModule::default(); let mut state_repository_mock = MockStateRepositoryLike::new(); let raw_identity = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(raw_identity).unwrap(); + let identity = Identity::from_object(raw_identity).unwrap(); let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); @@ -370,7 +370,7 @@ mod test { let bls = NativeBlsModule::default(); let mut state_repository_mock = MockStateRepositoryLike::new(); let raw_identity = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(raw_identity).unwrap(); + let identity = Identity::from_object(raw_identity).unwrap(); let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); @@ -402,7 +402,7 @@ mod test { let bls = NativeBlsModule::default(); let mut state_repository_mock = MockStateRepositoryLike::new(); let raw_identity = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(raw_identity).unwrap(); + let identity = Identity::from_object(raw_identity).unwrap(); let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); @@ -435,7 +435,7 @@ mod test { // 'should return InvalidSignaturePublicKeySecurityLevelConsensusError if InvalidSignaturePublicKeySecurityLevelError was thrown' let mut state_repository_mock = MockStateRepositoryLike::new(); let raw_identity = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(raw_identity).unwrap(); + let identity = Identity::from_object(raw_identity).unwrap(); let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); @@ -465,7 +465,7 @@ mod test { let bls = NativeBlsModule::default(); let mut state_repository_mock = MockStateRepositoryLike::new(); let raw_identity = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(raw_identity).unwrap(); + let identity = Identity::from_object(raw_identity).unwrap(); let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); @@ -493,7 +493,7 @@ mod test { // 'should return PubicKeySecurityLevelNotMetConsensusError if PubicKeySecurityLevelNotMetError was thrown' let mut state_repository_mock = MockStateRepositoryLike::new(); let raw_identity = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(raw_identity).unwrap(); + let identity = Identity::from_object(raw_identity).unwrap(); let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); @@ -524,7 +524,7 @@ mod test { // 'should return PublicKeyIsDisabledConsensusError if PublicKeyIsDisabledError was thrown' let mut state_repository_mock = MockStateRepositoryLike::new(); let raw_identity = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(raw_identity).unwrap(); + let identity = Identity::from_object(raw_identity).unwrap(); let owner_id = identity.get_id(); let mut state_transition = get_mock_state_transition(); diff --git a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs index de75cc522ca..41bd18987ef 100644 --- a/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/identity_fixture.rs @@ -64,5 +64,5 @@ pub fn identity_fixture_json() -> serde_json::Value { pub fn identity_fixture() -> Identity { let raw_object = identity_fixture_raw_object(); - Identity::from_raw_object(raw_object).unwrap() + Identity::from_object(raw_object).unwrap() } diff --git a/packages/rs-dpp/src/tests/identity/identity_spec.rs b/packages/rs-dpp/src/tests/identity/identity_spec.rs index 1747aa1b02f..f0cbf3eadea 100644 --- a/packages/rs-dpp/src/tests/identity/identity_spec.rs +++ b/packages/rs-dpp/src/tests/identity/identity_spec.rs @@ -151,7 +151,7 @@ mod conversions { fn from_raw_object() { let identity_fixture = identity_fixture_raw_object(); - let identity = Identity::from_raw_object(identity_fixture) + let identity = Identity::from_object(identity_fixture) .expect("Expected from_raw_object to parse an Object"); assert_eq!( From 3d629d20b3990757c2316b806d3e8ad9d15ddd9d Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 01:31:52 +0700 Subject: [PATCH 169/228] more work --- packages/rs-dpp/src/convertible.rs | 2 +- packages/rs-dpp/src/identity/identity.rs | 39 ++++++++++++++----- .../wasm-dpp/src/identity/identity_facade.rs | 2 +- packages/wasm-dpp/src/identity/mod.rs | 2 +- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/packages/rs-dpp/src/convertible.rs b/packages/rs-dpp/src/convertible.rs index f4125729810..0116caeb64b 100644 --- a/packages/rs-dpp/src/convertible.rs +++ b/packages/rs-dpp/src/convertible.rs @@ -15,7 +15,7 @@ pub trait Convertible { /// - Identifiers - with base58 /// - Binary data - with base64 fn to_json(&self) -> Result; - /// Returns the cibor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing + /// Returns the cbor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing /// the Protocol Version fn to_buffer(&self) -> Result, ProtocolError>; } diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index e416b98cea7..0764ee944c0 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -13,7 +13,9 @@ use crate::prelude::Revision; use crate::util::cbor_value::{CborBTreeMapHelper, CborCanonicalMap}; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; -use crate::{errors::ProtocolError, identifier::Identifier, metadata::Metadata, util::hash}; +use crate::{ + errors::ProtocolError, identifier::Identifier, metadata::Metadata, util::hash, Convertible, +}; use super::{IdentityPublicKey, KeyID}; @@ -84,6 +86,32 @@ mod public_key_serialization { } } +impl Convertible for Identity { + fn to_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + + fn into_object(self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + + fn to_json_object(&self) -> Result { + self.to_object()? + .try_into_validating_json() + .map_err(ProtocolError::ValueError) + } + + fn to_json(&self) -> Result { + self.to_object()? + .try_into() + .map_err(ProtocolError::ValueError) + } + + fn to_buffer(&self) -> Result, ProtocolError> { + self.to_cbor() + } +} + impl Identity { /// Get Identity protocol version pub fn get_protocol_version(&self) -> u32 { @@ -195,11 +223,6 @@ impl Identity { self.public_keys.keys().copied().max().unwrap_or_default() } - /// Converts the identity to a cbor buffer (same as to_cbor) - pub fn to_buffer(&self) -> Result, ProtocolError> { - self.to_cbor() - } - /// Converts the identity to a cbor buffer pub fn to_cbor(&self) -> Result, ProtocolError> { // Prepend protocol version to the result @@ -226,10 +249,6 @@ impl Identity { Ok(buf) } - pub fn to_object(&self) -> Result { - platform_value::to_value(self).map_err(ProtocolError::ValueError) - } - pub fn from_buffer(b: impl AsRef<[u8]>) -> Result { Self::from_cbor(b.as_ref()) } diff --git a/packages/wasm-dpp/src/identity/identity_facade.rs b/packages/wasm-dpp/src/identity/identity_facade.rs index b68fee7ee0f..ddc02fe5352 100644 --- a/packages/wasm-dpp/src/identity/identity_facade.rs +++ b/packages/wasm-dpp/src/identity/identity_facade.rs @@ -23,7 +23,7 @@ use crate::{ use dpp::dashcore::{consensus, InstantLock, Transaction}; use dpp::version::ProtocolVersionValidator; -use dpp::NonConsensusError; +use dpp::{Convertible, NonConsensusError}; use serde::Deserialize; #[derive(Clone)] diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index 6dfe787651e..1edccf61ceb 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -12,7 +12,7 @@ use dpp::identity::state_transition::asset_lock_proof::AssetLockProof; use dpp::identity::IdentityPublicKey; use dpp::identity::{Identity, KeyID}; use dpp::metadata::Metadata; -use dpp::{ProtocolError, SerdeParsingError}; +use dpp::{Convertible, ProtocolError, SerdeParsingError}; use crate::errors::from_dpp_err; use crate::identifier::IdentifierWrapper; From 3419cbe69d051bc7ff639d360a200cfb29d09b8c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 02:51:18 +0700 Subject: [PATCH 170/228] more fixes --- packages/rs-dpp/src/convertible.rs | 1 + .../rs-dpp/src/data_contract/data_contract.rs | 8 ++++++++ packages/rs-dpp/src/identity/identity.rs | 5 +++++ packages/rs-platform-value/src/lib.rs | 14 ++++++++++++++ .../src/data_contract/data_contract.rs | 6 +++--- .../validation.rs | 1 + .../src/identity/identity_public_key/mod.rs | 11 +++++++---- .../identity_public_key_transitions.rs | 9 ++++++--- ...ntractCreateTransitionBasicFactory.spec.js | 2 +- .../test/unit/identity/Identity.spec.js | 19 ++++++++++--------- 10 files changed, 56 insertions(+), 20 deletions(-) diff --git a/packages/rs-dpp/src/convertible.rs b/packages/rs-dpp/src/convertible.rs index 0116caeb64b..8313dceb7d0 100644 --- a/packages/rs-dpp/src/convertible.rs +++ b/packages/rs-dpp/src/convertible.rs @@ -6,6 +6,7 @@ use crate::ProtocolError; pub trait Convertible { /// Returns the [`platform_value::Value`] instance on an object fn to_object(&self) -> Result; + fn to_cleaned_object(&self) -> Result; /// Returns the [`platform_value::Value`] instance on an object fn into_object(self) -> Result; /// Returns the [`serde_json::Value`] instance that preserves the `Vec` representation diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index e3f3f07d0d5..06d6cdffd1d 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -46,6 +46,14 @@ impl Convertible for DataContract { platform_value::to_value(self).map_err(ProtocolError::ValueError) } + fn to_cleaned_object(&self) -> Result { + let mut value = platform_value::to_value(self).map_err(ProtocolError::ValueError)?; + if self.defs.is_none() { + value.remove(property_names::DEFINITIONS)?; + } + Ok(value) + } + fn into_object(self) -> Result { platform_value::to_value(self).map_err(ProtocolError::ValueError) } diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 0764ee944c0..531965520d2 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -91,6 +91,11 @@ impl Convertible for Identity { platform_value::to_value(self).map_err(ProtocolError::ValueError) } + fn to_cleaned_object(&self) -> Result { + //same as object for Identities + self.to_object() + } + fn into_object(self) -> Result { platform_value::to_value(self).map_err(ProtocolError::ValueError) } diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 7e0781a7a6a..e14508779b3 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -353,6 +353,10 @@ impl Value { Value::Bytes(vec) => Ok(vec), Value::Bytes32(vec) => Ok(vec.to_vec()), Value::Identifier(vec) => Ok(vec.to_vec()), + Value::Array(array) => Ok(array + .into_iter() + .map(|byte| byte.into_integer()) + .collect::, Error>>()?), _other => Err(Error::StructureError("value are not bytes".to_string())), } } @@ -374,6 +378,10 @@ impl Value { Value::Bytes(vec) => Ok(vec.clone()), Value::Bytes32(vec) => Ok(vec.to_vec()), Value::Identifier(vec) => Ok(vec.to_vec()), + Value::Array(array) => Ok(array + .iter() + .map(|byte| byte.to_integer()) + .collect::, Error>>()?), other => Err(Error::StructureError(format!( "ref value are not bytes found {} instead", other @@ -399,6 +407,12 @@ impl Value { Value::Bytes(vec) => Ok(BinaryData::new(vec.clone())), Value::Bytes32(vec) => Ok(BinaryData::new(vec.to_vec())), Value::Identifier(vec) => Ok(BinaryData::new(vec.to_vec())), + Value::Array(array) => Ok(BinaryData::new( + array + .iter() + .map(|byte| byte.to_integer()) + .collect::, Error>>()?, + )), other => Err(Error::StructureError(format!( "ref value are not bytes found {} instead", other diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index ef3fea8b686..a53ff4baeda 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -268,9 +268,9 @@ impl DataContractWasm { #[wasm_bindgen(js_name=toObject)] pub fn to_object(&self) -> Result { - let serializer = - serde_wasm_bindgen::Serializer::json_compatible().serialize_bytes_as_arrays(false); - let object = with_js_error!(self.0.serialize(&serializer))?; + let value = self.0.to_cleaned_object().with_js_error()?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + let object = with_js_error!(value.serialize(&serializer))?; js_sys::Reflect::set( &object, diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs index 90d08ed2fc6..9301b1e4138 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use dpp::platform_value::Value; use dpp::{ data_contract::state_transition::data_contract_create_transition::validation::state::{ validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index d84751fb6c8..778ed88755f 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -1,13 +1,15 @@ use dpp::dashcore::anyhow; +use dpp::document::document_transition::document_base_transition::JsonValue; pub use serde::{Deserialize, Serialize}; use std::convert::{TryFrom, TryInto}; use wasm_bindgen::prelude::*; use crate::errors::from_dpp_err; -use crate::utils::Inner; +use crate::utils::{Inner, WithJsError}; use crate::{buffer::Buffer, utils}; use dpp::identity::{IdentityPublicKey, KeyID}; use dpp::platform_value::BinaryData; +use dpp::ProtocolError; mod purpose; pub use purpose::*; @@ -28,10 +30,11 @@ impl IdentityPublicKeyWasm { #[wasm_bindgen(constructor)] pub fn new(raw_public_key: JsValue) -> Result { let data_string = utils::stringify(&raw_public_key)?; - let pk: IdentityPublicKeyWasm = - serde_json::from_str(&data_string).map_err(|e| e.to_string())?; + let value: JsonValue = serde_json::from_str(&data_string).map_err(|e| e.to_string())?; - Ok(pk) + let pk = IdentityPublicKey::from_json_object(value).with_js_error()?; + + Ok(IdentityPublicKeyWasm(pk)) } #[wasm_bindgen(js_name=getId)] diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 7b27fe2f6c7..f2a560773fe 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -1,5 +1,6 @@ //todo: move this file to transition use dpp::dashcore::anyhow; +use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::platform_value::BinaryData; pub use serde::{Deserialize, Serialize}; @@ -7,6 +8,7 @@ use std::convert::{TryFrom, TryInto}; use wasm_bindgen::prelude::*; use crate::errors::from_dpp_err; +use crate::utils::WithJsError; use crate::{buffer::Buffer, utils, with_js_error}; #[derive(Deserialize, Default)] @@ -24,10 +26,11 @@ impl IdentityPublicKeyCreateTransitionWasm { #[wasm_bindgen(constructor)] pub fn new(raw_public_key: JsValue) -> Result { let data_string = utils::stringify(&raw_public_key)?; - let pk: IdentityPublicKeyCreateTransitionWasm = - serde_json::from_str(&data_string).map_err(|e| e.to_string())?; + let value: JsonValue = serde_json::from_str(&data_string).map_err(|e| e.to_string())?; - Ok(pk) + let pk = IdentityPublicKeyWithWitness::from_json_object(value).with_js_error()?; + + Ok(IdentityPublicKeyCreateTransitionWasm(pk)) } #[wasm_bindgen(js_name=getId)] diff --git a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js index 1ad9eab98cf..38c46c678dd 100644 --- a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js @@ -128,7 +128,7 @@ describe('validateDataContractCreateTransitionBasicFactory', () => { it('should be valid', async () => { const result = await validateDataContractCreateTransitionBasic(rawStateTransition); - + console.log(result.errorsText()); expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); }); diff --git a/packages/wasm-dpp/test/unit/identity/Identity.spec.js b/packages/wasm-dpp/test/unit/identity/Identity.spec.js index 7e3a9b1c358..12b5b8d74f4 100644 --- a/packages/wasm-dpp/test/unit/identity/Identity.spec.js +++ b/packages/wasm-dpp/test/unit/identity/Identity.spec.js @@ -257,16 +257,17 @@ describe('Identity', () => { describe('#getPublicKeyMaxId', () => { it('should get the biggest public key ID', () => { + const key = new IdentityPublicKey({ + id: 99, + type: KeyType.ECDSA_SECP256K1, + data: Buffer.alloc(36).fill('a'), + purpose: KeyPurpose.AUTHENTICATION, + securityLevel: KeySecurityLevel.MASTER, + signature: Buffer.alloc(36).fill('a'), + readOnly: false, + }); identity.addPublicKeys( - new IdentityPublicKey({ - id: 99, - type: KeyType.ECDSA_SECP256K1, - data: Buffer.alloc(36).fill('a'), - purpose: KeyPurpose.AUTHENTICATION, - securityLevel: KeySecurityLevel.MASTER, - signature: Buffer.alloc(36).fill('a'), - readOnly: false, - }), + key, new IdentityPublicKey({ id: 50, type: KeyType.ECDSA_SECP256K1, From 442764066d1b32cec661d3607d7b3c892e4cab15 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 04:05:32 +0700 Subject: [PATCH 171/228] more fixes --- .../data_contract_create_transition/mod.rs | 21 +++++- .../data_contract_update_transition/mod.rs | 21 +++++- .../document_base_transition.rs | 5 ++ .../document_create_transition.rs | 6 +- .../document_delete_transition.rs | 4 + .../document_replace_transition.rs | 6 +- .../document_transition/mod.rs | 4 + .../documents_batch_transition/mod.rs | 19 +++++ .../src/identity/identity_public_key/mod.rs | 68 +++++++++++------ .../identity_create_transition.rs | 24 +++++- .../mod.rs | 12 ++- .../identity_public_key_transitions.rs | 73 ++++++++++--------- .../identity_topup_transition.rs | 14 +++- .../identity_update_transition.rs | 6 +- .../abstract_state_transition.rs | 5 ++ ...stract_state_transition_identity_signed.rs | 6 +- packages/rs-dpp/src/state_transition/mod.rs | 7 +- ...ate_state_transition_identity_signature.rs | 10 +-- .../src/data_contract/data_contract.rs | 3 +- .../src/identity/identity_public_key/mod.rs | 4 +- .../identity_public_key_transitions.rs | 1 + 21 files changed, 244 insertions(+), 75 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index f8c27ee8f04..60b4b64f872 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -199,7 +199,7 @@ impl StateTransitionConvert for DataContractCreateTransition { } fn to_json(&self, skip_signature: bool) -> Result { - self.to_object(skip_signature) + self.to_cleaned_object(skip_signature) .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } @@ -218,6 +218,25 @@ impl StateTransitionConvert for DataContractCreateTransition { object.insert(String::from(DATA_CONTRACT), self.data_contract.to_object()?)?; Ok(object) } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + let mut object: Value = platform_value::to_value(self)?; + if skip_signature { + Self::signature_property_paths() + .into_iter() + .try_for_each(|path| { + object + .remove_value_at_path(path) + .map_err(ProtocolError::ValueError) + .map(|_| ()) + })?; + } + object.insert( + String::from(DATA_CONTRACT), + self.data_contract.to_cleaned_object()?, + )?; + Ok(object) + } } #[cfg(test)] diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 3c38ef47867..8d7cc57c951 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -181,7 +181,7 @@ impl StateTransitionConvert for DataContractUpdateTransition { } fn to_json(&self, skip_signature: bool) -> Result { - self.to_object(skip_signature) + self.to_cleaned_object(skip_signature) .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } @@ -200,6 +200,25 @@ impl StateTransitionConvert for DataContractUpdateTransition { object.insert(String::from(DATA_CONTRACT), self.data_contract.to_object()?)?; Ok(object) } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + let mut object: Value = platform_value::to_value(self)?; + if skip_signature { + Self::signature_property_paths() + .into_iter() + .try_for_each(|path| { + object + .remove_value_at_path(path) + .map_err(ProtocolError::ValueError) + .map(|_| ()) + })?; + } + object.insert( + String::from(DATA_CONTRACT), + self.data_contract.to_cleaned_object()?, + )?; + Ok(object) + } } #[cfg(test)] diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs index c579655e1d1..6d48c47c1c8 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_base_transition.rs @@ -204,6 +204,10 @@ impl DocumentTransitionObjectLike for DocumentBaseTransition { .try_into() .map_err(ProtocolError::ValueError) } + + fn to_cleaned_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } } pub trait DocumentTransitionObjectLike { @@ -239,4 +243,5 @@ pub trait DocumentTransitionObjectLike { /// - base58 string for Identifiers /// - base64 string for other binary data fn to_json(&self) -> Result; + fn to_cleaned_object(&self) -> Result; } diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 0a877b202af..0226b1091de 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -190,10 +190,14 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { } fn to_json(&self) -> Result { - self.to_object()? + self.to_cleaned_object()? .try_into() .map_err(ProtocolError::ValueError) } + + fn to_cleaned_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } } #[cfg(test)] diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs index 54db8790a8f..492e079e951 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_delete_transition.rs @@ -58,6 +58,10 @@ impl DocumentTransitionObjectLike for DocumentDeleteTransition { fn to_json(&self) -> Result { self.base.to_json() } + + fn to_cleaned_object(&self) -> Result { + self.base.to_cleaned_object() + } } #[cfg(test)] diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index 26380fbdd6a..c980ca983e2 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -186,10 +186,14 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { } fn to_json(&self) -> Result { - self.to_object()? + self.to_cleaned_object()? .try_into() .map_err(ProtocolError::ValueError) } + + fn to_cleaned_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } } #[cfg(test)] diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs index 885909bf8e0..04543cff022 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/mod.rs @@ -145,6 +145,10 @@ impl DocumentTransitionObjectLike for DocumentTransition { call_method!(self, to_object) } + fn to_cleaned_object(&self) -> Result { + call_method!(self, to_cleaned_object) + } + fn from_value_map( map: BTreeMap, data_contract: DataContract, diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 2758aa5b7fe..06ab17c22e8 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -443,6 +443,25 @@ impl StateTransitionConvert for DocumentsBatchTransition { Ok(result_buf) } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + let mut object: Value = platform_value::to_value(self)?; + if skip_signature { + for path in Self::signature_property_paths() { + let _ = object.remove(path); + } + } + let mut transitions = vec![]; + for transition in self.transitions.iter() { + transitions.push(transition.to_cleaned_object()?) + } + object.insert( + String::from(property_names::TRANSITIONS), + Value::Array(transitions), + )?; + + Ok(object) + } } impl StateTransitionLike for DocumentsBatchTransition { diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index 7b6a319efdb..31f7c06e965 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -11,7 +11,7 @@ use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; use ciborium::value::Value as CborValue; use dashcore::PublicKey as ECDSAPublicKey; -use platform_value::{BinaryData, ReplacementType, Value}; +use platform_value::{BinaryData, ReplacementType, Value, ValueMapHelper}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; @@ -21,9 +21,8 @@ pub use crate::identity::purpose::Purpose; pub use crate::identity::security_level::SecurityLevel; use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; use crate::util::hash::ripemd160_sha256; -use crate::util::json_value::JsonValueExt; -use crate::util::vec; -use crate::SerdeParsingError; +use crate::util::{serializer, vec}; +use crate::Convertible; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; @@ -60,6 +59,48 @@ impl Into for &IdentityPublicKey { } } +impl Convertible for IdentityPublicKey { + fn to_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + + fn to_cleaned_object(&self) -> Result { + let mut value = platform_value::to_value(self).map_err(ProtocolError::ValueError)?; + if self.disabled_at.is_none() { + value + .remove("disabledAt") + .map_err(ProtocolError::ValueError)?; + } + Ok(value) + } + + fn into_object(self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + + fn to_json_object(&self) -> Result { + self.to_cleaned_object()? + .try_into_validating_json() + .map_err(ProtocolError::ValueError) + } + + fn to_json(&self) -> Result { + self.to_cleaned_object()? + .try_into() + .map_err(ProtocolError::ValueError) + } + + fn to_buffer(&self) -> Result, ProtocolError> { + let mut object = self.to_cleaned_object()?; + object + .to_map_mut() + .unwrap() + .sort_by_lexicographical_byte_ordering_keys_and_inner_maps(); + + serializer::serializable_value_to_cbor(&object, None) + } +} + impl IdentityPublicKey { /// Set disabledAt pub fn set_disabled_at(&mut self, timestamp_millis: u64) { @@ -125,25 +166,6 @@ impl IdentityPublicKey { Self::from_value(value) } - /// Return raw data, with all binary fields represented as arrays - pub fn to_raw_json_object(&self) -> Result { - let mut value = serde_json::to_value(self)?; - - if self.disabled_at.is_none() { - if let JsonValue::Object(ref mut o) = value { - o.remove("disabledAt"); - } - } - - Ok(value) - } - - /// Return json with all binary data converted to base64 - pub fn to_json(&self) -> Result { - let value: Value = self.try_into()?; - value.try_into().map_err(ProtocolError::ValueError) - } - pub fn from_cbor_value(cbor_value: &CborValue) -> Result { let key_value_map = cbor_value.as_map().ok_or_else(|| { ProtocolError::DecodingError(String::from( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 804b88a4e4a..472fc38d742 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -236,9 +236,31 @@ impl StateTransitionConvert for IdentityCreateTransition { } fn to_json(&self, skip_signature: bool) -> Result { - self.to_object(skip_signature) + self.to_cleaned_object(skip_signature) .and_then(|v| v.try_into().map_err(ProtocolError::ValueError)) } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + let mut value: Value = platform_value::to_value(self)?; + + if skip_signature { + value + .remove_values_at_paths(Self::signature_property_paths()) + .map_err(ProtocolError::ValueError)?; + } + + let mut public_keys: Vec = vec![]; + for key in self.public_keys.iter() { + public_keys.push(key.to_raw_object(skip_signature)?); + } + + value.insert( + property_names::PUBLIC_KEYS.to_owned(), + Value::Array(public_keys), + )?; + + Ok(value) + } } impl StateTransitionLike for IdentityCreateTransition { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index 534f9d05894..e5849faadce 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -190,7 +190,17 @@ impl StateTransitionConvert for IdentityCreditWithdrawalTransition { } fn to_json(&self, skip_signature: bool) -> Result { - self.to_object(skip_signature) + self.to_cleaned_object(skip_signature) .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + let mut value = platform_value::to_value(self)?; + if skip_signature { + value + .remove_many(&Self::signature_property_paths()) + .map_err(ProtocolError::ValueError)?; + } + Ok(value) + } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index f8651ddc6e5..9381aff56a2 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -5,13 +5,14 @@ use std::convert::{TryFrom, TryInto}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::{BinaryData, ReplacementType, Value}; +use platform_value::{BinaryData, ReplacementType, Value, ValueMapHelper}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::errors::ProtocolError; use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; -use crate::SerdeParsingError; +use crate::util::serializer; +use crate::{Convertible, SerdeParsingError}; pub const BINARY_DATA_FIELDS: [&str; 2] = ["data", "signature"]; @@ -29,6 +30,42 @@ pub struct IdentityPublicKeyWithWitness { pub signature: BinaryData, } +impl Convertible for IdentityPublicKeyWithWitness { + fn to_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + + fn to_cleaned_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + + fn into_object(self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + + fn to_json_object(&self) -> Result { + self.to_cleaned_object()? + .try_into_validating_json() + .map_err(ProtocolError::ValueError) + } + + fn to_json(&self) -> Result { + self.to_cleaned_object()? + .try_into() + .map_err(ProtocolError::ValueError) + } + + fn to_buffer(&self) -> Result, ProtocolError> { + let mut object = self.to_cleaned_object()?; + object + .to_map_mut() + .unwrap() + .sort_by_lexicographical_byte_ordering_keys_and_inner_maps(); + + serializer::serializable_value_to_cbor(&object, None) + } +} + impl IdentityPublicKeyWithWitness { pub fn to_identity_public_key(self) -> IdentityPublicKey { let Self { @@ -53,32 +90,6 @@ impl IdentityPublicKeyWithWitness { pub fn from_raw_object(raw_object: Value) -> Result { raw_object.try_into().map_err(ProtocolError::ValueError) - // Ok(Self { - // id: raw_object - // .get_integer("id") - // .map_err(ProtocolError::ValueError)?, - // purpose: raw_object - // .get_integer::("purpose") - // .map_err(ProtocolError::ValueError)? - // .try_into()?, - // security_level: raw_object - // .get_integer::("securityLevel") - // .map_err(ProtocolError::ValueError)? - // .try_into()?, - // key_type: raw_object - // .get_integer::("keyType") - // .map_err(ProtocolError::ValueError)? - // .try_into()?, - // data: raw_object - // .remove_bytes("data") - // .map_err(ProtocolError::ValueError)?, - // read_only: raw_object - // .get_bool("readOnly") - // .map_err(ProtocolError::ValueError)?, - // signature: raw_object - // .remove_bytes("signature") - // .map_err(ProtocolError::ValueError)?, - // }) } pub fn from_value_map(mut value_map: BTreeMap) -> Result { @@ -157,12 +168,6 @@ impl IdentityPublicKeyWithWitness { Into::::into(self).hash() } - /// Return json with all binary data converted to base64 - pub fn to_json(&self) -> Result { - let value: Value = self.try_into()?; - value.try_into().map_err(ProtocolError::ValueError) - } - pub fn from_cbor_value(cbor_value: &CborValue) -> Result { let key_value_map = cbor_value.as_map().ok_or_else(|| { ProtocolError::DecodingError(String::from( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index f53a4bee7a8..ecb0267ef51 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -155,9 +155,21 @@ impl StateTransitionConvert for IdentityTopUpTransition { } fn to_json(&self, skip_signature: bool) -> Result { - self.to_object(skip_signature) + self.to_cleaned_object(skip_signature) .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + let mut value: Value = platform_value::to_value(self)?; + + if skip_signature { + value + .remove_values_at_paths(Self::signature_property_paths()) + .map_err(ProtocolError::ValueError)?; + } + + Ok(value) + } } impl StateTransitionLike for IdentityTopUpTransition { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 00a63ef5a0b..94ec80238a4 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -264,9 +264,13 @@ impl StateTransitionConvert for IdentityUpdateTransition { } fn to_json(&self, skip_signature: bool) -> Result { - self.to_object(skip_signature) + self.to_cleaned_object(skip_signature) .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + self.to_object(skip_signature) + } } impl StateTransitionLike for IdentityUpdateTransition { diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index f7a757818a5..574e625085b 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -7,6 +7,7 @@ use serde::Serialize; use serde_json::Value as JsonValue; use crate::consensus::ConsensusError; +use crate::data_contract::state_transition::property_names::DATA_CONTRACT; use crate::errors::consensus::signature::SignatureError; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, StateTransitionIsNotSignedError, @@ -242,6 +243,10 @@ pub trait StateTransitionConvert: Serialize { fn hash(&self, skip_signature: bool) -> Result, ProtocolError> { Ok(hash::hash(self.to_buffer(skip_signature)?)) } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + self.to_object(skip_signature) + } } pub mod state_transition_helpers { diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index da97a025639..7f3c19abdaa 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -187,7 +187,7 @@ pub fn get_compressed_public_ec_key(private_key: &[u8]) -> Result<[u8; 33], Prot mod test { use bls_signatures::Serialize as BlsSerialize; use chrono::Utc; - use platform_value::BinaryData; + use platform_value::{BinaryData, Value}; use serde::{Deserialize, Serialize}; use serde_json::json; use std::convert::TryInto; @@ -230,6 +230,10 @@ mod test { fn signature_property_paths() -> Vec<&'static str> { vec!["signature", "signaturePublicKeyId"] } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + todo!() + } } impl From for StateTransition { diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 2978b079ba1..baf0711e8ec 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -4,7 +4,7 @@ pub use abstract_state_transition::{ state_transition_helpers, StateTransitionConvert, StateTransitionLike, }; pub use abstract_state_transition_identity_signed::StateTransitionIdentitySigned; -use platform_value::BinaryData; +use platform_value::{BinaryData, Value}; pub use state_transition_types::*; use crate::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; @@ -20,6 +20,7 @@ mod abstract_state_transition; mod abstract_state_transition_identity_signed; mod state_transition_facade; mod state_transition_factory; +use crate::ProtocolError; pub use state_transition_facade::*; pub use state_transition_factory::*; @@ -130,6 +131,10 @@ impl StateTransitionConvert for StateTransition { fn binary_property_paths() -> Vec<&'static str> { panic!("Static call is not supported") } + + fn to_cleaned_object(&self, skip_signature: bool) -> Result { + call_method!(self, to_cleaned_object, skip_signature) + } } impl StateTransitionLike for StateTransition { diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs index d05ae3e99f5..6b00637e6ed 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs @@ -163,7 +163,7 @@ mod test { }, NativeBlsModule, }; - use platform_value::BinaryData; + use platform_value::{BinaryData, Value}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -181,14 +181,14 @@ mod test { } impl StateTransitionConvert for ExampleStateTransition { - fn binary_property_paths() -> Vec<&'static str> { - vec!["signature"] + fn signature_property_paths() -> Vec<&'static str> { + vec!["signature", "signaturePublicKeyId"] } fn identifiers_property_paths() -> Vec<&'static str> { vec![] } - fn signature_property_paths() -> Vec<&'static str> { - vec!["signature", "signaturePublicKeyId"] + fn binary_property_paths() -> Vec<&'static str> { + vec!["signature"] } } diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index a53ff4baeda..6efab925999 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -289,8 +289,9 @@ impl DataContractWasm { #[wasm_bindgen(js_name=toJSON)] pub fn to_json(&self) -> Result { + let json = self.0.to_json().with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - with_js_error!(self.0.serialize(&serializer)) + with_js_error!(json.serialize(&serializer)) } #[wasm_bindgen(js_name=toBuffer)] diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index 778ed88755f..74b2d92b170 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -9,7 +9,7 @@ use crate::utils::{Inner, WithJsError}; use crate::{buffer::Buffer, utils}; use dpp::identity::{IdentityPublicKey, KeyID}; use dpp::platform_value::BinaryData; -use dpp::ProtocolError; +use dpp::{Convertible, ProtocolError}; mod purpose; pub use purpose::*; @@ -139,7 +139,7 @@ impl IdentityPublicKeyWasm { pub fn to_object(&self) -> Result { let val = self .0 - .to_raw_json_object() + .to_json_object() .map_err(|e| from_dpp_err(e.into()))?; let data_buffer = Buffer::from_bytes(self.0.data.as_slice()); diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs index f2a560773fe..46e57bf3f18 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -3,6 +3,7 @@ use dpp::dashcore::anyhow; use dpp::document::document_transition::document_base_transition::JsonValue; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::platform_value::BinaryData; +use dpp::Convertible; pub use serde::{Deserialize, Serialize}; use std::convert::{TryFrom, TryInto}; use wasm_bindgen::prelude::*; From a96fd1dcb732c774243c6993594dae798bac8b86 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 04:41:31 +0700 Subject: [PATCH 172/228] more fixes --- packages/rs-dpp/src/identity/identity.rs | 13 +++-- .../src/data_contract/data_contract.rs | 17 +++---- .../src/data_contract/data_contract_facade.rs | 2 +- .../data_contract_create_transition/mod.rs | 8 +-- .../validation.rs | 3 +- .../data_contract_update_transition/mod.rs | 8 +-- .../validation.rs | 3 +- .../data_contract_factory.rs | 4 +- .../wasm-dpp/src/identity/identity_facade.rs | 12 ++--- .../wasm-dpp/src/identity/identity_factory.rs | 10 ++-- .../src/identity/identity_public_key/mod.rs | 8 ++- packages/wasm-dpp/src/identity/mod.rs | 51 ++++--------------- .../identity_create_transition.rs | 4 +- ...ntity_create_transition_basic_validator.rs | 1 + .../identity_public_key_transitions.rs | 4 +- .../identity_topup_transition.rs | 5 +- .../identity_update_public_keys_validator.rs | 3 +- .../identity_update_transition.rs | 6 +-- ...ntity_update_transition_basic_validator.rs | 1 + ...ntity_update_transition_state_validator.rs | 3 +- .../validate_public_key_signatures.rs | 7 +-- .../identity/validation/identity_validator.rs | 1 + .../state_transition_facade.rs | 18 +++---- .../state_transition_factory.rs | 6 +-- ...validate_state_transition_key_signature.rs | 8 +-- 25 files changed, 88 insertions(+), 118 deletions(-) diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 531965520d2..c193d373f98 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -39,7 +39,6 @@ pub struct Identity { pub public_keys: BTreeMap, pub balance: u64, pub revision: Revision, - #[serde(skip)] pub asset_lock_proof: Option, #[serde(skip)] pub metadata: Option, @@ -93,7 +92,13 @@ impl Convertible for Identity { fn to_cleaned_object(&self) -> Result { //same as object for Identities - self.to_object() + let mut value = self.to_object()?; + if self.asset_lock_proof.is_none() { + value + .remove("assetLockProof") + .map_err(ProtocolError::ValueError)?; + } + Ok(value) } fn into_object(self) -> Result { @@ -101,13 +106,13 @@ impl Convertible for Identity { } fn to_json_object(&self) -> Result { - self.to_object()? + self.to_cleaned_object()? .try_into_validating_json() .map_err(ProtocolError::ValueError) } fn to_json(&self) -> Result { - self.to_object()? + self.to_cleaned_object()? .try_into() .map_err(ProtocolError::ValueError) } diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index 6efab925999..f10f3a9a0d9 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -88,7 +88,7 @@ impl DataContractWasm { DataContract::from_raw_object( platform_value::to_value(parameters).expect("Implements Serialize"), ) - .map_err(from_dpp_err) + .with_js_error() .map(Into::into) } @@ -186,7 +186,7 @@ impl DataContractWasm { #[wasm_bindgen(js_name=getDocumentSchema)] pub fn get_document_schema(&mut self, doc_type: &str) -> Result { - let doc_schema = self.0.get_document_schema(doc_type).map_err(from_dpp_err)?; + let doc_schema = self.0.get_document_schema(doc_type).with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); with_js_error!(doc_schema.serialize(&serializer)) } @@ -194,10 +194,7 @@ impl DataContractWasm { #[wasm_bindgen(js_name=getDocumentSchemaRef)] pub fn get_document_schema_ref(&self, doc_type: &str) -> Result { with_js_error!(serde_wasm_bindgen::to_value( - &self - .0 - .get_document_schema_ref(doc_type) - .map_err(from_dpp_err)? + &self.0.get_document_schema_ref(doc_type).with_js_error()? )) } @@ -252,7 +249,7 @@ impl DataContractWasm { with_js_error!(self .0 .get_binary_properties(doc_type) - .map_err(from_dpp_err)? + .with_js_error()? .serialize(&serializer)) } @@ -296,20 +293,20 @@ impl DataContractWasm { #[wasm_bindgen(js_name=toBuffer)] pub fn to_buffer(&self) -> Result { - let bytes = self.0.to_buffer().map_err(from_dpp_err)?; + let bytes = self.0.to_buffer().with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } #[wasm_bindgen(js_name=hash)] pub fn hash(&self) -> Result, JsValue> { - self.0.hash().map_err(from_dpp_err) + self.0.hash().with_js_error() } #[wasm_bindgen(js_name=from)] pub fn from_js_value(v: JsValue) -> Result { let json_contract: JsonValue = with_js_error!(serde_wasm_bindgen::from_value(v))?; Ok(DataContract::try_from(json_contract) - .map_err(from_dpp_err)? + .with_js_error()? .into()) } diff --git a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs index d2118d700e2..ceaa4f750a3 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs @@ -106,7 +106,7 @@ impl DataContractFacadeWasm { self.0 .create_data_contract_create_transition(data_contract.clone().into()) .map(DataContractCreateTransitionWasm::from) - .map_err(from_protocol_error) + .with_js_error() } /// Create Data Contract Update State Transition diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index bcdbcfe458f..3e44d94566b 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -66,7 +66,7 @@ impl DataContractCreateTransitionWasm { .with_js_error()?; DataContractCreateTransition::from_raw_object(transition_object) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=getDataContract)] @@ -100,7 +100,7 @@ impl DataContractCreateTransitionWasm { Ok(self .0 .to_json(skip_signature.unwrap_or(false)) - .map_err(from_dpp_err)? + .with_js_error()? .serialize(&serializer) .expect("JSON is a valid object")) } @@ -110,7 +110,7 @@ impl DataContractCreateTransitionWasm { let bytes = self .0 .to_buffer(skip_signature.unwrap_or(false)) - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } @@ -168,6 +168,6 @@ impl DataContractCreateTransitionWasm { &private_key, &bls_adapter, ) - .map_err(from_dpp_err) + .with_js_error() } } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs index 9301b1e4138..d3c38662ed7 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs @@ -13,6 +13,7 @@ use dpp::{ }; use wasm_bindgen::prelude::*; +use crate::utils::WithJsError; use crate::validation::ValidationResultWasm; use crate::{ errors::from_dpp_err, @@ -33,7 +34,7 @@ pub async fn validate_data_contract_create_transition_state( &state_transition.into(), ) .await - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 52203c4d428..343d193189e 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -65,7 +65,7 @@ impl DataContractUpdateTransitionWasm { .with_js_error()?; DataContractUpdateTransition::from_raw_object(raw_data_contract_update_transition) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=getDataContract)] @@ -99,7 +99,7 @@ impl DataContractUpdateTransitionWasm { Ok(self .0 .to_json(skip_signature.unwrap_or(false)) - .map_err(from_dpp_err)? + .with_js_error()? .serialize(&serializer) .expect("JSON is a valid object")) } @@ -109,7 +109,7 @@ impl DataContractUpdateTransitionWasm { let bytes = self .0 .to_buffer(skip_signature.unwrap_or(false)) - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } @@ -147,7 +147,7 @@ impl DataContractUpdateTransitionWasm { let bytes = self .0 .hash(skip_signature.unwrap_or(false)) - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index 6507b496a8d..8e577060430 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -14,6 +14,7 @@ use dpp::{ }; use wasm_bindgen::prelude::*; +use crate::utils::WithJsError; use crate::{ data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransitionParameters, errors::{from_dpp_err, protocol_error::from_protocol_error}, @@ -33,7 +34,7 @@ pub async fn validate_data_contract_update_transition_state( &state_transition.into(), ) .await - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(result.map(|_| JsValue::undefined()).into()) } diff --git a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs index 06d04fc924d..88965eb2a90 100644 --- a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs +++ b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs @@ -131,7 +131,7 @@ impl DataContractFactoryWasm { self.0 .create(identifier, documents_object, None, None) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=createFromObject)] @@ -175,6 +175,6 @@ impl DataContractFactoryWasm { self.0 .create_data_contract_create_transition(data_contract.clone().into()) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } } diff --git a/packages/wasm-dpp/src/identity/identity_facade.rs b/packages/wasm-dpp/src/identity/identity_facade.rs index ddc02fe5352..ca6a4665ef7 100644 --- a/packages/wasm-dpp/src/identity/identity_facade.rs +++ b/packages/wasm-dpp/src/identity/identity_facade.rs @@ -13,7 +13,7 @@ use crate::errors::{from_dpp_err, RustConversionError}; use crate::identifier::IdentifierWrapper; use crate::identity::errors::InvalidIdentityError; -use crate::utils::ToSerdeJSONExt; +use crate::utils::{ToSerdeJSONExt, WithJsError}; use crate::validation::ValidationResultWasm; use crate::{ create_asset_lock_proof_from_wasm_instance, with_js_error, ChainAssetLockProofWasm, @@ -60,7 +60,7 @@ impl IdentityFacadeWasm { self.0 .create(asset_lock_proof, public_keys) .map(|identity| identity.into()) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=createFromObject)] @@ -118,7 +118,7 @@ impl IdentityFacadeWasm { #[wasm_bindgen] pub fn validate(&self, identity: IdentityWasm) -> Result { let identity: Identity = identity.into(); - let identity_json = identity.to_object().map_err(from_dpp_err)?; + let identity_json = identity.to_object().with_js_error()?; let validation_result = self .0 @@ -174,7 +174,7 @@ impl IdentityFacadeWasm { self.0 .create_identity_create_transition(Identity::from(identity.to_owned())) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=createIdentityTopUpTransition)] @@ -188,7 +188,7 @@ impl IdentityFacadeWasm { self.0 .create_identity_topup_transition(identity_id.to_owned().into(), asset_lock_proof) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=createIdentityUpdateTransition)] @@ -209,7 +209,7 @@ impl IdentityFacadeWasm { Some(now), ) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } } diff --git a/packages/wasm-dpp/src/identity/identity_factory.rs b/packages/wasm-dpp/src/identity/identity_factory.rs index 6f2b9b0fe0d..01cbaf1fb80 100644 --- a/packages/wasm-dpp/src/identity/identity_factory.rs +++ b/packages/wasm-dpp/src/identity/identity_factory.rs @@ -20,7 +20,7 @@ use std::convert::TryInto; use std::sync::Arc; -use crate::utils::with_serde_to_platform_value; +use crate::utils::{with_serde_to_platform_value, WithJsError}; use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; @@ -56,7 +56,7 @@ impl IdentityFactoryWasm { self.0 .create(asset_lock_proof, public_keys) .map(|identity| identity.into()) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=createFromObject)] @@ -160,7 +160,7 @@ impl IdentityFactoryWasm { self.0 .create_identity_create_transition(Identity::from(identity.to_owned())) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=createIdentityTopUpTransition)] @@ -174,7 +174,7 @@ impl IdentityFactoryWasm { self.0 .create_identity_topup_transition(identity_id.to_owned().into(), asset_lock_proof) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=createIdentityUpdateTransition)] @@ -196,7 +196,7 @@ impl IdentityFactoryWasm { Some(now), ) .map(Into::into) - .map_err(from_dpp_err) + .with_js_error() } } diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index 74b2d92b170..1dd40092bb4 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -4,7 +4,6 @@ pub use serde::{Deserialize, Serialize}; use std::convert::{TryFrom, TryInto}; use wasm_bindgen::prelude::*; -use crate::errors::from_dpp_err; use crate::utils::{Inner, WithJsError}; use crate::{buffer::Buffer, utils}; use dpp::identity::{IdentityPublicKey, KeyID}; @@ -19,6 +18,7 @@ pub use security_level::*; mod key_type; +use crate::errors::from_dpp_err; pub use key_type::*; #[wasm_bindgen(js_name=IdentityPublicKey)] @@ -120,7 +120,7 @@ impl IdentityPublicKeyWasm { #[wasm_bindgen(js_name=hash)] pub fn hash(&self) -> Result, JsValue> { - self.0.hash().map_err(from_dpp_err) + self.0.hash().with_js_error() } #[wasm_bindgen(js_name=isMaster)] @@ -191,9 +191,7 @@ impl TryFrom for IdentityPublicKeyWasm { fn try_from(value: JsValue) -> Result { let str = String::from(js_sys::JSON::stringify(&value)?); let val = serde_json::from_str(&str).map_err(|e| from_dpp_err(e.into()))?; - Ok(Self( - IdentityPublicKey::from_value(val).map_err(from_dpp_err)?, - )) + Ok(Self(IdentityPublicKey::from_value(val).with_js_error()?)) } } diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index 1edccf61ceb..98e1770ef43 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -14,11 +14,10 @@ use dpp::identity::{Identity, KeyID}; use dpp::metadata::Metadata; use dpp::{Convertible, ProtocolError, SerdeParsingError}; -use crate::errors::from_dpp_err; use crate::identifier::IdentifierWrapper; -use crate::utils; use crate::utils::{to_vec_of_serde_values, WithJsError}; use crate::MetadataWasm; +use crate::{utils, with_js_error}; pub use identity_public_key::*; pub use state_transition::*; @@ -168,43 +167,16 @@ impl IdentityWasm { #[wasm_bindgen(js_name=toJSON)] pub fn to_json(&self) -> Result { - let pks = self - .0 - .public_keys - .values() - .map(|pk| pk.to_json()) - .collect::, ProtocolError>>() - .with_js_error()?; - - let mut identity_json = - serde_json::to_value(self.0.clone()).map_err(|e| from_dpp_err(e.into()))?; - - let map = identity_json.as_object_mut().ok_or_else(|| { - from_dpp_err(ProtocolError::Generic( - "Expect identity to be a json map".into(), - )) - })?; - map.insert("publicKeys".into(), serde_json::Value::from(pks)); - - let identity_json_string = - serde_json::to_string(&identity_json).map_err(|e| from_dpp_err(e.into()))?; - - js_sys::JSON::parse(&identity_json_string) + let json = self.0.to_json().with_js_error()?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + with_js_error!(json.serialize(&serializer)) } #[wasm_bindgen(js_name=toObject)] pub fn to_object(&self) -> Result { - let js_public_keys = js_sys::Array::new(); - for pk in self.0.public_keys.values() { - let pk_wasm = IdentityPublicKeyWasm::from(pk.to_owned()); - js_public_keys.push(&pk_wasm.to_object()?); - } - - let identity_json = - serde_json::to_value(self.0.clone()).map_err(|e| from_dpp_err(e.into()))?; - let identity_json_string = - serde_json::to_string(&identity_json).map_err(|e| from_dpp_err(e.into()))?; - let js_object = js_sys::JSON::parse(&identity_json_string)?; + let json = self.0.to_json_object().with_js_error()?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + let js_object = with_js_error!(json.serialize(&serializer))?; let id: IdentifierWrapper = self.0.id.into(); @@ -213,11 +185,6 @@ impl IdentityWasm { &"id".to_owned().into(), &JsValue::from(id.to_buffer()), )?; - js_sys::Reflect::set( - &js_object, - &"publicKeys".to_owned().into(), - &JsValue::from(&js_public_keys), - )?; Ok(js_object) } @@ -229,7 +196,7 @@ impl IdentityWasm { #[wasm_bindgen] pub fn hash(&self) -> Result, JsValue> { - self.0.hash().map_err(from_dpp_err) + self.0.hash().with_js_error() } #[wasm_bindgen(js_name=addPublicKey)] @@ -252,7 +219,7 @@ impl IdentityWasm { .into_iter() .map(IdentityPublicKey::from_json_object) .collect::, ProtocolError>>() - .map_err(from_dpp_err)?; + .with_js_error()?; self.0 .add_public_keys(public_keys.into_iter().map(Into::into)); diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index c2e9b0680fc..bf205e49ca2 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -19,7 +19,7 @@ use crate::{ }; use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; -use crate::errors::from_dpp_err; + use crate::utils::{generic_of_js_val, ToSerdeJSONExt, WithJsError}; use dpp::identity::state_transition::identity_create_transition::{ BINARY_FIELDS, IDENTIFIER_FIELDS, @@ -334,7 +334,7 @@ impl IdentityCreateTransitionWasm { self.0 .sign_by_private_key(private_key.as_slice(), key_type, &bls_adapter) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=getSignature)] diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs index 300b07ec6a9..fa98502d1bb 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs @@ -16,6 +16,7 @@ use std::sync::Arc; use wasm_bindgen::prelude::*; use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; + use crate::errors::from_dpp_err; use crate::utils::ToSerdeJSONExt; use crate::{ diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 46e57bf3f18..55c68c6210b 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -116,7 +116,7 @@ impl IdentityPublicKeyCreateTransitionWasm { #[wasm_bindgen(js_name=hash)] pub fn hash(&self) -> Result, JsValue> { - self.0.hash().map_err(from_dpp_err) + self.0.hash().with_js_error() } #[wasm_bindgen(js_name=isMaster)] @@ -200,7 +200,7 @@ impl TryFrom for IdentityPublicKeyCreateTransitionWasm { let str = String::from(js_sys::JSON::stringify(&value)?); let val = serde_json::from_str(&str).map_err(|e| from_dpp_err(e.into()))?; Ok(Self( - IdentityPublicKeyWithWitness::from_raw_json_object(val).map_err(from_dpp_err)?, + IdentityPublicKeyWithWitness::from_raw_json_object(val).with_js_error()?, )) } } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 3c831afb772..f992b3c7cb0 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -1,4 +1,4 @@ -use crate::utils::ToSerdeJSONExt; +use crate::utils::{ToSerdeJSONExt, WithJsError}; use std::convert::TryInto; use std::default::Default; @@ -19,7 +19,6 @@ use crate::{ }; use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; -use crate::errors::from_dpp_err; use dpp::platform_value::string_encoding; use dpp::platform_value::string_encoding::Encoding; @@ -268,7 +267,7 @@ impl IdentityTopUpTransitionWasm { self.0 .sign_by_private_key(private_key.as_slice(), key_type, &bls_adapter) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=getSignature)] diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs index 4b899a4724c..94d4f8079d6 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_public_keys_validator.rs @@ -1,5 +1,6 @@ use crate::errors::from_dpp_err; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyCreateTransitionWasm; +use crate::utils::WithJsError; use crate::validation::ValidationResultWasm; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::state_transition::identity_update_transition::validate_public_keys::IdentityUpdatePublicKeysValidator; @@ -33,7 +34,7 @@ impl IdentityUpdatePublicKeysValidatorWasm { let parsed_key: IdentityPublicKeyWithWitness = IdentityPublicKeyCreateTransitionWasm::new(raw_key)?.into(); - parsed_key.to_raw_object(false).map_err(from_dpp_err) + parsed_key.to_raw_object(false).with_js_error() }) .collect::, JsValue>>()?; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index af4ade53b15..d0aecbf2e89 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -15,7 +15,7 @@ use crate::{ }; use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; -use crate::errors::from_dpp_err; + use crate::utils::{generic_of_js_val, WithJsError}; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::{KeyID, TimestampMillis}; @@ -415,7 +415,7 @@ impl IdentityUpdateTransitionWasm { self.0 .sign_by_private_key(private_key.as_slice(), key_type, &bls_adapter) - .map_err(from_dpp_err) + .with_js_error() } #[wasm_bindgen(js_name=getSignature)] @@ -447,6 +447,6 @@ impl IdentityUpdateTransitionWasm { &private_key, &bls_adapter, ) - .map_err(from_dpp_err) + .with_js_error() } } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs index a3988f936c5..006f29ff5ae 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs @@ -12,6 +12,7 @@ use wasm_bindgen::prelude::*; use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; + use crate::utils::ToSerdeJSONExt; use crate::validation::ValidationResultWasm; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_state_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_state_validator.rs index 6ab1994cddd..74e388d5c1c 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_state_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_state_validator.rs @@ -1,5 +1,5 @@ use std::sync::Arc; -use crate::errors::from_dpp_err; + use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; use crate::validation::ValidationResultWasm; use crate::{IdentityUpdateTransitionWasm}; @@ -8,6 +8,7 @@ use wasm_bindgen::JsValue; use dpp::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; use dpp::identity::state_transition::identity_update_transition::validate_identity_update_transition_state::IdentityUpdateTransitionStateValidator; use dpp::identity::state_transition::identity_update_transition::validate_public_keys::IdentityUpdatePublicKeysValidator; +use crate::errors::from_dpp_err; #[wasm_bindgen(js_name=IdentityUpdateTransitionStateValidator)] pub struct IdentityUpdateTransitionStateValidatorWasm( diff --git a/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs b/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs index 2667bba29e0..2543c102843 100644 --- a/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs +++ b/packages/wasm-dpp/src/identity/state_transition/validate_public_key_signatures.rs @@ -1,6 +1,6 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; -use crate::errors::from_dpp_err; -use crate::utils::ToSerdeJSONExt; + +use crate::utils::{ToSerdeJSONExt, WithJsError}; use crate::validation::ValidationResultWasm; @@ -12,6 +12,7 @@ use dpp::identity::state_transition::validate_public_key_signatures::{ use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; +use crate::errors::from_dpp_err; use dpp::platform_value::Value; use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; @@ -45,7 +46,7 @@ impl PublicKeysSignaturesValidatorWasm { .map(|raw_key| { let parsed_key: IdentityPublicKeyWithWitness = IdentityPublicKeyCreateTransitionWasm::new(raw_key)?.into(); - parsed_key.to_raw_object(false).map_err(from_dpp_err) + parsed_key.to_raw_object(false).with_js_error() }) .collect::, JsValue>>()?; diff --git a/packages/wasm-dpp/src/identity/validation/identity_validator.rs b/packages/wasm-dpp/src/identity/validation/identity_validator.rs index 35ab49e1b95..9aa7050bd8d 100644 --- a/packages/wasm-dpp/src/identity/validation/identity_validator.rs +++ b/packages/wasm-dpp/src/identity/validation/identity_validator.rs @@ -1,4 +1,5 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; + use crate::errors::from_dpp_err; use crate::utils::with_serde_to_platform_value; use crate::validation::ValidationResultWasm; diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index e3080e31b39..2d4695cacb2 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -1,8 +1,8 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; -use crate::errors::from_dpp_err; + use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; use crate::state_transition_factory::StateTransitionFactoryWasm; -use crate::utils::ToSerdeJSONExt; +use crate::utils::{ToSerdeJSONExt, WithJsError}; use crate::validation::ValidationResultWasm; use crate::with_js_error; use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; @@ -35,7 +35,7 @@ impl StateTransitionFacadeWasm { adapter, protocol_version_validator, ) - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(StateTransitionFacadeWasm(state_transition_facade)) } @@ -126,7 +126,7 @@ impl StateTransitionFacadeWasm { .0 .create_from_object(state_transition_json.clone(), true) .await - .map_err(from_dpp_err)?; + .with_js_error()?; (state_transition, state_transition_json, execution_context) }; @@ -139,7 +139,7 @@ impl StateTransitionFacadeWasm { options.into(), ) .await - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } @@ -173,7 +173,7 @@ impl StateTransitionFacadeWasm { .0 .validate_basic(&state_transition_json, &execution_context) .await - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } @@ -192,7 +192,7 @@ impl StateTransitionFacadeWasm { .0 .validate_signature(state_transition) .await - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } @@ -211,7 +211,7 @@ impl StateTransitionFacadeWasm { .0 .validate_fee(&state_transition) .await - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } @@ -230,7 +230,7 @@ impl StateTransitionFacadeWasm { .0 .validate_state(&state_transition) .await - .map_err(from_dpp_err)?; + .with_js_error()?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index ca123e3da74..bfd31fc23dc 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -10,7 +10,7 @@ use dpp::{state_transition::{ use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; use dpp::platform_value::Value; -use crate::utils::ToSerdeJSONExt; +use crate::utils::{ToSerdeJSONExt, WithJsError}; use crate::{ bls_adapter::{BlsAdapter, JsBlsAdapter}, errors::{from_dpp_err, from_dpp_init_error}, @@ -120,7 +120,7 @@ impl StateTransitionFactoryWasm { DataContractCreateTransitionBasicValidator::new( protocol_version_validator.clone(), ) - .map_err(from_dpp_err)?, + .with_js_error()?, DataContractUpdateTransitionBasicValidator::new( state_repository_wrapper.clone(), protocol_version_validator.clone(), @@ -140,7 +140,7 @@ impl StateTransitionFactoryWasm { pk_validator, pk_sig_validator, ) - .map_err(from_dpp_err)?, + .with_js_error()?, IdentityTopUpTransitionBasicValidator::new( ProtocolVersionValidator::default(), asset_lock_validator, diff --git a/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs b/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs index 0188aa7c445..32c87c43db3 100644 --- a/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs +++ b/packages/wasm-dpp/src/state_transition/validation/validate_state_transition_key_signature.rs @@ -1,5 +1,5 @@ -use crate::errors::from_dpp_err; use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; +use crate::utils::WithJsError; use crate::validation::ValidationResultWasm; use dpp::identity::state_transition::asset_lock_proof::{ AssetLockPublicKeyHashFetcher, AssetLockTransactionOutputFetcher, @@ -52,11 +52,7 @@ impl StateTransitionKeySignatureValidatorWasm { &state_transition, )?; - let validation_result = self - .0 - .validate(&state_transition) - .await - .map_err(from_dpp_err)?; + let validation_result = self.0.validate(&state_transition).await.with_js_error()?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } } From fa964db4c56e07b8f57c83565267f78befe71251 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 06:01:50 +0700 Subject: [PATCH 173/228] trials --- .../data_contract/data_contract_factory.rs | 27 +++++++++---------- .../data_contract_create_transition/mod.rs | 12 ++++----- ...e_data_contract_update_transition_basic.rs | 20 +++++++++----- ...tract_immutable_properties_update_error.rs | 19 ++++++++++--- .../src/data_contract/data_contract.rs | 1 + .../validation.rs | 17 +++++++++--- ...ntractUpdateTransitionBasicFactory.spec.js | 2 +- 7 files changed, 64 insertions(+), 34 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index fda3110e063..4ae539264e3 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -4,13 +4,14 @@ use std::convert::TryInto; use std::sync::Arc; use data_contract::state_transition::property_names as st_prop; -use platform_value::{Bytes32, Value}; +use platform_value::{BinaryData, Bytes32, Value}; use crate::data_contract::contract_config::ContractConfig; use crate::data_contract::errors::InvalidDataContractError; use crate::data_contract::property_names::PROTOCOL_VERSION; +use crate::state_transition::StateTransitionType; use crate::{ data_contract::{self, generate_data_contract_id}, decode_protocol_entity_factory::DecodeProtocolEntity, @@ -189,19 +190,17 @@ impl DataContractFactory { &self, data_contract: DataContract, ) -> Result { - let entropy = Value::Bytes32(data_contract.entropy.to_buffer()); - let raw_object = BTreeMap::from([ - ( - st_prop::PROTOCOL_VERSION.to_string(), - Value::U32(self.protocol_version), - ), - ( - st_prop::DATA_CONTRACT.to_string(), - data_contract.try_into()?, - ), - (st_prop::ENTROPY.to_string(), entropy), - ]); - DataContractCreateTransition::from_value_map(raw_object) + //todo: is this right for entropy? + let entropy = data_contract.entropy.clone(); + Ok(DataContractCreateTransition { + protocol_version: self.protocol_version, + transition_type: StateTransitionType::DataContractCreate, + data_contract, + entropy, + signature_public_key_id: 0, + signature: Default::default(), + execution_context: Default::default(), + }) } pub fn create_data_contract_update_transition( diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 60b4b64f872..829625d1b45 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -84,26 +84,26 @@ impl DataContractCreateTransition { } pub fn from_value_map( - mut raw_data_contract_update_transition: BTreeMap, + mut raw_data_contract_create_transition: BTreeMap, ) -> Result { Ok(DataContractCreateTransition { - protocol_version: raw_data_contract_update_transition + protocol_version: raw_data_contract_create_transition .get_integer(PROTOCOL_VERSION) .map_err(ProtocolError::ValueError)?, - signature: raw_data_contract_update_transition + signature: raw_data_contract_create_transition .remove_optional_binary_data(SIGNATURE) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), - signature_public_key_id: raw_data_contract_update_transition + signature_public_key_id: raw_data_contract_create_transition .remove_optional_integer(SIGNATURE_PUBLIC_KEY_ID) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), - entropy: raw_data_contract_update_transition + entropy: raw_data_contract_create_transition .remove_optional_bytes_32(ENTROPY) .map_err(ProtocolError::ValueError)? .unwrap_or_default(), data_contract: DataContract::from_raw_object( - raw_data_contract_update_transition + raw_data_contract_create_transition .remove(DATA_CONTRACT) .ok_or(ProtocolError::DecodingError( "data contract missing on state transition".to_string(), diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index c4b060bed3f..4d659a33ff6 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -177,6 +177,14 @@ where DataContractImmutablePropertiesUpdateError::new( operation.to_owned(), property_name.to_owned(), + existing_data_contract_object + .get(property_name.split_at(1).1)? + .cloned() + .unwrap_or(Value::Null), + new_base_data_contract + .get(property_name.split_at(1).1)? + .cloned() + .unwrap_or(Value::Null), ), )) } @@ -267,12 +275,12 @@ fn get_operation_and_property_name(p: &PatchOperation) -> (&'static str, &str) { fn get_operation_and_property_name_json(p: &json_patch::PatchOperation) -> (&'static str, &str) { match &p { - json_patch::PatchOperation::Add(ref o) => ("add", o.path.as_str()), - json_patch::PatchOperation::Copy(ref o) => ("copy", o.path.as_str()), - json_patch::PatchOperation::Remove(ref o) => ("remove", o.path.as_str()), - json_patch::PatchOperation::Replace(ref o) => ("replace", o.path.as_str()), - json_patch::PatchOperation::Move(ref o) => ("move", o.path.as_str()), - json_patch::PatchOperation::Test(ref o) => ("test", o.path.as_str()), + json_patch::PatchOperation::Add(ref o) => ("add json", o.path.as_str()), + json_patch::PatchOperation::Copy(ref o) => ("copy json", o.path.as_str()), + json_patch::PatchOperation::Remove(ref o) => ("remove json", o.path.as_str()), + json_patch::PatchOperation::Replace(ref o) => ("replace json", o.path.as_str()), + json_patch::PatchOperation::Move(ref o) => ("move json", o.path.as_str()), + json_patch::PatchOperation::Test(ref o) => ("test json", o.path.as_str()), } } diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/data_contract_immutable_properties_update_error.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/data_contract_immutable_properties_update_error.rs index 6a8d6b1ba56..e683708eb33 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/data_contract/data_contract_immutable_properties_update_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/data_contract_immutable_properties_update_error.rs @@ -1,20 +1,25 @@ use crate::consensus::basic::BasicError; +use platform_value::Value; use thiserror::Error; use crate::consensus::ConsensusError; -#[derive(Error, Debug, Clone, PartialEq, Eq)] -#[error("Only $defs, version and documents fields are allowed to be updated. Forbidden operation '{operation}' on '{field_path}'")] +#[derive(Error, Debug, Clone)] +#[error("only $defs, version and documents fields are allowed to be updated. Forbidden operation '{operation}' on '{field_path}' old value is '{old_value}', new value is '{new_value}'")] pub struct DataContractImmutablePropertiesUpdateError { operation: String, field_path: String, + old_value: Value, + new_value: Value, } impl DataContractImmutablePropertiesUpdateError { - pub fn new(operation: String, field_path: String) -> Self { + pub fn new(operation: String, field_path: String, old_value: Value, new_value: Value) -> Self { Self { operation, field_path, + old_value, + new_value, } } @@ -25,6 +30,14 @@ impl DataContractImmutablePropertiesUpdateError { pub fn field_path(&self) -> String { self.field_path.clone() } + + pub fn old_value(&self) -> Value { + self.old_value.clone() + } + + pub fn new_value(&self) -> Value { + self.new_value.clone() + } } impl From for ConsensusError { diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index f10f3a9a0d9..1cd6d45c1db 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -10,6 +10,7 @@ use wasm_bindgen::prelude::*; use dpp::data_contract::{DataContract, SCHEMA_URI}; use dpp::platform_value::string_encoding::Encoding; use dpp::platform_value::{Bytes32, Value}; +use dpp::prelude::Identifier; use dpp::{platform_value, Convertible}; use crate::errors::{from_dpp_err, RustConversionError}; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index 8e577060430..960525e7486 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -1,7 +1,10 @@ use std::{collections::BTreeMap, sync::Arc}; +use dpp::data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition; +use dpp::platform_value::{ReplacementType, Value}; use dpp::validation::AsyncDataValidatorWithContext; use dpp::{ + data_contract, data_contract::state_transition::data_contract_update_transition::validation::{ basic::{ validate_indices_are_backward_compatible as dpp_validate_indices_are_backward_compatible, @@ -11,6 +14,7 @@ use dpp::{ }, platform_value, version::ProtocolVersionValidator, + ProtocolError, }; use wasm_bindgen::prelude::*; @@ -67,6 +71,14 @@ pub async fn validate_data_contract_update_transition_basic( let parameters: DataContractUpdateTransitionParameters = serde_wasm_bindgen::from_value(raw_parameters)?; + let mut value = platform_value::to_value(¶meters)?; + value.replace_at_paths( + data_contract::IDENTIFIER_FIELDS, + ReplacementType::Identifier, + )?; + value.replace_at_paths(data_contract::BINARY_FIELDS, ReplacementType::BinaryBytes)?; + value.set_into_value("protocolVersion", 1u32)?; + let validator: DataContractUpdateTransitionBasicValidator = DataContractUpdateTransitionBasicValidator::new( Arc::new(ExternalStateRepositoryLikeWrapper::new(state_repository)), @@ -74,10 +86,7 @@ pub async fn validate_data_contract_update_transition_basic( )?; let validation_result = validator - .validate( - &platform_value::to_value(¶meters)?, - &execution_context.into(), - ) + .validate(&value, &execution_context.into()) .await?; Ok(validation_result.map(|_| JsValue::undefined()).into()) diff --git a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js index 4e04c9edb45..5f0abf53037 100644 --- a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js @@ -373,7 +373,7 @@ describe('validateDataContractUpdateTransitionBasicFactory', () => { rawStateTransition, executionContext, ); - + console.log(result.errorsText()); expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); }); From a44de5ce642e781f8f72aaa7566539d910d06bc9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 16:00:48 +0700 Subject: [PATCH 174/228] another fix --- packages/rs-dpp/src/data_contract/mod.rs | 2 +- .../data_contract_update_transition/mod.rs | 29 +++- .../btreemap_field_replacement.rs | 31 ++++ packages/rs-platform-value/src/display.rs | 9 +- packages/rs-platform-value/src/lib.rs | 31 +++- packages/rs-platform-value/src/replace.rs | 150 ++++++++++++++++++ .../validation.rs | 8 +- ...ntractUpdateTransitionBasicFactory.spec.js | 2 +- 8 files changed, 251 insertions(+), 11 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index fea292b6849..4710e36b0c5 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -20,7 +20,7 @@ pub mod serialization; pub mod state_transition; pub mod validation; -pub(self) mod property_names { +pub mod property_names { pub const PROTOCOL_VERSION: &str = "protocolVersion"; pub const ID: &str = "$id"; pub const OWNER_ID: &str = "ownerId"; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 8d7cc57c951..2519a8bb261 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -1,6 +1,6 @@ use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::{BinaryData, Value}; +use platform_value::{BinaryData, IntegerReplacementType, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::collections::BTreeMap; @@ -23,6 +23,27 @@ use super::property_names::*; pub mod apply_data_contract_update_transition_factory; pub mod validation; +pub mod property_names { + pub const PROTOCOL_VERSION: &str = "protocolVersion"; + pub const DATA_CONTRACT: &str = "dataContract"; + pub const DATA_CONTRACT_ID: &str = "dataContract.$id"; + pub const DATA_CONTRACT_OWNER_ID: &str = "dataContract.ownerId"; + pub const DATA_CONTRACT_ENTROPY: &str = "dataContract.entropy"; + pub const DATA_CONTRACT_PROTOCOL_VERSION: &str = "dataContract.protocolVersion"; + pub const SIGNATURE_PUBLIC_KEY_ID: &str = "signaturePublicKeyId"; + pub const SIGNATURE: &str = "signature"; +} + +pub const IDENTIFIER_FIELDS: [&str; 2] = [ + property_names::DATA_CONTRACT_ID, + property_names::DATA_CONTRACT_OWNER_ID, +]; +pub const BINARY_FIELDS: [&str; 1] = [property_names::DATA_CONTRACT_ENTROPY]; +pub const U32_FIELDS: [&str; 2] = [ + property_names::PROTOCOL_VERSION, + property_names::DATA_CONTRACT_PROTOCOL_VERSION, +]; + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct DataContractUpdateTransition { @@ -104,6 +125,12 @@ impl DataContractUpdateTransition { }) } + pub fn clean_value(value: &mut Value) { + value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; + value.replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes)?; + value.replace_integer_type_at_paths(U32_FIELDS, IntegerReplacementType::U32)?; + } + pub fn get_data_contract(&self) -> &DataContract { &self.data_contract } diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs index 7222b5680a8..404723dd6c7 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs @@ -5,6 +5,37 @@ use std::collections::BTreeMap; use std::iter::Peekable; use std::vec::IntoIter; +#[derive(Debug, Clone, Copy)] +pub enum IntegerReplacementType { + U128, + I128, + U64, + I64, + U32, + I32, + U16, + I16, + U8, + I8, +} + +impl IntegerReplacementType { + pub fn replace_for_value(&self, value: Value) -> Result { + Ok(match self { + IntegerReplacementType::U128 => Value::U128(value.try_into()?), + IntegerReplacementType::I128 => Value::I128(value.try_into()?), + IntegerReplacementType::U64 => Value::U64(value.try_into()?), + IntegerReplacementType::I64 => Value::I64(value.try_into()?), + IntegerReplacementType::U32 => Value::U32(value.try_into()?), + IntegerReplacementType::I32 => Value::I32(value.try_into()?), + IntegerReplacementType::U16 => Value::U16(value.try_into()?), + IntegerReplacementType::I16 => Value::I16(value.try_into()?), + IntegerReplacementType::U8 => Value::U8(value.try_into()?), + IntegerReplacementType::I8 => Value::I8(value.try_into()?), + }) + } +} + #[derive(Debug, Clone, Copy)] pub enum ReplacementType { Identifier, diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index 105e7741338..72a5bc791a4 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -35,7 +35,14 @@ impl Value { .join(", "); format!("array of [{}]", inner_values) } - Value::Map(_) => "Map".to_string(), + Value::Map(map) => { + let inner_string = map + .iter() + .map(|(key, value)| format!("{key}: {value}")) + .collect::>() + .join(",\n"); + format!("Map {{ {} }}", inner_string) + } Value::U128(i) => format!("(u128){}", i), Value::I128(i) => format!("(i128){}", i), Value::U64(i) => format!("(u64){}", i), diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index e14508779b3..46ef8f31861 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -32,7 +32,9 @@ use std::collections::BTreeMap; pub type Hash256 = [u8; 32]; -pub use btreemap_extensions::btreemap_field_replacement::ReplacementType; +pub use btreemap_extensions::btreemap_field_replacement::{ + IntegerReplacementType, ReplacementType, +}; pub use types::binary_data::BinaryData; pub use types::bytes_32::Bytes32; pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; @@ -1153,6 +1155,33 @@ macro_rules! implfrom { }; } +macro_rules! impltryinto { + ($($t:ty),+ $(,)?) => { + $( + impl TryInto<$t> for Value { + type Error = Error; + #[inline] + fn try_into(self) -> Result<$t, Self::Error> { + self.to_integer() + } + } + )+ + }; +} + +impltryinto! { + u128, + i128, + u64, + i64, + u32, + i32, + u16, + i16, + u8, + i8, +} + implfrom! { U128(u128), I128(i128), diff --git a/packages/rs-platform-value/src/replace.rs b/packages/rs-platform-value/src/replace.rs index 5d62af0b195..64ed56fb31d 100644 --- a/packages/rs-platform-value/src/replace.rs +++ b/packages/rs-platform-value/src/replace.rs @@ -1,3 +1,4 @@ +use crate::btreemap_extensions::btreemap_field_replacement::IntegerReplacementType; use crate::inner_value_at_path::is_array_path; use crate::{Error, ReplacementType, Value, ValueMapHelper}; use std::collections::HashSet; @@ -163,6 +164,155 @@ impl Value { .try_for_each(|path| self.replace_at_path(path, replacement_type)) } + /// If the `Value` is a `Map`, replaces the value at the path inside the map. + /// This is used to set inner values as Identifiers or BinaryData, or from Identifiers or + /// BinaryData to base58 or base64 strings. + /// Either returns `Err(Error::Structure("reason"))` or `Err(Error::ByteLengthNot32BytesError))` + /// if the replacement can not happen. + /// + /// ``` + /// # use platform_value::{Error, Identifier, IntegerReplacementType, Value}; + /// # + /// let mut inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("food_id")), Value::U8(5)), + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), inner_value), + /// ] + /// ); + /// + /// value.replace_integer_type_at_path("foods.food_id", IntegerReplacementType::U32).expect("expected to replace at path with identifier"); + /// + /// assert_eq!(value.get_value_at_path("foods.food_id"), Ok(&Value::U32(5))); + /// + /// let mut tangerine_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("food_id")), Value::U128(8)), + /// ] + /// ); + /// let mut mandarin_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("food_id")), Value::U32(2)), + /// ] + /// ); + /// let mut oranges_value = Value::Array( + /// vec![ + /// tangerine_value, + /// mandarin_value + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), oranges_value), + /// ] + /// ); + /// + /// value.replace_integer_type_at_path("foods[].food_id", IntegerReplacementType::U16).expect("expected to replace at path with identifier"); + /// + /// assert_eq!(value.get_value_at_path("foods[0].food_id"), Ok(&Value::U16(8))); + /// + /// ``` + pub fn replace_integer_type_at_path( + &mut self, + path: &str, + replacement_type: IntegerReplacementType, + ) -> Result<(), Error> { + let mut split = path.split('.').peekable(); + let mut current_values = vec![self]; + while let Some(path_component) = split.next() { + if let Some((string_part, number_part)) = is_array_path(path_component)? { + current_values = current_values + .into_iter() + .map(|current_value| { + let map = current_value.to_map_mut()?; + let array_value = map.get_key_mut(string_part)?; + let array = array_value.to_array_mut()?; + if let Some(number_part) = number_part { + if array.len() < number_part { + //this already exists + Ok(vec![array.get_mut(number_part).unwrap()]) + } else { + return Err(Error::StructureError(format!( + "element at position {number_part} in array does not exist" + ))); + } + } else { + // we are replacing all members in array + Ok(array.into_iter().collect()) + } + }) + .collect::>, Error>>()? + .into_iter() + .flatten() + .collect() + } else { + current_values = current_values + .into_iter() + .filter_map(|current_value| { + let map = match current_value.as_map_mut_ref() { + Ok(map) => map, + Err(err) => return Some(Err(err)), + }; + let Some(new_value) = map.get_optional_key_mut(path_component) else { + return None; + }; + + if split.peek().is_none() { + *new_value = match replacement_type.replace_for_value(new_value.clone()) + { + Ok(value) => value, + Err(err) => return Some(Err(err)), + }; + return None; + } + Some(Ok(new_value)) + }) + .collect::, Error>>()?; + } + } + Ok(()) + } + + /// Calls replace_at_path for every path in a given array. + /// Either returns `Err(Error::Structure("reason"))` or `Err(Error::ByteLengthNot32BytesError))` + /// if the replacement can not happen. + /// + /// ``` + /// # use platform_value::{Error, Identifier, IntegerReplacementType, ReplacementType, Value}; + /// # + /// let mut inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("grapes")), Value::U16(5)), + /// (Value::Text(String::from("oranges")), Value::I32(6)), + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), inner_value), + /// ] + /// ); + /// + /// let paths = vec!["foods.grapes", "foods.oranges"]; + /// + /// value.replace_integer_type_at_paths(paths, IntegerReplacementType::U32).expect("expected to replace at paths with identifier"); + /// + /// assert_eq!(value.get_value_at_path("foods.grapes"), Ok(&Value::U32(5))); + /// assert_eq!(value.get_value_at_path("foods.oranges"), Ok(&Value::U32(6))); + /// + /// ``` + pub fn replace_integer_type_at_paths<'a, I: IntoIterator>( + &mut self, + paths: I, + replacement_type: IntegerReplacementType, + ) -> Result<(), Error> { + paths + .into_iter() + .try_for_each(|path| self.replace_integer_type_at_path(path, replacement_type)) + } + /// `replace_to_binary_types_when_setting_with_path` will replace a value with a corresponding /// binary type (Identifier or Binary Data) if that data is in one of the given paths. /// Paths can either be terminal, or can represent an object or an array (with values) where diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index 960525e7486..ba4c26bd46b 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -1,5 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; +use dpp::data_contract::state_transition::data_contract_update_transition; use dpp::data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition; use dpp::platform_value::{ReplacementType, Value}; use dpp::validation::AsyncDataValidatorWithContext; @@ -72,12 +73,7 @@ pub async fn validate_data_contract_update_transition_basic( serde_wasm_bindgen::from_value(raw_parameters)?; let mut value = platform_value::to_value(¶meters)?; - value.replace_at_paths( - data_contract::IDENTIFIER_FIELDS, - ReplacementType::Identifier, - )?; - value.replace_at_paths(data_contract::BINARY_FIELDS, ReplacementType::BinaryBytes)?; - value.set_into_value("protocolVersion", 1u32)?; + DataContractUpdateTransition::clean_value(&mut value); let validator: DataContractUpdateTransitionBasicValidator = DataContractUpdateTransitionBasicValidator::new( diff --git a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js index 5f0abf53037..4e04c9edb45 100644 --- a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js @@ -373,7 +373,7 @@ describe('validateDataContractUpdateTransitionBasicFactory', () => { rawStateTransition, executionContext, ); - console.log(result.errorsText()); + expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); }); From c1a0e39194ff289856187417818b479b463dc4c0 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 17:22:55 +0700 Subject: [PATCH 175/228] more fixes --- .../document_type/document_field.rs | 4 +- .../data_contract_create_transition/mod.rs | 35 ++++++++- .../data_contract_update_transition/mod.rs | 8 +- .../identity_create_transition.rs | 10 ++- packages/rs-platform-value/src/display.rs | 8 +- packages/rs-platform-value/src/error.rs | 3 + packages/rs-platform-value/src/lib.rs | 74 +++++++++++++++++++ .../validation.rs | 10 ++- .../validation.rs | 2 +- .../identity_create_transition.rs | 8 +- 10 files changed, 140 insertions(+), 22 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_field.rs b/packages/rs-dpp/src/data_contract/document_type/document_field.rs index a6e838352b7..73bb528a561 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_field.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_field.rs @@ -712,13 +712,13 @@ impl DocumentFieldType { } DocumentFieldType::Integer => str.parse::().map(Value::I128).map_err(|_| { ProtocolError::DataContractError(DataContractError::ValueWrongType( - "value is not an integer", + "value is not an integer from string", )) }), DocumentFieldType::Number | DocumentFieldType::Date => { str.parse::().map(Value::Float).map_err(|_| { ProtocolError::DataContractError(DataContractError::ValueWrongType( - "value is not a float", + "value is not a float from string", )) }) } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 829625d1b45..1d9ad7892d5 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -3,7 +3,7 @@ use std::convert::TryInto; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::{BinaryData, Bytes32, Value}; +use platform_value::{BinaryData, Bytes32, IntegerReplacementType, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -24,6 +24,32 @@ use super::property_names::*; pub mod apply_data_contract_create_transition_factory; pub mod validation; +pub mod property_names { + pub const PROTOCOL_VERSION: &str = "protocolVersion"; + pub const DATA_CONTRACT: &str = "dataContract"; + pub const DATA_CONTRACT_ID: &str = "dataContract.$id"; + pub const DATA_CONTRACT_OWNER_ID: &str = "dataContract.ownerId"; + pub const DATA_CONTRACT_ENTROPY: &str = "dataContract.entropy"; + pub const ENTROPY: &str = "entropy"; + pub const DATA_CONTRACT_PROTOCOL_VERSION: &str = "dataContract.protocolVersion"; + pub const SIGNATURE_PUBLIC_KEY_ID: &str = "signaturePublicKeyId"; + pub const SIGNATURE: &str = "signature"; +} + +pub const IDENTIFIER_FIELDS: [&str; 2] = [ + property_names::DATA_CONTRACT_ID, + property_names::DATA_CONTRACT_OWNER_ID, +]; +pub const BINARY_FIELDS: [&str; 3] = [ + property_names::ENTROPY, + property_names::DATA_CONTRACT_ENTROPY, + property_names::SIGNATURE, +]; +pub const U32_FIELDS: [&str; 2] = [ + property_names::PROTOCOL_VERSION, + property_names::DATA_CONTRACT_PROTOCOL_VERSION, +]; + #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct DataContractCreateTransition { @@ -129,6 +155,13 @@ impl DataContractCreateTransition { pub fn get_modified_data_ids(&self) -> Vec { vec![self.data_contract.id] } + + pub fn clean_value(value: &mut Value) -> Result<(), ProtocolError> { + value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; + value.replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes)?; + value.replace_integer_type_at_paths(U32_FIELDS, IntegerReplacementType::U32)?; + Ok(()) + } } impl StateTransitionIdentitySigned for DataContractCreateTransition { diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 2519a8bb261..d0c9b2a1cff 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -38,7 +38,10 @@ pub const IDENTIFIER_FIELDS: [&str; 2] = [ property_names::DATA_CONTRACT_ID, property_names::DATA_CONTRACT_OWNER_ID, ]; -pub const BINARY_FIELDS: [&str; 1] = [property_names::DATA_CONTRACT_ENTROPY]; +pub const BINARY_FIELDS: [&str; 2] = [ + property_names::DATA_CONTRACT_ENTROPY, + property_names::SIGNATURE, +]; pub const U32_FIELDS: [&str; 2] = [ property_names::PROTOCOL_VERSION, property_names::DATA_CONTRACT_PROTOCOL_VERSION, @@ -125,10 +128,11 @@ impl DataContractUpdateTransition { }) } - pub fn clean_value(value: &mut Value) { + pub fn clean_value(value: &mut Value) -> Result<(), ProtocolError> { value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; value.replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes)?; value.replace_integer_type_at_paths(U32_FIELDS, IntegerReplacementType::U32)?; + Ok(()) } pub fn get_data_contract(&self) -> &DataContract { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 472fc38d742..6a53a8d815a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -1,7 +1,7 @@ use std::convert::{TryFrom, TryInto}; use platform_value::btreemap_extensions::BTreeValueMapHelper; -use platform_value::{BinaryData, Value}; +use platform_value::{BinaryData, IntegerReplacementType, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -20,6 +20,7 @@ pub const BINARY_FIELDS: [&str; 2] = [ property_names::PUBLIC_KEYS_DATA, property_names::PUBLIC_KEYS_SIGNATURE, ]; +pub const U32_FIELDS: [&str; 1] = [property_names::PROTOCOL_VERSION]; mod property_names { pub const PUBLIC_KEYS: &str = "publicKeys"; @@ -200,6 +201,13 @@ impl IdentityCreateTransition { pub fn set_protocol_version(&mut self, protocol_version: u32) { self.protocol_version = protocol_version; } + + pub fn clean_value(value: &mut Value) -> Result<(), ProtocolError> { + value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; + value.replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes)?; + value.replace_integer_type_at_paths(U32_FIELDS, IntegerReplacementType::U32)?; + Ok(()) + } } impl StateTransitionConvert for IdentityCreateTransition { diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index 72a5bc791a4..41385e27219 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -12,19 +12,19 @@ impl Value { match self { Value::Bytes(bytes) => format!("bytes {}", hex::encode(bytes)), Value::Float(float) => { - format!("{}", float) + format!("float {}", float) } Value::Text(text) => { let len = text.len(); if len > 20 { let first_text = text.split_at(20).0.to_string(); - format!("{}[...({})]", first_text, len) + format!("string {}[...({})]", first_text, len) } else { - text.clone() + format!("string {}", text) } } Value::Bool(b) => { - format!("{}", b) + format!("bool {}", b) } Value::Null => "Null".to_string(), Value::Array(value) => { diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index 696f4fac38d..ce5579f85e0 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -16,6 +16,9 @@ pub enum Error { #[error("integer out of bounds")] IntegerSizeError, + #[error("integer parsing")] + IntegerParsingError, + #[error("string decoding error {0}")] StringDecodingError(String), diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 46ef8f31861..aca0a33a7dd 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -266,6 +266,80 @@ impl Value { } } + /// If the `Value` is an `Integer`, a `String` or a `Float` or even a `Bool`, returns the + /// associated `Integer` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Value, Error}; + /// # + /// let value = Value::U64(17); + /// let r_value : Result = value.to_integer_broad_conversion(); + /// assert_eq!(r_value, Ok(17)); + /// + /// let value = Value::Text("17".to_string()); + /// let r_value : Result = value.to_integer_broad_conversion(); + /// assert_eq!(r_value, Ok(17)); + /// + /// let value = Value::Bool(true); + /// let r_value : Result = value.to_integer_broad_conversion(); + /// assert_eq!(r_value, Ok(1)); + /// ``` + pub fn to_integer_broad_conversion(&self) -> Result + where + T: TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom + + TryFrom, + { + match self { + Value::U128(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::I128(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::U64(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::I64(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::U32(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::I32(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::U16(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::I16(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::U8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::I8(int) => (*int).try_into().map_err(|_| Error::IntegerSizeError), + Value::Float(float) => { + let max_f64 = u128::MAX as f64; + let min_f64 = i128::MIN as f64; + if *float > 0f64 && *float < max_f64 { + (*float as u128) + .try_into() + .map_err(|_| Error::IntegerSizeError) + } else if *float > min_f64 && *float < 0f64 { + (*float as i128) + .try_into() + .map_err(|_| Error::IntegerSizeError) + } else { + Err(Error::IntegerSizeError) + } + } + Value::Bool(bool) => { + let i: u8 = (*bool).into(); + i.try_into().map_err(|_| Error::IntegerSizeError) + } + Value::Text(text) => text + .parse::() + .map_err(|_| Error::IntegerSizeError)? + .try_into() + .map_err(|_| Error::IntegerSizeError), + other => Err(Error::StructureError(format!( + "value can not be converted to an integer, found {}", + other + ))), + } + } + /// Returns true if the `Value` is a `Bytes`. Returns false otherwise. /// /// ``` diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs index d3c38662ed7..fa664dd9aa3 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use dpp::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; use dpp::platform_value::Value; use dpp::{ data_contract::state_transition::data_contract_create_transition::validation::state::{ @@ -45,14 +46,15 @@ pub async fn validate_data_contract_create_transition_basic( let parameters: DataContractCreateTransitionParameters = serde_wasm_bindgen::from_value(raw_parameters)?; + let mut value = platform_value::to_value(¶meters)?; + DataContractCreateTransition::clean_value(&mut value)?; + let validator = DataContractCreateTransitionBasicValidator::new(Arc::new( ProtocolVersionValidator::default(), ))?; - let validation_result = validator.validate( - &platform_value::to_value(¶meters)?, - &StateTransitionExecutionContext::default(), - )?; + let validation_result = + validator.validate(&value, &StateTransitionExecutionContext::default())?; Ok(validation_result.map(|_| JsValue::undefined()).into()) } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index ba4c26bd46b..874dda2adfd 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -73,7 +73,7 @@ pub async fn validate_data_contract_update_transition_basic( serde_wasm_bindgen::from_value(raw_parameters)?; let mut value = platform_value::to_value(¶meters)?; - DataContractUpdateTransition::clean_value(&mut value); + DataContractUpdateTransition::clean_value(&mut value)?; let validator: DataContractUpdateTransitionBasicValidator = DataContractUpdateTransitionBasicValidator::new( diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index bf205e49ca2..aa14ce5e702 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -21,9 +21,6 @@ use crate::{ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::utils::{generic_of_js_val, ToSerdeJSONExt, WithJsError}; -use dpp::identity::state_transition::identity_create_transition::{ - BINARY_FIELDS, IDENTIFIER_FIELDS, -}; use dpp::platform_value::string_encoding::Encoding; use dpp::platform_value::{string_encoding, ReplacementType}; use dpp::{ @@ -57,10 +54,7 @@ impl IdentityCreateTransitionWasm { #[wasm_bindgen(constructor)] pub fn new(raw_parameters: JsValue) -> Result { let mut raw_state_transition = raw_parameters.with_serde_to_platform_value()?; - raw_state_transition - .replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes) - .map_err(ProtocolError::ValueError) - .with_js_error()?; + IdentityCreateTransition::clean_value(&mut raw_state_transition).with_js_error()?; let identity_create_transition = IdentityCreateTransition::new(raw_state_transition) .map_err(|e| RustConversionError::Error(e.to_string()).to_js_value())?; From 632ed2a7e8799c25d9f48739e9c0a07b00acca8a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 17:37:20 +0700 Subject: [PATCH 176/228] more fixes --- .../data_contract_create_transition/mod.rs | 2 +- .../errors/consensus/abstract_consensus_error.rs | 6 ++++++ packages/wasm-dpp/lib/test/expect/expectError.js | 10 ++++++++++ .../data_contract_create_transition/validation.rs | 13 ++++++++++--- ...DataContractCreateTransitionBasicFactory.spec.js | 13 ++++++------- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 1d9ad7892d5..f71ce1d189c 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -156,7 +156,7 @@ impl DataContractCreateTransition { vec![self.data_contract.id] } - pub fn clean_value(value: &mut Value) -> Result<(), ProtocolError> { + pub fn clean_value(value: &mut Value) -> Result<(), platform_value::Error> { value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; value.replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes)?; value.replace_integer_type_at_paths(U32_FIELDS, IntegerReplacementType::U32)?; diff --git a/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs b/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs index a6b2f2c7fe7..9c5bad54ac9 100644 --- a/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs +++ b/packages/rs-dpp/src/errors/consensus/abstract_consensus_error.rs @@ -339,3 +339,9 @@ impl From for ConsensusError { Self::FeeError(err) } } + +impl From for ConsensusError { + fn from(err: ValueError) -> Self { + Self::ValueError(err) + } +} diff --git a/packages/wasm-dpp/lib/test/expect/expectError.js b/packages/wasm-dpp/lib/test/expect/expectError.js index a7e0aff5662..7f7be61d2d6 100644 --- a/packages/wasm-dpp/lib/test/expect/expectError.js +++ b/packages/wasm-dpp/lib/test/expect/expectError.js @@ -31,6 +31,16 @@ const expectError = { const wasmDpp = await loadWasmDpp(); await expectError.expectValidationError(result, wasmDpp.JsonSchemaError, count); }, + + /** + * + * @param {ValidationResult} result + * @param [count] + */ + async expectPlatformValueError(result, count = 1) { + const wasmDpp = await loadWasmDpp(); + await expectError.expectValidationError(result, wasmDpp.PlatformValueError, count); + }, }; module.exports = expectError; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs index fa664dd9aa3..d9b512c5fd6 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs @@ -1,7 +1,9 @@ use std::sync::Arc; +use dpp::block_time_window::validation_result; use dpp::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; use dpp::platform_value::Value; +use dpp::validation::SimpleValidationResult; use dpp::{ data_contract::state_transition::data_contract_create_transition::validation::state::{ validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, @@ -11,6 +13,7 @@ use dpp::{ state_transition::state_transition_execution_context::StateTransitionExecutionContext, validation::DataValidatorWithContext, version::ProtocolVersionValidator, + ProtocolError, }; use wasm_bindgen::prelude::*; @@ -47,14 +50,18 @@ pub async fn validate_data_contract_create_transition_basic( serde_wasm_bindgen::from_value(raw_parameters)?; let mut value = platform_value::to_value(¶meters)?; - DataContractCreateTransition::clean_value(&mut value)?; + let mut validation_result = SimpleValidationResult::default(); + if let Some(err) = DataContractCreateTransition::clean_value(&mut value).err() { + validation_result.add_error(err); + return Ok(validation_result.map(|_| JsValue::undefined()).into()); + } let validator = DataContractCreateTransitionBasicValidator::new(Arc::new( ProtocolVersionValidator::default(), ))?; - let validation_result = - validator.validate(&value, &StateTransitionExecutionContext::default())?; + validation_result + .merge(validator.validate(&value, &StateTransitionExecutionContext::default())?); Ok(validation_result.map(|_| JsValue::undefined()).into()) } diff --git a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js index 38c46c678dd..6418baaf2bf 100644 --- a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractCreateTransition/validation/basic/validateDataContractCreateTransitionBasicFactory.spec.js @@ -2,7 +2,7 @@ const crypto = require('crypto'); const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); const getDataContractFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); -const { expectJsonSchemaError, expectValidationError } = require('../../../../../../../lib/test/expect/expectError'); +const { expectJsonSchemaError, expectValidationError, expectPlatformValueError } = require('../../../../../../../lib/test/expect/expectError'); const { default: loadWasmDpp } = require('../../../../../../../dist'); @@ -15,7 +15,7 @@ describe('validateDataContractCreateTransitionBasicFactory', () => { let DataContractCreateTransition; let validateDataContractCreateTransitionBasic; let ValidationResult; - let ProtocolVersionParsingError; + let PlatformValueError; let InvalidDataContractIdError; before(async () => { @@ -23,7 +23,7 @@ describe('validateDataContractCreateTransitionBasicFactory', () => { DataContractCreateTransition, validateDataContractCreateTransitionBasic, ValidationResult, - ProtocolVersionParsingError, + PlatformValueError, InvalidDataContractIdError, } = await loadWasmDpp()); }); @@ -63,12 +63,11 @@ describe('validateDataContractCreateTransitionBasicFactory', () => { const result = await validateDataContractCreateTransitionBasic(rawStateTransition); - await expectJsonSchemaError(result); + await expectPlatformValueError(result); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/protocolVersion'); - expect(error.getKeyword()).to.equal('type'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should be valid', async () => { @@ -77,7 +76,7 @@ describe('validateDataContractCreateTransitionBasicFactory', () => { const result = await validateDataContractCreateTransitionBasic(rawStateTransition); const [error] = result.getErrors(); - expect(error).to.be.an.instanceOf(ProtocolVersionParsingError); + expect(error).to.be.an.instanceOf(PlatformValueError); }); }); From 1b9c7fe40ede58939c97af545fd9a17c7d473a28 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 17:44:42 +0700 Subject: [PATCH 177/228] more fixes --- .../data_contract_update_transition/mod.rs | 2 +- .../validation.rs | 12 ++++++++---- ...ntractUpdateTransitionBasicFactory.spec.js | 19 +++++++++---------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index d0c9b2a1cff..6c638ec75e3 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -128,7 +128,7 @@ impl DataContractUpdateTransition { }) } - pub fn clean_value(value: &mut Value) -> Result<(), ProtocolError> { + pub fn clean_value(value: &mut Value) -> Result<(), platform_value::Error> { value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; value.replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes)?; value.replace_integer_type_at_paths(U32_FIELDS, IntegerReplacementType::U32)?; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index 874dda2adfd..ab92b1c92b6 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -3,7 +3,7 @@ use std::{collections::BTreeMap, sync::Arc}; use dpp::data_contract::state_transition::data_contract_update_transition; use dpp::data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition; use dpp::platform_value::{ReplacementType, Value}; -use dpp::validation::AsyncDataValidatorWithContext; +use dpp::validation::{AsyncDataValidatorWithContext, SimpleValidationResult}; use dpp::{ data_contract, data_contract::state_transition::data_contract_update_transition::validation::{ @@ -73,7 +73,11 @@ pub async fn validate_data_contract_update_transition_basic( serde_wasm_bindgen::from_value(raw_parameters)?; let mut value = platform_value::to_value(¶meters)?; - DataContractUpdateTransition::clean_value(&mut value)?; + let mut validation_result = SimpleValidationResult::default(); + if let Some(err) = DataContractUpdateTransition::clean_value(&mut value).err() { + validation_result.add_error(err); + return Ok(validation_result.map(|_| JsValue::undefined()).into()); + } let validator: DataContractUpdateTransitionBasicValidator = DataContractUpdateTransitionBasicValidator::new( @@ -81,9 +85,9 @@ pub async fn validate_data_contract_update_transition_basic( Arc::new(ProtocolVersionValidator::default()), )?; - let validation_result = validator + validation_result.merge(validator .validate(&value, &execution_context.into()) - .await?; + .await?); Ok(validation_result.map(|_| JsValue::undefined()).into()) } diff --git a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js index 4e04c9edb45..1ce0c361574 100644 --- a/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/dataContract/stateTransition/DataContractUpdateTransition/validation/basic/validateDataContractUpdateTransitionBasicFactory.spec.js @@ -1,7 +1,7 @@ const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); const getDataContractFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); -const { expectJsonSchemaError, expectValidationError } = require('../../../../../../../lib/test/expect/expectError'); +const { expectJsonSchemaError, expectValidationError, expectPlatformValueError } = require('../../../../../../../lib/test/expect/expectError'); const { default: loadWasmDpp } = require('../../../../../../../dist'); @@ -10,7 +10,7 @@ describe('validateDataContractUpdateTransitionBasicFactory', () => { let validateDataContractUpdateTransitionBasic; let ValidationResult; let StateTransitionExecutionContext; - let ProtocolVersionParsingError; + let PlatformValueError; let DataContractValidator; let DataContractFactory; let DataContractImmutablePropertiesUpdateError; @@ -30,7 +30,7 @@ describe('validateDataContractUpdateTransitionBasicFactory', () => { validateDataContractUpdateTransitionBasic, ValidationResult, StateTransitionExecutionContext, - ProtocolVersionParsingError, + PlatformValueError, DataContractValidator, DataContractFactory, DataContractImmutablePropertiesUpdateError, @@ -93,12 +93,11 @@ describe('validateDataContractUpdateTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result); + await expectPlatformValueError(result); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/protocolVersion'); - expect(error.getKeyword()).to.equal('type'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should be valid', async () => { @@ -109,11 +108,11 @@ describe('validateDataContractUpdateTransitionBasicFactory', () => { executionContext, ); - await expectValidationError(result); + await expectPlatformValueError(result); const [error] = result.getErrors(); - expect(error).to.be.an.instanceOf(ProtocolVersionParsingError); + expect(error).to.be.an.instanceOf(PlatformValueError); }); }); @@ -182,7 +181,7 @@ describe('validateDataContractUpdateTransitionBasicFactory', () => { const [error] = result.getErrors(); expect(error).to.be.an.instanceOf(IncompatibleDataContractSchemaError); - expect(error.getOperation()).to.equal('remove'); + expect(error.getOperation()).to.equal('remove json'); expect(error.getFieldPath()).to.equal('/additionalProperties'); }); @@ -213,7 +212,7 @@ describe('validateDataContractUpdateTransitionBasicFactory', () => { const [error] = result.getErrors(); expect(error).to.be.an.instanceOf(IncompatibleDataContractSchemaError); - expect(error.getOperation()).to.equal('replace'); + expect(error.getOperation()).to.equal('replace json'); expect(error.getFieldPath()).to.equal('/properties/firstName/maxLength'); }); From 19d1eb568285f245c03c222449eacf7670019868 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 17:57:44 +0700 Subject: [PATCH 178/228] more fixes --- .../validation/multi_validator.rs | 3 +- packages/rs-platform-value/src/display.rs | 47 +++++++++++++++++++ .../validation.rs | 8 ++-- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs index 8b409faca04..0e2e3adba27 100644 --- a/packages/rs-dpp/src/data_contract/validation/multi_validator.rs +++ b/packages/rs-dpp/src/data_contract/validation/multi_validator.rs @@ -19,7 +19,8 @@ pub fn validate(raw_data_contract: &Value, validators: &[SubValidator]) -> Valid Value::Map(current_map) => { for (key, current_value) in current_map.iter() { if current_value.is_map() || current_value.is_array() { - let new_path = format!("{}/{}", path, key); + let new_path = + format!("{}/{}", path, key.non_qualified_string_representation()); values_queue.push((current_value, new_path)) } match key.to_str().map_err(ConsensusError::ValueError) { diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index 41385e27219..62b0c944938 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -8,6 +8,53 @@ impl Display for Value { } impl Value { + pub fn non_qualified_string_representation(&self) -> String { + match self { + Value::Bytes(bytes) => format!("bytes {}", hex::encode(bytes)), + Value::Float(float) => { + format!("{}", float) + } + Value::Text(text) => text.clone(), + Value::Bool(b) => { + format!("{}", b) + } + Value::Null => "Null".to_string(), + Value::Array(value) => { + let inner_values = value + .iter() + .map(|v| v.string_representation()) + .collect::>() + .join(", "); + format!("array of [{}]", inner_values) + } + Value::Map(map) => { + let inner_string = map + .iter() + .map(|(key, value)| format!("{key}: {value}")) + .collect::>() + .join(",\n"); + format!("Map {{ {} }}", inner_string) + } + Value::U128(i) => format!("{}", i), + Value::I128(i) => format!("{}", i), + Value::U64(i) => format!("{}", i), + Value::I64(i) => format!("{}", i), + Value::U32(i) => format!("{}", i), + Value::I32(i) => format!("{}", i), + Value::U16(i) => format!("{}", i), + Value::I16(i) => format!("{}", i), + Value::U8(i) => format!("{}", i), + Value::I8(i) => format!("{}", i), + Value::Bytes32(bytes32) => format!("bytes32 {}", base64::encode(bytes32.as_slice())), + Value::Identifier(identifier) => format!( + "identifier {}", + bs58::encode(identifier.as_slice()).into_string() + ), + Value::EnumU8(_) => todo!(), + Value::EnumString(_) => todo!(), + } + } + fn string_representation(&self) -> String { match self { Value::Bytes(bytes) => format!("bytes {}", hex::encode(bytes)), diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index ab92b1c92b6..380e2ccde10 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -85,9 +85,11 @@ pub async fn validate_data_contract_update_transition_basic( Arc::new(ProtocolVersionValidator::default()), )?; - validation_result.merge(validator - .validate(&value, &execution_context.into()) - .await?); + validation_result.merge( + validator + .validate(&value, &execution_context.into()) + .await?, + ); Ok(validation_result.map(|_| JsValue::undefined()).into()) } From f1146de51cd60c27ccadfc55010111ad520225c3 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 18:33:16 +0700 Subject: [PATCH 179/228] more fixes --- packages/rs-dpp/src/identity/identity.rs | 9 +++++++++ .../chain/chain_asset_lock_proof.rs | 8 ++++++++ .../instant/instant_asset_lock_proof.rs | 7 +++++++ .../identity_create_transition.rs | 2 +- .../identity_public_key_transitions.rs | 15 ++++++++++++++- .../src/identity/identity_public_key/mod.rs | 11 ++++------- packages/wasm-dpp/src/identity/mod.rs | 4 ++-- .../chain/chain_asset_lock_proof.rs | 9 ++++----- .../instant/instant_asset_lock_proof.rs | 9 ++++----- 9 files changed, 53 insertions(+), 21 deletions(-) diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index c193d373f98..05bff0e927e 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -98,6 +98,15 @@ impl Convertible for Identity { .remove("assetLockProof") .map_err(ProtocolError::ValueError)?; } + if let Some(keys) = value.get_optional_array_mut_ref(property_names::PUBLIC_KEYS)? { + for key in keys.iter_mut() { + if let Some(value) = key.get_optional_value("disabledAt")? { + if value.is_null() { + key.remove("disabledAt")?; + } + } + } + } Ok(value) } diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index f5319ff3f94..d6594371d0c 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -5,6 +5,7 @@ use std::convert::TryFrom; use crate::{ errors::NonConsensusError, identifier::Identifier, util::hash::hash, util::vec::vec_to_array, + ProtocolError, }; #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] @@ -25,6 +26,13 @@ impl TryFrom for ChainAssetLockProof { } impl ChainAssetLockProof { + pub fn to_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + pub fn to_cleaned_object(&self) -> Result { + self.to_object() + } + pub fn new(core_chain_locked_height: u32, out_point: [u8; 36]) -> Self { Self { // TODO: change to const diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs index 30da46607cc..7a62ce329a8 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs @@ -79,6 +79,13 @@ impl InstantAssetLockProof { } } + pub fn to_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + pub fn to_cleaned_object(&self) -> Result { + self.to_object() + } + pub fn asset_lock_type(&self) -> u8 { self.asset_lock_type } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 6a53a8d815a..6765890120e 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -259,7 +259,7 @@ impl StateTransitionConvert for IdentityCreateTransition { let mut public_keys: Vec = vec![]; for key in self.public_keys.iter() { - public_keys.push(key.to_raw_object(skip_signature)?); + public_keys.push(key.to_raw_cleaned_object(skip_signature)?); } value.insert( diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 9381aff56a2..723b715976b 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -134,7 +134,20 @@ impl IdentityPublicKeyWithWitness { /// Return raw data, with all binary fields represented as arrays pub fn to_raw_object(&self, skip_signature: bool) -> Result { - let mut value = platform_value::to_value(self)?; + let mut value = self.to_object()?; + + if skip_signature || self.signature.is_empty() { + value + .remove("signature") + .map_err(ProtocolError::ValueError)?; + } + + Ok(value) + } + + /// Return raw data, with all binary fields represented as arrays + pub fn to_raw_cleaned_object(&self, skip_signature: bool) -> Result { + let mut value = self.to_cleaned_object()?; if skip_signature || self.signature.is_empty() { value diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index 1dd40092bb4..4e2d6b93b97 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -5,7 +5,7 @@ use std::convert::{TryFrom, TryInto}; use wasm_bindgen::prelude::*; use crate::utils::{Inner, WithJsError}; -use crate::{buffer::Buffer, utils}; +use crate::{buffer::Buffer, utils, with_js_error}; use dpp::identity::{IdentityPublicKey, KeyID}; use dpp::platform_value::BinaryData; use dpp::{Convertible, ProtocolError}; @@ -137,15 +137,12 @@ impl IdentityPublicKeyWasm { #[wasm_bindgen(js_name=toObject)] pub fn to_object(&self) -> Result { - let val = self - .0 - .to_json_object() - .map_err(|e| from_dpp_err(e.into()))?; + let value = self.0.to_cleaned_object().with_js_error()?; let data_buffer = Buffer::from_bytes(self.0.data.as_slice()); - let json = val.to_string(); - let js_object = js_sys::JSON::parse(&json)?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + let js_object = with_js_error!(value.serialize(&serializer))?; js_sys::Reflect::set( &js_object, diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index 98e1770ef43..9e4cb47bffc 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -174,9 +174,9 @@ impl IdentityWasm { #[wasm_bindgen(js_name=toObject)] pub fn to_object(&self) -> Result { - let json = self.0.to_json_object().with_js_error()?; + let value = self.0.to_cleaned_object().with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - let js_object = with_js_error!(json.serialize(&serializer))?; + let js_object = with_js_error!(value.serialize(&serializer))?; let id: IdentifierWrapper = self.0.id.into(); diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index 09f84dec020..4e5d31fe2f6 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -2,6 +2,7 @@ use serde::{Deserialize, Serialize}; use std::convert::TryInto; use wasm_bindgen::prelude::*; +use crate::utils::WithJsError; use crate::{ buffer::Buffer, errors::{from_dpp_err, RustConversionError}, @@ -104,12 +105,10 @@ impl ChainAssetLockProofWasm { #[wasm_bindgen(js_name=toObject)] pub fn to_object(&self) -> Result { - let asset_lock_json = - serde_json::to_value(self.0.clone()).map_err(|e| from_dpp_err(e.into()))?; + let asset_lock_value = self.0.to_cleaned_object().with_js_error()?; - let asset_lock_json_string = - serde_json::to_string(&asset_lock_json).map_err(|e| from_dpp_err(e.into()))?; - let js_object = js_sys::JSON::parse(&asset_lock_json_string)?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + let js_object = with_js_error!(asset_lock_value.serialize(&serializer))?; let out_point = self.get_out_point(); diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs index 3fbcc104756..15f9af11d7d 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof.rs @@ -7,6 +7,7 @@ use serde::{Deserialize, Serialize}; use std::convert::TryInto; use wasm_bindgen::prelude::*; +use crate::utils::WithJsError; use crate::{ buffer::Buffer, errors::{from_dpp_err, RustConversionError}, @@ -115,12 +116,10 @@ impl InstantAssetLockProofWasm { #[wasm_bindgen(js_name=toObject)] pub fn to_object(&self) -> Result { - let asset_lock_json = - serde_json::to_value(self.0.clone()).map_err(|e| from_dpp_err(e.into()))?; + let asset_lock_value = self.0.to_cleaned_object().with_js_error()?; - let asset_lock_json_string = - serde_json::to_string(&asset_lock_json).map_err(|e| from_dpp_err(e.into()))?; - let js_object = js_sys::JSON::parse(&asset_lock_json_string)?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + let js_object = with_js_error!(asset_lock_value.serialize(&serializer))?; let transaction = self.get_transaction(); let instant_lock = self.get_instant_lock(); From b6e633cd4764f0e438d36417182cf3886dc9d9c3 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 22:36:23 +0700 Subject: [PATCH 180/228] more fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 25 ++--- .../src/btreemap_extensions/mod.rs | 99 ++++++++++--------- .../document_batch_transition/mod.rs | 15 +-- packages/wasm-dpp/src/errors/value_error.rs | 3 +- packages/wasm-dpp/src/identity/mod.rs | 12 +++ 5 files changed, 84 insertions(+), 70 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 06d6cdffd1d..dad7d9cf8ae 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -130,20 +130,17 @@ impl DataContract { .into_btree_string_map() .map_err(ProtocolError::ValueError)?; - let mutability = get_contract_configuration_properties(&data_contract_map) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + let mutability = get_contract_configuration_properties(&data_contract_map)?; let definition_references = get_definitions(&data_contract_map)?; let document_types = get_document_types_from_contract( &data_contract_map, &definition_references, mutability.documents_keep_history_contract_default, mutability.documents_mutable_contract_default, - ) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + )?; - let protocol_version = data_contract_map - .remove_integer(property_names::PROTOCOL_VERSION) - .map_err(ProtocolError::ValueError)?; + let protocol_version = + data_contract_map.remove_integer(property_names::PROTOCOL_VERSION)?; let documents = data_contract_map .remove(property_names::DOCUMENTS) @@ -151,8 +148,7 @@ impl DataContract { .transpose()? .unwrap_or_default(); - let mutability = get_contract_configuration_properties(&data_contract_map) - .map_err(|e| ProtocolError::ParsingError(e.to_string()))?; + let mutability = get_contract_configuration_properties(&data_contract_map)?; // Defs let defs = @@ -162,6 +158,7 @@ impl DataContract { .iter() .map(|(doc_type, schema)| (String::from(doc_type), get_binary_properties(schema))) .collect(); + let data_contract = DataContract { protocol_version, id: data_contract_map @@ -509,15 +506,7 @@ pub fn get_definitions( contract: &BTreeMap, ) -> Result, ProtocolError> { Ok(contract - .get("$defs") - .map(|definition_value| { - definition_value - .as_map() - .map(Value::map_ref_into_btree_string_map) - .transpose() - }) - .transpose()? - .flatten() + .get_optional_str_value_map("$defs")? .unwrap_or_default()) } diff --git a/packages/rs-platform-value/src/btreemap_extensions/mod.rs b/packages/rs-platform-value/src/btreemap_extensions/mod.rs index 8858d7bb133..9e3aefea0c5 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/mod.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/mod.rs @@ -80,11 +80,8 @@ pub trait BTreeValueMapHelper { key: &str, ) -> Result, Error>; fn get_inner_string_array>(&self, key: &str) -> Result; - fn get_optional_inner_borrowed_map( - &self, - key: &str, - ) -> Result>, Error>; - fn get_optional_inner_borrowed_str_value_map<'a, I: FromIterator<(String, &'a Value)>>( + fn get_optional_map(&self, key: &str) -> Result>, Error>; + fn get_optional_str_value_map<'a, I: FromIterator<(String, &'a Value)>>( &'a self, key: &str, ) -> Result, Error>; @@ -280,22 +277,25 @@ where ) -> Result, Error> { self.get(key) .map(|v| { - v.borrow() - .as_array() - .map(|inner| { - inner - .iter() - .map(|v| { - let Some(str) = v.as_text() else { - return Err(Error::StructureError(format!("{key} must be an string"))) - }; - Ok(str.to_string()) - }) - .collect::>() - }) - .transpose()? - .ok_or_else(|| Error::StructureError(format!("{key} must be a bool"))) - }) + let value = v.borrow(); + if value.is_null() { + None + } else { + Some(value.to_array_ref() + .and_then(|inner| { + inner + .iter() + .map(|v| { + let Some(str) = v.as_text() else { + return Err(Error::StructureError(format!("{key} must be an string"))) + }; + Ok(str.to_string()) + }) + .collect::>() + })) + } + + }).flatten() .transpose() } @@ -305,33 +305,43 @@ where }) } - fn get_optional_inner_borrowed_map(&self, key: &str) -> Result, Error> { + fn get_optional_map(&self, key: &str) -> Result, Error> { self.get(key) .map(|v| { - v.borrow() - .as_map() - .ok_or_else(|| Error::StructureError(format!("{key} must be a map"))) + let value = v.borrow(); + if value.is_null() { + None + } else { + Some( + value + .as_map() + .ok_or_else(|| Error::StructureError(format!("{key} must be a map"))), + ) + } }) + .flatten() .transpose() } - fn get_optional_inner_borrowed_str_value_map<'a, I: FromIterator<(String, &'a Value)>>( + fn get_optional_str_value_map<'a, I: FromIterator<(String, &'a Value)>>( &'a self, key: &str, ) -> Result, Error> { self.get(key) .map(|v| { - v.borrow() - .as_map() - .map(|inner| { + let value = v.borrow(); + if value.is_null() { + None + } else { + Some(value.to_map_ref().and_then(|inner| { inner .iter() .map(|(k, v)| Ok((k.to_text()?, v))) .collect::>() - }) - .transpose()? - .ok_or_else(|| Error::StructureError(format!("{key} must be a bool"))) + })) + } }) + .flatten() .transpose() } @@ -339,12 +349,11 @@ where &'a self, key: &str, ) -> Result { - self.get_optional_inner_borrowed_str_value_map(key)? - .ok_or_else(|| { - Error::StructureError(format!( - "unable to get borrowed str value map property {key}" - )) - }) + self.get_optional_str_value_map(key)?.ok_or_else(|| { + Error::StructureError(format!( + "unable to get borrowed str value map property {key}" + )) + }) } fn get_optional_inner_str_json_value_map>( @@ -353,17 +362,19 @@ where ) -> Result, Error> { self.get(key) .map(|v| { - v.borrow() - .as_map() - .map(|inner| { + let value = v.borrow(); + if value.is_null() { + None + } else { + Some(value.to_map_ref().and_then(|inner| { inner .iter() .map(|(k, v)| Ok((k.to_text()?, v.clone().try_into()?))) .collect::>() - }) - .transpose()? - .ok_or_else(|| Error::StructureError(format!("{key} must be a bool"))) + })) + } }) + .flatten() .transpose() } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 7f43bb2429c..4601d3c4fee 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -55,29 +55,30 @@ impl DocumentsBatchTransitionWasm { let data_contracts_array_js = Array::from(&data_contracts); let mut data_contracts: Vec = vec![]; + for contract in data_contracts_array_js.iter() { - let json_value = contract.with_serde_to_json_value()?; - let data_contract = DataContract::from_json_object(json_value).with_js_error()?; + let value = contract.with_serde_to_platform_value()?; + let data_contract = DataContract::from_raw_object(value).with_js_error()?; data_contracts.push(data_contract); } - let mut batch_transition_value = js_raw_transition.with_serde_to_platform_value_map()?; + let mut batch_transition_value = js_raw_transition.with_serde_to_platform_value()?; let base_identifier_fields = document_base_transition::IDENTIFIER_FIELDS .iter() - .map(|field| format!("{}.{}", property_names::TRANSITIONS, field)); + .map(|field| format!("{}[].{}", property_names::TRANSITIONS, field)) + .collect::>(); batch_transition_value .replace_at_paths( DocumentsBatchTransition::identifiers_property_paths() .into_iter() - .map(|field| field.to_string()) - .chain(base_identifier_fields), + .chain(base_identifier_fields.iter().map(|s| s.as_str())), ReplacementType::Identifier, ) .map_err(ProtocolError::ValueError) .with_js_error()?; let documents_batch_transition = - DocumentsBatchTransition::from_value_map(batch_transition_value, data_contracts) + DocumentsBatchTransition::from_raw_object(batch_transition_value, data_contracts) .with_js_error()?; Ok(documents_batch_transition.into()) diff --git a/packages/wasm-dpp/src/errors/value_error.rs b/packages/wasm-dpp/src/errors/value_error.rs index b90c4f3ad0a..5539dddbd16 100644 --- a/packages/wasm-dpp/src/errors/value_error.rs +++ b/packages/wasm-dpp/src/errors/value_error.rs @@ -1,7 +1,8 @@ use dpp::platform_value::Error as PlatformValueError; use wasm_bindgen::prelude::*; -#[wasm_bindgen(js_name=PlatformValueError)] +#[wasm_bindgen(js_name=PlatformValueError, inspectable)] +#[derive(Debug)] pub struct PlatformValueErrorWasm { message: String, } diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index 9e4cb47bffc..747839b2ade 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -174,6 +174,12 @@ impl IdentityWasm { #[wasm_bindgen(js_name=toObject)] pub fn to_object(&self) -> Result { + let js_public_keys = js_sys::Array::new(); + for pk in self.0.public_keys.values() { + let pk_wasm = IdentityPublicKeyWasm::from(pk.to_owned()); + js_public_keys.push(&pk_wasm.to_object()?); + } + let value = self.0.to_cleaned_object().with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_object = with_js_error!(value.serialize(&serializer))?; @@ -186,6 +192,12 @@ impl IdentityWasm { &JsValue::from(id.to_buffer()), )?; + js_sys::Reflect::set( + &js_object, + &"publicKeys".to_owned().into(), + &JsValue::from(&js_public_keys), + )?; + Ok(js_object) } From 223873d6631006b99395756957d0281f61691a4f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 20 Mar 2023 23:24:13 +0700 Subject: [PATCH 181/228] more fixes --- .../documents_batch_transition/mod.rs | 35 +++++++++--- ...lidate_documents_batch_transition_basic.rs | 17 ++++-- ...cumentsBatchTransitionBasicFactory.spec.js | 57 ++++++++----------- 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 06ab17c22e8..cd77f51b422 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -7,13 +7,11 @@ use integer_encoding::VarInt; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; -use platform_value::{BinaryData, ReplacementType, Value}; +use platform_value::{BinaryData, IntegerReplacementType, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use crate::data_contract::DataContract; -use crate::document::document_transition::document_base_transition::IDENTIFIER_FIELDS; -use crate::document::document_transition::document_create_transition::BINARY_FIELDS; use crate::document::document_transition::DocumentTransitionObjectLike; use crate::prelude::{DocumentTransition, Identifier}; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; @@ -43,6 +41,8 @@ pub mod property_names { pub const DATA_CONTRACT_ID: &str = "$dataContractId"; pub const DOCUMENT_TYPE: &str = "$type"; pub const TRANSITIONS: &str = "transitions"; + pub const TRANSITIONS_ID: &str = "transitions[].$id"; + pub const TRANSITIONS_DATA_CONTRACT_ID: &str = "transitions[].$dataContractId"; pub const OWNER_ID: &str = "ownerId"; pub const SIGNATURE_PUBLIC_KEY_ID: &str = "signaturePublicKeyId"; pub const SIGNATURE: &str = "signature"; @@ -50,6 +50,13 @@ pub mod property_names { pub const SECURITY_LEVEL_REQUIREMENT: &str = "signatureSecurityLevelRequirement"; } +pub const IDENTIFIER_FIELDS: [&str; 3] = [ + property_names::OWNER_ID, + property_names::TRANSITIONS_ID, + property_names::TRANSITIONS_DATA_CONTRACT_ID, +]; +pub const U32_FIELDS: [&str; 1] = [property_names::PROTOCOL_VERSION]; + const DEFAULT_SECURITY_LEVEL: SecurityLevel = SecurityLevel::HIGH; const EMPTY_VEC: Vec = vec![]; @@ -217,17 +224,21 @@ impl DocumentsBatchTransition { raw_transition_map .replace_at_paths( - identifiers - .into_iter() - .chain(IDENTIFIER_FIELDS.iter().map(|a| a.to_string())), + identifiers.into_iter().chain( + document_base_transition::IDENTIFIER_FIELDS + .iter() + .map(|a| a.to_string()), + ), ReplacementType::Identifier, ) .map_err(ProtocolError::ValueError)?; raw_transition_map .replace_at_paths( - binary_paths - .into_iter() - .chain(BINARY_FIELDS.iter().map(|a| a.to_string())), + binary_paths.into_iter().chain( + document_create_transition::BINARY_FIELDS + .iter() + .map(|a| a.to_string()), + ), ReplacementType::BinaryBytes, ) .map_err(ProtocolError::ValueError)?; @@ -245,6 +256,12 @@ impl DocumentsBatchTransition { pub fn get_transitions(&self) -> &Vec { &self.transitions } + + pub fn clean_value(value: &mut Value) -> Result<(), platform_value::Error> { + value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; + value.replace_integer_type_at_paths(U32_FIELDS, IntegerReplacementType::U32)?; + Ok(()) + } } impl StateTransitionIdentitySigned for DocumentsBatchTransition { diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index d53e2494984..3e1cc1333f7 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -1,4 +1,6 @@ use dpp::document::validation::basic::validate_documents_batch_transition_basic; +use dpp::document::DocumentsBatchTransition; +use dpp::validation::SimpleValidationResult; use std::sync::Arc; use wasm_bindgen::prelude::*; @@ -18,17 +20,24 @@ pub async fn validate_documents_batch_transition_basic_wasm( execution_context: StateTransitionExecutionContextWasm, ) -> Result { let wrapped_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository); - let raw_state_transition = js_raw_state_transition.with_serde_to_platform_value()?; + let mut value = js_raw_state_transition.with_serde_to_platform_value()?; - let validation_result = + let mut validation_result = SimpleValidationResult::default(); + if let Some(err) = DocumentsBatchTransition::clean_value(&mut value).err() { + validation_result.add_error(err); + return Ok(validation_result.map(|_| JsValue::undefined()).into()); + } + + validation_result.merge( validate_documents_batch_transition_basic::validate_documents_batch_transition_basic( &protocol_version_validator.into(), - &raw_state_transition, + &value, Arc::new(wrapped_state_repository), &execution_context.into(), ) .await - .with_js_error()?; + .with_js_error()?, + ); Ok(validation_result.map(|_| JsValue::undefined()).into()) } diff --git a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js index 50ba8bacb86..a7fa277532e 100644 --- a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js @@ -6,7 +6,7 @@ const getDataContractFixture = require('@dashevo/dpp/lib/test/fixtures/getDataCo const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); const { default: loadWasmDpp } = require('../../../../../../../dist'); -const { expectJsonSchemaError, expectValidationError } = require('../../../../../../../lib/test/expect/expectError'); +const { expectJsonSchemaError, expectValidationError, expectPlatformValueError } = require('../../../../../../../lib/test/expect/expectError'); let DataContract; let DocumentsBatchTransition; @@ -25,6 +25,7 @@ let DuplicateDocumentTransitionsWithIndicesError; let DuplicateDocumentTransitionsWithIdsError; let ValidationResult; let ProtocolVersionValidator; +let PlatformValueError; describe('validateDocumentsBatchTransitionBasicFactory', () => { let dataContract; @@ -56,6 +57,7 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { InvalidDocumentTransitionIdError, DuplicateDocumentTransitionsWithIndicesError, DuplicateDocumentTransitionsWithIdsError, + PlatformValueError, } = await loadWasmDpp()); const dataContractJs = getDataContractFixture(); @@ -117,12 +119,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result, 1); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/protocolVersion'); - expect(error.getKeyword()).to.equal('type'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should be valid - Rust', async () => { @@ -210,12 +211,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result, 32); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/ownerId/0'); - expect(error.getKeyword()).to.equal('type'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should be no less than 32 bytes - Rust', async () => { @@ -228,12 +228,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result, 1); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/ownerId'); - expect(error.getKeyword()).to.equal('minItems'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should be no longer than 32 bytes - Rust', async () => { @@ -246,12 +245,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result, 1); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/ownerId'); - expect(error.getKeyword()).to.equal('maxItems'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); }); @@ -265,13 +263,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { rawStateTransition, executionContext, ); - await expectJsonSchemaError(result, 1); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal(''); - expect(error.getKeyword()).to.equal('required'); - expect(error.getParams().missingProperty).to.equal('transitions'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should be an array - Rust', async () => { @@ -284,12 +280,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result, 1); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/transitions'); - expect(error.getKeyword()).to.equal('type'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should have at least one element - Rust', async () => { @@ -340,12 +335,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result, 1); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/transitions/0'); - expect(error.getKeyword()).to.equal('type'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); describe('document transition', () => { @@ -382,12 +376,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result, 32); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/$id/0'); - expect(error.getKeyword()).to.equal('type'); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should be no less than 32 bytes - Rust', async () => { @@ -402,13 +395,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectJsonSchemaError(result); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/$id'); - expect(error.getKeyword()).to.equal('minItems'); - expect(error.getParams().minItems).to.equal(32); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should be no longer than 32 bytes - Rust', async () => { @@ -422,13 +413,11 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { rawStateTransition, executionContext, ); - await expectJsonSchemaError(result); + await expectPlatformValueError(result, 1); const [error] = result.getErrors(); - expect(error.getInstancePath()).to.equal('/$id'); - expect(error.getKeyword()).to.equal('maxItems'); - expect(error.getParams().maxItems).to.equal(32); + expect(error).to.be.an.instanceOf(PlatformValueError); }); it('should no have duplicate IDs in the state transition - Rust', async () => { From e28d36523fc6972eda12f26c357cf87b0e5a938e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 01:29:22 +0700 Subject: [PATCH 182/228] more fixes --- packages/wasm-dpp/src/document/factory.rs | 4 ++-- packages/wasm-dpp/src/identifier/mod.rs | 4 +++- packages/wasm-dpp/test/unit/Identifier.spec.js | 8 ++++---- .../test/unit/document/DocumentFactory.spec.js | 18 ++++++------------ 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 47a38f912d0..bbf8b7aad46 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use anyhow::anyhow; use dpp::platform_value::ReplacementType; use dpp::{ @@ -10,14 +9,15 @@ use dpp::{ }, ProtocolError, }; +use std::collections::HashMap; use wasm_bindgen::prelude::*; +use crate::document::errors::InvalidActionNameError; use dpp::platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use dpp::prelude::ExtendedDocument; use std::convert::TryFrom; use std::sync::Arc; -use crate::document::errors::InvalidActionNameError; use crate::{ identifier::identifier_from_js_value, diff --git a/packages/wasm-dpp/src/identifier/mod.rs b/packages/wasm-dpp/src/identifier/mod.rs index bd4646dbc78..e1556b3db84 100644 --- a/packages/wasm-dpp/src/identifier/mod.rs +++ b/packages/wasm-dpp/src/identifier/mod.rs @@ -75,7 +75,9 @@ impl IdentifierWrapper { let vec = js_value.dyn_into::()?.to_vec(); - let identifier = Identifier::from_bytes(&vec).map_err(ProtocolError::ValueError).with_js_error()?; + let identifier = Identifier::from_bytes(&vec) + .map_err(ProtocolError::ValueError) + .with_js_error()?; Ok(IdentifierWrapper { wrapped: identifier, diff --git a/packages/wasm-dpp/test/unit/Identifier.spec.js b/packages/wasm-dpp/test/unit/Identifier.spec.js index f6568ad56bc..0013fb812c0 100644 --- a/packages/wasm-dpp/test/unit/Identifier.spec.js +++ b/packages/wasm-dpp/test/unit/Identifier.spec.js @@ -1,6 +1,6 @@ const crypto = require('crypto'); const bs58 = require('bs58'); -let { Identifier, IdentifierError } = require('../..'); +let { Identifier, IdentifierError, PlatformValueError } = require('../..'); const { default: loadWasmDpp } = require('../..'); describe('Identifier', () => { @@ -9,7 +9,7 @@ describe('Identifier', () => { beforeEach(async () => { buffer = crypto.randomBytes(32); - ({ Identifier, IdentifierError } = await loadWasmDpp()); + ({ Identifier, IdentifierError, PlatformValueError } = await loadWasmDpp()); }); describe('#constructor', () => { @@ -39,8 +39,8 @@ describe('Identifier', () => { expect.fail('Expected to throw error'); } catch (e) { - expect(e).to.be.instanceOf(IdentifierError); - expect(e.toString()).to.be.equal('IdentifierError: Identifier must be 32 bytes long'); + expect(e).to.be.instanceOf(PlatformValueError); + expect(e.getMessage()).to.equal('byte length not 32 bytes error: Identifier must be 32 bytes long'); } }); }); diff --git a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js index 4ef6cfb4296..2fba0cfee9b 100644 --- a/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/DocumentFactory.spec.js @@ -14,7 +14,7 @@ let { Identifier, DocumentFactory, DataContract, ExtendedDocument, DocumentValidator, ProtocolVersionValidator, InvalidDocumentTypeInDataContractError, InvalidDocumentError, JsonSchemaError, NoDocumentsSuppliedError, MismatchOwnerIdsError, InvalidInitialRevisionError, - InvalidActionNameError, + InvalidActionNameError, PlatformValueError, } = require('../../..'); const { default: loadWasmDpp } = require('../../..'); @@ -54,6 +54,7 @@ describe('DocumentFactory', () => { MismatchOwnerIdsError, InvalidInitialRevisionError, InvalidActionNameError, + PlatformValueError, } = await loadWasmDpp()); }); @@ -228,20 +229,14 @@ describe('DocumentFactory', () => { it('should throw InvalidDocumentError if Data Contract is not valid', async () => { const dc = DataContract.fromBuffer(dataContractJs.toBuffer()); dc.setDocuments({ '$%34': { '^&*': 'Keck' } }); - const oldDataContract = DataContract.fromBuffer(dataContractJs.toBuffer()); stateRepositoryMock.fetchDataContract.resolves(dc); try { await factory.createFromObject(rawDocumentJs); - expect.fail('InvalidDocumentError should be thrown'); + expect.fail('InvalidDocumentTypeInDataContractError should be thrown'); } catch (e) { - expect(e).to.be.an.instanceOf(InvalidDocumentError); - - expect(e.getErrors()).to.have.length(1); - expect( - (new Document(e.getRawDocument(), oldDataContract).toObject()), - ).to.deep.equal(rawDocumentJs); + expect(e).to.be.an.instanceOf(InvalidDocumentTypeInDataContractError); expect(stateRepositoryMock.fetchDataContract.callCount).to.be.equal(1); const callArguments = stateRepositoryMock.fetchDataContract.getCall(0).args[0]; @@ -293,9 +288,8 @@ describe('DocumentFactory', () => { expect.fail('should throw an error'); } catch (e) { - // TODO - parsing errors are not handled yet, as they happen directly in the rust code when - // trying to access a field - expect(e).to.startsWith('Error conversion not implemented:'); + expect(e).to.be.instanceOf(PlatformValueError); + expect(e.getMessage()).to.equal('structure error: value is not a map'); } }); }); describe('createStateTransition', () => { From bbb2face22932cdc7daf4eff77c68c24f2d25229 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 04:08:25 +0700 Subject: [PATCH 183/228] more fixes --- packages/js-dpp/CHANGELOG.md | 2 +- .../getIdentityUpdateTransitionFixture.js | 2 ++ .../src/data_trigger/dpns_triggers/mod.rs | 2 +- packages/rs-dpp/src/identity/identity.rs | 6 +----- .../identity_create_transition.rs | 3 ++- .../identity_update_transition.rs | 17 ++++++++++++++- .../get_identity_update_transition_fixture.rs | 2 ++ .../src/data_contract/data_contract.rs | 2 +- .../src/data_contract/data_contract_facade.rs | 6 +++--- .../data_contract_factory.rs | 10 ++------- packages/wasm-dpp/src/identity/mod.rs | 1 + .../identity_update_transition.rs | 21 ++++++++++++------- .../unit/identity/IdentityFactory.spec.js | 2 +- ...plyIdentityUpdateTransitionFactory.spec.js | 3 ++- 14 files changed, 48 insertions(+), 31 deletions(-) diff --git a/packages/js-dpp/CHANGELOG.md b/packages/js-dpp/CHANGELOG.md index eb45f6a4308..975e305a759 100644 --- a/packages/js-dpp/CHANGELOG.md +++ b/packages/js-dpp/CHANGELOG.md @@ -288,7 +288,7 @@ ### Bug Fixes * do not allow to change `ownerId` and `entropy` ([bff5807](https://github.com/dashevo/js-dpp/commit/bff580701322e2100e484989c476d583d26af38a)) -* json schema for `signaturePublicKeyId` ([#161](https://github.com/dashevo/js-dpp/issues/161)) +* json schema for `signature_public_key_id` ([#161](https://github.com/dashevo/js-dpp/issues/161)) * wrong entropy size ([#157](https://github.com/dashevo/js-dpp/issues/157)) * data contract definitions might be `null` or `undefined` ([#153](https://github.com/dashevo/js-dpp/issues/153)) * identity existence validation in data contract structure validation ([#149](https://github.com/dashevo/js-dpp/issues/149)) diff --git a/packages/js-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js b/packages/js-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js index efb80c3e12d..cc3413ac5ed 100644 --- a/packages/js-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js +++ b/packages/js-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js @@ -7,6 +7,8 @@ const IdentityPublicKey = require('../../identity/IdentityPublicKey'); module.exports = function getIdentityUpdateTransitionFixture() { const rawStateTransition = { + signature: Buffer.alloc(0), + signaturePublicKeyId: 0, protocolVersion: protocolVersion.latestVersion, type: stateTransitionTypes.IDENTITY_UPDATE, assetLockProof: getInstantAssetLockProofFixture().toObject(), diff --git a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs index 43d2fda79a2..955a14c80ad 100644 --- a/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-dpp/src/data_trigger/dpns_triggers/mod.rs @@ -195,7 +195,7 @@ where if (!parent_domain .properties - .get_bool(PROPERTY_ALLOW_SUBDOMAINS)?) + .get_bool_at_path(PROPERTY_ALLOW_SUBDOMAINS)?) && context.owner_id != &parent_domain.owner_id { let err = create_error( diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 05bff0e927e..81c2f7f56d2 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -39,6 +39,7 @@ pub struct Identity { pub public_keys: BTreeMap, pub balance: u64, pub revision: Revision, + #[serde(skip)] pub asset_lock_proof: Option, #[serde(skip)] pub metadata: Option, @@ -93,11 +94,6 @@ impl Convertible for Identity { fn to_cleaned_object(&self) -> Result { //same as object for Identities let mut value = self.to_object()?; - if self.asset_lock_proof.is_none() { - value - .remove("assetLockProof") - .map_err(ProtocolError::ValueError)?; - } if let Some(keys) = value.get_optional_array_mut_ref(property_names::PUBLIC_KEYS)? { for key in keys.iter_mut() { if let Some(value) = key.get_optional_value("disabledAt")? { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 6765890120e..69e153a2f6a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -16,9 +16,10 @@ use crate::{NonConsensusError, ProtocolError}; use platform_value::btreemap_extensions::BTreeValueRemoveInnerValueFromMapHelper; pub const IDENTIFIER_FIELDS: [&str; 1] = [property_names::IDENTITY_ID]; -pub const BINARY_FIELDS: [&str; 2] = [ +pub const BINARY_FIELDS: [&str; 3] = [ property_names::PUBLIC_KEYS_DATA, property_names::PUBLIC_KEYS_SIGNATURE, + property_names::SIGNATURE, ]; pub const U32_FIELDS: [&str; 1] = [property_names::PROTOCOL_VERSION]; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 94ec80238a4..d2fa68d02ab 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -1,4 +1,4 @@ -use platform_value::{BinaryData, Value}; +use platform_value::{BinaryData, IntegerReplacementType, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::convert::{TryFrom, TryInto}; @@ -21,6 +21,8 @@ pub mod property_names { pub const TYPE: &str = "type"; pub const IDENTITY_ID: &str = "identityId"; pub const REVISION: &str = "revision"; + pub const ADD_PUBLIC_KEYS_DATA: &str = "addPublicKeys[].data"; + pub const ADD_PUBLIC_KEYS_SIGNATURE: &str = "addPublicKeys[].signature"; pub const ADD_PUBLIC_KEYS: &str = "addPublicKeys"; pub const DISABLE_PUBLIC_KEYS: &str = "disablePublicKeys"; pub const PUBLIC_KEYS_DISABLED_AT: &str = "publicKeysDisabledAt"; @@ -28,6 +30,13 @@ pub mod property_names { pub const SIGNATURE_PUBLIC_KEY_ID: &str = "signaturePublicKeyId"; } +pub const IDENTIFIER_FIELDS: [&str; 1] = [property_names::IDENTITY_ID]; +pub const BINARY_FIELDS: [&str; 3] = [ + property_names::ADD_PUBLIC_KEYS_DATA, + property_names::ADD_PUBLIC_KEYS_SIGNATURE, + property_names::SIGNATURE, +]; + #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct IdentityUpdateTransition { @@ -182,6 +191,12 @@ impl IdentityUpdateTransition { pub fn set_protocol_version(&mut self, protocol_version: u32) { self.protocol_version = protocol_version; } + + pub fn clean_value(value: &mut Value) -> Result<(), platform_value::Error> { + value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; + value.replace_at_paths(BINARY_FIELDS, ReplacementType::BinaryBytes)?; + Ok(()) + } } /// if the property isn't present the empty list is returned. If property is defined, the function diff --git a/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs index 9590f17829d..2cd2f589a51 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_identity_update_transition_fixture.rs @@ -15,6 +15,8 @@ pub fn get_identity_update_transition_fixture() -> IdentityUpdateTransition { IdentityUpdateTransition { protocol_version: LATEST_VERSION, transition_type: StateTransitionType::IdentityUpdate, + signature: BinaryData::new(vec![0; 65]), + signature_public_key_id: 0, identity_id: generate_random_identifier_struct(), revision: 0, add_public_keys: vec![IdentityPublicKeyWithWitness { diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index 1cd6d45c1db..d9ea3d7d4f0 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -72,7 +72,7 @@ pub(crate) struct DataContractParameters { _extras: serde_json::Value, // Captures excess fields to trigger validation failure later. } -pub fn js_value_to_platform_value(object: JsValue) -> Result { +pub fn js_value_to_data_contract_value(object: JsValue) -> Result { let parameters: DataContractParameters = with_js_error!(serde_wasm_bindgen::from_value(object))?; diff --git a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs index ceaa4f750a3..69684a80ae3 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs @@ -1,7 +1,7 @@ use crate::errors::protocol_error::from_protocol_error; use crate::{ - js_value_to_platform_value, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, + js_value_to_data_contract_value, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, DataContractWasm, }; use dpp::data_contract::DataContractFacade; @@ -73,7 +73,7 @@ impl DataContractFacadeWasm { self.0 .create_from_object( - js_value_to_platform_value(js_raw_data_contract)?, + js_value_to_data_contract_value(js_raw_data_contract)?, skip_validation, ) .await @@ -126,7 +126,7 @@ impl DataContractFacadeWasm { &self, js_raw_data_contract: JsValue, ) -> Result { - let raw_data_contract = js_value_to_platform_value(js_raw_data_contract)?; + let raw_data_contract = js_value_to_data_contract_value(js_raw_data_contract)?; self.0 .validate(raw_data_contract) diff --git a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs index 88965eb2a90..3b1cb57e8b4 100644 --- a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs +++ b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs @@ -14,13 +14,7 @@ use dpp::{ use wasm_bindgen::prelude::*; use crate::utils::WithJsError; -use crate::{ - data_contract::errors::InvalidDataContractError, - errors::{from_dpp_err, protocol_error::from_protocol_error}, - js_value_to_platform_value, - validation::ValidationResultWasm, - with_js_error, DataContractCreateTransitionWasm, DataContractParameters, DataContractWasm, -}; +use crate::{data_contract::errors::InvalidDataContractError, errors::{from_dpp_err, protocol_error::from_protocol_error}, js_value_to_identity_update_transition_object, validation::ValidationResultWasm, with_js_error, DataContractCreateTransitionWasm, DataContractParameters, DataContractWasm, js_value_to_data_contract_value}; #[wasm_bindgen(js_name=DataContractValidator)] pub struct DataContractValidatorWasm(DataContractValidator); @@ -140,7 +134,7 @@ impl DataContractFactoryWasm { object: JsValue, skip_validation: Option, ) -> Result { - let parameters_value = js_value_to_platform_value(object.clone())?; + let parameters_value = js_value_to_data_contract_value(object.clone())?; let result = self .0 .create_from_object(parameters_value, skip_validation.unwrap_or(false)) diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index 747839b2ade..8b05f3ae538 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -181,6 +181,7 @@ impl IdentityWasm { } let value = self.0.to_cleaned_object().with_js_error()?; + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_object = with_js_error!(value.serialize(&serializer))?; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index d0aecbf2e89..3e9d52289c8 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -19,7 +19,7 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::utils::{generic_of_js_val, WithJsError}; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::{KeyID, TimestampMillis}; -use dpp::platform_value::string_encoding; +use dpp::platform_value::{string_encoding, Value}; use dpp::platform_value::string_encoding::Encoding; use dpp::prelude::Revision; use dpp::state_transition::StateTransitionIdentitySigned; @@ -36,7 +36,8 @@ pub struct IdentityUpdateTransitionWasm(IdentityUpdateTransition); #[derive(Deserialize, Serialize)] #[serde(rename_all = "camelCase")] struct IdentityUpdateTransitionParams { - signature: Option>, + signature: Vec, + signature_public_key_id: KeyID, protocol_version: u32, identity_id: Vec, revision: Revision, @@ -57,18 +58,22 @@ impl From for IdentityUpdateTransition { } } +pub fn js_value_to_identity_update_transition_object(object: JsValue) -> Result { + let parameters: IdentityUpdateTransitionParams = + with_js_error!(serde_wasm_bindgen::from_value(object))?; + + platform_value::to_value(parameters).map_err(|e| e.to_string().into()) +} + #[wasm_bindgen(js_class = IdentityUpdateTransition)] impl IdentityUpdateTransitionWasm { #[wasm_bindgen(constructor)] pub fn new(raw_parameters: JsValue) -> Result { - let parameters: IdentityUpdateTransitionParams = - with_js_error!(serde_wasm_bindgen::from_value(raw_parameters))?; + let mut identity_update_transition_object = js_value_to_identity_update_transition_object(raw_parameters)?; - let raw_state_transition = platform_value::to_value(parameters) - .map_err(ProtocolError::ValueError) - .with_js_error()?; + IdentityUpdateTransition::clean_value(&mut identity_update_transition_object).map_err(ProtocolError::ValueError).with_js_error()?; - let identity_update_transition = IdentityUpdateTransition::new(raw_state_transition) + let identity_update_transition = IdentityUpdateTransition::new(identity_update_transition_object) .map_err(|e| RustConversionError::Error(e.to_string()).to_js_value())?; Ok(identity_update_transition.into()) diff --git a/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js b/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js index 70ea57e0dcf..59bdb60fa80 100644 --- a/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js +++ b/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js @@ -139,7 +139,7 @@ describe('IdentityFactory', () => { expect(e).to.be.an.instanceOf(InvalidIdentityError); const [innerError] = e.getErrors(); - expect(innerError).to.be.instanceOf(JsonSchemaError); + expect(innerError).to.be.instanceOf(UnsupportedProtocolVersionError); } }); diff --git a/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js index b9c5b0ad2d3..76d98e91b4f 100644 --- a/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js @@ -23,8 +23,9 @@ describe('applyIdentityUpdateTransition', () => { }); beforeEach(async function beforeEach() { + const object = getIdentityUpdateTransitionFixture().toObject(); stateTransition = new IdentityUpdateTransition( - getIdentityUpdateTransitionFixture().toObject(), + object, ); stateTransition.setRevision(stateTransition.getRevision() + 1); From 754e7934f011343912376f458fb4eadf5ebad3cb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 14:00:34 +0700 Subject: [PATCH 184/228] more fixes --- .../asset_lock_transaction_output_fetcher.rs | 2 +- .../chain/chain_asset_lock_proof.rs | 9 +- ...in_asset_lock_proof_structure_validator.rs | 18 +- ...nt_asset_lock_proof_structure_validator.rs | 7 +- .../state_transition/asset_lock_proof/mod.rs | 2 +- .../validation/state/mod.rs | 7 +- ...tity_credit_withdrawal_transition_state.rs | 7 +- ...lidate_identity_update_transition_state.rs | 14 +- .../identity_update_transition_spec.rs | 4 +- .../btreemap_field_replacement.rs | 17 ++ .../src/converter/ciborium.rs | 1 + .../src/converter/serde_json.rs | 13 ++ packages/rs-platform-value/src/display.rs | 2 + packages/rs-platform-value/src/error.rs | 3 + packages/rs-platform-value/src/index.rs | 1 + packages/rs-platform-value/src/lib.rs | 15 +- packages/rs-platform-value/src/patch/diff.rs | 1 + .../rs-platform-value/src/system_bytes.rs | 102 +++++++++- .../rs-platform-value/src/types/bytes_36.rs | 184 ++++++++++++++++++ packages/rs-platform-value/src/types/mod.rs | 1 + .../src/value_serialization/de.rs | 11 +- .../src/value_serialization/ser.rs | 9 + .../src/data_contract/data_contract_facade.rs | 4 +- .../data_contract_factory.rs | 8 +- .../src/document/extended_document.rs | 3 + packages/wasm-dpp/src/document/mod.rs | 3 + .../chain/chain_asset_lock_proof.rs | 4 +- .../identity_update_transition.rs | 14 +- .../StateTransitionFacade.spec.js | 3 +- 29 files changed, 435 insertions(+), 34 deletions(-) create mode 100644 packages/rs-platform-value/src/types/bytes_36.rs diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs index fe951b16d53..96ce12b407d 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/asset_lock_transaction_output_fetcher.rs @@ -45,7 +45,7 @@ pub async fn fetch_asset_lock_transaction_output( .ok_or_else(|| DPPError::from(AssetLockOutputNotFoundError::new())) .cloned(), AssetLockProof::Chain(asset_lock_proof) => { - let out_point = OutPoint::from(asset_lock_proof.out_point); + let out_point = OutPoint::from(asset_lock_proof.out_point.to_buffer()); let output_index = out_point.vout as usize; let transaction_hash = out_point.txid; diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index d6594371d0c..3493b07c608 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -1,4 +1,4 @@ -use platform_value::Value; +use platform_value::{Bytes36, Value}; use serde::{Deserialize, Serialize}; use serde_big_array::BigArray; use std::convert::TryFrom; @@ -14,8 +14,7 @@ pub struct ChainAssetLockProof { #[serde(rename = "type")] asset_lock_type: u8, pub core_chain_locked_height: u32, - #[serde(with = "BigArray")] - pub out_point: [u8; 36], + pub out_point: Bytes36, } impl TryFrom for ChainAssetLockProof { @@ -38,7 +37,7 @@ impl ChainAssetLockProof { // TODO: change to const asset_lock_type: 1, core_chain_locked_height, - out_point, + out_point: Bytes36::new(out_point), } } @@ -49,7 +48,7 @@ impl ChainAssetLockProof { /// Create identifier pub fn create_identifier(&self) -> Result { - let array = vec_to_array(hash(self.out_point).as_ref())?; + let array = vec_to_array(hash(self.out_point.as_slice()).as_ref())?; Ok(Identifier::new(array)) } } diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs index 2c7d0bc7d85..69e04462318 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof_structure_validator.rs @@ -88,7 +88,7 @@ where let proof: ChainAssetLockProof = platform_value::from_value(asset_lock_proof_object.clone()) - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; + .map_err(NonConsensusError::ValueError)?; let proof_core_chain_locked_height = proof.core_chain_locked_height; @@ -96,7 +96,7 @@ where .state_repository .fetch_latest_platform_core_chain_locked_height() .await - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))? + .map_err(|e| NonConsensusError::StateRepositoryFetchError(format!("state repository fetch current core chain locked height for chain asset lock proof verification error: {}",e.to_string())))? .unwrap_or(0); if current_core_chain_locked_height < proof_core_chain_locked_height { @@ -119,12 +119,22 @@ where .state_repository .fetch_transaction(&transaction_hash_string, execution_context) .await - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; + .map_err(|e| { + NonConsensusError::StateRepositoryFetchError(format!( + "transaction fetching error for chain lock: {}", + e.to_string() + )) + })?; let transaction_result = transaction_fetch_result .try_into() .map_err(Into::into) - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; + .map_err(|e| { + NonConsensusError::StateRepositoryFetchError(format!( + "transaction decoding error: {}", + e.to_string() + )) + })?; if let Some(tx_height) = transaction_result.height { if proof_core_chain_locked_height < tx_height { diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs index 03d481c70bc..03d24b254b6 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/instant/instant_asset_lock_proof_structure_validator.rs @@ -83,7 +83,12 @@ where .state_repository .verify_instant_lock(&instant_lock, execution_context) .await - .map_err(|err| NonConsensusError::StateRepositoryFetchError(err.to_string()))?; + .map_err(|e| { + NonConsensusError::StateRepositoryFetchError(format!( + "state repository verify instant send lock error: {}", + e.to_string() + )) + })?; if !is_signature_verified { result.add_error(InvalidInstantAssetLockProofSignatureError::new()); diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index d5388ef5ed3..054efcca58b 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -132,7 +132,7 @@ impl AssetLockProof { pub fn out_point(&self) -> Option<[u8; 36]> { match self { AssetLockProof::Instant(proof) => proof.out_point(), - AssetLockProof::Chain(proof) => Some(proof.out_point), + AssetLockProof::Chain(proof) => Some(proof.out_point.to_buffer()), } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs index af39143a4a7..a064cbb11b4 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs @@ -60,7 +60,12 @@ pub async fn validate_identity_create_transition_state( let balance = state_repository .fetch_identity_balance(identity_id, state_transition.get_execution_context()) .await - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; + .map_err(|e| { + NonConsensusError::StateRepositoryFetchError(format!( + "state repository fetch identity balance error: {}", + e.to_string() + )) + })?; if state_transition.get_execution_context().is_dry_run() { return Ok(result); diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/state/validate_identity_credit_withdrawal_transition_state.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/state/validate_identity_credit_withdrawal_transition_state.rs index 0dfa0ca7f41..a3d05d06d21 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/state/validate_identity_credit_withdrawal_transition_state.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/validation/state/validate_identity_credit_withdrawal_transition_state.rs @@ -43,7 +43,12 @@ where .map(TryInto::try_into) .transpose() .map_err(Into::into) - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; + .map_err(|e| { + NonConsensusError::StateRepositoryFetchError(format!( + "state repository fetch identity for credit withdrawal verification error: {}", + e.to_string() + )) + })?; let Some(existing_identity) = maybe_existing_identity else { let err = IdentityNotFoundError::new(state_transition.identity_id); diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs index 5c411894d67..0df01c27c9f 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_state.rs @@ -48,7 +48,12 @@ where .map(TryInto::try_into) .transpose() .map_err(Into::into) - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; + .map_err(|e| { + NonConsensusError::StateRepositoryFetchError(format!( + "state repository fetch identity for identity update validation error: {}", + e.to_string() + )) + })?; if state_transition.get_execution_context().is_dry_run() { return Ok(validation_result); @@ -105,7 +110,12 @@ where .state_repository .fetch_latest_platform_block_time() .await - .map_err(|e| NonConsensusError::StateRepositoryFetchError(e.to_string()))?; + .map_err(|e| { + NonConsensusError::StateRepositoryFetchError(format!( + "state repository fetch latest platform block time error: {}", + e.to_string() + )) + })?; let disabled_at_ms = state_transition.get_public_keys_disabled_at().ok_or( NonConsensusError::RequiredPropertyError { diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index e95fb139be8..aab679bd883 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -137,7 +137,7 @@ fn to_object() { let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1u32, "type" : 5u8, - "signature" : BinaryData::default(), + "signature" : BinaryData::new(vec![0u8;65]), "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id, "revision": 0 as Revision, @@ -200,7 +200,7 @@ fn to_json() { let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1u32, "type" : 5u8, - "signature" : BinaryData::default(), + "signature" : BinaryData::new(vec![0u8;65]), "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id, "revision": 0 as Revision, diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs index 404723dd6c7..b62ea9a45a9 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_field_replacement.rs @@ -69,6 +69,17 @@ impl ReplacementType { } } + pub fn replace_for_bytes_36(&self, bytes: [u8; 36]) -> Result { + match self { + ReplacementType::BinaryBytes => Ok(Value::Bytes36(bytes)), + ReplacementType::TextBase58 => Ok(Value::Text(bs58::encode(bytes).into_string())), + ReplacementType::TextBase64 => Ok(Value::Text(base64::encode(bytes))), + _ => Err(Error::ByteLengthNot36BytesError( + "trying to replace 36 bytes into an identifier".to_string(), + )), + } + } + pub fn replace_consume_value(&self, value: Value) -> Result { let bytes = value.into_identifier_bytes()?; self.replace_for_bytes(bytes) @@ -113,6 +124,9 @@ fn replace_down( Value::Bytes32(bytes) => { *new_value = replacement_type.replace_for_bytes_32(*bytes)?; } + Value::Bytes36(bytes) => { + *new_value = replacement_type.replace_for_bytes_36(*bytes)?; + } _ => { let bytes = match replacement_type { ReplacementType::Identifier | ReplacementType::TextBase58 => { @@ -167,6 +181,9 @@ impl BTreeValueMapReplacementPathHelper for BTreeMap { Value::Bytes32(bytes) => { *current_value = replacement_type.replace_for_bytes_32(*bytes)?; } + Value::Bytes36(bytes) => { + *current_value = replacement_type.replace_for_bytes_36(*bytes)?; + } _ => { let bytes = match replacement_type { ReplacementType::Identifier | ReplacementType::TextBase58 => { diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 18f6eb53fc1..9d893cc4e8e 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -99,6 +99,7 @@ impl TryInto for Value { Value::I8(i) => CborValue::Integer(i.into()), Value::Bytes(bytes) => CborValue::Bytes(bytes), Value::Bytes32(bytes) => CborValue::Bytes(bytes.to_vec()), + Value::Bytes36(bytes) => CborValue::Bytes(bytes.to_vec()), Value::Float(float) => CborValue::Float(float), Value::Text(string) => CborValue::Text(string), Value::Bool(value) => CborValue::Bool(value), diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index c6f56e290e7..e0a1379b008 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -78,6 +78,12 @@ impl Value { .map(|byte| JsonValue::Number(byte.into())) .collect(), ), + Value::Bytes36(bytes) => JsonValue::Array( + bytes + .into_iter() + .map(|byte| JsonValue::Number(byte.into())) + .collect(), + ), Value::EnumU8(_) => todo!(), Value::EnumString(_) => todo!(), }) @@ -154,6 +160,12 @@ impl Value { .map(|byte| JsonValue::Number((*byte).into())) .collect(), ), + Value::Bytes36(bytes) => JsonValue::Array( + bytes + .iter() + .map(|byte| JsonValue::Number((*byte).into())) + .collect(), + ), Value::EnumU8(_) => todo!(), Value::EnumString(_) => todo!(), }) @@ -268,6 +280,7 @@ impl TryInto for Value { Value::I8(i) => JsonValue::Number(i.into()), Value::Bytes(bytes) => JsonValue::String(base64::encode(bytes.as_slice())), Value::Bytes32(bytes) => JsonValue::String(base64::encode(bytes.as_slice())), + Value::Bytes36(bytes) => JsonValue::String(base64::encode(bytes.as_slice())), Value::Float(float) => JsonValue::Number(Number::from_f64(float).unwrap_or(0.into())), Value::Text(string) => JsonValue::String(string), Value::Bool(value) => JsonValue::Bool(value), diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index 62b0c944938..c2b96e208d8 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -46,6 +46,7 @@ impl Value { Value::U8(i) => format!("{}", i), Value::I8(i) => format!("{}", i), Value::Bytes32(bytes32) => format!("bytes32 {}", base64::encode(bytes32.as_slice())), + Value::Bytes36(bytes36) => format!("bytes36 {}", base64::encode(bytes36.as_slice())), Value::Identifier(identifier) => format!( "identifier {}", bs58::encode(identifier.as_slice()).into_string() @@ -101,6 +102,7 @@ impl Value { Value::U8(i) => format!("(u8){}", i), Value::I8(i) => format!("(i8){}", i), Value::Bytes32(bytes32) => format!("bytes32 {}", base64::encode(bytes32.as_slice())), + Value::Bytes36(bytes36) => format!("bytes36 {}", base64::encode(bytes36.as_slice())), Value::Identifier(identifier) => format!( "identifier {}", bs58::encode(identifier.as_slice()).into_string() diff --git a/packages/rs-platform-value/src/error.rs b/packages/rs-platform-value/src/error.rs index ce5579f85e0..906f62f4c64 100644 --- a/packages/rs-platform-value/src/error.rs +++ b/packages/rs-platform-value/src/error.rs @@ -28,6 +28,9 @@ pub enum Error { #[error("byte length not 32 bytes error: {0}")] ByteLengthNot32BytesError(String), + #[error("byte length not 36 bytes error: {0}")] + ByteLengthNot36BytesError(String), + #[error("serde serialization error: {0}")] SerdeSerializationError(String), diff --git a/packages/rs-platform-value/src/index.rs b/packages/rs-platform-value/src/index.rs index 8a9a61fa77e..6ba956dc41c 100644 --- a/packages/rs-platform-value/src/index.rs +++ b/packages/rs-platform-value/src/index.rs @@ -163,6 +163,7 @@ impl<'a> Display for Type<'a> { Value::I8(_) => formatter.write_str("i8"), Value::Bytes(_) => formatter.write_str("bytes"), Value::Bytes32(_) => formatter.write_str("bytes32"), + Value::Bytes36(_) => formatter.write_str("bytes36"), Value::Identifier(_) => formatter.write_str("identifier"), Value::EnumU8(_) => formatter.write_str("enum u8"), Value::EnumString(_) => formatter.write_str("enum string"), diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 96ef9bdfb4d..be78bd8ba75 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -37,6 +37,7 @@ pub use btreemap_extensions::btreemap_field_replacement::{ }; pub use types::binary_data::BinaryData; pub use types::bytes_32::Bytes32; +pub use types::bytes_36::Bytes36; pub use types::identifier::{Identifier, IDENTIFIER_MEDIA_TYPE}; pub use value_serialization::{from_value, to_value}; @@ -83,6 +84,9 @@ pub enum Value { /// Bytes 32 Bytes32([u8; 32]), + /// Bytes 36 : Useful for outpoints + Bytes36([u8; 36]), + /// An enumeration of u8 EnumU8(Vec), @@ -369,10 +373,14 @@ impl Value { /// let value = Value::Bytes32([1u8;32]); /// /// assert!(value.is_any_bytes_type()); + /// + /// let value = Value::Bytes36([1u8;36]); + /// + /// assert!(value.is_any_bytes_type()); /// ``` pub fn is_any_bytes_type(&self) -> bool { match self { - Value::Bytes(_) | Value::Bytes32(_) | Value::Identifier(_) => true, + Value::Bytes(_) | Value::Bytes32(_) | Value::Bytes36(_) | Value::Identifier(_) => true, _ => false, } } @@ -428,6 +436,7 @@ impl Value { match self { Value::Bytes(vec) => Ok(vec), Value::Bytes32(vec) => Ok(vec.to_vec()), + Value::Bytes36(vec) => Ok(vec.to_vec()), Value::Identifier(vec) => Ok(vec.to_vec()), Value::Array(array) => Ok(array .into_iter() @@ -453,6 +462,7 @@ impl Value { match self { Value::Bytes(vec) => Ok(vec.clone()), Value::Bytes32(vec) => Ok(vec.to_vec()), + Value::Bytes36(vec) => Ok(vec.to_vec()), Value::Identifier(vec) => Ok(vec.to_vec()), Value::Array(array) => Ok(array .iter() @@ -482,6 +492,7 @@ impl Value { match self { Value::Bytes(vec) => Ok(BinaryData::new(vec.clone())), Value::Bytes32(vec) => Ok(BinaryData::new(vec.to_vec())), + Value::Bytes36(vec) => Ok(BinaryData::new(vec.to_vec())), Value::Identifier(vec) => Ok(BinaryData::new(vec.to_vec())), Value::Array(array) => Ok(BinaryData::new( array @@ -512,6 +523,8 @@ impl Value { match self { Value::Bytes(vec) => Ok(vec), Value::Bytes32(vec) => Ok(vec.as_slice()), + Value::Bytes36(vec) => Ok(vec.as_slice()), + Value::Identifier(vec) => Ok(vec.as_slice()), _other => Err(Error::StructureError( "ref value are not bytes slice".to_string(), )), diff --git a/packages/rs-platform-value/src/patch/diff.rs b/packages/rs-platform-value/src/patch/diff.rs index 9b2ff790bb1..fe57ceca6c4 100644 --- a/packages/rs-platform-value/src/patch/diff.rs +++ b/packages/rs-platform-value/src/patch/diff.rs @@ -194,6 +194,7 @@ impl From for Option { Value::I8(i) => Some(PlatformItemKey::SignedIndex(i as i64)), Value::Bytes(bytes) => Some(PlatformItemKey::Bytes(bytes)), Value::Bytes32(bytes) => Some(PlatformItemKey::Bytes(bytes.into())), + Value::Bytes36(bytes) => Some(PlatformItemKey::Bytes(bytes.into())), Value::EnumU8(_) => None, Value::EnumString(_) => None, Value::Identifier(bytes) => Some(PlatformItemKey::Bytes(bytes.into())), diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index dc2b551e43e..ad8c942cfea 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -1,4 +1,4 @@ -use crate::{BinaryData, Bytes32, Error, Identifier, Value}; +use crate::{BinaryData, Bytes32, Bytes36, Error, Identifier, Value}; impl Value { /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the @@ -362,8 +362,8 @@ impl Value { })?), Value::Array(array) => Bytes32::from_vec( array - .iter() - .map(|byte| byte.to_integer()) + .into_iter() + .map(|byte| byte.into_integer()) .collect::, Error>>()?, ), Value::Bytes32(bytes) => Ok(Bytes32::new(bytes)), @@ -427,6 +427,102 @@ impl Value { } } + /// If the `Value` is a `Bytes`, a `Text` using base 64 or Vector of `U8`, returns the + /// associated `Bytes36` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Bytes36, Error, Value}; + /// + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 50, 51, 52, 53]); + /// assert_eq!(value.into_bytes_36(), Ok(Bytes36([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 50, 51, 52, 53]))); /// + /// + /// let value = Value::Text("sNr9aH0VUnzvKDADkuJUlZ4Yj7Yd7gbNnnOR4ANNat2g498D".to_string()); + /// assert_eq!(value.into_bytes_36(), Ok(Bytes36([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117, 00, 00, 00, 00]))); + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.into_bytes_36(), Err(Error::ByteLengthNot36BytesError("buffer was not 36 bytes long".to_string()))); + /// + /// let value = Value::Text("a811Ii".to_string()); + /// assert_eq!(value.into_bytes_36(), Err(Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(101), Value::U8(101), Value::U8(101), Value::U8(101)]); + /// assert_eq!(value.into_bytes_36(), Ok(Bytes36([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 101, 101, 101, 101]))); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.into_bytes_36(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn into_bytes_36(self) -> Result { + match self { + Value::Text(text) => Bytes36::from_vec(base64::decode(text).map_err(|_| { + Error::StructureError( + "value was a string, but could not be decoded from base 64".to_string(), + ) + })?), + Value::Array(array) => Bytes36::from_vec( + array + .into_iter() + .map(|byte| byte.into_integer()) + .collect::, Error>>()?, + ), + Value::Bytes36(bytes) => Ok(Bytes36::new(bytes)), + Value::Bytes(vec) => Bytes36::from_vec(vec), + _other => Err(Error::StructureError( + "value are not bytes, a string, or an array of values representing bytes" + .to_string(), + )), + } + } + + /// If the `Value` is a `Bytes`, a `Text` using base 64 or Vector of `U8`, returns the + /// associated `Bytes36` data as `Ok`. + /// Returns `Err(Error::Structure("reason"))` otherwise. + /// + /// ``` + /// # use platform_value::{Bytes36, Error, Value}; + /// + /// # + /// let value = Value::Bytes(vec![104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 50, 51, 52, 53]); + /// assert_eq!(value.to_bytes_36(), Ok(Bytes36([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 50, 51, 52, 53]))); /// + /// + /// let value = Value::Text("sNr9aH0VUnzvKDADkuJUlZ4Yj7Yd7gbNnnOR4ANNat2g498D".to_string()); + /// assert_eq!(value.to_bytes_36(), Ok(Bytes36([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117, 00, 00, 00, 00]))); + /// + /// let value = Value::Text("a811".to_string()); + /// assert_eq!(value.to_bytes_36(), Err(Error::ByteLengthNot36BytesError("buffer was not 36 bytes long".to_string()))); + /// + /// let value = Value::Text("a811Ii".to_string()); + /// assert_eq!(value.to_bytes_36(), Err(Error::StructureError("value was a string, but could not be decoded from base 64".to_string()))); + /// + /// let value = Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(101), Value::U8(101), Value::U8(101), Value::U8(101)]); + /// assert_eq!(value.to_bytes_36(), Ok(Bytes36([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 101, 101, 101, 101]))); + /// + /// let value = Value::Bool(true); + /// assert_eq!(value.to_bytes_36(), Err(Error::StructureError("value are not bytes, a string, or an array of values representing bytes".to_string()))); + /// ``` + pub fn to_bytes_36(&self) -> Result { + match self { + Value::Text(text) => Bytes36::from_vec(base64::decode(text).map_err(|_| { + Error::StructureError( + "value was a string, but could not be decoded from base 64".to_string(), + ) + })?), + Value::Array(array) => Bytes36::from_vec( + array + .iter() + .map(|byte| byte.to_integer()) + .collect::, Error>>()?, + ), + Value::Bytes36(bytes) => Ok(Bytes36::new(*bytes)), + Value::Bytes(vec) => Bytes36::from_vec(vec.clone()), + _other => Err(Error::StructureError( + "value are not bytes, a string, or an array of values representing bytes" + .to_string(), + )), + } + } + /// If the `Value` is a `Bytes`, a `Text` using base 58 or Vector of `U8`, returns the /// associated `Identifier` data as `Ok`. /// Returns `Err(Error::Structure("reason"))` otherwise. diff --git a/packages/rs-platform-value/src/types/bytes_36.rs b/packages/rs-platform-value/src/types/bytes_36.rs new file mode 100644 index 00000000000..1ee1529b134 --- /dev/null +++ b/packages/rs-platform-value/src/types/bytes_36.rs @@ -0,0 +1,184 @@ +use crate::string_encoding::Encoding; +use crate::types::encoding_string_to_encoding; +use crate::{string_encoding, Error, Value}; +use serde::de::Visitor; +use serde::{Deserialize, Serialize}; +use std::fmt; + +#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, Copy)] +pub struct Bytes36(pub [u8; 36]); + +impl Bytes36 { + pub fn new(buffer: [u8; 36]) -> Self { + Bytes36(buffer) + } + + pub fn from_vec(buffer: Vec) -> Result { + let buffer: [u8; 36] = buffer.try_into().map_err(|_| { + Error::ByteLengthNot36BytesError("buffer was not 36 bytes long".to_string()) + })?; + Ok(Bytes36::new(buffer)) + } + + pub fn as_slice(&self) -> &[u8] { + self.0.as_slice() + } + + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } + + pub fn to_buffer(&self) -> [u8; 36] { + self.0 + } + + pub fn from_string(encoded_value: &str, encoding: Encoding) -> Result { + let vec = string_encoding::decode(encoded_value, encoding)?; + + Bytes36::from_vec(vec) + } + + pub fn from_string_with_encoding_string( + encoded_value: &str, + encoding_string: Option<&str>, + ) -> Result { + let encoding = encoding_string_to_encoding(encoding_string); + + Bytes36::from_string(encoded_value, encoding) + } + + pub fn to_string(&self, encoding: Encoding) -> String { + string_encoding::encode(&self.0, encoding) + } + + pub fn to_string_with_encoding_string(&self, encoding_string: Option<&str>) -> String { + let encoding = encoding_string_to_encoding(encoding_string); + + self.to_string(encoding) + } +} + +impl Default for Bytes36 { + fn default() -> Self { + Bytes36([0u8; 36]) + } +} + +impl Serialize for Bytes36 { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if serializer.is_human_readable() { + serializer.serialize_str(&base64::encode(self.0)) + } else { + serializer.serialize_bytes(&self.0) + } + } +} + +impl<'de> Deserialize<'de> for Bytes36 { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + if deserializer.is_human_readable() { + struct StringVisitor; + + impl<'de> Visitor<'de> for StringVisitor { + type Value = Bytes36; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a base64-encoded string with length 44") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + let bytes = base64::decode(v).map_err(|e| E::custom(format!("{}", e)))?; + if bytes.len() != 36 { + return Err(E::invalid_length(bytes.len(), &self)); + } + let mut array = [0u8; 36]; + array.copy_from_slice(&bytes); + Ok(Bytes36(array)) + } + } + + deserializer.deserialize_string(StringVisitor) + } else { + struct BytesVisitor; + + impl<'de> Visitor<'de> for BytesVisitor { + type Value = Bytes36; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a byte array with length 36") + } + + fn visit_bytes(self, v: &[u8]) -> Result + where + E: serde::de::Error, + { + let mut bytes = [0u8; 36]; + if v.len() != 36 { + return Err(E::invalid_length(v.len(), &self)); + } + bytes.copy_from_slice(v); + Ok(Bytes36(bytes)) + } + } + + deserializer.deserialize_bytes(BytesVisitor) + } + } +} + +impl TryFrom for Bytes36 { + type Error = Error; + + fn try_from(value: Value) -> Result { + value.into_bytes_36() + } +} + +impl TryFrom<&Value> for Bytes36 { + type Error = Error; + + fn try_from(value: &Value) -> Result { + value.to_bytes_36() + } +} + +impl From for Value { + fn from(value: Bytes36) -> Self { + Value::Bytes36(value.0) + } +} + +impl From<&Bytes36> for Value { + fn from(value: &Bytes36) -> Self { + Value::Bytes36(value.0) + } +} + +impl TryFrom for Bytes36 { + type Error = Error; + + fn try_from(data: String) -> Result { + Self::from_string(&data, Encoding::Base64) + } +} + +impl From for String { + fn from(val: Bytes36) -> Self { + val.to_string(Encoding::Base64) + } +} + +impl From<&Bytes36> for String { + fn from(val: &Bytes36) -> Self { + val.to_string(Encoding::Base64) + } +} diff --git a/packages/rs-platform-value/src/types/mod.rs b/packages/rs-platform-value/src/types/mod.rs index a3623b191d9..6d8051c3457 100644 --- a/packages/rs-platform-value/src/types/mod.rs +++ b/packages/rs-platform-value/src/types/mod.rs @@ -2,6 +2,7 @@ use crate::string_encoding::Encoding; pub(crate) mod binary_data; pub(crate) mod bytes_32; +pub(crate) mod bytes_36; pub(crate) mod identifier; fn encoding_string_to_encoding(encoding_string: Option<&str>) -> Encoding { diff --git a/packages/rs-platform-value/src/value_serialization/de.rs b/packages/rs-platform-value/src/value_serialization/de.rs index 499bce4873c..ad81fc67c20 100644 --- a/packages/rs-platform-value/src/value_serialization/de.rs +++ b/packages/rs-platform-value/src/value_serialization/de.rs @@ -25,7 +25,8 @@ impl<'a> From<&'a Value> for de::Unexpected<'a> { Value::I16(x) => Self::Signed(*x as i64), Value::U8(x) => Self::Unsigned(*x as u64), Value::I8(x) => Self::Signed(*x as i64), - Value::Bytes32(_) => Self::Seq, + Value::Bytes32(x) => Self::Bytes(x), + Value::Bytes36(x) => Self::Bytes(x), Value::EnumU8(_x) => todo!(), Value::EnumString(_x) => todo!(), Value::Identifier(x) => Self::Bytes(x), @@ -196,6 +197,13 @@ impl<'de> de::Deserializer<'de> for Deserializer { visitor.visit_bytes(&x) } } + Value::Bytes36(x) => { + if human_readable { + visitor.visit_str(base64::encode(x).as_str()) + } else { + visitor.visit_bytes(&x) + } + } Value::EnumU8(_x) => todo!(), Value::EnumString(_x) => todo!(), Value::Identifier(x) => { @@ -312,6 +320,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { match value { Value::Bytes(x) => visitor.visit_bytes(&x), Value::Bytes32(x) => visitor.visit_bytes(x.as_slice()), + Value::Bytes36(x) => visitor.visit_bytes(x.as_slice()), Value::Identifier(x) => visitor.visit_bytes(x.as_slice()), _ => Err(de::Error::invalid_type((&value).into(), &"bytes")), } diff --git a/packages/rs-platform-value/src/value_serialization/ser.rs b/packages/rs-platform-value/src/value_serialization/ser.rs index 31c3c9ae5f7..ee8f4889584 100644 --- a/packages/rs-platform-value/src/value_serialization/ser.rs +++ b/packages/rs-platform-value/src/value_serialization/ser.rs @@ -57,6 +57,13 @@ impl Serialize for Value { serializer.serialize_bytes(bytes) } } + Value::Bytes36(bytes) => { + if serializer.is_human_readable() { + serializer.serialize_str(base64::encode(bytes).as_str()) + } else { + serializer.serialize_bytes(bytes) + } + } Value::Identifier(bytes) => { if serializer.is_human_readable() { serializer.serialize_str(bs58::encode(bytes).into_string().as_str()) @@ -187,6 +194,8 @@ impl serde::Serializer for Serializer { fn serialize_bytes(self, value: &[u8]) -> Result { if value.len() == 32 { Ok(Value::Bytes32(value.try_into().unwrap())) + } else if value.len() == 36 { + Ok(Value::Bytes36(value.try_into().unwrap())) } else { Ok(Value::Bytes(value.to_vec())) } diff --git a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs index 69684a80ae3..d15ab415d07 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract_facade.rs @@ -1,8 +1,8 @@ use crate::errors::protocol_error::from_protocol_error; use crate::{ - js_value_to_data_contract_value, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, - DataContractWasm, + js_value_to_data_contract_value, DataContractCreateTransitionWasm, + DataContractUpdateTransitionWasm, DataContractWasm, }; use dpp::data_contract::DataContractFacade; use dpp::identifier::Identifier; diff --git a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs index 3b1cb57e8b4..ad62a304f22 100644 --- a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs +++ b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs @@ -14,7 +14,13 @@ use dpp::{ use wasm_bindgen::prelude::*; use crate::utils::WithJsError; -use crate::{data_contract::errors::InvalidDataContractError, errors::{from_dpp_err, protocol_error::from_protocol_error}, js_value_to_identity_update_transition_object, validation::ValidationResultWasm, with_js_error, DataContractCreateTransitionWasm, DataContractParameters, DataContractWasm, js_value_to_data_contract_value}; +use crate::{ + data_contract::errors::InvalidDataContractError, + errors::{from_dpp_err, protocol_error::from_protocol_error}, + js_value_to_data_contract_value, js_value_to_identity_update_transition_object, + validation::ValidationResultWasm, + with_js_error, DataContractCreateTransitionWasm, DataContractParameters, DataContractWasm, +}; #[wasm_bindgen(js_name=DataContractValidator)] pub struct DataContractValidatorWasm(DataContractValidator); diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index f43618ce932..16f01e77904 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -191,6 +191,9 @@ impl ExtendedDocumentWasm { Value::Bytes32(bytes) => { return Buffer::from_bytes(bytes.as_slice()).into(); } + Value::Bytes36(bytes) => { + return Buffer::from_bytes(bytes.as_slice()).into(); + } Value::Identifier(bytes) => { let id: IdentifierWrapper = Identifier::new(*bytes).into(); diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 8e10054932d..91940018c82 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -172,6 +172,9 @@ impl DocumentWasm { Value::Bytes32(bytes) => { return Ok(Buffer::from_bytes(bytes.as_slice()).into()); } + Value::Bytes36(bytes) => { + return Ok(Buffer::from_bytes(bytes.as_slice()).into()); + } Value::Identifier(identifier) => { let id: IdentifierWrapper = Identifier::new(*identifier).into(); return Ok(id.into()); diff --git a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index 4e5d31fe2f6..c57bca84243 100644 --- a/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/wasm-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -10,8 +10,8 @@ use crate::{ with_js_error, }; use dpp::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; -use dpp::platform_value::string_encoding; use dpp::platform_value::string_encoding::Encoding; +use dpp::platform_value::{string_encoding, Bytes36}; #[wasm_bindgen(js_name=ChainAssetLockProof)] #[derive(Clone)] @@ -82,7 +82,7 @@ impl ChainAssetLockProofWasm { RustConversionError::Error(String::from("outPoint must be a 36 byte array")) .to_js_value() })?; - self.0.out_point = out_point; + self.0.out_point = Bytes36::new(out_point); Ok(()) } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 3e9d52289c8..9a0bf44d340 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -19,8 +19,8 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::utils::{generic_of_js_val, WithJsError}; use dpp::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyWithWitness; use dpp::identity::{KeyID, TimestampMillis}; -use dpp::platform_value::{string_encoding, Value}; use dpp::platform_value::string_encoding::Encoding; +use dpp::platform_value::{string_encoding, Value}; use dpp::prelude::Revision; use dpp::state_transition::StateTransitionIdentitySigned; use dpp::{ @@ -69,12 +69,16 @@ pub fn js_value_to_identity_update_transition_object(object: JsValue) -> Result< impl IdentityUpdateTransitionWasm { #[wasm_bindgen(constructor)] pub fn new(raw_parameters: JsValue) -> Result { - let mut identity_update_transition_object = js_value_to_identity_update_transition_object(raw_parameters)?; + let mut identity_update_transition_object = + js_value_to_identity_update_transition_object(raw_parameters)?; - IdentityUpdateTransition::clean_value(&mut identity_update_transition_object).map_err(ProtocolError::ValueError).with_js_error()?; + IdentityUpdateTransition::clean_value(&mut identity_update_transition_object) + .map_err(ProtocolError::ValueError) + .with_js_error()?; - let identity_update_transition = IdentityUpdateTransition::new(identity_update_transition_object) - .map_err(|e| RustConversionError::Error(e.to_string()).to_js_value())?; + let identity_update_transition = + IdentityUpdateTransition::new(identity_update_transition_object) + .map_err(|e| RustConversionError::Error(e.to_string()).to_js_value())?; Ok(identity_update_transition.into()) } diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 16674bd4125..b53fdcd0c55 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -113,8 +113,9 @@ describe('StateTransitionFacade', () => { describe('createFromObject', () => { it('should create State Transition from plain object', async () => { + const object = dataContractCreateTransition.toObject(); const result = await dpp.stateTransition.createFromObject( - dataContractCreateTransition.toObject(), + object, ); expect(result).to.be.an.instanceOf(DataContractCreateTransition); From 737865a6c7b4ac53c7e5185fe5cafb82a465334a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 14:11:19 +0700 Subject: [PATCH 185/228] slight change --- packages/wasm-dpp/test/unit/document/Document.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/wasm-dpp/test/unit/document/Document.spec.js b/packages/wasm-dpp/test/unit/document/Document.spec.js index d70747dfe1f..2356a795354 100644 --- a/packages/wasm-dpp/test/unit/document/Document.spec.js +++ b/packages/wasm-dpp/test/unit/document/Document.spec.js @@ -384,8 +384,9 @@ describe('Document', () => { const value = { identifier }; document.set(path, value); + const returnedIdentifier = document.get(identifierPath); - expect(document.get(identifierPath).toBuffer()).to.deep.equal(buffer); + expect(returnedIdentifier.toBuffer()).to.deep.equal(buffer); }); }); From bc55f10962e2ee9889c7cc01d8128bb6d2a10ea9 Mon Sep 17 00:00:00 2001 From: Anton Suprunchuk Date: Tue, 21 Mar 2023 16:36:00 +0800 Subject: [PATCH 186/228] fix $type should be present for document factory --- packages/wasm-dpp/src/errors/value_error.rs | 5 +++++ .../document/validation/validateDocumentFactory.spec.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/wasm-dpp/src/errors/value_error.rs b/packages/wasm-dpp/src/errors/value_error.rs index 5539dddbd16..51e6b2f6652 100644 --- a/packages/wasm-dpp/src/errors/value_error.rs +++ b/packages/wasm-dpp/src/errors/value_error.rs @@ -37,4 +37,9 @@ impl PlatformValueErrorWasm { pub fn get_message(&self) -> String { self.message.clone() } + + #[wasm_bindgen(js_name=toString)] + pub fn to_string(&self) -> String { + format!("PlatformValueError: {}", self.message) + } } diff --git a/packages/wasm-dpp/test/integration/document/validation/validateDocumentFactory.spec.js b/packages/wasm-dpp/test/integration/document/validation/validateDocumentFactory.spec.js index 2f35411b7ef..b487757b3b7 100644 --- a/packages/wasm-dpp/test/integration/document/validation/validateDocumentFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/validation/validateDocumentFactory.spec.js @@ -149,7 +149,7 @@ describe('validateDocumentFactory', () => { } catch (e) { // TODO - fix error when conversion errors are enabled // expect(error.getCode()).to.equal(1028); - expect(e).to.startsWith("the property '$type' doesn't exist"); + expect(e.getMessage()).to.be.equal('structure error: $type not found in map'); } }); From 2356e8d26dd31b8fec35f5719be080ff3df36561 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 15:52:17 +0700 Subject: [PATCH 187/228] fixed duplicate validation error with $ownerId --- ...alidate_documents_batch_transition_basic.rs | 18 +++++++++++------- ...alidate_documents_batch_transition_state.rs | 10 +++++----- ...te_documents_batch_transition_state_spec.rs | 2 +- packages/rs-platform-value/src/system_bytes.rs | 4 ++-- ...ocumentsBatchTransitionBasicFactory.spec.js | 1 + 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 9896983b504..09fe7701d9f 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -147,7 +147,7 @@ pub async fn validate_documents_batch_transition_basic( HashMap::new(); for raw_document_transition in raw_document_transitions { - let identifier = match raw_document_transition + let contract_identifier = match raw_document_transition .get_optional_identifier(property_names::DATA_CONTRACT_ID) { Ok(None) => { @@ -163,7 +163,7 @@ pub async fn validate_documents_batch_transition_basic( } }; - match document_transitions_by_contracts.entry(identifier) { + match document_transitions_by_contracts.entry(contract_identifier) { Entry::Vacant(vacant) => { vacant.insert(vec![raw_document_transition]); } @@ -194,7 +194,7 @@ pub async fn validate_documents_batch_transition_basic( }; let validation_result = - validate_document_transitions(&data_contract, &owner_id, transitions)?; + validate_document_transitions(&data_contract, owner_id, transitions)?; result.merge(validation_result); } @@ -203,7 +203,7 @@ pub async fn validate_documents_batch_transition_basic( fn validate_document_transitions<'a>( data_contract: &DataContract, - owner_id: &Identifier, + owner_id: Identifier, raw_document_transitions: impl IntoIterator>, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); @@ -252,11 +252,12 @@ fn validate_raw_transitions<'a>( data_contract: &DataContract, raw_document_transitions: impl IntoIterator>, enriched_contracts_by_action: &HashMap, - owner_id: &Identifier, + owner_id: Identifier, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); let mut raw_document_transitions_as_value: Vec = vec![]; - for raw_document_transition in raw_document_transitions { + let owner_id_value : Value = owner_id.into(); + for mut raw_document_transition in raw_document_transitions { let Some(document_type) = raw_document_transition.get_optional_str("$type").map_err(ProtocolError::ValueError)? else { result.add_error(BasicError::MissingDocumentTransitionTypeError); return Ok(result); @@ -311,7 +312,7 @@ fn validate_raw_transitions<'a>( let entropy = raw_document_transition.get_bytes("$entropy")?; // validate the id generation let generated_document_id = - generate_document_id(&data_contract.id, owner_id, document_type, &entropy); + generate_document_id(&data_contract.id, &owner_id, document_type, &entropy); if generated_document_id != document_id { result.add_error(BasicError::InvalidDocumentTransitionIdError( @@ -338,6 +339,9 @@ fn validate_raw_transitions<'a>( } } } + // we passed validation, let's add the owner_id now so we can validate indices (that might + // use the ownerId) + raw_document_transition.insert("$ownerId".to_string(), &owner_id_value); raw_document_transitions_as_value.push(raw_document_transition.into()) } let raw_document_transitions_as_value_iter = raw_document_transitions_as_value.iter(); diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index 9e9e59cf4fd..1ee44141084 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -70,7 +70,7 @@ pub async fn validate_document_batch_transition_state( state_transition: &DocumentsBatchTransition, ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); - let owner_id = state_transition.get_owner_id(); + let owner_id = *state_transition.get_owner_id(); let transitions_by_data_contract_id = state_transition .get_transitions() @@ -97,7 +97,7 @@ pub async fn validate_document_batch_transition_state( pub async fn validate_document_transitions( state_repository: &impl StateRepositoryLike, data_contract_id: &Identifier, - owner_id: &Identifier, + owner_id: Identifier, document_transitions: impl IntoIterator>, execution_context: &StateTransitionExecutionContext, ) -> Result, ProtocolError> { @@ -136,7 +136,7 @@ pub async fn validate_document_transitions( transition.as_ref(), &fetched_documents, last_header_time_millis, - owner_id, + &owner_id, ); result.merge(validation_result); } @@ -147,7 +147,7 @@ pub async fn validate_document_transitions( let validation_result = validate_documents_uniqueness_by_indices( state_repository, - owner_id, + &owner_id, transitions .iter() .filter(|d| d.as_ref().as_transition_delete().is_none()), @@ -162,7 +162,7 @@ pub async fn validate_document_transitions( let data_trigger_execution_context = DataTriggerExecutionContext { state_repository: state_repository.to_owned(), - owner_id, + owner_id: &owner_id, data_contract: &data_contract, state_transition_execution_context: execution_context, }; diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs index c4cba82b141..a09a420b4d9 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transition_state_spec.rs @@ -131,7 +131,7 @@ async fn should_throw_error_if_data_contract_was_not_found() { let error = validate_document_transitions( &state_repository_mock, &data_contract.id, - &owner_id, + owner_id, document_transitions, &Default::default(), ) diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index ad8c942cfea..3e4eacaf220 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -439,7 +439,7 @@ impl Value { /// assert_eq!(value.into_bytes_36(), Ok(Bytes36([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 50, 51, 52, 53]))); /// /// /// let value = Value::Text("sNr9aH0VUnzvKDADkuJUlZ4Yj7Yd7gbNnnOR4ANNat2g498D".to_string()); - /// assert_eq!(value.into_bytes_36(), Ok(Bytes36([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117, 00, 00, 00, 00]))); + /// assert_eq!(value.into_bytes_36(), Ok(Bytes36([176, 218, 253, 104, 125, 21, 82, 124, 239, 40, 48, 3, 146, 226, 84, 149, 158, 24, 143, 182, 29, 238, 6, 205, 158, 115, 145, 224, 3, 77, 106, 221, 160, 227, 223, 3]))); /// /// let value = Value::Text("a811".to_string()); /// assert_eq!(value.into_bytes_36(), Err(Error::ByteLengthNot36BytesError("buffer was not 36 bytes long".to_string()))); @@ -487,7 +487,7 @@ impl Value { /// assert_eq!(value.to_bytes_36(), Ok(Bytes36([104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 104, 101, 108, 108, 111, 32, 12, 50, 50, 51, 52, 53]))); /// /// /// let value = Value::Text("sNr9aH0VUnzvKDADkuJUlZ4Yj7Yd7gbNnnOR4ANNat2g498D".to_string()); - /// assert_eq!(value.to_bytes_36(), Ok(Bytes36([86, 35, 118, 67, 167, 43, 101, 109, 72, 97, 35, 99, 0, 254, 108, 154, 254, 154, 190, 40, 237, 25, 58, 246, 111, 19, 44, 215, 141, 140, 156, 117, 00, 00, 00, 00]))); + /// assert_eq!(value.to_bytes_36(), Ok(Bytes36([176, 218, 253, 104, 125, 21, 82, 124, 239, 40, 48, 3, 146, 226, 84, 149, 158, 24, 143, 182, 29, 238, 6, 205, 158, 115, 145, 224, 3, 77, 106, 221, 160, 227, 223, 3]))); /// /// let value = Value::Text("a811".to_string()); /// assert_eq!(value.to_bytes_36(), Err(Error::ByteLengthNot36BytesError("buffer was not 36 bytes long".to_string()))); diff --git a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js index a7fa277532e..b2d6d4c68aa 100644 --- a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js @@ -894,6 +894,7 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { duplicatedTransition.$type, duplicatedTransition.$entropy, ); + duplicatedTransition.firstName = 'Ted'; const duplicates = [duplicatedTransition, indexedTransition]; stateTransition = new DocumentsBatchTransition({ From 945bf1511d169954aaea93ebfe8351a7f18717c1 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 16:50:38 +0700 Subject: [PATCH 188/228] fixes --- ...cumentsBatchTransitionBasicFactory.spec.js | 36 +++++++++---------- .../validateDocumentFactory.spec.js | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js index b2d6d4c68aa..59a9410a7a7 100644 --- a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js @@ -128,16 +128,19 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { it('should be valid - Rust', async () => { rawStateTransition.protocolVersion = -1; - try { - await validateDocumentsBatchTransitionBasic( - protocolVersionValidator, - stateRepositoryMock, - rawStateTransition, - executionContext, - ); - } catch (e) { - expect(e).equal('Error conversion not implemented: unable convert -1 to u64'); - } + const result = await validateDocumentsBatchTransitionBasic( + protocolVersionValidator, + stateRepositoryMock, + rawStateTransition, + executionContext, + ); + + await expectPlatformValueError(result, 1); + + const [error] = result.getErrors(); + + expect(error).to.be.an.instanceOf(PlatformValueError); + expect(error.getMessage()).equal('integer out of bounds'); }); }); @@ -488,18 +491,15 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { executionContext, ); - await expectValidationError(result, InvalidIdentifierError); + await expectPlatformValueError(result); const [error] = result.getErrors(); - expect(error.getCode()).to.equal(1006); - - expect(error.getIdentifierName()).to.equal('$dataContractId'); - expect(error.getIdentifierError()).to.equal('Identifier Error: Identifier must be 32 bytes long'); + expect(error.getMessage()).to.equal('byte length not 32 bytes error: Trying to replace into an identifier, but not 32 bytes long'); - expect(stateRepositoryMock.fetchDataContract).to.have.been.calledOnce(); - const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; - expect(fetchDataContractId.toBuffer()).is.deep.equal(dataContract.getId().toBuffer()); + // we won't call fetch data contract, because the state transition structure validation + // happens first + expect(stateRepositoryMock.fetchDataContract).to.have.not.been.called(); }); it('should exists in the state - Rust', async () => { diff --git a/packages/wasm-dpp/test/integration/document/validation/validateDocumentFactory.spec.js b/packages/wasm-dpp/test/integration/document/validation/validateDocumentFactory.spec.js index b487757b3b7..d3d87ff2da8 100644 --- a/packages/wasm-dpp/test/integration/document/validation/validateDocumentFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/validation/validateDocumentFactory.spec.js @@ -72,7 +72,7 @@ describe('validateDocumentFactory', () => { documentValidator.validate(rawDocument, dataContract); } catch (e) { // TODO - fix error when conversion errors are enabled - expect(e).to.equal('Error conversion not implemented: unable convert -1 to u64'); + expect(e.getMessage()).to.equal('integer out of bounds'); } }); }); From 3949de767b4a0bb783ded47bcc727eeb90bc0756 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 10:53:34 +0000 Subject: [PATCH 189/228] test(wasm-dpp): fix state transition facade validation tests --- packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js | 2 +- .../state_transition/data_contract_create_transition/mod.rs | 2 +- .../integration/stateTransition/StateTransitionFacade.spec.js | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js b/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js index 01ef859a448..e0ff5e05dca 100644 --- a/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js +++ b/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js @@ -251,7 +251,7 @@ module.exports = async function getDataContractFixture(ownerId = randomOwnerId) const dataContractValidator = new DataContractValidator(); const factory = new DataContractFactory( - protocolVersion.latestProtocolVersion, + protocolVersion.latestVersion, dataContractValidator, ); diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 3e44d94566b..3adada64938 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -147,7 +147,7 @@ impl DataContractCreateTransitionWasm { pub fn to_object(&self, skip_signature: Option) -> Result { let serde_object = self .0 - .to_object(skip_signature.unwrap_or(false)) + .to_cleaned_object(skip_signature.unwrap_or(false)) .map_err(from_protocol_error)?; serde_object .serialize(&serde_wasm_bindgen::Serializer::json_compatible()) diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index b53fdcd0c55..8591cc76c12 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -197,6 +197,7 @@ describe('StateTransitionFacade', () => { it('should validate DocumentsBatchTransition', async () => { stateRepositoryMock.fetchDocuments.resolves([]); + stateRepositoryMock.fetchExtendedDocuments.resolves([]); stateRepositoryMock.fetchDataContract.resolves(dataContract); const result = await dpp.stateTransition.validate( From 29b8042b59ec128e147fca5921b6ce593e79d23a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 18:05:19 +0700 Subject: [PATCH 190/228] clean recursive --- packages/rs-platform-value/src/replace.rs | 41 +++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/rs-platform-value/src/replace.rs b/packages/rs-platform-value/src/replace.rs index 64ed56fb31d..a44b4e62e5b 100644 --- a/packages/rs-platform-value/src/replace.rs +++ b/packages/rs-platform-value/src/replace.rs @@ -383,4 +383,45 @@ impl Value { } Ok(()) } + + /// Cleans all values and removes null inner values at any depth. + /// if the replacement can not happen. + /// + /// ``` + /// # use platform_value::{Error, Identifier, IntegerReplacementType, ReplacementType, Value}; + /// # + /// let mut inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("grapes")), Value::Null), + /// (Value::Text(String::from("oranges")), Value::I32(6)), + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), inner_value), + /// ] + /// ); + /// + /// value = value.clean_recursive().unwrap(); + /// + /// assert_eq!(value.get_optional_value_at_path("foods.grapes"), Ok(None)); + /// + pub fn clean_recursive(self) -> Result { + Ok(Value::Map(self + .into_map()? + .into_iter() + .filter_map(|(key, value)| { + if value.is_null() { + None + } else if value.is_map() { + match value.clean_recursive() { + Ok(value) => Some(Ok((key, value))), + Err(e) => Some(Err(e)) + } + } else { + Some(Ok((key, value))) + } + }) + .collect::, Error>>()?)) + } } From 850227edb5e96fb1c08463d73b1f7ca3a2617794 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 11:09:26 +0000 Subject: [PATCH 191/228] fix(rs-dpp): use to_cleaned_object in to_buffer --- .../abstract_state_transition.rs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 17f62e64079..b526f6efa85 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -218,6 +218,20 @@ pub trait StateTransitionConvert: Serialize { Ok(object) } + /// Returns the [`platform_value::Value`] instance that preserves the `Vec` representation + /// for Identifiers and binary data + fn to_canonical_cleaned_object(&self, skip_signature: bool) -> Result { + let skip_signature_paths = if skip_signature { + Self::signature_property_paths() + } else { + vec![] + }; + let mut object = state_transition_helpers::to_cleaned_object(self, skip_signature_paths)?; + + object.as_map_mut_ref().unwrap().sort_by_keys(); + Ok(object) + } + /// Returns the [`serde_json::Value`] instance that encodes: /// - Identifiers - with base58 /// - Binary data - with base64 @@ -232,7 +246,7 @@ pub trait StateTransitionConvert: Serialize { // Returns the cbor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { - let mut value = self.to_canonical_object(skip_signature)?; + let mut value = self.to_canonical_cleaned_object(skip_signature)?; let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; serializer::serializable_value_to_cbor(&value, Some(protocol_version)) @@ -273,4 +287,21 @@ pub mod state_transition_helpers { })?; Ok(value) } + + pub fn to_cleaned_object<'a, I: IntoIterator>( + serializable: impl Serialize, + skip_signature_paths: I, + ) -> Result { + let mut value: Value = platform_value::to_value(serializable)?; + + value = value.clean_recursive()?; + + skip_signature_paths.into_iter().try_for_each(|path| { + value + .remove_value_at_path(path) + .map_err(ProtocolError::ValueError) + .map(|_| ()) + })?; + Ok(value) + } } From 38181b4653c30ec3fa33642a1cb5a22e498e1fd7 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 19:00:56 +0700 Subject: [PATCH 192/228] remove values matching path --- .../src/inner_value_at_path.rs | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index 62111924a1f..0ab592ddd05 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -49,6 +49,64 @@ impl Value { map.remove_key(last_path_component) } + pub fn remove_values_matching_path(&mut self, path: &str) -> Result, Error> { + let mut split = path.split('.').peekable(); + let mut current_values = vec![self]; + let mut removed_values = vec![]; + while let Some(path_component) = split.next() { + if let Some((string_part, number_part)) = is_array_path(path_component)? { + current_values = current_values + .into_iter() + .map(|current_value| { + let map = current_value.to_map_mut()?; + let array_value = map.get_key_mut(string_part)?; + let array = array_value.to_array_mut()?; + if let Some(number_part) = number_part { + if array.len() < number_part { + //this already exists + Ok(vec![array.get_mut(number_part).unwrap()]) + } else { + return Err(Error::StructureError(format!( + "element at position {number_part} in array does not exist" + ))); + } + } else { + // we are replacing all members in array + Ok(array.into_iter().collect()) + } + }) + .collect::>, Error>>()? + .into_iter() + .flatten() + .collect() + } else { + current_values = current_values + .into_iter() + .filter_map(|current_value| { + let map = match current_value.as_map_mut_ref() { + Ok(map) => map, + Err(err) => return Some(Err(err)), + }; + + + if split.peek().is_none() { + if let Some(removed) = map.remove_optional_key(path_component) { + removed_values.push(removed) + } + None + } else { + let Some(new_value) = map.get_optional_key_mut(path_component) else { + return None; + }; + Some(Ok(new_value)) + } + }) + .collect::, Error>>()?; + } + } + Ok(removed_values) + } + pub fn remove_value_at_path_into>( &mut self, path: &str, @@ -70,6 +128,16 @@ impl Value { .collect() } + pub fn remove_values_matching_paths<'a>( + &'a mut self, + paths: Vec<&'a str>, + ) -> Result>, Error> { + paths + .into_iter() + .map(|path| Ok((path, self.remove_values_matching_path(path)?))) + .collect() + } + pub fn get_value_at_path<'a, 'b>(&'a self, path: &'b str) -> Result<&'a Value, Error> { let split = path.split('.'); let mut current_value = self; From d8a87a42c02192be8a097072e1f7870ba2720a9b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 19:16:29 +0700 Subject: [PATCH 193/228] fix --- ...lidate_documents_batch_transition_basic.rs | 2 +- .../src/inner_value_at_path.rs | 35 ++++++++++++++----- packages/rs-platform-value/src/replace.rs | 31 ++++++++-------- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 09fe7701d9f..fa11222b5f7 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -256,7 +256,7 @@ fn validate_raw_transitions<'a>( ) -> Result, ProtocolError> { let mut result = ValidationResult::default(); let mut raw_document_transitions_as_value: Vec = vec![]; - let owner_id_value : Value = owner_id.into(); + let owner_id_value: Value = owner_id.into(); for mut raw_document_transition in raw_document_transitions { let Some(document_type) = raw_document_transition.get_optional_str("$type").map_err(ProtocolError::ValueError)? else { result.add_error(BasicError::MissingDocumentTransitionTypeError); diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index 0ab592ddd05..cde99bef838 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -57,22 +57,36 @@ impl Value { if let Some((string_part, number_part)) = is_array_path(path_component)? { current_values = current_values .into_iter() - .map(|current_value| { - let map = current_value.to_map_mut()?; - let array_value = map.get_key_mut(string_part)?; - let array = array_value.to_array_mut()?; + .filter_map(|current_value| { + if current_value.is_null() { + return None; + } + let Some(map) = current_value.as_map_mut() else { + return Some(Err(Error::StructureError("value is not a map during removal".to_string()))); + }; + + let Some(array_value) = map.get_optional_key_mut(string_part) else { + return None; + }; + + if array_value.is_null() { + return None; + } + let Some(array) = current_value.as_array_mut() else { + return Some(Err(Error::StructureError("value is not an array during removal".to_string()))); + }; if let Some(number_part) = number_part { if array.len() < number_part { //this already exists - Ok(vec![array.get_mut(number_part).unwrap()]) + Some(Ok(vec![array.get_mut(number_part).unwrap()])) } else { - return Err(Error::StructureError(format!( + Some(Err(Error::StructureError(format!( "element at position {number_part} in array does not exist" - ))); + )))) } } else { // we are replacing all members in array - Ok(array.into_iter().collect()) + Some(Ok(array.into_iter().collect())) } }) .collect::>, Error>>()? @@ -83,12 +97,15 @@ impl Value { current_values = current_values .into_iter() .filter_map(|current_value| { + if current_value.is_null() { + return None; + } + let map = match current_value.as_map_mut_ref() { Ok(map) => map, Err(err) => return Some(Err(err)), }; - if split.peek().is_none() { if let Some(removed) = map.remove_optional_key(path_component) { removed_values.push(removed) diff --git a/packages/rs-platform-value/src/replace.rs b/packages/rs-platform-value/src/replace.rs index a44b4e62e5b..b89098456d5 100644 --- a/packages/rs-platform-value/src/replace.rs +++ b/packages/rs-platform-value/src/replace.rs @@ -407,21 +407,22 @@ impl Value { /// assert_eq!(value.get_optional_value_at_path("foods.grapes"), Ok(None)); /// pub fn clean_recursive(self) -> Result { - Ok(Value::Map(self - .into_map()? - .into_iter() - .filter_map(|(key, value)| { - if value.is_null() { - None - } else if value.is_map() { - match value.clean_recursive() { - Ok(value) => Some(Ok((key, value))), - Err(e) => Some(Err(e)) + Ok(Value::Map( + self.into_map()? + .into_iter() + .filter_map(|(key, value)| { + if value.is_null() { + None + } else if value.is_map() { + match value.clean_recursive() { + Ok(value) => Some(Ok((key, value))), + Err(e) => Some(Err(e)), + } + } else { + Some(Ok((key, value))) } - } else { - Some(Ok((key, value))) - } - }) - .collect::, Error>>()?)) + }) + .collect::, Error>>()?, + )) } } From 48e1fe65ff6882e896868003e5d48ece1b93a443 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 12:22:03 +0000 Subject: [PATCH 194/228] fix(rs-dpp): remove public keys signatures --- .../identity_create_transition.rs | 5 ++++- .../identity_update_transition.rs | 6 +++++- .../src/state_transition/abstract_state_transition.rs | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 69e153a2f6a..ebfca1d5763 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -213,7 +213,10 @@ impl IdentityCreateTransition { impl StateTransitionConvert for IdentityCreateTransition { fn signature_property_paths() -> Vec<&'static str> { - vec![property_names::SIGNATURE] + vec![ + property_names::SIGNATURE, + property_names::PUBLIC_KEYS_SIGNATURE, + ] } fn identifiers_property_paths() -> Vec<&'static str> { vec![property_names::IDENTITY_ID] diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index d2fa68d02ab..fce46109a9a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -240,7 +240,10 @@ where impl StateTransitionConvert for IdentityUpdateTransition { fn binary_property_paths() -> Vec<&'static str> { - vec![property_names::SIGNATURE] + vec![ + property_names::SIGNATURE, + property_names::ADD_PUBLIC_KEYS_SIGNATURE, + ] } fn identifiers_property_paths() -> Vec<&'static str> { @@ -251,6 +254,7 @@ impl StateTransitionConvert for IdentityUpdateTransition { vec![ property_names::SIGNATURE, property_names::SIGNATURE_PUBLIC_KEY_ID, + property_names::ADD_PUBLIC_KEYS_SIGNATURE, ] } diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index b526f6efa85..9d4eb071a91 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -298,7 +298,7 @@ pub mod state_transition_helpers { skip_signature_paths.into_iter().try_for_each(|path| { value - .remove_value_at_path(path) + .remove_values_matching_path(path) .map_err(ProtocolError::ValueError) .map(|_| ()) })?; From 9bab7d4a01a9a4ea4251ed7d45ebb7c1c855d2c7 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 19:29:07 +0700 Subject: [PATCH 195/228] fixes --- .../src/state_transition/abstract_state_transition.rs | 2 +- .../src/btreemap_extensions/btreemap_path_extensions.rs | 4 +++- packages/rs-platform-value/src/inner_value_at_path.rs | 8 +++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 9d4eb071a91..d17bcbe9219 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -281,7 +281,7 @@ pub mod state_transition_helpers { let mut value: Value = platform_value::to_value(serializable)?; skip_signature_paths.into_iter().try_for_each(|path| { value - .remove_value_at_path(path) + .remove_values_matching_path(path) .map_err(ProtocolError::ValueError) .map(|_| ()) })?; diff --git a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs index e039a778965..1c095bcb4ac 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/btreemap_path_extensions.rs @@ -150,7 +150,9 @@ where for path_component in split { let map = current_value.to_map_ref()?; current_value = map.get_optional_key(path_component).ok_or_else(|| { - Error::StructureError(format!("unable to get property {path_component} in {path}")) + Error::StructureError(format!( + "unable to get property at path {path_component} in {path}" + )) })?; } Ok(current_value) diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index cde99bef838..8622bf652bc 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -37,7 +37,7 @@ impl Value { let map = current_value.to_map_mut()?; current_value = map.get_optional_key_mut(path_component).ok_or_else(|| { Error::StructureError(format!( - "unable to get property {path_component} in {path}" + "unable to remove property {path_component} in {path}" )) })?; }; @@ -72,7 +72,7 @@ impl Value { if array_value.is_null() { return None; } - let Some(array) = current_value.as_array_mut() else { + let Some(array) = array_value.as_array_mut() else { return Some(Err(Error::StructureError("value is not an array during removal".to_string()))); }; if let Some(number_part) = number_part { @@ -227,7 +227,9 @@ impl Value { for path_component in split { let map = current_value.to_map_mut()?; current_value = map.get_optional_key_mut(path_component).ok_or_else(|| { - Error::StructureError(format!("unable to get property {path_component} in {path}")) + Error::StructureError(format!( + "unable to get mut property {path_component} in {path}" + )) })?; } Ok(current_value) From 963fac8a8d528930caed23adbeb497513a25b234 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 20:12:09 +0700 Subject: [PATCH 196/228] another fix --- packages/rs-platform-value/src/replace.rs | 71 ++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/packages/rs-platform-value/src/replace.rs b/packages/rs-platform-value/src/replace.rs index b89098456d5..4ad6ecec645 100644 --- a/packages/rs-platform-value/src/replace.rs +++ b/packages/rs-platform-value/src/replace.rs @@ -345,12 +345,12 @@ impl Value { /// /// let identifier_paths = HashSet::from(["foods.oranges.tangerines"]); /// - /// value.replace_to_binary_types_when_setting_with_path("foods.oranges", identifier_paths, HashSet::new()).expect("expected to replace at paths with identifier"); + /// value.replace_to_binary_types_of_root_value_when_setting_at_path("foods.oranges", identifier_paths, HashSet::new()).expect("expected to replace at paths with identifier"); /// /// assert_eq!(value.get_value_at_path("foods.oranges.tangerines"), Ok(&Value::Identifier([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); /// /// ``` - pub fn replace_to_binary_types_when_setting_with_path( + pub fn replace_to_binary_types_of_root_value_when_setting_at_path( &mut self, path: &str, identifier_paths: HashSet<&str>, @@ -384,6 +384,73 @@ impl Value { Ok(()) } + /// `replace_to_binary_types_when_setting_with_path` will replace a value with a corresponding + /// binary type (Identifier or Binary Data) if that data is in one of the given paths. + /// Paths can either be terminal, or can represent an object or an array (with values) where + /// all subvalues must be set to the bianry type. + /// Either returns `Err(Error::Structure("reason"))` or `Err(Error::ByteLengthNot32BytesError))` + /// if the replacement can not happen. + /// + /// ``` + /// # use std::collections::HashSet; + /// use platform_value::{Error, Identifier, ReplacementType, Value}; + /// # + /// let mut inner_inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("mandarins")), Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string())), + /// (Value::Text(String::from("tangerines")), Value::Array(vec![Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101), Value::U8(108),Value::U8(104), Value::U8(101)])), + /// ] + /// ); + /// let mut inner_value = Value::Map( + /// vec![ + /// (Value::Text(String::from("grapes")), Value::Text("6oFRdsUNiAtXscRn52atKYCiF8RBnH9vbUzhtzY3d83e".to_string())), + /// (Value::Text(String::from("oranges")), inner_inner_value), + /// ] + /// ); + /// let mut value = Value::Map( + /// vec![ + /// (Value::Text(String::from("foods")), inner_value), + /// ] + /// ); + /// + /// + /// let identifier_paths = HashSet::from(["foods.oranges.tangerines"]); + /// + /// let oranges = value.get_mut_value_at_path("foods.oranges").unwrap(); + /// oranges.replace_to_binary_types_when_setting_with_path("foods.oranges", identifier_paths, HashSet::new()).expect("expected to replace at paths with identifier"); + /// + /// assert_eq!(value.get_value_at_path("foods.oranges.tangerines"), Ok(&Value::Identifier([104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101, 108, 104, 101]))); + /// + /// ``` + pub fn replace_to_binary_types_when_setting_with_path( + &mut self, + path: &str, + identifier_paths: HashSet<&str>, + binary_paths: HashSet<&str>, + ) -> Result<(), Error> { + let mut path = path.to_string(); + path.push('.'); + identifier_paths + .into_iter() + .try_for_each(|identifier_path| { + if let Some(suffix) = identifier_path.strip_prefix(path.as_str()) { + self.replace_at_path(suffix, ReplacementType::Identifier) + .map(|_| ()) + } else { + Ok(()) + } + })?; + binary_paths.into_iter().try_for_each(|binary_path| { + if let Some(suffix) = binary_path.strip_prefix(path.as_str()) { + self.replace_at_path(suffix, ReplacementType::BinaryBytes) + .map(|_| ()) + } else { + Ok(()) + } + })?; + Ok(()) + } + /// Cleans all values and removes null inner values at any depth. /// if the replacement can not happen. /// From 54b5e646414615e40c2c3e14f0eb361ab9f50fcb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 20:21:43 +0700 Subject: [PATCH 197/228] fix --- packages/rs-platform-value/src/replace.rs | 36 +++++++++++++---------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/rs-platform-value/src/replace.rs b/packages/rs-platform-value/src/replace.rs index 4ad6ecec645..1e92602bd3f 100644 --- a/packages/rs-platform-value/src/replace.rs +++ b/packages/rs-platform-value/src/replace.rs @@ -428,26 +428,32 @@ impl Value { identifier_paths: HashSet<&str>, binary_paths: HashSet<&str>, ) -> Result<(), Error> { - let mut path = path.to_string(); - path.push('.'); - identifier_paths - .into_iter() - .try_for_each(|identifier_path| { - if let Some(suffix) = identifier_path.strip_prefix(path.as_str()) { - self.replace_at_path(suffix, ReplacementType::Identifier) + if identifier_paths.contains(path) { + ReplacementType::Identifier.replace_value_in_place(self)?; + } else if binary_paths.contains(path) { + ReplacementType::BinaryBytes.replace_value_in_place(self)?; + } else { + let mut path = path.to_string(); + path.push('.'); + identifier_paths + .into_iter() + .try_for_each(|identifier_path| { + if let Some(suffix) = identifier_path.strip_prefix(path.as_str()) { + self.replace_at_path(suffix, ReplacementType::Identifier) + .map(|_| ()) + } else { + Ok(()) + } + })?; + binary_paths.into_iter().try_for_each(|binary_path| { + if let Some(suffix) = binary_path.strip_prefix(path.as_str()) { + self.replace_at_path(suffix, ReplacementType::BinaryBytes) .map(|_| ()) } else { Ok(()) } })?; - binary_paths.into_iter().try_for_each(|binary_path| { - if let Some(suffix) = binary_path.strip_prefix(path.as_str()) { - self.replace_at_path(suffix, ReplacementType::BinaryBytes) - .map(|_| ()) - } else { - Ok(()) - } - })?; + } Ok(()) } From f0ac157f9669ab186a03069c3f1980d7b88ca816 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 20:30:24 +0700 Subject: [PATCH 198/228] another fix --- packages/rs-platform-value/src/inner_value.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index b167b6a010f..cc53e3ce2ef 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -766,7 +766,11 @@ impl Value { } if key.as_text().expect("confirmed as text") == search_key { - return Some(value); + return if value.is_null() { + None + } else { + Some(value) + } } } None @@ -783,7 +787,11 @@ impl Value { } if key.as_text().expect("confirmed as text") == search_key { - return Some(value); + return if value.is_null() { + None + } else { + Some(value) + }; } } None From fdc68f7300c2b2495aba4fd0797e326e8ffcb660 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 20:36:17 +0700 Subject: [PATCH 199/228] another fix --- packages/rs-platform-value/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index be78bd8ba75..973ed888718 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -936,12 +936,12 @@ impl Value { /// assert_eq!(value.to_array_slice(), Ok(vec![Value::U64(17), Value::Float(18.)].as_slice())); /// /// let value = Value::Bool(true); - /// assert_eq!(value.to_array_slice(), Err(Error::StructureError("value is not an array".to_string()))); + /// assert_eq!(value.to_array_slice(), Err(Error::StructureError("value is not an array got bool true".to_string()))); /// ``` pub fn to_array_slice(&self) -> Result<&[Value], Error> { match self { Value::Array(vec) => Ok(vec.as_slice()), - _other => Err(Error::StructureError("value is not an array".to_string())), + other => Err(Error::StructureError(format!("value is not an array got {}", other))), } } From e9e237b8d550fc2aed470775d92e18f6a93c1759 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 20:42:30 +0700 Subject: [PATCH 200/228] more logging --- packages/rs-platform-value/src/lib.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 973ed888718..590349db19f 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -917,8 +917,10 @@ impl Value { /// assert_eq!(value, Value::Array(vec![])); /// ``` pub fn to_array_mut(&mut self) -> Result<&mut Vec, Error> { - self.as_array_mut() - .ok_or(Error::StructureError("value is not an array".to_string())) + match self { + Value::Array(vec) => Ok(vec), + other => Err(Error::StructureError(format!("value is not a mut array got {}", other))), + } } /// If the `Value` is a `Array`, returns a the associated `&[Value]` slice as `Ok`. @@ -960,12 +962,12 @@ impl Value { /// assert_eq!(value.to_array_ref(), Ok(&vec![Value::U64(17), Value::Float(18.)])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.to_array_ref(), Err(Error::StructureError("value is not an array".to_string()))); + /// assert_eq!(value.to_array_ref(), Err(Error::StructureError("value is not an array got bool true".to_string()))); /// ``` pub fn to_array_ref(&self) -> Result<&Vec, Error> { match self { Value::Array(vec) => Ok(vec), - _other => Err(Error::StructureError("value is not an array".to_string())), + other => Err(Error::StructureError(format!("value is not an array got {}", other))), } } @@ -984,12 +986,12 @@ impl Value { /// assert_eq!(value.to_array_owned(), Ok(vec![Value::U64(17), Value::Float(18.)])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.to_array_owned(), Err(Error::StructureError("value is not an array".to_string()))); + /// assert_eq!(value.to_array_owned(), Err(Error::StructureError("value is not an owned array got bool true".to_string()))); /// ``` pub fn to_array_owned(&self) -> Result, Error> { match self { Value::Array(vec) => Ok(vec.clone()), - _other => Err(Error::StructureError("value is not an array".to_string())), + other => Err(Error::StructureError(format!("value is not an owned array got {}", other))), } } @@ -1008,12 +1010,12 @@ impl Value { /// assert_eq!(value.into_array(), Ok(vec![Value::U64(17), Value::Float(18.)])); /// /// let value = Value::Bool(true); - /// assert_eq!(value.into_array(), Err(Error::StructureError("value is not an array".to_string()))); + /// assert_eq!(value.into_array(), Err(Error::StructureError("value is not an array (into) got bool true".to_string()))); /// ``` pub fn into_array(self) -> Result, Error> { match self { Value::Array(vec) => Ok(vec), - _other => Err(Error::StructureError("value is not an array".to_string())), + other => Err(Error::StructureError(format!("value is not an array (into) got {}", other))), } } @@ -1032,12 +1034,12 @@ impl Value { /// assert_eq!(value.as_slice(), Ok(vec![Value::U64(17), Value::Float(18.)].as_slice())); /// /// let value = Value::Bool(true); - /// assert_eq!(value.as_slice(), Err(Error::StructureError("value is not an array".to_string()))); + /// assert_eq!(value.as_slice(), Err(Error::StructureError("value is not a slice got bool true".to_string()))); /// ``` pub fn as_slice(&self) -> Result<&[Value], Error> { match self { Value::Array(vec) => Ok(vec), - _other => Err(Error::StructureError("value is not an array".to_string())), + other => Err(Error::StructureError(format!("value is not a slice got {}", other))), } } From 8d6fa9e431d265df5f350bdbeeea1705962e037e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 21:01:21 +0700 Subject: [PATCH 201/228] added test --- .../src/converter/serde_json.rs | 39 +++++++++++++++++++ packages/rs-platform-value/src/inner_value.rs | 12 +----- packages/rs-platform-value/src/lib.rs | 30 +++++++++++--- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index e0a1379b008..ab1278e92d8 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -405,3 +405,42 @@ impl From<&BTreeMap> for Value { Value::Map(map) } } + +#[cfg(test)] +mod tests { + use crate::Value; + use serde_json::json; + + #[test] + fn test_json_array() { + let json = json!({ + "type": 5, + "protocolVersion": 1, + "revision": 0, + "signature": "HxtcTSpRdACokorvpx/f4ezM40e0WtgW2GUvjiwNkHPwKDppkIoS2cirhqpZURlhDuYdu+E0KllbHNlYghcK9Bg=", + "signaturePublicKeyId": 1, + "publicKeysDisabledAt": 1234567, + "addPublicKeys": [ + { + "id": 0, + "purpose": 0, + "securityLevel": 0, + "type": 0, + "data": "Aya0WP8EhKQ6Dq+51sAnqdPah664X9CUciVJYAfvfTnX", + "readOnly": false, + "signature": "HxtcTSpRdACokorvpx/f4ezM40e0WtgW2GUvjiwNkHPwKDppkIoS2cirhqpZURlhDuYdu+E0KllbHNlYghcK9Bg=" + } + ], + "disablePublicKeys": [ 0 ], + "identityId": "62DHhTfZV3NvUbXUha1mavLqSEy2GaWYja2qeTYNUhk" + }); + + let value: Value = json.into(); + let array = value + .get_optional_array_slice("addPublicKeys") + .expect("expected to get array slice") + .unwrap(); + assert_eq!(array.len(), 1); + assert!(array.get(0).unwrap().is_map()); + } +} diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index cc53e3ce2ef..6cc6f816640 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -766,11 +766,7 @@ impl Value { } if key.as_text().expect("confirmed as text") == search_key { - return if value.is_null() { - None - } else { - Some(value) - } + return if value.is_null() { None } else { Some(value) }; } } None @@ -787,11 +783,7 @@ impl Value { } if key.as_text().expect("confirmed as text") == search_key { - return if value.is_null() { - None - } else { - Some(value) - }; + return if value.is_null() { None } else { Some(value) }; } } None diff --git a/packages/rs-platform-value/src/lib.rs b/packages/rs-platform-value/src/lib.rs index 590349db19f..7f61520dacb 100644 --- a/packages/rs-platform-value/src/lib.rs +++ b/packages/rs-platform-value/src/lib.rs @@ -919,7 +919,10 @@ impl Value { pub fn to_array_mut(&mut self) -> Result<&mut Vec, Error> { match self { Value::Array(vec) => Ok(vec), - other => Err(Error::StructureError(format!("value is not a mut array got {}", other))), + other => Err(Error::StructureError(format!( + "value is not a mut array got {}", + other + ))), } } @@ -943,7 +946,10 @@ impl Value { pub fn to_array_slice(&self) -> Result<&[Value], Error> { match self { Value::Array(vec) => Ok(vec.as_slice()), - other => Err(Error::StructureError(format!("value is not an array got {}", other))), + other => Err(Error::StructureError(format!( + "value is not an array got {}", + other + ))), } } @@ -967,7 +973,10 @@ impl Value { pub fn to_array_ref(&self) -> Result<&Vec, Error> { match self { Value::Array(vec) => Ok(vec), - other => Err(Error::StructureError(format!("value is not an array got {}", other))), + other => Err(Error::StructureError(format!( + "value is not an array got {}", + other + ))), } } @@ -991,7 +1000,10 @@ impl Value { pub fn to_array_owned(&self) -> Result, Error> { match self { Value::Array(vec) => Ok(vec.clone()), - other => Err(Error::StructureError(format!("value is not an owned array got {}", other))), + other => Err(Error::StructureError(format!( + "value is not an owned array got {}", + other + ))), } } @@ -1015,7 +1027,10 @@ impl Value { pub fn into_array(self) -> Result, Error> { match self { Value::Array(vec) => Ok(vec), - other => Err(Error::StructureError(format!("value is not an array (into) got {}", other))), + other => Err(Error::StructureError(format!( + "value is not an array (into) got {}", + other + ))), } } @@ -1039,7 +1054,10 @@ impl Value { pub fn as_slice(&self) -> Result<&[Value], Error> { match self { Value::Array(vec) => Ok(vec), - other => Err(Error::StructureError(format!("value is not a slice got {}", other))), + other => Err(Error::StructureError(format!( + "value is not a slice got {}", + other + ))), } } From 0b325044571a69e8ff21831d87804b876f0b838b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 21:11:37 +0700 Subject: [PATCH 202/228] fix --- .../rs-platform-value/src/converter/serde_json.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index ab1278e92d8..137c776843f 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -190,7 +190,9 @@ impl From for Value { JsonValue::String(string) => Self::Text(string), JsonValue::Array(array) => { let u8_max = u8::MAX as u64; - if !array.is_empty() + //todo: hacky solution, to fix + let len = array.len(); + if (len == 20 || len == 32 || len == 36) && array.iter().all(|v| { let Some(int) = v.as_u64() else { return false; @@ -234,7 +236,9 @@ impl From<&JsonValue> for Value { JsonValue::String(string) => Self::Text(string.clone()), JsonValue::Array(array) => { let u8_max = u8::MAX as u64; - if !array.is_empty() + //todo: hacky solution, to fix + let len = array.len(); + if (len == 20 || len == 32 || len == 36) && array.iter().all(|v| { let Some(int) = v.as_u64() else { return false; @@ -442,5 +446,10 @@ mod tests { .unwrap(); assert_eq!(array.len(), 1); assert!(array.get(0).unwrap().is_map()); + let array = value + .get_optional_array_slice("disablePublicKeys") + .expect("expected to get array slice") + .unwrap(); + assert_eq!(array.len(), 1); } } From 8170f312ea7547e3ae195f67a6d4236a099f78d5 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 21:14:46 +0700 Subject: [PATCH 203/228] fix --- packages/rs-platform-value/src/converter/serde_json.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 137c776843f..246d54c091b 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -192,7 +192,7 @@ impl From for Value { let u8_max = u8::MAX as u64; //todo: hacky solution, to fix let len = array.len(); - if (len == 20 || len == 32 || len == 36) + if len >= 20 && array.iter().all(|v| { let Some(int) = v.as_u64() else { return false; @@ -238,7 +238,7 @@ impl From<&JsonValue> for Value { let u8_max = u8::MAX as u64; //todo: hacky solution, to fix let len = array.len(); - if (len == 20 || len == 32 || len == 36) + if len >= 20 && array.iter().all(|v| { let Some(int) = v.as_u64() else { return false; From 61a8c2dcd0ab6eac6f65d40690398810eedbbd65 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 14:19:50 +0000 Subject: [PATCH 204/228] refactor(rs-dpp): use get_optional_array_slice --- .../validate_identity_update_transition_basic.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs index 5c870f6681a..006bdce219d 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs @@ -78,8 +78,7 @@ where } let maybe_raw_public_keys = raw_state_transition - .get_optional_value(property_names::ADD_PUBLIC_KEYS) - .and_then(|value| value.map(|value| value.to_array_slice()).transpose()) + .get_optional_array_slice(property_names::ADD_PUBLIC_KEYS) .map_err(NonConsensusError::ValueError)?; match maybe_raw_public_keys { From cc09396b6b695d848e08a780e2566f498ada0775 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 14:46:26 +0000 Subject: [PATCH 205/228] test(wasm-dpp): fix Buffer byte size in validateDocumentsBatchTransitionBasicFactory.spec.js --- packages/rs-platform-value/src/converter/serde_json.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 246d54c091b..f2ab72bc334 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -192,7 +192,7 @@ impl From for Value { let u8_max = u8::MAX as u64; //todo: hacky solution, to fix let len = array.len(); - if len >= 20 + if len >= 10 && array.iter().all(|v| { let Some(int) = v.as_u64() else { return false; @@ -238,7 +238,7 @@ impl From<&JsonValue> for Value { let u8_max = u8::MAX as u64; //todo: hacky solution, to fix let len = array.len(); - if len >= 20 + if len >= 10 && array.iter().all(|v| { let Some(int) = v.as_u64() else { return false; From 1a31cecce28a431722bd4def76e68cd351c766bf Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 14:46:33 +0000 Subject: [PATCH 206/228] test(wasm-dpp): fix Buffer byte size in validateDocumentsBatchTransitionBasicFactory.spec.js --- .../basic/validateDocumentsBatchTransitionBasicFactory.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js index 59a9410a7a7..1037d2cd318 100644 --- a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js @@ -482,7 +482,7 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { it('should be a byte array - Rust', async () => { const [firstDocumentTransition] = rawStateTransition.transitions; - firstDocumentTransition.$dataContractId = Buffer.alloc(2); + firstDocumentTransition.$dataContractId = Buffer.alloc(10); const result = await validateDocumentsBatchTransitionBasic( protocolVersionValidator, From dd4dacfcc8cef494e4c3a1eb38274d8524a7e2e4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 21 Mar 2023 23:35:33 +0700 Subject: [PATCH 207/228] another fix --- packages/rs-dpp/src/identity/identity.rs | 6 +----- packages/rs-platform-value/src/inner_value.rs | 5 +++++ packages/rs-platform-value/src/value_map.rs | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 81c2f7f56d2..442237f5bd3 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -96,11 +96,7 @@ impl Convertible for Identity { let mut value = self.to_object()?; if let Some(keys) = value.get_optional_array_mut_ref(property_names::PUBLIC_KEYS)? { for key in keys.iter_mut() { - if let Some(value) = key.get_optional_value("disabledAt")? { - if value.is_null() { - key.remove("disabledAt")?; - } - } + key.remove_optional_value_if_null("disabledAt")?; } } Ok(value) diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 6cc6f816640..c54c6ca05f3 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -89,6 +89,11 @@ impl Value { Ok(map.remove_optional_key(key)) } + pub fn remove_optional_value_if_null(&mut self, key: &str) -> Result<(), Error> { + let map = self.as_map_mut_ref()?; + Ok(map.remove_optional_key_if_null(key)) + } + pub fn remove_integer(&mut self, key: &str) -> Result where T: TryFrom diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index 57310eb0738..bd5e4f8b7c1 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -18,6 +18,7 @@ pub trait ValueMapHelper { fn insert_string_key_value(&mut self, key: String, value: Value); fn remove_key(&mut self, search_key: &str) -> Result; fn remove_optional_key(&mut self, key: &str) -> Option; + fn remove_optional_key_if_null(&mut self, search_key: &str); fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option; } @@ -170,6 +171,23 @@ impl ValueMapHelper for ValueMap { .map(|pos| self.remove(pos).1) } + fn remove_optional_key_if_null(&mut self, search_key: &str) { + self.iter() + .position(|(key, value)| { + if let Value::Text(text) = key { + if text == search_key { + value.is_null() + } else { + false + } + } else { + false + } + }) + .map(|pos| self.remove(pos).1); + } + + fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option { self.iter() .position(|(key, _)| search_key_value == key) From 646749acf188db86120bbe65886f719fca4820e6 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 00:18:50 +0700 Subject: [PATCH 208/228] remove optional value path --- .../src/inner_value_at_path.rs | 23 +++++++++++++++++++ packages/rs-platform-value/src/value_map.rs | 1 - 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index 8622bf652bc..738a9d58c23 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -49,6 +49,29 @@ impl Value { map.remove_key(last_path_component) } + pub fn remove_optional_value_at_path(&mut self, path: &str) -> Result, Error> { + let mut split = path.split('.').peekable(); + let mut current_value = self; + let mut last_path_component = None; + while let Some(path_component) = split.next() { + if split.peek().is_none() { + last_path_component = Some(path_component); + } else { + let map = current_value.to_map_mut()?; + if let Some(maybe_value) = map.get_optional_key_mut(path_component) { + current_value = maybe_value; + } else { + return Ok(None); + } + }; + } + let Some(last_path_component) = last_path_component else { + return Err(Error::StructureError("path was empty".to_string())); + }; + let map = current_value.as_map_mut_ref()?; + OK(map.remove_optional_key(last_path_component)) + } + pub fn remove_values_matching_path(&mut self, path: &str) -> Result, Error> { let mut split = path.split('.').peekable(); let mut current_values = vec![self]; diff --git a/packages/rs-platform-value/src/value_map.rs b/packages/rs-platform-value/src/value_map.rs index bd5e4f8b7c1..e2006f845aa 100644 --- a/packages/rs-platform-value/src/value_map.rs +++ b/packages/rs-platform-value/src/value_map.rs @@ -187,7 +187,6 @@ impl ValueMapHelper for ValueMap { .map(|pos| self.remove(pos).1); } - fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option { self.iter() .position(|(key, _)| search_key_value == key) From 4aaa396a7d5a0c8d3af098b956283358f9c05441 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 00:19:33 +0700 Subject: [PATCH 209/228] fix --- .../asset_lock_proof/chain/chain_asset_lock_proof.rs | 1 - packages/rs-platform-value/src/inner_value_at_path.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index 3493b07c608..7c94c06942c 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -1,6 +1,5 @@ use platform_value::{Bytes36, Value}; use serde::{Deserialize, Serialize}; -use serde_big_array::BigArray; use std::convert::TryFrom; use crate::{ diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index 738a9d58c23..f6c5fede574 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -69,7 +69,7 @@ impl Value { return Err(Error::StructureError("path was empty".to_string())); }; let map = current_value.as_map_mut_ref()?; - OK(map.remove_optional_key(last_path_component)) + Ok(map.remove_optional_key(last_path_component)) } pub fn remove_values_matching_path(&mut self, path: &str) -> Result, Error> { From 7a41890e80ef10fd3835263bde28d239b960ca62 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 17:29:56 +0000 Subject: [PATCH 210/228] fix(wasm-dpp): use to_cleaned_object in IdentityFacade validate --- packages/wasm-dpp/src/identity/identity_facade.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/src/identity/identity_facade.rs b/packages/wasm-dpp/src/identity/identity_facade.rs index ca6a4665ef7..d0f44847420 100644 --- a/packages/wasm-dpp/src/identity/identity_facade.rs +++ b/packages/wasm-dpp/src/identity/identity_facade.rs @@ -118,7 +118,7 @@ impl IdentityFacadeWasm { #[wasm_bindgen] pub fn validate(&self, identity: IdentityWasm) -> Result { let identity: Identity = identity.into(); - let identity_json = identity.to_object().with_js_error()?; + let identity_json = identity.to_cleaned_object().with_js_error()?; let validation_result = self .0 From ed84a646fb5657df44d5fedf3a099a1b01fd17e1 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 17:30:26 +0000 Subject: [PATCH 211/228] refactor(wasm-dpp): dpp rework path removal functions in to_object --- .../data_contract_create_transition/mod.rs | 4 +- .../data_contract_update_transition/mod.rs | 4 +- .../documents_batch_transition/mod.rs | 4 +- .../identity_create_transition.rs | 4 +- .../mod.rs | 4 +- .../identity_topup_transition.rs | 4 +- .../document_batch_transition/mod.rs | 41 +++++++++++-------- 7 files changed, 36 insertions(+), 29 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index f71ce1d189c..82bc16a2b53 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -243,7 +243,7 @@ impl StateTransitionConvert for DataContractCreateTransition { .into_iter() .try_for_each(|path| { object - .remove_value_at_path(path) + .remove_values_matching_path(path) .map_err(ProtocolError::ValueError) .map(|_| ()) })?; @@ -259,7 +259,7 @@ impl StateTransitionConvert for DataContractCreateTransition { .into_iter() .try_for_each(|path| { object - .remove_value_at_path(path) + .remove_values_matching_path(path) .map_err(ProtocolError::ValueError) .map(|_| ()) })?; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 6c638ec75e3..165bfaba1d7 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -223,7 +223,7 @@ impl StateTransitionConvert for DataContractUpdateTransition { .into_iter() .try_for_each(|path| { object - .remove_value_at_path(path) + .remove_values_matching_path(path) .map_err(ProtocolError::ValueError) .map(|_| ()) })?; @@ -239,7 +239,7 @@ impl StateTransitionConvert for DataContractUpdateTransition { .into_iter() .try_for_each(|path| { object - .remove_value_at_path(path) + .remove_values_matching_path(path) .map_err(ProtocolError::ValueError) .map(|_| ()) })?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index cd77f51b422..ede118adcc3 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -376,7 +376,7 @@ impl StateTransitionConvert for DocumentsBatchTransition { let mut object: Value = platform_value::to_value(self)?; if skip_signature { for path in Self::signature_property_paths() { - let _ = object.remove(path); + let _ = object.remove_values_matching_path(path); } } let mut transitions = vec![]; @@ -465,7 +465,7 @@ impl StateTransitionConvert for DocumentsBatchTransition { let mut object: Value = platform_value::to_value(self)?; if skip_signature { for path in Self::signature_property_paths() { - let _ = object.remove(path); + let _ = object.remove_values_matching_path(path); } } let mut transitions = vec![]; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index ebfca1d5763..739538723da 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -230,7 +230,7 @@ impl StateTransitionConvert for IdentityCreateTransition { if skip_signature { value - .remove_values_at_paths(Self::signature_property_paths()) + .remove_values_matching_paths(Self::signature_property_paths()) .map_err(ProtocolError::ValueError)?; } @@ -257,7 +257,7 @@ impl StateTransitionConvert for IdentityCreateTransition { if skip_signature { value - .remove_values_at_paths(Self::signature_property_paths()) + .remove_values_matching_paths(Self::signature_property_paths()) .map_err(ProtocolError::ValueError)?; } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index e5849faadce..9bca3abde5c 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs @@ -183,7 +183,7 @@ impl StateTransitionConvert for IdentityCreditWithdrawalTransition { let mut value = platform_value::to_value(self)?; if skip_signature { value - .remove_many(&Self::signature_property_paths()) + .remove_values_matching_paths(Self::signature_property_paths()) .map_err(ProtocolError::ValueError)?; } Ok(value) @@ -198,7 +198,7 @@ impl StateTransitionConvert for IdentityCreditWithdrawalTransition { let mut value = platform_value::to_value(self)?; if skip_signature { value - .remove_many(&Self::signature_property_paths()) + .remove_values_matching_paths(Self::signature_property_paths()) .map_err(ProtocolError::ValueError)?; } Ok(value) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index ecb0267ef51..7381a2d0578 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -147,7 +147,7 @@ impl StateTransitionConvert for IdentityTopUpTransition { if skip_signature { value - .remove_values_at_paths(Self::signature_property_paths()) + .remove_values_matching_paths(Self::signature_property_paths()) .map_err(ProtocolError::ValueError)?; } @@ -164,7 +164,7 @@ impl StateTransitionConvert for IdentityTopUpTransition { if skip_signature { value - .remove_values_at_paths(Self::signature_property_paths()) + .remove_values_matching_paths(Self::signature_property_paths()) .map_err(ProtocolError::ValueError)?; } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 5f7ab3b5df9..7e15b529050 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -160,7 +160,10 @@ impl DocumentsBatchTransitionWasm { Default::default() }; - let mut value = self.0.to_object(options.skip_signature).with_js_error()?; + let mut value = self + .0 + .to_cleaned_object(options.skip_signature) + .with_js_error()?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_value = value.serialize(&serializer)?; let is_signature_present = value @@ -185,26 +188,30 @@ impl DocumentsBatchTransitionWasm { // Transform paths that are specific to the DocumentsBatchTransition for path in DocumentsBatchTransition::binary_property_paths() { - let bytes = value - .remove_value_at_path(path) - .and_then(|value| value.to_binary_bytes()) + if let Some(bytes) = value + .remove_optional_value_at_path(path) + .and_then(|value| value.map(|value| value.to_binary_bytes()).transpose()) .map_err(ProtocolError::ValueError) - .with_js_error()?; - let buffer = Buffer::from_bytes_owned(bytes); - lodash_set(&js_value, path, buffer.into()); + .with_js_error()? + { + let buffer = Buffer::from_bytes_owned(bytes); + lodash_set(&js_value, path, buffer.into()); + } } for path in DocumentsBatchTransition::identifiers_property_paths() { - let bytes = value - .remove_value_at_path(path) - .and_then(|value| value.to_identifier_bytes()) + if let Some(bytes) = value + .remove_optional_value_at_path(path) + .and_then(|value| value.map(|value| value.to_identifier_bytes()).transpose()) .map_err(ProtocolError::ValueError) - .with_js_error()?; - let buffer = Buffer::from_bytes_owned(bytes); - if !options.skip_identifiers_conversion { - lodash_set(&js_value, path, buffer.into()); - } else { - let id = IdentifierWrapper::new(buffer.into())?; - lodash_set(&js_value, path, id.into()); + .with_js_error()? + { + let buffer = Buffer::from_bytes_owned(bytes); + if !options.skip_identifiers_conversion { + lodash_set(&js_value, path, buffer.into()); + } else { + let id = IdentifierWrapper::new(buffer.into())?; + lodash_set(&js_value, path, id.into()); + } } } From 8e84332ff217e2d788eba66711620252596befae Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 17:35:08 +0000 Subject: [PATCH 212/228] refactor(wasm-dpp): eslint --- ...idateDocumentsBatchTransitionBasicFactory.spec.js | 2 -- .../applyDocumentsBatchTransitionFactory.spec.js | 3 ++- .../validation/state/fetchDocumentsFactory.spec.js | 2 -- ...idateDocumentsBatchTransitionStateFactory.spec.js | 12 ++++++++---- ...lidateDocumentsUniquenessByIndicesFactory.spec.js | 4 +++- .../test/unit/identity/IdentityFactory.spec.js | 3 +-- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js index 1037d2cd318..a0df164b1a6 100644 --- a/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/document/stateTransition/DocumentsBatchTransition/validation/basic/validateDocumentsBatchTransitionBasicFactory.spec.js @@ -14,7 +14,6 @@ let StateTransitionExecutionContext; let validateDocumentsBatchTransitionBasic; let generateDocumentId; let MissingDataContractIdError; -let InvalidIdentifierError; let DataContractNotPresentError; let MissingDocumentTransitionTypeError; let InvalidDocumentTypeError; @@ -47,7 +46,6 @@ describe('validateDocumentsBatchTransitionBasicFactory', () => { ValidationResult, validateDocumentsBatchTransitionBasic, generateDocumentId, - InvalidIdentifierError, MissingDataContractIdError, DataContractNotPresentError, MissingDocumentTransitionTypeError, diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js index 99d16d84976..58f6b9d0c27 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/applyDocumentsBatchTransitionFactory.spec.js @@ -166,7 +166,8 @@ describe('applyDocumentsBatchTransitionFactory', () => { await applyDocumentsBatchTransition(stateRepositoryMock, stateTransition); expect(stateRepositoryMock.createDocument).to.have.been.calledOnce(); - const [fetchContractId, fetchDocumentType] = stateRepositoryMock.fetchExtendedDocuments.getCall(0).args; + const [fetchContractId, fetchDocumentType] = stateRepositoryMock + .fetchExtendedDocuments.getCall(0).args; expect(fetchContractId.toBuffer()).to.deep.equal(documentTransitionsJs[1].getDataContractId()); expect(fetchDocumentType).to.equal(documentTransitionsJs[1].getType()); diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js index dcb2f988462..647d30018ed 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/fetchDocumentsFactory.spec.js @@ -10,7 +10,6 @@ const { default: loadWasmDpp } = require('../../../../../../../dist'); let Identifier; let DataContract; -let Document; let fetchExtendedDocuments; let DocumentTransition; let DocumentCreateTransition; @@ -28,7 +27,6 @@ describe('fetchDocumentsFactory', () => { beforeEach(async function beforeEach() { ({ Identifier, - Document, DataContract, DocumentTransition, DocumentCreateTransition, diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js index 22e938de6b4..f4e9da79b90 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsBatchTransitionStateFactory.spec.js @@ -182,7 +182,8 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.callCount(documentTransitionsJs.length); + expect(stateRepositoryMock.fetchExtendedDocuments) + .to.have.been.callCount(documentTransitionsJs.length); }); it('should return invalid result if document transition with action "delete" is not present - Rust', async () => { @@ -212,7 +213,8 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.callCount(documentTransitionsJs.length); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been + .callCount(documentTransitionsJs.length); }); it('should return invalid result if document transition with action "replace" has wrong revision - Rust', async () => { @@ -250,7 +252,8 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.callCount(documentTransitionsJs.length); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been + .callCount(documentTransitionsJs.length); }); it('should return invalid result if document transition with action "replace" has mismatch of ownerId with previous revision - Rust', async () => { @@ -292,7 +295,8 @@ describe('validateDocumentsBatchTransitionStateFactory', () => { const [fetchDataContractId] = stateRepositoryMock.fetchDataContract.getCall(0).args; expect(fetchDataContractId.toBuffer()).to.deep.equal(dataContract.getId().toBuffer()); - expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been.callCount(documentTransitionsJs.length); + expect(stateRepositoryMock.fetchExtendedDocuments).to.have.been + .callCount(documentTransitionsJs.length); }); it('should throw an error if document transition has invalid action - Rust', async () => { diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js index e4a29c68029..9d865356ce3 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js @@ -232,7 +232,9 @@ describe('validateDocumentsUniquenessByIndices', () => { it('should return valid result if Document has undefined field from index - Rust', async () => { const indexedDocumentJs = documentsJs[7]; - const indexedDocument = new Document(indexedDocumentJs.toObject(), dataContract.clone(), indexedDocumentJs.getType()); + const indexedDocument = new Document( + indexedDocumentJs.toObject(), dataContract.clone(), indexedDocumentJs.getType(), + ); const indexedDocumentTransitions = getDocumentTransitionsFixture({ create: [indexedDocumentJs], }).map( diff --git a/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js b/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js index 59bdb60fa80..fc3c883d529 100644 --- a/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js +++ b/packages/wasm-dpp/test/unit/identity/IdentityFactory.spec.js @@ -23,7 +23,6 @@ describe('IdentityFactory', () => { let InvalidIdentityError; let PlatformValueError; let UnsupportedProtocolVersionError; - let JsonSchemaError; let ChainAssetLockProof; before(async () => { @@ -31,7 +30,7 @@ describe('IdentityFactory', () => { Identity, IdentityFactory, IdentityValidator, InstantAssetLockProof, ChainAssetLockProof, IdentityUpdateTransition, IdentityCreateTransition, IdentityTopUpTransition, IdentityPublicKeyCreateTransition, - InvalidIdentityError, UnsupportedProtocolVersionError, PlatformValueError, JsonSchemaError, + InvalidIdentityError, UnsupportedProtocolVersionError, PlatformValueError, } = await loadWasmDpp()); }); From 97c654253c3979ffad766dd6a50549cf5e1b5177 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 00:47:55 +0700 Subject: [PATCH 213/228] renamed method --- .../identity_update_transition/identity_update_transition.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index fce46109a9a..cfe305b6ec3 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -117,7 +117,7 @@ impl IdentityUpdateTransition { .map_err(ProtocolError::ValueError)?; let add_public_keys = get_list(&mut raw_object, property_names::ADD_PUBLIC_KEYS)?; let disable_public_keys = - get_integer_list(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; + remove_integer_list_or_default(&mut raw_object, property_names::DISABLE_PUBLIC_KEYS)?; let public_keys_disabled_at = raw_object .remove_optional_integer(property_names::PUBLIC_KEYS_DISABLED_AT) .map_err(ProtocolError::ValueError)?; @@ -216,7 +216,7 @@ fn get_list>( /// if the property isn't present the empty list is returned. If property is defined, the function /// might return some serialization-related errors -fn get_integer_list(value: &mut Value, property_name: &str) -> Result, ProtocolError> +fn remove_integer_list_or_default(value: &mut Value, property_name: &str) -> Result, ProtocolError> where T: TryFrom + TryFrom From bfae9c8735141981a43086cde0bae47a451c4c73 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 00:54:05 +0700 Subject: [PATCH 214/228] fixes --- .../identity_update_transition.rs | 2 +- .../abstract_state_transition_identity_signed.rs | 2 +- packages/wasm-dpp/src/data_contract/data_contract.rs | 4 ++-- .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_create_transition/validation.rs | 6 ++---- .../data_contract_update_transition/mod.rs | 2 +- .../data_contract_update_transition/validation.rs | 8 +++----- .../src/data_contract_factory/data_contract_factory.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 2 +- packages/wasm-dpp/src/identity/identity_public_key/mod.rs | 2 +- packages/wasm-dpp/src/identity/mod.rs | 2 +- .../identity_create_transition.rs | 3 +-- 12 files changed, 16 insertions(+), 21 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index cfe305b6ec3..17011676398 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -1,4 +1,4 @@ -use platform_value::{BinaryData, IntegerReplacementType, ReplacementType, Value}; +use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; use std::convert::{TryFrom, TryInto}; diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index 7f3c19abdaa..5b673e9fcb7 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs @@ -231,7 +231,7 @@ mod test { vec!["signature", "signaturePublicKeyId"] } - fn to_cleaned_object(&self, skip_signature: bool) -> Result { + fn to_cleaned_object(&self, _skip_signature: bool) -> Result { todo!() } } diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index d9ea3d7d4f0..21c919aac9b 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -10,10 +10,10 @@ use wasm_bindgen::prelude::*; use dpp::data_contract::{DataContract, SCHEMA_URI}; use dpp::platform_value::string_encoding::Encoding; use dpp::platform_value::{Bytes32, Value}; -use dpp::prelude::Identifier; + use dpp::{platform_value, Convertible}; -use crate::errors::{from_dpp_err, RustConversionError}; +use crate::errors::{RustConversionError}; use crate::identifier::identifier_from_js_value; use crate::metadata::MetadataWasm; use crate::utils::WithJsError; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 3adada64938..4dcda7dee01 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -21,7 +21,7 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::protocol_error::from_protocol_error; use crate::utils::WithJsError; use crate::{ - buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper, with_js_error, + buffer::Buffer, identifier::IdentifierWrapper, with_js_error, DataContractParameters, DataContractWasm, IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, }; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs index d9b512c5fd6..65a9b37a790 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs @@ -1,8 +1,8 @@ use std::sync::Arc; -use dpp::block_time_window::validation_result; + use dpp::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; -use dpp::platform_value::Value; + use dpp::validation::SimpleValidationResult; use dpp::{ data_contract::state_transition::data_contract_create_transition::validation::state::{ @@ -13,14 +13,12 @@ use dpp::{ state_transition::state_transition_execution_context::StateTransitionExecutionContext, validation::DataValidatorWithContext, version::ProtocolVersionValidator, - ProtocolError, }; use wasm_bindgen::prelude::*; use crate::utils::WithJsError; use crate::validation::ValidationResultWasm; use crate::{ - errors::from_dpp_err, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, DataContractCreateTransitionWasm, }; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 343d193189e..b9b4e28fd1e 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -20,7 +20,7 @@ use wasm_bindgen::prelude::*; use crate::utils::WithJsError; use crate::{ buffer::Buffer, - errors::{from_dpp_err, protocol_error::from_protocol_error}, + errors::{protocol_error::from_protocol_error}, identifier::IdentifierWrapper, with_js_error, DataContractParameters, DataContractWasm, StateTransitionExecutionContextWasm, }; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index 380e2ccde10..84e85cd0a22 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -1,11 +1,10 @@ use std::{collections::BTreeMap, sync::Arc}; -use dpp::data_contract::state_transition::data_contract_update_transition; + use dpp::data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition; -use dpp::platform_value::{ReplacementType, Value}; + use dpp::validation::{AsyncDataValidatorWithContext, SimpleValidationResult}; use dpp::{ - data_contract, data_contract::state_transition::data_contract_update_transition::validation::{ basic::{ validate_indices_are_backward_compatible as dpp_validate_indices_are_backward_compatible, @@ -15,14 +14,13 @@ use dpp::{ }, platform_value, version::ProtocolVersionValidator, - ProtocolError, }; use wasm_bindgen::prelude::*; use crate::utils::WithJsError; use crate::{ data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransitionParameters, - errors::{from_dpp_err, protocol_error::from_protocol_error}, + errors::{protocol_error::from_protocol_error}, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, validation::ValidationResultWasm, DataContractUpdateTransitionWasm, StateTransitionExecutionContextWasm, diff --git a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs index ad62a304f22..1ebbf0e9e11 100644 --- a/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs +++ b/packages/wasm-dpp/src/data_contract_factory/data_contract_factory.rs @@ -17,7 +17,7 @@ use crate::utils::WithJsError; use crate::{ data_contract::errors::InvalidDataContractError, errors::{from_dpp_err, protocol_error::from_protocol_error}, - js_value_to_data_contract_value, js_value_to_identity_update_transition_object, + js_value_to_data_contract_value, validation::ValidationResultWasm, with_js_error, DataContractCreateTransitionWasm, DataContractParameters, DataContractWasm, }; diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 91940018c82..2dc4db9f52b 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -1,7 +1,7 @@ use dpp::dashcore::anyhow::Context; use dpp::prelude::{DataContract, Identifier}; use dpp::util::json_schema::JsonSchemaExt; -use dpp::util::json_value::JsonValueExt; + use anyhow::anyhow; use serde::{Deserialize, Serialize}; diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index 4e2d6b93b97..271720c4c61 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -8,7 +8,7 @@ use crate::utils::{Inner, WithJsError}; use crate::{buffer::Buffer, utils, with_js_error}; use dpp::identity::{IdentityPublicKey, KeyID}; use dpp::platform_value::BinaryData; -use dpp::{Convertible, ProtocolError}; +use dpp::{Convertible}; mod purpose; pub use purpose::*; diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index 8b05f3ae538..fcabf210d07 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -12,7 +12,7 @@ use dpp::identity::state_transition::asset_lock_proof::AssetLockProof; use dpp::identity::IdentityPublicKey; use dpp::identity::{Identity, KeyID}; use dpp::metadata::Metadata; -use dpp::{Convertible, ProtocolError, SerdeParsingError}; +use dpp::{Convertible, ProtocolError}; use crate::identifier::IdentifierWrapper; use crate::utils::{to_vec_of_serde_values, WithJsError}; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index aa14ce5e702..de67f1f6824 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -22,7 +22,7 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::utils::{generic_of_js_val, ToSerdeJSONExt, WithJsError}; use dpp::platform_value::string_encoding::Encoding; -use dpp::platform_value::{string_encoding, ReplacementType}; +use dpp::platform_value::{string_encoding}; use dpp::{ identifier::Identifier, identity::state_transition::{ @@ -30,7 +30,6 @@ use dpp::{ identity_public_key_transitions::IdentityPublicKeyWithWitness, }, state_transition::StateTransitionLike, - ProtocolError, }; #[wasm_bindgen(js_name=IdentityCreateTransition)] From df23c37f8408d1e9379baddfe12e5d806c05eb3a Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 21 Mar 2023 18:02:15 +0000 Subject: [PATCH 215/228] test(wasm-dpp): add getIdentityUpdateTransitionFixture.js --- .../getIdentityUpdateTransitionFixture.js | 5 +- .../getIdentityUpdateTransitionFixture.js | 35 ++++++++++ .../getInstantAssetLockProofFixture.js | 65 +++++++++++++++++++ ...entityUpdateTransitionBasicFactory.spec.js | 7 +- ...entityUpdateTransitionStateFactory.spec.js | 8 +-- .../IdentityUpdateTransition.spec.js | 12 ++-- ...plyIdentityUpdateTransitionFactory.spec.js | 9 +-- 7 files changed, 112 insertions(+), 29 deletions(-) create mode 100644 packages/wasm-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js create mode 100644 packages/wasm-dpp/lib/test/fixtures/getInstantAssetLockProofFixture.js diff --git a/packages/js-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js b/packages/js-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js index cc3413ac5ed..1f4c4099762 100644 --- a/packages/js-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js +++ b/packages/js-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js @@ -7,11 +7,10 @@ const IdentityPublicKey = require('../../identity/IdentityPublicKey'); module.exports = function getIdentityUpdateTransitionFixture() { const rawStateTransition = { - signature: Buffer.alloc(0), - signaturePublicKeyId: 0, protocolVersion: protocolVersion.latestVersion, type: stateTransitionTypes.IDENTITY_UPDATE, - assetLockProof: getInstantAssetLockProofFixture().toObject(), + assetLockProof: getInstantAssetLockProofFixture() + .toObject(), identityId: generateRandomIdentifier(), revision: 0, addPublicKeys: [ diff --git a/packages/wasm-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js b/packages/wasm-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js new file mode 100644 index 00000000000..ebdb365521c --- /dev/null +++ b/packages/wasm-dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture.js @@ -0,0 +1,35 @@ +const generateRandomIdentifierAsync = require('../utils/generateRandomIdentifierAsync'); + +const getInstantAssetLockProofFixture = require('./getInstantAssetLockProofFixture'); + +const { default: loadWasmDpp } = require('../../..'); +let { IdentityUpdateTransition, IdentityPublicKey } = require('../../..'); + +module.exports = async function getIdentityUpdateTransitionFixture() { + ({ IdentityUpdateTransition, IdentityPublicKey } = await loadWasmDpp()); + + const rawStateTransition = { + signature: Buffer.alloc(0), + signaturePublicKeyId: 0, + protocolVersion: 1, + type: 5, + assetLockProof: (await getInstantAssetLockProofFixture()).toObject(), + identityId: (await generateRandomIdentifierAsync()).toBuffer(), + revision: 0, + addPublicKeys: [ + { + id: 3, + type: IdentityPublicKey.TYPES.ECDSA_SECP256K1, + data: Buffer.from('AkVuTKyF3YgKLAQlLEtaUL2HTditwGILfWUVqjzYnIgH', 'base64'), + purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, + securityLevel: IdentityPublicKey.SECURITY_LEVELS.MASTER, + signature: Buffer.alloc(0), + readOnly: false, + }, + ], + disablePublicKeys: [0], + publicKeysDisabledAt: 1234567, + }; + + return new IdentityUpdateTransition(rawStateTransition); +}; diff --git a/packages/wasm-dpp/lib/test/fixtures/getInstantAssetLockProofFixture.js b/packages/wasm-dpp/lib/test/fixtures/getInstantAssetLockProofFixture.js new file mode 100644 index 00000000000..a1635315091 --- /dev/null +++ b/packages/wasm-dpp/lib/test/fixtures/getInstantAssetLockProofFixture.js @@ -0,0 +1,65 @@ +const { + Transaction, + InstantLock, + PrivateKey, + Script, + Opcode, +} = require('@dashevo/dashcore-lib'); + +const { default: loadWasmDpp } = require('../../..'); +let { InstantAssetLockProof } = require('../../..'); + +/** + * @param {PrivateKey} [oneTimePrivateKey] + */ +async function getInstantAssetLockProofFixture(oneTimePrivateKey = new PrivateKey()) { + ({ InstantAssetLockProof } = await loadWasmDpp()); + + const privateKeyHex = 'cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY'; + const privateKey = new PrivateKey(privateKeyHex); + const fromAddress = privateKey.toAddress(); + + const oneTimePublicKey = oneTimePrivateKey.toPublicKey(); + + const transaction = new Transaction() + .from({ + address: fromAddress, + txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458', + outputIndex: 0, + script: Script.buildPublicKeyHashOut(fromAddress) + .toString(), + satoshis: 100000, + }) + // eslint-disable-next-line no-underscore-dangle + .addBurnOutput(90000, oneTimePublicKey._getID()) + .to(fromAddress, 5000) + .addOutput(Transaction.Output({ + satoshis: 5000, + script: Script() + .add(Opcode.OP_RETURN) + .add(Buffer.from([1, 2, 3])), + })) + .sign(privateKey); + + const instantLock = new InstantLock({ + version: 1, + inputs: [ + { + outpointHash: '6e200d059fb567ba19e92f5c2dcd3dde522fd4e0a50af223752db16158dabb1d', + outpointIndex: 0, + }, + ], + txid: transaction.id, + cyclehash: '7c30826123d0f29fe4c4a8895d7ba4eb469b1fafa6ad7b23896a1a591766a536', + signature: '8967c46529a967b3822e1ba8a173066296d02593f0f59b3a78a30a7eef9c8a120847729e62e4a32954339286b79fe7590221331cd28d576887a263f45b595d499272f656c3f5176987c976239cac16f972d796ad82931d532102a4f95eec7d80', + }); + + return new InstantAssetLockProof({ + type: 0, + instantLock: instantLock.toBuffer(), + transaction: transaction.toBuffer(), + outputIndex: 0, + }); +} + +module.exports = getInstantAssetLockProofFixture; diff --git a/packages/wasm-dpp/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/basic/validateIdentityUpdateTransitionBasicFactory.spec.js b/packages/wasm-dpp/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/basic/validateIdentityUpdateTransitionBasicFactory.spec.js index eebe193f823..8b711df8f36 100644 --- a/packages/wasm-dpp/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/basic/validateIdentityUpdateTransitionBasicFactory.spec.js +++ b/packages/wasm-dpp/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/basic/validateIdentityUpdateTransitionBasicFactory.spec.js @@ -1,5 +1,5 @@ const { PrivateKey } = require('@dashevo/dashcore-lib'); -const getIdentityUpdateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture'); +const getIdentityUpdateTransitionFixture = require('../../../../../../../lib/test/fixtures/getIdentityUpdateTransitionFixture'); const { expectJsonSchemaError, expectValidationError } = require('../../../../../../../lib/test/expect/expectError'); const { default: loadWasmDpp } = require('../../../../../../../dist'); @@ -11,7 +11,6 @@ describe('validateIdentityUpdateTransitionBasicFactory', () => { let stateTransition; let publicKeyToAdd; - let IdentityUpdateTransition; let IdentityPublicKey; let IdentityPublicKeyCreateTransition; let UnsupportedProtocolVersionError; @@ -21,7 +20,6 @@ describe('validateIdentityUpdateTransitionBasicFactory', () => { before(async () => { ({ - IdentityUpdateTransition, UnsupportedProtocolVersionError, InvalidIdentityKeySignatureError, DuplicatedIdentityPublicKeyIdStateError, @@ -37,8 +35,7 @@ describe('validateIdentityUpdateTransitionBasicFactory', () => { const validator = new IdentityUpdateTransitionBasicValidator(blsAdapter); validateIdentityUpdateTransitionBasic = (st) => validator.validate(st); - const stateTransitionJS = getIdentityUpdateTransitionFixture(); - stateTransition = new IdentityUpdateTransition(stateTransitionJS.toObject()); + stateTransition = await getIdentityUpdateTransitionFixture(); const privateKey = new PrivateKey('9b67f852093bc61cea0eeca38599dbfba0de28574d2ed9b99d10d33dc1bde7b2'); const publicKey = privateKey.toPublicKey().toBuffer(); diff --git a/packages/wasm-dpp/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js b/packages/wasm-dpp/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js index c1ef4d0deee..c763c5841b7 100644 --- a/packages/wasm-dpp/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js +++ b/packages/wasm-dpp/test/integration/identity/stateTransition/IdentityUpdateTransition/validation/state/validateIdentityUpdateTransitionStateFactory.spec.js @@ -1,9 +1,9 @@ const identitySchema = require('@dashevo/dpp/schema/identity/identity.json'); const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); -const getIdentityUpdateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture'); const getIdentityFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityFixture'); const ValidationResult = require('@dashevo/dpp/lib/validation/ValidationResult'); const SomeConsensusError = require('@dashevo/dpp/lib/test/mocks/SomeConsensusError'); +const getIdentityUpdateTransitionFixture = require('../../../../../../../lib/test/fixtures/getIdentityUpdateTransitionFixture'); const { default: loadWasmDpp } = require('../../../../../../../dist'); const { expectValidationError } = require('../../../../../../../lib/test/expect/expectError'); @@ -22,7 +22,6 @@ describe('validateIdentityUpdateTransitionStateFactory', () => { let Identity; let IdentityPublicKey; - let IdentityUpdateTransition; let InvalidIdentityRevisionError; let IdentityPublicKeyIsReadOnlyError; let IdentityPublicKeyIsDisabledError; @@ -37,7 +36,6 @@ describe('validateIdentityUpdateTransitionStateFactory', () => { ({ Identity, IdentityPublicKey, - IdentityUpdateTransition, InvalidIdentityRevisionError, IdentityPublicKeyIsReadOnlyError, IdentityPublicKeyIsDisabledError, @@ -68,9 +66,7 @@ describe('validateIdentityUpdateTransitionStateFactory', () => { const validator = new IdentityUpdateTransitionStateValidator(stateRepositoryMock, blsAdapter); validateIdentityUpdateTransitionState = (st) => validator.validate(st); - stateTransition = new IdentityUpdateTransition( - getIdentityUpdateTransitionFixture().toObject(), - ); + stateTransition = await getIdentityUpdateTransitionFixture(); stateTransition.setRevision(identity.getRevision() + 1); stateTransition.setPublicKeyIdsToDisable(undefined); diff --git a/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/IdentityUpdateTransition.spec.js b/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/IdentityUpdateTransition.spec.js index 8ed78740189..c3210650134 100644 --- a/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/IdentityUpdateTransition.spec.js +++ b/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/IdentityUpdateTransition.spec.js @@ -4,7 +4,7 @@ const stateTransitionTypes = require( const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); -const getIdentityUpdateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture'); +const getIdentityUpdateTransitionFixture = require('../../../../../lib/test/fixtures/getIdentityUpdateTransitionFixture'); const { default: loadWasmDpp } = require('../../../../../dist'); const generateRandomIdentifierAsync = require('../../../../../lib/test/utils/generateRandomIdentifierAsync'); @@ -13,25 +13,21 @@ describe('IdentityUpdateTransition', () => { let rawStateTransition; let stateTransition; - let IdentityUpdateTransition; let IdentityPublicKey; let Identifier; let IdentityPublicKeyCreateTransition; before(async () => { ({ - IdentityUpdateTransition, IdentityPublicKey, Identifier, IdentityPublicKeyCreateTransition, } = await loadWasmDpp()); }); - beforeEach(() => { - rawStateTransition = getIdentityUpdateTransitionFixture().toObject(); - stateTransition = new IdentityUpdateTransition( - rawStateTransition, - ); + beforeEach(async () => { + stateTransition = await getIdentityUpdateTransitionFixture(); + rawStateTransition = stateTransition.toObject(); }); describe('#getType', () => { diff --git a/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js index 76d98e91b4f..fc9cb6b61c9 100644 --- a/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/identity/stateTransition/IdentityUpdateTransition/applyIdentityUpdateTransitionFactory.spec.js @@ -1,5 +1,5 @@ const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); -const getIdentityUpdateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityUpdateTransitionFixture'); +const getIdentityUpdateTransitionFixture = require('../../../../../lib/test/fixtures/getIdentityUpdateTransitionFixture'); const { default: loadWasmDpp } = require('../../../../../dist'); @@ -10,23 +10,18 @@ describe('applyIdentityUpdateTransition', () => { let executionContext; let StateTransitionExecutionContext; - let IdentityUpdateTransition; let applyIdentityUpdateTransitionDPP; before(async () => { ({ StateTransitionExecutionContext, - IdentityUpdateTransition, applyIdentityUpdateTransition: applyIdentityUpdateTransitionDPP, } = await loadWasmDpp()); }); beforeEach(async function beforeEach() { - const object = getIdentityUpdateTransitionFixture().toObject(); - stateTransition = new IdentityUpdateTransition( - object, - ); + stateTransition = await getIdentityUpdateTransitionFixture(); stateTransition.setRevision(stateTransition.getRevision() + 1); executionContext = new StateTransitionExecutionContext(); From 390eb2e7b575182b622195e3caf402617950e647 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 01:10:14 +0700 Subject: [PATCH 216/228] more fixes --- packages/rs-drive-abci/src/state/genesis.rs | 3 +-- .../src/btreemap_extensions/mod.rs | 13 +++++-------- packages/rs-platform-value/src/inner_value.rs | 3 ++- .../rs-platform-value/src/inner_value_at_path.rs | 2 +- packages/rs-platform-value/src/replace.rs | 4 ++-- packages/rs-platform-value/src/types/identifier.rs | 2 +- .../src/identity/identity_public_key/mod.rs | 2 +- .../identity_public_key_transitions.rs | 2 +- packages/wasm-dpp/src/version/protocol_version.rs | 5 ++--- 9 files changed, 16 insertions(+), 20 deletions(-) diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index a6b37effd0c..b0c155fb363 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -308,8 +308,7 @@ mod tests { assert_eq!( root_hash, [ - 52, 133, 20, 245, 44, 13, 159, 73, 228, 237, 23, 190, 110, 242, 54, 217, 16, - 231, 15, 161, 56, 19, 25, 224, 45, 42, 68, 252, 21, 187, 113, 210 + 111, 88, 10, 143, 94, 71, 51, 8, 40, 196, 201, 45, 155, 81, 130, 150, 9, 253, 0, 184, 61, 2, 173, 157, 131, 24, 71, 199, 114, 11, 16, 44 ] ) } diff --git a/packages/rs-platform-value/src/btreemap_extensions/mod.rs b/packages/rs-platform-value/src/btreemap_extensions/mod.rs index 9e3aefea0c5..ddb6810d574 100644 --- a/packages/rs-platform-value/src/btreemap_extensions/mod.rs +++ b/packages/rs-platform-value/src/btreemap_extensions/mod.rs @@ -276,7 +276,7 @@ where key: &str, ) -> Result, Error> { self.get(key) - .map(|v| { + .and_then(|v| { let value = v.borrow(); if value.is_null() { None @@ -295,7 +295,7 @@ where })) } - }).flatten() + }) .transpose() } @@ -307,7 +307,7 @@ where fn get_optional_map(&self, key: &str) -> Result, Error> { self.get(key) - .map(|v| { + .and_then(|v| { let value = v.borrow(); if value.is_null() { None @@ -319,7 +319,6 @@ where ) } }) - .flatten() .transpose() } @@ -328,7 +327,7 @@ where key: &str, ) -> Result, Error> { self.get(key) - .map(|v| { + .and_then(|v| { let value = v.borrow(); if value.is_null() { None @@ -341,7 +340,6 @@ where })) } }) - .flatten() .transpose() } @@ -361,7 +359,7 @@ where key: &str, ) -> Result, Error> { self.get(key) - .map(|v| { + .and_then(|v| { let value = v.borrow(); if value.is_null() { None @@ -374,7 +372,6 @@ where })) } }) - .flatten() .transpose() } diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index c54c6ca05f3..69c52bd38a9 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -91,7 +91,8 @@ impl Value { pub fn remove_optional_value_if_null(&mut self, key: &str) -> Result<(), Error> { let map = self.as_map_mut_ref()?; - Ok(map.remove_optional_key_if_null(key)) + map.remove_optional_key_if_null(key); + Ok(()) } pub fn remove_integer(&mut self, key: &str) -> Result diff --git a/packages/rs-platform-value/src/inner_value_at_path.rs b/packages/rs-platform-value/src/inner_value_at_path.rs index f6c5fede574..e3e5dbab1e5 100644 --- a/packages/rs-platform-value/src/inner_value_at_path.rs +++ b/packages/rs-platform-value/src/inner_value_at_path.rs @@ -109,7 +109,7 @@ impl Value { } } else { // we are replacing all members in array - Some(Ok(array.into_iter().collect())) + Some(Ok(array.iter_mut().collect())) } }) .collect::>, Error>>()? diff --git a/packages/rs-platform-value/src/replace.rs b/packages/rs-platform-value/src/replace.rs index 1e92602bd3f..05ff094788f 100644 --- a/packages/rs-platform-value/src/replace.rs +++ b/packages/rs-platform-value/src/replace.rs @@ -81,7 +81,7 @@ impl Value { } } else { // we are replacing all members in array - Ok(array.into_iter().collect()) + Ok(array.iter_mut().collect()) } }) .collect::>, Error>>()? @@ -241,7 +241,7 @@ impl Value { } } else { // we are replacing all members in array - Ok(array.into_iter().collect()) + Ok(array.iter_mut().collect()) } }) .collect::>, Error>>()? diff --git a/packages/rs-platform-value/src/types/identifier.rs b/packages/rs-platform-value/src/types/identifier.rs index 127153bde9f..b28583da2cf 100644 --- a/packages/rs-platform-value/src/types/identifier.rs +++ b/packages/rs-platform-value/src/types/identifier.rs @@ -67,7 +67,7 @@ impl<'de> Deserialize<'de> for IdentifierBytes32 { deserializer.deserialize_string(StringVisitor) } else { - let value = Value::deserialize(deserializer).map_err(|err| err.into())?; + let value = Value::deserialize(deserializer)?; Ok(IdentifierBytes32( value diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index 271720c4c61..fac3e71f92f 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -130,7 +130,7 @@ impl IdentityPublicKeyWasm { #[wasm_bindgen(js_name=toJSON)] pub fn to_json(&self) -> Result { - let val = self.0.to_json().map_err(|e| from_dpp_err(e.into()))?; + let val = self.0.to_json().map_err(from_dpp_err)?; let json = val.to_string(); js_sys::JSON::parse(&json) } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 55c68c6210b..3cc52cc1738 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -126,7 +126,7 @@ impl IdentityPublicKeyCreateTransitionWasm { #[wasm_bindgen(js_name=toJSON)] pub fn to_json(&self) -> Result { - let val = self.0.to_json().map_err(|e| from_dpp_err(e.into()))?; + let val = self.0.to_json().map_err(from_dpp_err)?; let json = val.to_string(); js_sys::JSON::parse(&json) } diff --git a/packages/wasm-dpp/src/version/protocol_version.rs b/packages/wasm-dpp/src/version/protocol_version.rs index 9bc8437aef7..1bde02460a5 100644 --- a/packages/wasm-dpp/src/version/protocol_version.rs +++ b/packages/wasm-dpp/src/version/protocol_version.rs @@ -41,13 +41,13 @@ impl ProtocolVersionValidatorWasm { .map(|(key, value)| { let new_key = key .parse::() - .map_err(|e| JsError::new(&*e.to_string()))?; + .map_err(|e| JsError::new(&e.to_string()))?; let new_value_64 = value.as_u64().ok_or_else(|| { JsError::new("Expect values in compatibility map to contain only numbers") })?; let new_value = - u32::try_from(new_value_64).map_err(|e| JsError::new(&*e.to_string()))?; + u32::try_from(new_value_64).map_err(|e| JsError::new(&e.to_string()))?; Ok((new_key, new_value)) }) @@ -68,7 +68,6 @@ impl ProtocolVersionValidatorWasm { .map(|v| v.map(|_| JsValue::undefined())) .map(ValidationResultWasm::from) .map_err(|e| CompatibleProtocolVersionIsNotDefinedErrorWasm::new(e).into()) - .into() } } From 157e128e55b458f04517b5c3391e93b128572897 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 01:17:31 +0700 Subject: [PATCH 217/228] formatting --- .../identity_update_transition/identity_update_transition.rs | 5 ++++- packages/rs-drive-abci/src/state/genesis.rs | 3 ++- packages/wasm-dpp/src/data_contract/data_contract.rs | 2 +- .../state_transition/data_contract_create_transition/mod.rs | 5 ++--- .../data_contract_create_transition/validation.rs | 1 - .../state_transition/data_contract_update_transition/mod.rs | 4 +--- .../data_contract_update_transition/validation.rs | 3 +-- packages/wasm-dpp/src/document/mod.rs | 1 - packages/wasm-dpp/src/identity/identity_public_key/mod.rs | 2 +- .../identity_create_transition/identity_create_transition.rs | 2 +- 10 files changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index 17011676398..84d87e0e2b1 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -216,7 +216,10 @@ fn get_list>( /// if the property isn't present the empty list is returned. If property is defined, the function /// might return some serialization-related errors -fn remove_integer_list_or_default(value: &mut Value, property_name: &str) -> Result, ProtocolError> +fn remove_integer_list_or_default( + value: &mut Value, + property_name: &str, +) -> Result, ProtocolError> where T: TryFrom + TryFrom diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index b0c155fb363..1a033f4d996 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -308,7 +308,8 @@ mod tests { assert_eq!( root_hash, [ - 111, 88, 10, 143, 94, 71, 51, 8, 40, 196, 201, 45, 155, 81, 130, 150, 9, 253, 0, 184, 61, 2, 173, 157, 131, 24, 71, 199, 114, 11, 16, 44 + 111, 88, 10, 143, 94, 71, 51, 8, 40, 196, 201, 45, 155, 81, 130, 150, 9, 253, + 0, 184, 61, 2, 173, 157, 131, 24, 71, 199, 114, 11, 16, 44 ] ) } diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index 21c919aac9b..fd22177cfa1 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -13,7 +13,7 @@ use dpp::platform_value::{Bytes32, Value}; use dpp::{platform_value, Convertible}; -use crate::errors::{RustConversionError}; +use crate::errors::RustConversionError; use crate::identifier::identifier_from_js_value; use crate::metadata::MetadataWasm; use crate::utils::WithJsError; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 4dcda7dee01..f2aa659507c 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -21,9 +21,8 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::protocol_error::from_protocol_error; use crate::utils::WithJsError; use crate::{ - buffer::Buffer, identifier::IdentifierWrapper, with_js_error, - DataContractParameters, DataContractWasm, IdentityPublicKeyWasm, - StateTransitionExecutionContextWasm, + buffer::Buffer, identifier::IdentifierWrapper, with_js_error, DataContractParameters, + DataContractWasm, IdentityPublicKeyWasm, StateTransitionExecutionContextWasm, }; #[derive(Clone)] diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs index 65a9b37a790..ee2c94dffc5 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/validation.rs @@ -1,6 +1,5 @@ use std::sync::Arc; - use dpp::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; use dpp::validation::SimpleValidationResult; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index b9b4e28fd1e..e7754ceae5f 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -19,9 +19,7 @@ use wasm_bindgen::prelude::*; use crate::utils::WithJsError; use crate::{ - buffer::Buffer, - errors::{protocol_error::from_protocol_error}, - identifier::IdentifierWrapper, + buffer::Buffer, errors::protocol_error::from_protocol_error, identifier::IdentifierWrapper, with_js_error, DataContractParameters, DataContractWasm, StateTransitionExecutionContextWasm, }; diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index 84e85cd0a22..7e39c531f34 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -1,6 +1,5 @@ use std::{collections::BTreeMap, sync::Arc}; - use dpp::data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition; use dpp::validation::{AsyncDataValidatorWithContext, SimpleValidationResult}; @@ -20,7 +19,7 @@ use wasm_bindgen::prelude::*; use crate::utils::WithJsError; use crate::{ data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransitionParameters, - errors::{protocol_error::from_protocol_error}, + errors::protocol_error::from_protocol_error, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, validation::ValidationResultWasm, DataContractUpdateTransitionWasm, StateTransitionExecutionContextWasm, diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 2dc4db9f52b..dd0e3f1cfe0 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -2,7 +2,6 @@ use dpp::dashcore::anyhow::Context; use dpp::prelude::{DataContract, Identifier}; use dpp::util::json_schema::JsonSchemaExt; - use anyhow::anyhow; use serde::{Deserialize, Serialize}; use std::convert::TryInto; diff --git a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs index fac3e71f92f..4f5ab91492c 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/mod.rs @@ -8,7 +8,7 @@ use crate::utils::{Inner, WithJsError}; use crate::{buffer::Buffer, utils, with_js_error}; use dpp::identity::{IdentityPublicKey, KeyID}; use dpp::platform_value::BinaryData; -use dpp::{Convertible}; +use dpp::Convertible; mod purpose; pub use purpose::*; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index de67f1f6824..a3709b55586 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -21,8 +21,8 @@ use crate::{ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::utils::{generic_of_js_val, ToSerdeJSONExt, WithJsError}; +use dpp::platform_value::string_encoding; use dpp::platform_value::string_encoding::Encoding; -use dpp::platform_value::{string_encoding}; use dpp::{ identifier::Identifier, identity::state_transition::{ From 7c13ffa03fd4f02b2d8679e0f6c23da1dd4616d9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 02:40:31 +0700 Subject: [PATCH 218/228] more refactoring --- .../rs-dpp/src/data_contract/data_contract.rs | 44 ++++++++-------- packages/rs-dpp/src/document/document.rs | 51 ++----------------- .../rs-dpp/src/document/extended_document.rs | 10 ++-- .../document_create_transition.rs | 2 +- .../document_replace_transition.rs | 2 +- .../documents_batch_transition/mod.rs | 2 +- .../rs-platform-value/src/system_bytes.rs | 1 + packages/wasm-dpp/src/document/factory.rs | 2 +- packages/wasm-dpp/src/document/mod.rs | 2 +- .../document_create_transition.rs | 2 +- .../document_replace_transition.rs | 2 +- 11 files changed, 41 insertions(+), 79 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index dad7d9cf8ae..b31199d92d6 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -331,29 +331,31 @@ impl DataContract { Ok((identifiers_paths, binary_paths)) } - pub fn get_identifiers_and_binary_paths_owned( + pub fn get_identifiers_and_binary_paths_owned< + I: IntoIterator + Extend + Default, + >( &self, document_type: &str, - ) -> Result<(HashSet, HashSet), ProtocolError> { + ) -> Result<(I, I), ProtocolError> { let binary_properties = self.get_optional_binary_properties(document_type)?; // At this point we don't bother about returned error from `get_binary_properties`. // If document of given type isn't found, then empty vectors will be returned. - let (binary_paths, identifiers_paths) = match binary_properties { - None => (HashSet::new(), HashSet::new()), - Some(binary_properties) => binary_properties.iter().partition_map(|(path, v)| { - if let Some(JsonValue::String(content_type)) = v.get("contentMediaType") { - if content_type == platform_value::IDENTIFIER_MEDIA_TYPE { - Either::Right(path.clone()) + Ok(binary_properties + .map(|binary_properties| { + binary_properties.iter().partition_map(|(path, v)| { + if let Some(JsonValue::String(content_type)) = v.get("contentMediaType") { + if content_type == platform_value::IDENTIFIER_MEDIA_TYPE { + Either::Left(path.clone()) + } else { + Either::Right(path.clone()) + } } else { - Either::Left(path.clone()) + Either::Right(path.clone()) } - } else { - Either::Left(path.clone()) - } - }), - }; - Ok((identifiers_paths, binary_paths)) + }) + }) + .unwrap_or_default()) } } @@ -371,19 +373,19 @@ impl TryFrom for DataContract { } } -impl TryInto for DataContract { +impl TryFrom for Value { type Error = ProtocolError; - fn try_into(self) -> Result { - self.into_object() + fn try_from(value: DataContract) -> Result { + value.into_object() } } -impl TryInto for &DataContract { +impl TryFrom<&DataContract> for Value { type Error = ProtocolError; - fn try_into(self) -> Result { - self.to_object() + fn try_from(value: &DataContract) -> Result { + value.to_object() } } diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 7071024e60a..485a5d21a3f 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -120,53 +120,10 @@ impl Document { } _ => {} } - // split the key path - let key_paths: Vec<&str> = key_path.split('.').collect::>(); - // key is the first key of the key path and rest_key_paths are the rest - let (key, rest_key_paths) = key_paths.split_first().ok_or({ - ProtocolError::DataContractError(DataContractError::MissingRequiredKey( - "key must not be null when getting from document", - )) - })?; - - /// Gets the value at the given path. Returns `value` if `key_paths` is empty. - fn get_value_at_path<'a>( - value: &'a Value, - key_paths: &'a [&str], - ) -> Result, ProtocolError> { - // return value if key_paths is empty - if key_paths.is_empty() { - Ok(Some(value)) - } else { - // split first again - let (key, rest_key_paths) = key_paths.split_first().ok_or({ - ProtocolError::DataContractError(DataContractError::MissingRequiredKey( - "key must not be null when getting from document", - )) - })?; - let map_values = value.as_map().ok_or({ - ProtocolError::DataContractError(DataContractError::ValueWrongType( - "inner key must refer to a value map", - )) - })?; - // given a map of values and a key, get the corresponding value - match Value::get_optional_from_map(map_values, key) { - None => Ok(None), - Some(value) => get_value_at_path(value, rest_key_paths), - } - } - } - - // match the value at the given key - match self.properties.get(*key) { - None => Ok(None), - Some(value) => match get_value_at_path(value, rest_key_paths)? { - None => Ok(None), - Some(path_value) => Ok(Some( - document_type.serialize_value_for_key(key_path, path_value)?, - )), - }, - } + self.properties + .get_optional_at_path(key_path)? + .map(|value| document_type.serialize_value_for_key(key_path, value)) + .transpose() } } diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 58567434709..7d85d1f590e 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -178,7 +178,7 @@ impl ExtendedDocument { .map_err(ProtocolError::ValueError)?; //Because we don't know how the json came in we need to sanitize it - let (identifiers, binary_paths) = + let (identifiers, binary_paths): (HashSet<_>, HashSet<_>) = data_contract.get_identifiers_and_binary_paths_owned(document_type_name.as_str())?; let mut extended_document = Self { @@ -387,10 +387,12 @@ impl ExtendedDocument { Ok((identifiers_paths, binary_paths)) } - pub fn get_identifiers_and_binary_paths_owned( + pub fn get_identifiers_and_binary_paths_owned< + I: IntoIterator + Extend + Default, + >( &self, - ) -> Result<(HashSet, HashSet), ProtocolError> { - let (mut identifiers_paths, binary_paths) = self + ) -> Result<(I, I), ProtocolError> { + let (mut identifiers_paths, binary_paths): (I, I) = self .data_contract .get_identifiers_and_binary_paths_owned(&self.document_type_name)?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs index 0226b1091de..6cc2b207242 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_create_transition.rs @@ -111,7 +111,7 @@ impl DocumentTransitionObjectLike for DocumentCreateTransition { let document_type = map.get_str("$type")?; - let (identifiers_paths, binary_paths) = + let (identifiers_paths, binary_paths): (Vec<_>, Vec<_>) = data_contract.get_identifiers_and_binary_paths_owned(document_type)?; map.replace_at_paths( diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs index c980ca983e2..58a7d022183 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/document_transition/document_replace_transition.rs @@ -118,7 +118,7 @@ impl DocumentTransitionObjectLike for DocumentReplaceTransition { let document_type = map.get_str("$type")?; - let (identifiers_paths, binary_paths) = + let (identifiers_paths, binary_paths): (Vec<_>, Vec<_>) = data_contract.get_identifiers_and_binary_paths_owned(document_type)?; map.replace_at_paths(binary_paths.into_iter(), ReplacementType::BinaryBytes)?; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index ede118adcc3..265ecbac66d 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs @@ -219,7 +219,7 @@ impl DocumentsBatchTransition { })?; //Because we don't know how the json came in we need to sanitize it - let (identifiers, binary_paths) = + let (identifiers, binary_paths): (Vec<_>, Vec<_>) = data_contract.get_identifiers_and_binary_paths_owned(document_type)?; raw_transition_map diff --git a/packages/rs-platform-value/src/system_bytes.rs b/packages/rs-platform-value/src/system_bytes.rs index 3e4eacaf220..5b1f01312b6 100644 --- a/packages/rs-platform-value/src/system_bytes.rs +++ b/packages/rs-platform-value/src/system_bytes.rs @@ -203,6 +203,7 @@ impl Value { .collect::, Error>>(), Value::Bytes(vec) => Ok(vec.clone()), Value::Bytes32(vec) => Ok(vec.to_vec()), + Value::Bytes36(vec) => Ok(vec.to_vec()), Value::Identifier(identifier) => Ok(Vec::from(identifier.as_slice())), _other => Err(Error::StructureError( "value are not bytes, a string, or an array of values representing bytes" diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index bbf8b7aad46..1a7cc21c24b 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -162,7 +162,7 @@ impl DocumentFactoryWASM { .create_from_object(raw_document, options) .await .with_js_error()?; - let (identifier_paths, binary_paths) = document + let (identifier_paths, binary_paths): (Vec<_>, Vec<_>) = document .get_identifiers_and_binary_paths_owned() .with_js_error()?; // When data contract is available, replace remaining dynamic paths diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index dd0e3f1cfe0..30de808b273 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -335,7 +335,7 @@ pub(crate) fn document_data_to_bytes( contract: &DataContract, document_type: &str, ) -> Result<(), JsValue> { - let (identifier_paths, binary_paths) = contract + let (identifier_paths, binary_paths): (Vec<_>, Vec<_>) = contract .get_identifiers_and_binary_paths_owned(document_type) .with_js_error()?; document diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 5778a475c0b..33d6584ba7d 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -61,7 +61,7 @@ impl DocumentCreateTransitionWasm { .map_err(ProtocolError::ValueError) .with_js_error()?; - let (identifier_paths, _) = data_contract + let (identifier_paths, _): (Vec<_>, Vec<_>) = data_contract .get_identifiers_and_binary_paths_owned(document_type.as_str()) .with_js_error()?; value diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs index 48cfbd2a3fc..051c616ab06 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs @@ -60,7 +60,7 @@ impl DocumentReplaceTransitionWasm { .map_err(ProtocolError::ValueError) .with_js_error()?; - let (identifier_paths, _) = data_contract + let (identifier_paths, _): (Vec<_>, Vec<_>) = data_contract .get_identifiers_and_binary_paths_owned(document_type.as_str()) .with_js_error()?; value From afd2bd1e29ef1e58e6f0dbd446921a8624e90824 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 02:51:04 +0700 Subject: [PATCH 219/228] more fixes --- .../rs-dpp/src/identity/identity_public_key/mod.rs | 12 ++++++------ .../identity_public_key_transitions.rs | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/rs-dpp/src/identity/identity_public_key/mod.rs b/packages/rs-dpp/src/identity/identity_public_key/mod.rs index 31f7c06e965..34ca4c7522c 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -220,19 +220,19 @@ impl Into for &IdentityPublicKey { } } -impl TryInto for &IdentityPublicKey { +impl TryFrom<&IdentityPublicKey> for Value { type Error = platform_value::Error; - fn try_into(self) -> Result { - platform_value::to_value(self) + fn try_from(value: &IdentityPublicKey) -> Result { + platform_value::to_value(value) } } -impl TryInto for IdentityPublicKey { +impl TryFrom for Value { type Error = platform_value::Error; - fn try_into(self) -> Result { - platform_value::to_value(self) + fn try_from(value: IdentityPublicKey) -> Result { + platform_value::to_value(value) } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs index 723b715976b..f22f8b4f027 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions.rs @@ -252,18 +252,18 @@ impl TryFrom for IdentityPublicKeyWithWitness { } } -impl TryInto for IdentityPublicKeyWithWitness { +impl TryFrom for Value { type Error = platform_value::Error; - fn try_into(self) -> Result { - platform_value::to_value(self) + fn try_from(value: IdentityPublicKeyWithWitness) -> Result { + platform_value::to_value(value) } } -impl TryInto for &IdentityPublicKeyWithWitness { +impl TryFrom<&IdentityPublicKeyWithWitness> for Value { type Error = platform_value::Error; - fn try_into(self) -> Result { - platform_value::to_value(self) + fn try_from(value: &IdentityPublicKeyWithWitness) -> Result { + platform_value::to_value(value) } } From 0c51c90f30dfd6a17d48403c556e7b7eb0951efe Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Wed, 22 Mar 2023 13:02:24 +0800 Subject: [PATCH 220/228] tests: update document query to allow limit null --- .../integration/document/DocumentRepository.spec.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/js-drive/test/integration/document/DocumentRepository.spec.js b/packages/js-drive/test/integration/document/DocumentRepository.spec.js index fefad588c89..e0db19ab936 100644 --- a/packages/js-drive/test/integration/document/DocumentRepository.spec.js +++ b/packages/js-drive/test/integration/document/DocumentRepository.spec.js @@ -83,14 +83,6 @@ const nonNumberTestCases = [ typesTestCases.buffer, ]; -const nonNumberAndUndefinedTestCases = [ - typesTestCases.string, - typesTestCases.boolean, - typesTestCases.null, - typesTestCases.object, - typesTestCases.buffer, -]; - const nonNumberNullAndUndefinedTestCases = [ typesTestCases.string, typesTestCases.boolean, @@ -2611,7 +2603,7 @@ describe('DocumentRepository', function main() { } }); - nonNumberAndUndefinedTestCases.forEach(({ type, value }) => { + nonNumberNullAndUndefinedTestCases.forEach(({ type, value }) => { it(`should return invalid result if "limit" is not a number, but ${type}`, async () => { try { await documentRepository.find(queryDataContract, 'documentNumber', { From 21869d58fd184fdec713bb9fe5ee8120955cb052 Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Wed, 22 Mar 2023 13:02:49 +0800 Subject: [PATCH 221/228] tests: add query document by createAt test --- packages/rs-drive/tests/query_tests.rs | 138 +++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 2c488eae388..4312cced79b 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -30,6 +30,7 @@ //! Query Tests //! +use ciborium::cbor; #[cfg(feature = "full")] use grovedb::TransactionArg; #[cfg(feature = "full")] @@ -94,6 +95,7 @@ use dpp::platform_value::Value; #[cfg(feature = "full")] use dpp::prelude::DataContract; +use dpp::prelude::Revision; #[cfg(feature = "full")] use dpp::util::serializer; #[cfg(feature = "full")] @@ -102,8 +104,12 @@ use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; use drive::contract::Contract; #[cfg(feature = "full")] use drive::drive::block_info::BlockInfo; +use drive::drive::defaults; #[cfg(feature = "full")] use drive::drive::query::QueryDocumentsOutcome; +use drive::query; +use drive::query::{WhereClause, WhereOperator}; +use drive::tests::helpers::setup::setup_drive_with_initial_state_structure; #[cfg(feature = "full")] #[derive(Serialize, Deserialize)] @@ -4336,6 +4342,138 @@ fn test_query_a_b_c_d_e_contract() { .expect("should perform query"); } +#[cfg(feature = "full")] +#[test] +fn test_query_documents_by_created_at() { + let drive = setup_drive_with_initial_state_structure(); + + let contract = json!({ + "protocolVersion": 1, + "$id": "BZUodcFoFL6KvnonehrnMVggTvCe8W5MiRnZuqLb6M54", + "$schema": "https://schema.dash.org/dpp-0-4-0/meta/data-contract", + "version": 1, + "ownerId": "GZVdTnLFAN2yE9rLeCHBDBCr7YQgmXJuoExkY347j7Z5", + "documents": { + "indexedDocument": { + "type": "object", + "indices": [ + {"name":"index1", "properties": [{"$ownerId":"asc"}, {"firstName":"desc"}], "unique":true}, + {"name":"index2", "properties": [{"$ownerId":"asc"}, {"lastName":"desc"}], "unique":true}, + {"name":"index3", "properties": [{"lastName":"asc"}]}, + {"name":"index4", "properties": [{"$createdAt":"asc"}, {"$updatedAt":"asc"}]}, + {"name":"index5", "properties": [{"$updatedAt":"asc"}]}, + {"name":"index6", "properties": [{"$createdAt":"asc"}]} + ], + "properties":{ + "firstName": { + "type": "string", + "maxLength": 63, + }, + "lastName": { + "type": "string", + "maxLength": 63, + } + }, + "required": ["firstName", "$createdAt", "$updatedAt", "lastName"], + "additionalProperties": false, + }, + }, + }); + + let contract_cbor = + serializer::serializable_value_to_cbor(&contract, Some(defaults::PROTOCOL_VERSION)) + .expect("expected to serialize to cbor"); + + let contract = + DataContract::from_cbor(&contract_cbor).expect("should create a contract from cbor"); + + drive + .apply_contract( + &contract, + contract_cbor.clone(), + BlockInfo::default(), + true, + None, + None, + ) + .expect("should apply contract"); + + // Create document + + let created_at = 1647535750329_u64; + + let document = platform_value!({ + "$protocolVersion": 1u32, + "$id": "DLRWw2eRbLAW5zDU2c7wwsSFQypTSZPhFYzpY48tnaXN", + "$type": "indexedDocument", + "$dataContractId": "BZUodcFoFL6KvnonehrnMVggTvCe8W5MiRnZuqLb6M54", + "$ownerId": "GZVdTnLFAN2yE9rLeCHBDBCr7YQgmXJuoExkY347j7Z5", + "$revision": 1 as Revision, + "firstName": "myName", + "lastName": "lastName", + "$createdAt": created_at, + "$updatedAt": created_at, + }); + + let serialized_document = + serializer::serializable_value_to_cbor(&document, Some(defaults::PROTOCOL_VERSION)) + .expect("expected to serialize to cbor"); + + drive + .add_serialized_document_for_serialized_contract( + serialized_document.as_slice(), + contract_cbor.as_slice(), + "indexedDocument", + None, + true, + BlockInfo::default(), + true, + StorageFlags::optional_default_as_cow(), + None, + ) + .expect("should add document"); + + // Query document + + let query_cbor = cbor!({ + "where" => [ + ["$createdAt", "==", created_at] + ] + }) + .expect("should create cbor"); + + let query_bytes = serializer::serializable_value_to_cbor(&query_cbor, None) + .expect("should serialize cbor value to bytes"); + + let document_type = contract + .document_type_for_name("indexedDocument") + .expect("should get document type"); + + let query = DriveQuery::from_cbor(&query_bytes, &contract, document_type) + .expect("should create a query from cbor"); + + assert_eq!( + query.internal_clauses.equal_clauses.get("$createdAt"), + Some(&WhereClause { + field: "$createdAt".to_string(), + operator: WhereOperator::Equal, + value: Value::I128(created_at as i128) + }) + ); + + let query_result = drive + .query_documents_cbor_with_document_type_lookup( + &query_bytes, + contract.id.to_buffer(), + "indexedDocument", + None, + None, + ) + .expect("should query documents"); + + assert_eq!(query_result.items.len(), 1); +} + #[cfg(feature = "full")] #[test] #[ignore] From deb36fe8176c69bd1b62825556149bab746ae8ef Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 13:08:01 +0700 Subject: [PATCH 222/228] fixed test with timestamp --- .../document_type/document_field.rs | 7 ++- .../src/data_contract/document_type/mod.rs | 2 +- packages/rs-dpp/src/document/document.rs | 8 ++-- .../src/contracts/reward_shares.rs | 4 +- .../tests/strategy_tests/main.rs | 2 +- packages/rs-drive-nodejs/src/lib.rs | 4 +- .../drive/identity/withdrawals/documents.rs | 10 ++-- packages/rs-drive/src/drive/query/mod.rs | 46 ++++++++++++++++++- packages/rs-drive/tests/query_tests.rs | 18 +++----- 9 files changed, 72 insertions(+), 29 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_field.rs b/packages/rs-dpp/src/data_contract/document_type/document_field.rs index 73bb528a561..d35bafd1516 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_field.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_field.rs @@ -12,6 +12,7 @@ use rand::distributions::{Alphanumeric, Standard}; use rand::rngs::StdRng; use rand::Rng; use serde::{Deserialize, Serialize}; +use crate::prelude::TimestampMillis; use super::array_field::ArrayFieldType; @@ -654,7 +655,7 @@ impl DocumentFieldType { } } DocumentFieldType::Date => { - encode_float(value.to_float().map_err(ProtocolError::ValueError)?) + encode_date_timestamp(value.to_integer().map_err(ProtocolError::ValueError)?) } DocumentFieldType::Integer => { let value_as_i64 = value.to_integer().map_err(ProtocolError::ValueError)?; @@ -778,6 +779,10 @@ fn get_field_type_matching_error() -> ProtocolError { )) } +pub fn encode_date_timestamp(val: TimestampMillis) -> Result, ProtocolError> { + encode_unsigned_integer(val) +} + pub fn encode_unsigned_integer(val: u64) -> Result, ProtocolError> { // Positive integers are represented in binary with the signed bit set to 0 // Negative integers are represented in 2's complement form diff --git a/packages/rs-dpp/src/data_contract/document_type/mod.rs b/packages/rs-dpp/src/data_contract/document_type/mod.rs index 909be9c9cdb..a9c1a193518 100644 --- a/packages/rs-dpp/src/data_contract/document_type/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/mod.rs @@ -10,7 +10,7 @@ use super::errors::DataContractError; pub use { array_field::ArrayFieldType, document_field::{ - encode_float, encode_signed_integer, encode_unsigned_integer, DocumentField, + encode_float, encode_signed_integer, encode_unsigned_integer, encode_date_timestamp, DocumentField, DocumentFieldType, }, document_type::{DocumentType, IndexLevel}, diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 485a5d21a3f..23af4ac3c9c 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -46,7 +46,7 @@ use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; use serde::{Deserialize, Serialize}; -use crate::data_contract::document_type::{encode_unsigned_integer, DocumentType}; +use crate::data_contract::document_type::{encode_date_timestamp, DocumentType}; use crate::data_contract::errors::DataContractError; use crate::document::errors::DocumentError; @@ -100,6 +100,8 @@ impl Document { document_type: &DocumentType, owner_id: Option<[u8; 32]>, ) -> Result>, ProtocolError> { + // todo: maybe merge with document_type.serialize_value_for_key() because we use different + // code paths for query and index creation // returns the owner id if the key path is $ownerId and an owner id is given if key_path == "$ownerId" && owner_id.is_some() { Ok(Some(Vec::from(owner_id.unwrap()))) @@ -111,12 +113,12 @@ impl Document { "$createdAt" => { return Ok(self .created_at - .map(|time| encode_unsigned_integer(time).unwrap())) + .map(|time| encode_date_timestamp(time).unwrap())) } "$updatedAt" => { return Ok(self .updated_at - .map(|time| encode_unsigned_integer(time).unwrap())) + .map(|time| encode_date_timestamp(time).unwrap())) } _ => {} } diff --git a/packages/rs-drive-abci/src/contracts/reward_shares.rs b/packages/rs-drive-abci/src/contracts/reward_shares.rs index 9a9ee1325d1..b9b2c0efdff 100644 --- a/packages/rs-drive-abci/src/contracts/reward_shares.rs +++ b/packages/rs-drive-abci/src/contracts/reward_shares.rs @@ -45,7 +45,7 @@ use drive::dpp::document::Document; use drive::dpp::util::serializer; use drive::drive::block_info::BlockInfo; use drive::drive::flags::StorageFlags; -use drive::drive::query::QueryDocumentsOutcome; +use drive::drive::query::QuerySerializedDocumentsOutcome; use drive::grovedb::TransactionArg; use serde_json::json; use std::borrow::Cow; @@ -75,7 +75,7 @@ impl Platform { let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) .expect("expected to serialize to cbor"); - let QueryDocumentsOutcome { items, .. } = + let QuerySerializedDocumentsOutcome { items, .. } = self.drive.query_documents_cbor_with_document_type_lookup( &query_cbor, MN_REWARD_SHARES_CONTRACT_ID, diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 9062030ac04..ec4fa39d63f 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -263,7 +263,7 @@ impl Strategy { DriveQuery::any_item_query(&op.contract, &op.document_type); let mut items = platform .drive - .query_documents(any_item_query, Some(&block_info.epoch), None) + .query_documents_as_serialized(any_item_query, Some(&block_info.epoch), None) .expect("expect to execute query") .items; diff --git a/packages/rs-drive-nodejs/src/lib.rs b/packages/rs-drive-nodejs/src/lib.rs index f623819ae19..9bc942dc2e0 100644 --- a/packages/rs-drive-nodejs/src/lib.rs +++ b/packages/rs-drive-nodejs/src/lib.rs @@ -14,7 +14,7 @@ use drive::dpp::identity::{KeyID, TimestampMillis}; use drive::dpp::prelude::Revision; use drive::dpp::Convertible; use drive::drive::flags::StorageFlags; -use drive::drive::query::QueryDocumentsOutcome; +use drive::drive::query::QuerySerializedDocumentsOutcome; use drive::error::Error; use drive::fee::credits::Credits; use drive::fee_pools::epochs::Epoch; @@ -2143,7 +2143,7 @@ impl PlatformWrapper { let callback = js_callback.into_inner(&mut task_context); let this = task_context.undefined(); let callback_arguments: Vec> = match result { - Ok(QueryDocumentsOutcome { + Ok(QuerySerializedDocumentsOutcome { items, skipped, cost, diff --git a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs index 04e4865a7e9..dc2b897a98e 100644 --- a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs +++ b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs @@ -9,7 +9,7 @@ use indexmap::IndexMap; use lazy_static::__Deref; use crate::{ - drive::{query::QueryDocumentsOutcome, Drive}, + drive::{query::QuerySerializedDocumentsOutcome, Drive}, error::{drive::DriveError, Error}, query::{DriveQuery, InternalClauses, OrderClause, WhereClause}, }; @@ -76,11 +76,11 @@ impl Drive { block_time: None, }; - let QueryDocumentsOutcome { + let QuerySerializedDocumentsOutcome { items, skipped: _, cost: _, - } = self.query_documents(drive_query, None, transaction)?; + } = self.query_documents_as_serialized(drive_query, None, transaction)?; let documents = items .iter() @@ -157,11 +157,11 @@ impl Drive { block_time: None, }; - let QueryDocumentsOutcome { + let QuerySerializedDocumentsOutcome { items, skipped: _, cost: _, - } = self.query_documents(drive_query, None, transaction)?; + } = self.query_documents_as_serialized(drive_query, None, transaction)?; let documents = items .iter() diff --git a/packages/rs-drive/src/drive/query/mod.rs b/packages/rs-drive/src/drive/query/mod.rs index e9de2a2af30..5eeec016bdf 100644 --- a/packages/rs-drive/src/drive/query/mod.rs +++ b/packages/rs-drive/src/drive/query/mod.rs @@ -44,12 +44,25 @@ use crate::fee::op::DriveOperation; use crate::query::DriveQuery; use dpp::data_contract::document_type::DocumentType; use dpp::data_contract::DriveContractExt; +use dpp::document::Document; +use dpp::ProtocolError; use crate::drive::block_info::BlockInfo; use crate::fee_pools::epochs::Epoch; +#[derive(Debug)] /// The outcome of a query pub struct QueryDocumentsOutcome { + /// returned items + pub documents: Vec, + /// skipped item count + pub skipped: u16, + /// the processing cost + pub cost: u64, +} + +/// The outcome of a query +pub struct QuerySerializedDocumentsOutcome { /// returned items pub items: Vec>, /// skipped item count @@ -80,6 +93,10 @@ impl Drive { let mut drive_operations: Vec = vec![]; let (items, skipped) = query.execute_serialized_no_proof_internal(self, transaction, &mut drive_operations)?; + let documents = items + .into_iter() + .map(|serialized| Document::from_cbor(serialized.as_slice(), None, None)) + .collect::, ProtocolError>>()?; let cost = if let Some(epoch) = epoch { let fee_result = calculate_fee(None, Some(drive_operations), epoch)?; fee_result.processing_fee @@ -88,6 +105,31 @@ impl Drive { }; Ok(QueryDocumentsOutcome { + documents, + skipped, + cost, + }) + } + + /// Performs and returns the result of the specified query along with skipped items + /// and the cost. + pub fn query_documents_as_serialized( + &self, + query: DriveQuery, + epoch: Option<&Epoch>, + transaction: TransactionArg, + ) -> Result { + let mut drive_operations: Vec = vec![]; + let (items, skipped) = + query.execute_serialized_no_proof_internal(self, transaction, &mut drive_operations)?; + let cost = if let Some(epoch) = epoch { + let fee_result = calculate_fee(None, Some(drive_operations), epoch)?; + fee_result.processing_fee + } else { + 0 + }; + + Ok(QuerySerializedDocumentsOutcome { items, skipped, cost, @@ -136,7 +178,7 @@ impl Drive { document_type_name: &str, epoch: Option<&Epoch>, transaction: TransactionArg, - ) -> Result { + ) -> Result { let mut drive_operations: Vec = vec![]; let contract = self .get_contract_with_fetch_info_and_add_to_operations( @@ -154,7 +196,7 @@ impl Drive { let query = DriveQuery::from_cbor(query_cbor, &contract.contract, document_type)?; - self.query_documents(query, epoch, transaction) + self.query_documents_as_serialized(query, epoch, transaction) } /// Performs and returns the result of the specified query along with skipped items and the cost. diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 4312cced79b..77b4b93ed30 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -106,7 +106,7 @@ use drive::contract::Contract; use drive::drive::block_info::BlockInfo; use drive::drive::defaults; #[cfg(feature = "full")] -use drive::drive::query::QueryDocumentsOutcome; +use drive::drive::query::QuerySerializedDocumentsOutcome; use drive::query; use drive::query::{WhereClause, WhereOperator}; use drive::tests::helpers::setup::setup_drive_with_initial_state_structure; @@ -2615,7 +2615,7 @@ fn test_query_with_cached_contract() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); - let QueryDocumentsOutcome { items, .. } = drive + let QuerySerializedDocumentsOutcome { items, .. } = drive .query_documents_cbor_with_document_type_lookup( where_cbor.as_slice(), *contract.id.as_bytes(), @@ -4385,7 +4385,7 @@ fn test_query_documents_by_created_at() { .expect("expected to serialize to cbor"); let contract = - DataContract::from_cbor(&contract_cbor).expect("should create a contract from cbor"); + DataContract::from_json_object(contract).expect("should create a contract from cbor"); drive .apply_contract( @@ -4438,7 +4438,7 @@ fn test_query_documents_by_created_at() { let query_cbor = cbor!({ "where" => [ ["$createdAt", "==", created_at] - ] + ], }) .expect("should create cbor"); @@ -4462,16 +4462,10 @@ fn test_query_documents_by_created_at() { ); let query_result = drive - .query_documents_cbor_with_document_type_lookup( - &query_bytes, - contract.id.to_buffer(), - "indexedDocument", - None, - None, - ) + .query_documents(query, None, None) .expect("should query documents"); - assert_eq!(query_result.items.len(), 1); + assert_eq!(query_result.documents.len(), 1); } #[cfg(feature = "full")] From fc86d4c06fc0fa6207c45b8ade1961605a0a8af7 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 13:08:29 +0700 Subject: [PATCH 223/228] fmt --- .../src/data_contract/document_type/document_field.rs | 2 +- packages/rs-dpp/src/data_contract/document_type/mod.rs | 4 ++-- packages/rs-drive-abci/tests/strategy_tests/main.rs | 6 +++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/document_field.rs b/packages/rs-dpp/src/data_contract/document_type/document_field.rs index d35bafd1516..81017ff7cc0 100644 --- a/packages/rs-dpp/src/data_contract/document_type/document_field.rs +++ b/packages/rs-dpp/src/data_contract/document_type/document_field.rs @@ -4,6 +4,7 @@ use std::io::{BufReader, Read}; use crate::data_contract::errors::DataContractError; +use crate::prelude::TimestampMillis; use crate::ProtocolError; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use integer_encoding::{VarInt, VarIntReader}; @@ -12,7 +13,6 @@ use rand::distributions::{Alphanumeric, Standard}; use rand::rngs::StdRng; use rand::Rng; use serde::{Deserialize, Serialize}; -use crate::prelude::TimestampMillis; use super::array_field::ArrayFieldType; diff --git a/packages/rs-dpp/src/data_contract/document_type/mod.rs b/packages/rs-dpp/src/data_contract/document_type/mod.rs index a9c1a193518..65b738370b2 100644 --- a/packages/rs-dpp/src/data_contract/document_type/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/mod.rs @@ -10,8 +10,8 @@ use super::errors::DataContractError; pub use { array_field::ArrayFieldType, document_field::{ - encode_float, encode_signed_integer, encode_unsigned_integer, encode_date_timestamp, DocumentField, - DocumentFieldType, + encode_date_timestamp, encode_float, encode_signed_integer, encode_unsigned_integer, + DocumentField, DocumentFieldType, }, document_type::{DocumentType, IndexLevel}, index::{Index, IndexProperty}, diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index ec4fa39d63f..f92fc5fa502 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -263,7 +263,11 @@ impl Strategy { DriveQuery::any_item_query(&op.contract, &op.document_type); let mut items = platform .drive - .query_documents_as_serialized(any_item_query, Some(&block_info.epoch), None) + .query_documents_as_serialized( + any_item_query, + Some(&block_info.epoch), + None, + ) .expect("expect to execute query") .items; From 7e81918840c95f7c1c34d2fc7ff8f6549c86045a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 13:09:23 +0700 Subject: [PATCH 224/228] fix --- packages/rs-drive/tests/query_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 77b4b93ed30..34fe1613da1 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -107,7 +107,7 @@ use drive::drive::block_info::BlockInfo; use drive::drive::defaults; #[cfg(feature = "full")] use drive::drive::query::QuerySerializedDocumentsOutcome; -use drive::query; + use drive::query::{WhereClause, WhereOperator}; use drive::tests::helpers::setup::setup_drive_with_initial_state_structure; From ccfd5437a7eab313bd20e8ad93a2b0ed241f9f22 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 13:28:44 +0700 Subject: [PATCH 225/228] fix --- packages/rs-drive/src/drive/identity/key/fetch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-drive/src/drive/identity/key/fetch.rs b/packages/rs-drive/src/drive/identity/key/fetch.rs index f21dc0c66e2..42f7e117f76 100644 --- a/packages/rs-drive/src/drive/identity/key/fetch.rs +++ b/packages/rs-drive/src/drive/identity/key/fetch.rs @@ -1,7 +1,7 @@ #[cfg(any(feature = "full", feature = "verify"))] use crate::drive::identity::{identity_key_tree_path_vec, identity_query_keys_tree_path_vec}; -#[cfg(feature = "full")] +#[cfg(any(feature = "full", feature = "verify"))] use crate::drive::identity::key::fetch::KeyKindRequestType::{ AllKeysOfKindRequest, CurrentKeyOfKindRequest, }; From 77b816b5e684a1303226c746960d8254bc6e2657 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 13:31:54 +0700 Subject: [PATCH 226/228] small changes exposing verify --- packages/rs-drive/src/drive/mod.rs | 4 +++- packages/rs-drive/src/drive/verify/mod.rs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/rs-drive/src/drive/mod.rs b/packages/rs-drive/src/drive/mod.rs index c8e1e9bf0e1..38fb507f929 100644 --- a/packages/rs-drive/src/drive/mod.rs +++ b/packages/rs-drive/src/drive/mod.rs @@ -109,8 +109,10 @@ pub mod query; mod system; #[cfg(test)] mod test_utils; + +/// Contains a set of useful grovedb proof verification functions #[cfg(any(feature = "full", feature = "verify"))] -mod verify; +pub mod verify; #[cfg(feature = "full")] use crate::drive::block_info::BlockInfo; diff --git a/packages/rs-drive/src/drive/verify/mod.rs b/packages/rs-drive/src/drive/verify/mod.rs index fc39726210a..38dcfa4f96c 100644 --- a/packages/rs-drive/src/drive/verify/mod.rs +++ b/packages/rs-drive/src/drive/verify/mod.rs @@ -14,6 +14,7 @@ use crate::fee::credits::Credits; use grovedb::GroveDb; use std::collections::BTreeMap; +/// Represents the root hash of the grovedb tree pub type RootHash = [u8; 32]; impl Drive { From 83b5c042f94302e04c1aaad59272d4b7bd9db2ea Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 22 Mar 2023 13:35:29 +0700 Subject: [PATCH 227/228] fixes for verify --- packages/rs-drive/src/query/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index c8036c1dd83..cca5cc5ab7a 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -62,10 +62,8 @@ use crate::drive::block_info::BlockInfo; #[cfg(any(feature = "full", feature = "verify"))] pub use conditions::WhereClause; /// Import conditions -#[cfg(feature = "full")] +#[cfg(any(feature = "full", feature = "verify"))] pub use conditions::WhereOperator; -#[cfg(feature = "full")] -use conditions::WhereOperator::{Equal, In}; #[cfg(any(feature = "full", feature = "verify"))] use dpp::data_contract::document_type::DocumentType; #[cfg(feature = "full")] @@ -174,7 +172,7 @@ impl InternalClauses { let primary_key_equal_clauses_array = all_where_clauses .iter() .filter_map(|where_clause| match where_clause.operator { - Equal => match where_clause.is_identifier() { + WhereOperator::Equal => match where_clause.is_identifier() { true => Some(where_clause.clone()), false => None, }, @@ -185,7 +183,7 @@ impl InternalClauses { let primary_key_in_clauses_array = all_where_clauses .iter() .filter_map(|where_clause| match where_clause.operator { - In => match where_clause.is_identifier() { + WhereOperator::In => match where_clause.is_identifier() { true => Some(where_clause.clone()), false => None, }, From 73d22407557f662ee51ebe70cc622b8652cd206c Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Wed, 22 Mar 2023 15:17:48 +0800 Subject: [PATCH 228/228] tests: fix document repository timestamp tests --- .../test/integration/document/DocumentRepository.spec.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/js-drive/test/integration/document/DocumentRepository.spec.js b/packages/js-drive/test/integration/document/DocumentRepository.spec.js index e0db19ab936..803e6673f77 100644 --- a/packages/js-drive/test/integration/document/DocumentRepository.spec.js +++ b/packages/js-drive/test/integration/document/DocumentRepository.spec.js @@ -1843,7 +1843,9 @@ describe('DocumentRepository', function main() { expect.fail('should throw an error'); } catch (e) { - expect(e.message).to.equal('value error: structure error: value is not a float'); + expect(e.message).to.startsWith( + 'value error: structure error: value is not an integer', + ); expect(e).to.be.instanceOf(InvalidQueryError); } }); @@ -1857,8 +1859,8 @@ describe('DocumentRepository', function main() { expect.fail('should throw an error'); } catch (e) { expect(e).to.be.instanceOf(InvalidQueryError); - expect(e.message).to.equal( - 'value error: structure error: value is not a float', + expect(e.message).to.startsWith( + 'value error: structure error: value is not an integer', ); } });