From 910a325f257d83aa5f650923b19ba2898c9f635f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 22 Apr 2023 04:53:21 +0700 Subject: [PATCH 01/50] more deserialization --- .../rs-dpp/src/data_contract/extra/common.rs | 15 +++++ .../data_contract/serialization/bincode.rs | 12 +++- .../src/contracts/reward_shares.rs | 4 +- .../tests/strategy_tests/main.rs | 32 +++++----- packages/rs-drive/src/common/mod.rs | 3 +- .../src/drive/batch/drive_op_batch/mod.rs | 61 +++++++++++-------- packages/rs-drive/src/drive/contract/mod.rs | 48 ++++++--------- .../rs-drive/src/drive/document/delete.rs | 16 ++--- .../rs-drive/src/drive/identity/update.rs | 4 +- packages/rs-drive/src/query/mod.rs | 8 +-- packages/rs-drive/src/tests/helpers/setup.rs | 9 +-- 11 files changed, 113 insertions(+), 99 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index 8c7a598ffc6..4c7cc99731d 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -1,4 +1,5 @@ use crate::data_contract::errors::StructureError; +use crate::document::Document; use crate::util::cbor_value::cbor_value_into_json_value; use crate::util::serializer::serializable_value_to_cbor; use crate::ProtocolError; @@ -279,6 +280,20 @@ pub fn json_document_to_cbor( serializable_value_to_cbor(&json, protocol_version) } +/// Reads a JSON file and converts it a document. +pub fn json_document_to_document(path: impl AsRef) -> Result { + let file = File::open(path.as_ref()).map_err(|_| { + ProtocolError::FileNotFound(format!( + "file not found at path {}", + path.as_ref().to_str().unwrap() + )) + })?; + + let reader = BufReader::new(file); + serde_json::from_reader(reader) + .map_err(|_| ProtocolError::DecodingError("error decoding value from document".to_string())) +} + /// Make sure the protocol version is correct. pub const fn check_protocol_version(_version: u32) -> bool { // Temporary disabled due protocol version is dynamic and goes from consensus params diff --git a/packages/rs-dpp/src/data_contract/serialization/bincode.rs b/packages/rs-dpp/src/data_contract/serialization/bincode.rs index 5a62d060068..8fa873c5cf2 100644 --- a/packages/rs-dpp/src/data_contract/serialization/bincode.rs +++ b/packages/rs-dpp/src/data_contract/serialization/bincode.rs @@ -25,7 +25,17 @@ impl DataContract { } pub fn deserialize(bytes: &[u8]) -> Result { - let config = config::standard().with_big_endian().with_limit::<15000>(); + let config = config::standard().with_big_endian(); + let inner: DataContractInner = bincode::decode_from_slice(bytes, config) + .map_err(|e| { + ProtocolError::EncodingError(format!("unable to deserialize data contract {}", e)) + }) + .map(|(a, _)| a)?; + inner.try_into() + } + + pub fn deserialize_with_limit(bytes: &[u8]) -> Result { + let config = config::standard().with_big_endian().with_limit::<20000>(); let inner: DataContractInner = bincode::decode_from_slice(bytes, config) .map_err(|e| { ProtocolError::EncodingError(format!("unable to deserialize data contract {}", e)) diff --git a/packages/rs-drive-abci/src/contracts/reward_shares.rs b/packages/rs-drive-abci/src/contracts/reward_shares.rs index d2ad43a8cb0..65e99a8e003 100644 --- a/packages/rs-drive-abci/src/contracts/reward_shares.rs +++ b/packages/rs-drive-abci/src/contracts/reward_shares.rs @@ -96,8 +96,8 @@ impl Platform { let contract_cbor = hex::decode(contract_hex).expect("Decoding failed"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 41096e1209b..38e307862d1 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -2301,8 +2301,8 @@ mod tests { Some(PROTOCOL_VERSION), ) .expect("expected to get cbor from a json document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let strategy = Strategy { contracts_with_updates: vec![(contract, None)], @@ -2374,8 +2374,8 @@ mod tests { Some(PROTOCOL_VERSION), ) .expect("expected to get cbor from a json document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let contract_cbor_update_1 = json_document_to_cbor( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable-update-1.json", @@ -2476,8 +2476,8 @@ mod tests { Some(PROTOCOL_VERSION), ) .expect("expected to get cbor from a json document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let document_op = DocumentOp { contract: contract.clone(), @@ -2544,8 +2544,8 @@ mod tests { Some(PROTOCOL_VERSION), ) .expect("expected to get cbor from a json document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let document_op = DocumentOp { contract: contract.clone(), @@ -2622,8 +2622,8 @@ mod tests { Some(PROTOCOL_VERSION), ) .expect("expected to get cbor from a json document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let document_insertion_op = DocumentOp { contract: contract.clone(), @@ -2718,8 +2718,8 @@ mod tests { Some(PROTOCOL_VERSION), ) .expect("expected to get cbor from a json document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let document_insertion_op = DocumentOp { contract: contract.clone(), @@ -2815,8 +2815,8 @@ mod tests { Some(PROTOCOL_VERSION), ) .expect("expected to get cbor from a json document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let document_insertion_op = DocumentOp { contract: contract.clone(), @@ -2914,8 +2914,8 @@ mod tests { Some(PROTOCOL_VERSION), ) .expect("expected to get cbor from a json document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let document_insertion_op = DocumentOp { contract: contract.clone(), diff --git a/packages/rs-drive/src/common/mod.rs b/packages/rs-drive/src/common/mod.rs index 3a3055c9322..82dbd28e67a 100644 --- a/packages/rs-drive/src/common/mod.rs +++ b/packages/rs-drive/src/common/mod.rs @@ -103,8 +103,7 @@ pub fn setup_contract_from_hex( transaction: TransactionArg, ) -> Contract { let contract_cbor = cbor_from_hex(hex_string); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); drive .apply_contract_cbor( contract_cbor, 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 22c961efe14..050f3fe1fdb 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 @@ -212,7 +212,7 @@ mod tests { use super::*; - use dpp::data_contract::extra::common::json_document_to_cbor; + use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_document}; use dpp::data_contract::DriveContractExt; use dpp::document::Document; use dpp::util::serializer; @@ -232,12 +232,15 @@ mod tests { use crate::drive::batch::drive_op_batch::document::{ DocumentOperationsForContractDocumentType, UpdateOperationInfo, }; + use crate::drive::batch::DocumentOperationType::AddDocumentForContract; use crate::drive::batch::DriveOperation::{ContractOperation, DocumentOperation}; use crate::drive::config::DriveConfig; use crate::drive::contract::paths::contract_root_path; use crate::drive::flags::StorageFlags; - use crate::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; - use crate::drive::object_size_info::OwnedDocumentInfo; + use crate::drive::object_size_info::DocumentInfo::{ + DocumentRefAndSerialization, DocumentRefWithoutSerialization, + }; + use crate::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use crate::drive::Drive; #[test] @@ -257,8 +260,8 @@ mod tests { Some(crate::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to get cbor contract"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let serialized_contract = DriveContractExt::to_cbor(&contract).expect("contract should be serialized"); @@ -350,8 +353,8 @@ mod tests { Some(crate::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to get cbor contract"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let serialized_contract = DriveContractExt::to_cbor(&contract).expect("contract should be serialized"); @@ -365,36 +368,44 @@ mod tests { storage_flags: None, })); - let dashpay_cr_serialized_document = json_document_to_cbor( + let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), ) .expect("expected to get cbor contract"); let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - drive_operations.push(DocumentOperation(AddSerializedDocumentForContract { - serialized_document: dashpay_cr_serialized_document.as_slice(), - contract: &contract, - document_type_name: "contactRequest", - owner_id: Some(random_owner_id), + drive_operations.push(DocumentOperation(AddDocumentForContract { + document_and_contract_info: DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization((&dashpay_cr_document, None)), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type: &contract + .document_type_for_name("contactRequest") + .expect("expected to get document type"), + }, override_document: false, - storage_flags: StorageFlags::optional_default_as_cow(), })); - let dashpay_cr_serialized_document2 = json_document_to_cbor( + let dashpay_cr_1_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request1.json", - Some(1), ) .expect("expected to get cbor contract"); - drive_operations.push(DocumentOperation(AddSerializedDocumentForContract { - serialized_document: dashpay_cr_serialized_document2.as_slice(), - contract: &contract, - document_type_name: "contactRequest", - owner_id: Some(random_owner_id), + drive_operations.push(DocumentOperation(AddDocumentForContract { + document_and_contract_info: DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization((&dashpay_cr_1_document, None)), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type: &contract + .document_type_for_name("contactRequest") + .expect("expected to get document type"), + }, override_document: false, - storage_flags: StorageFlags::optional_default_as_cow(), })); drive @@ -431,8 +442,8 @@ mod tests { Some(crate::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to get cbor contract"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("contract should be deserialized"); + let contract = + Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); let serialized_contract = DriveContractExt::to_cbor(&contract).expect("contract should be serialized"); diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 946ad00fa6d..0be3e88846e 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -113,6 +113,7 @@ use crate::fee::result::FeeResult; use crate::query::QueryResultEncoding; #[cfg(feature = "full")] use dpp::block::epoch::Epoch; +use dpp::prelude::DataContract; #[cfg(feature = "full")] /// Adds operations to the op batch relevant to initializing the contract's structure. @@ -914,8 +915,7 @@ impl Drive { Ok(Element::Item(stored_contract_bytes, element_flag)) => { let contract = cost_return_on_error_no_add!( &cost, - ::from_cbor(&stored_contract_bytes, None,) - .map_err(Error::Protocol) + DataContract::deserialize(&stored_contract_bytes).map_err(Error::Protocol) ); let drive_operation = CalculatedCostOperation(cost.clone()); let fee = if let Some(epoch) = epoch { @@ -1156,8 +1156,8 @@ mod tests { let contract_cbor = json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); drive .apply_contract_with_serialization( &contract, @@ -1185,8 +1185,8 @@ mod tests { // let's construct the grovedb structure for the dashpay data contract let contract_cbor = json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); drive .apply_contract_with_serialization( &contract, @@ -1214,12 +1214,11 @@ mod tests { // let's construct the grovedb structure for the dashpay data contract let contract_cbor = json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); drive - .apply_contract_with_serialization( + .apply_contract( &contract, - contract_cbor.clone(), BlockInfo::default(), true, StorageFlags::optional_default_as_cow(), @@ -1364,8 +1363,8 @@ mod tests { // let's construct the grovedb structure for the dashpay data contract let contract_cbor = json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); drive .apply_contract_with_serialization( &contract, @@ -1393,8 +1392,8 @@ mod tests { // let's construct the grovedb structure for the dashpay data contract let contract_cbor = json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); drive .apply_contract_with_serialization( &contract, @@ -1421,8 +1420,8 @@ mod tests { // let's construct the grovedb structure for the dashpay data contract let contract_cbor = json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); // Create a contract first drive @@ -1545,12 +1544,9 @@ mod tests { for i in 0..150u8 { ref_contract.id = Identifier::from([i; 32]); - let ref_contract_cbor = ref_contract.to_cbor().expect("should serialize contract"); - drive - .apply_contract_with_serialization( + .apply_contract( &ref_contract, - ref_contract_cbor, BlockInfo::default(), true, StorageFlags::optional_default_as_cow(), @@ -1563,12 +1559,11 @@ mod tests { let contract_path = "tests/supporting_files/contract/deepNested/deep-nested10.json"; let contract_cbor = json_document_to_cbor(contract_path, Some(1)) .expect("expected to get cbor document"); - let deep_contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let deep_contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); drive - .apply_contract_with_serialization( + .apply_contract( &deep_contract, - contract_cbor, BlockInfo::default(), true, StorageFlags::optional_default_as_cow(), @@ -1695,12 +1690,9 @@ mod tests { for i in 150..200u8 { ref_contract.id = Identifier::from([i; 32]); - let ref_contract_cbor = ref_contract.to_cbor().expect("should serialize contract"); - drive - .apply_contract_with_serialization( + .apply_contract( &ref_contract, - ref_contract_cbor, BlockInfo::default(), true, StorageFlags::optional_default_as_cow(), diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 0f91ddc79ab..8c99d79d7f3 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -816,7 +816,9 @@ mod tests { use crate::drive::document::tests::setup_dashpay; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentAndContractInfo; - use crate::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; + use crate::drive::object_size_info::DocumentInfo::{ + DocumentRefAndSerialization, DocumentRefWithoutSerialization, + }; use crate::drive::Drive; use crate::fee::credits::Creditable; use crate::fee::default_costs::EpochCosts; @@ -1076,11 +1078,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_serialized_document, - storage_flags, - )), + document_info: DocumentRefWithoutSerialization((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -1115,11 +1113,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_serialized_document, - storage_flags, - )), + document_info: DocumentRefWithoutSerialization((&document, storage_flags)), owner_id: None, }, contract: &contract, diff --git a/packages/rs-drive/src/drive/identity/update.rs b/packages/rs-drive/src/drive/identity/update.rs index 8dc6b7a189d..2b76679cd95 100644 --- a/packages/rs-drive/src/drive/identity/update.rs +++ b/packages/rs-drive/src/drive/identity/update.rs @@ -385,8 +385,8 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 345492000, - processing_fee: 9665800, + storage_fee: 346086000, + processing_fee: 9556170, ..Default::default() } ); diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 1d69db84799..1ba63c5e217 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -1540,8 +1540,8 @@ mod tests { // let's construct the grovedb structure for the dashpay data contract let contract_cbor = json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); drive @@ -1572,8 +1572,8 @@ mod tests { // let's construct the grovedb structure for the dashpay data contract let contract_cbor = json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = ::from_cbor(&contract_cbor, None) - .expect("expected to deserialize the contract"); + let contract = + Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); drive .apply_contract_with_serialization( diff --git a/packages/rs-drive/src/tests/helpers/setup.rs b/packages/rs-drive/src/tests/helpers/setup.rs index ec68697e7fa..21baa212e91 100644 --- a/packages/rs-drive/src/tests/helpers/setup.rs +++ b/packages/rs-drive/src/tests/helpers/setup.rs @@ -87,14 +87,7 @@ pub fn setup_system_data_contract( transaction: TransactionArg, ) { drive - .apply_contract_cbor( - data_contract.to_cbor().unwrap(), - Some(data_contract.id.to_buffer()), - BlockInfo::default(), - true, - None, - transaction, - ) + .apply_contract(data_contract, BlockInfo::default(), true, None, transaction) .unwrap(); } From 1c60fb81bb2ad464c3367e0eba976ee78e7bc686 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 22 Apr 2023 07:15:52 +0700 Subject: [PATCH 02/50] more work --- .../rs-dpp/src/data_contract/extra/common.rs | 49 ++++++++++++++----- .../src/drive/batch/drive_op_batch/mod.rs | 5 +- 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index 4c7cc99731d..928ad245f18 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -10,6 +10,10 @@ use std::fs::File; use std::io::BufReader; use std::iter::FromIterator; use std::path::Path; +use platform_value::Identifier; +use crate::data_contract::document_type::DocumentType; +use crate::prelude::DataContract; +use crate::ProtocolError::ValueError; pub fn cbor_map_into_btree_map( cbor_map: Vec<(Value, Value)>, @@ -258,7 +262,7 @@ pub fn bytes_for_system_value_from_tree_map( } /// Reads a JSON file and converts it to serde_value. -pub fn json_document_to_value(path: impl AsRef) -> Result { +pub fn json_document_to_json_value(path: impl AsRef) -> Result { let file = File::open(path.as_ref()).map_err(|_| { ProtocolError::FileNotFound(format!( "file not found at path {}", @@ -271,17 +275,8 @@ pub fn json_document_to_value(path: impl AsRef) -> Result, - protocol_version: Option, -) -> Result, ProtocolError> { - let json = json_document_to_value(path)?; - serializable_value_to_cbor(&json, protocol_version) -} - -/// Reads a JSON file and converts it a document. -pub fn json_document_to_document(path: impl AsRef) -> Result { +/// Reads a JSON file and converts it to serde_value. +pub fn json_document_to_platform_value(path: impl AsRef) -> Result { let file = File::open(path.as_ref()).map_err(|_| { ProtocolError::FileNotFound(format!( "file not found at path {}", @@ -294,6 +289,36 @@ pub fn json_document_to_document(path: impl AsRef) -> Result, + protocol_version: Option, +) -> Result, ProtocolError> { + let json = json_document_to_json_value(path)?; + serializable_value_to_cbor(&json, protocol_version) +} + +/// Reads a JSON file and converts it a document. +pub fn json_document_to_document(path: impl AsRef, owner_id: Option) -> Result { + if let Some(owner_id) = owner_id { + let mut value = json_document_to_platform_value(path)?; + dbg!(&value); + value.set_value("$ownerId", platform_value::Value::Identifier(owner_id.into_buffer()))?; + platform_value::from_value(value).map_err(ValueError) + } else { + let file = File::open(path.as_ref()).map_err(|_| { + ProtocolError::FileNotFound(format!( + "file not found at path {}", + path.as_ref().to_str().unwrap() + )) + })?; + + let reader = BufReader::new(file); + serde_json::from_reader(reader) + .map_err(|e| ProtocolError::DecodingError(format!("error decoding document from json document {e}"))) + } +} + /// Make sure the protocol version is correct. pub const fn check_protocol_version(_version: u32) -> bool { // Temporary disabled due protocol version is dynamic and goes from consensus params 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 050f3fe1fdb..91edef7780b 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 @@ -367,13 +367,15 @@ mod tests { serialized_contract, storage_flags: None, })); + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", + Some(random_owner_id.into()), ) .expect("expected to get cbor contract"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + drive_operations.push(DocumentOperation(AddDocumentForContract { document_and_contract_info: DocumentAndContractInfo { @@ -391,6 +393,7 @@ mod tests { let dashpay_cr_1_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request1.json", + Some(random_owner_id.into()), ) .expect("expected to get cbor contract"); From d974b28fbd38b39ede0ff6b1d5ab9a7858ae6b71 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 22 Apr 2023 21:52:53 +0700 Subject: [PATCH 03/50] more work on efficient data serialization --- .../document_type/array_field.rs | 47 +++----- .../document_type/document_field.rs | 67 +++++++---- .../document_type/document_type.rs | 113 +++++++++++++++++- .../document_type/random_document_type.rs | 4 + .../rs-dpp/src/data_contract/extra/common.rs | 43 ++++--- .../rs-dpp/src/document/document_factory.rs | 1 + .../src/drive/batch/drive_op_batch/mod.rs | 2 - 7 files changed, 197 insertions(+), 80 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 468419732ab..6774de26827 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 @@ -10,6 +10,7 @@ pub enum ArrayFieldType { Number, String(Option, Option), ByteArray(Option, Option), + Identifier, Boolean, Date, } @@ -44,22 +45,14 @@ impl ArrayFieldType { Ok(value_bytes) } ArrayFieldType::ByteArray(_, _) => { - let mut bytes = match value { - Value::Bytes(bytes) => Ok(bytes), - 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 - .into_iter() - .map(|byte| byte.to_integer().map_err(ProtocolError::ValueError)) - .collect::, ProtocolError>>(), - _ => Err(get_field_type_matching_error()), - }?; + let mut bytes = value.into_binary_bytes()?; + + let mut r_vec = bytes.len().encode_var_vec(); + r_vec.append(&mut bytes); + Ok(r_vec) + } + ArrayFieldType::Identifier => { + let mut bytes = value.into_identifier_bytes()?; let mut r_vec = bytes.len().encode_var_vec(); r_vec.append(&mut bytes); @@ -101,20 +94,14 @@ impl ArrayFieldType { Ok(value_bytes) } ArrayFieldType::ByteArray(_, _) => { - let mut bytes = match value { - Value::Bytes(bytes) => Ok(bytes.clone()), - Value::Text(text) => { - let value_as_bytes = base64::decode(text).map_err(|_| { - 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) + } + ArrayFieldType::Identifier => { + let mut bytes = value.to_identifier_bytes()?; let mut r_vec = bytes.len().encode_var_vec(); r_vec.append(&mut bytes); 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 81017ff7cc0..ab260791063 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 @@ -1,4 +1,5 @@ use std::collections::BTreeMap; +use std::convert::TryInto; use std::io::{BufReader, Read}; @@ -8,7 +9,7 @@ use crate::prelude::TimestampMillis; use crate::ProtocolError; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use integer_encoding::{VarInt, VarIntReader}; -use platform_value::Value; +use platform_value::{Identifier, Value}; use rand::distributions::{Alphanumeric, Standard}; use rand::rngs::StdRng; use rand::Rng; @@ -29,6 +30,7 @@ pub enum DocumentFieldType { Number, String(Option, Option), ByteArray(Option, Option), + Identifier, Boolean, Date, Object(BTreeMap), @@ -57,6 +59,7 @@ impl DocumentFieldType { .sum(), DocumentFieldType::Array(_) => None, DocumentFieldType::VariableTypeArray(_) => None, + DocumentFieldType::Identifier => Some(32), } } @@ -80,6 +83,7 @@ impl DocumentFieldType { .sum(), DocumentFieldType::Array(_) => None, DocumentFieldType::VariableTypeArray(_) => None, + DocumentFieldType::Identifier => Some(32), } } @@ -103,6 +107,7 @@ impl DocumentFieldType { .sum(), DocumentFieldType::Array(_) => None, DocumentFieldType::VariableTypeArray(_) => None, + DocumentFieldType::Identifier => Some(32), } } @@ -126,6 +131,7 @@ impl DocumentFieldType { .sum(), DocumentFieldType::Array(_) => None, DocumentFieldType::VariableTypeArray(_) => None, + DocumentFieldType::Identifier => Some(32), } } @@ -215,6 +221,7 @@ impl DocumentFieldType { } DocumentFieldType::Array(_) => Value::Null, DocumentFieldType::VariableTypeArray(_) => Value::Null, + DocumentFieldType::Identifier => Value::Identifier(rng.gen()), } } @@ -254,6 +261,7 @@ impl DocumentFieldType { } DocumentFieldType::Array(_) => Value::Null, DocumentFieldType::VariableTypeArray(_) => Value::Null, + DocumentFieldType::Identifier => Value::Identifier(rng.gen()), } } @@ -347,6 +355,18 @@ impl DocumentFieldType { let bytes = Self::read_varint_value(buf)?; Ok(bytes.map(Value::Bytes)) } + DocumentFieldType::Identifier => { + let bytes = Self::read_varint_value(buf)?; + + bytes + .map(|bytes| { + let fixed_bytes = bytes.try_into().map_err(|_| { + ProtocolError::DecodingError("identifier was not 32 bytes".to_string()) + })?; + Ok(Value::Identifier(fixed_bytes)) + }) + .transpose() + } DocumentFieldType::Object(inner_fields) => { let values = inner_fields @@ -435,27 +455,14 @@ impl DocumentFieldType { } } DocumentFieldType::ByteArray(_, _) => { - let mut bytes = match value { - Value::Bytes(bytes) => Ok(bytes), - 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 - .into_iter() - .map(|byte| match byte { - Value::U8(value_as_u8) => Ok(value_as_u8), - _ => Err(ProtocolError::DataContractError( - DataContractError::ValueWrongType("not an array of bytes"), - )), - }) - .collect::, ProtocolError>>(), - _ => Err(get_field_type_matching_error()), - }?; + let mut bytes = value.into_binary_bytes()?; + + let mut r_vec = bytes.len().encode_var_vec(); + r_vec.append(&mut bytes); + Ok(r_vec) + } + DocumentFieldType::Identifier => { + let mut bytes = value.into_identifier_bytes()?; let mut r_vec = bytes.len().encode_var_vec(); r_vec.append(&mut bytes); @@ -576,6 +583,14 @@ impl DocumentFieldType { } DocumentFieldType::ByteArray(_, _) => { let mut bytes = value.to_binary_bytes()?; + + let mut r_vec = bytes.len().encode_var_vec(); + r_vec.append(&mut bytes); + Ok(r_vec) + } + DocumentFieldType::Identifier => { + let mut bytes = value.to_identifier_bytes()?; + let mut r_vec = bytes.len().encode_var_vec(); r_vec.append(&mut bytes); Ok(r_vec) @@ -668,6 +683,9 @@ impl DocumentFieldType { DocumentFieldType::ByteArray(_, _) => { value.to_binary_bytes().map_err(ProtocolError::ValueError) } + DocumentFieldType::Identifier => value + .to_identifier_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 { @@ -734,7 +752,7 @@ impl DocumentFieldType { if let Some(max) = max { if str.len() / 2 > *max as usize { return Err(ProtocolError::DataContractError( - DataContractError::FieldRequirementUnmet("byte array is too big"), + DataContractError::FieldRequirementUnmet("byte array is too big"), )); } } @@ -744,6 +762,9 @@ impl DocumentFieldType { )) })?)) } + DocumentFieldType::Identifier => Ok(Value::Identifier( + Value::Text(str.to_owned()).to_identifier()?.into_buffer(), + )), DocumentFieldType::Boolean => { if str.to_lowercase().as_str() == "true" { Ok(Value::Bool(true)) 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 72e0b92a26e..b6031ae131b 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 @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::convert::TryInto; use super::{ @@ -9,10 +9,13 @@ use crate::data_contract::document_type::{property_names, ArrayFieldType}; use crate::data_contract::errors::{DataContractError, StructureError}; use crate::document::document_transition::INITIAL_REVISION; +use crate::document::Document; use crate::prelude::Revision; use crate::ProtocolError; -use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; -use platform_value::{Identifier, Value}; +use platform_value::btreemap_extensions::{ + BTreeValueMapHelper, BTreeValueMapReplacementPathHelper, BTreeValueRemoveFromMapHelper, +}; +use platform_value::{Identifier, ReplacementType, Value}; use serde::{Deserialize, Serialize}; pub const PROTOCOL_VERSION: u32 = 1; @@ -37,6 +40,10 @@ pub struct DocumentType { #[serde(skip)] pub index_structure: IndexLevel, pub properties: BTreeMap, + #[serde(skip)] + pub identifier_paths: BTreeSet, + #[serde(skip)] + pub binary_paths: BTreeSet, pub required_fields: BTreeSet, pub documents_keep_history: bool, pub documents_mutable: bool, @@ -93,11 +100,14 @@ impl DocumentType { documents_mutable: bool, ) -> Self { let index_structure = IndexLevel::from(indices.as_slice()); + let (identifier_paths, binary_paths) = Self::find_identifier_and_binary_paths(&properties); DocumentType { name, indices, index_structure, properties, + identifier_paths, + binary_paths, required_fields, documents_keep_history, documents_mutable, @@ -181,6 +191,33 @@ impl DocumentType { } } + pub fn convert_value_to_document(&self, mut data: Value) -> Result { + let mut document = Document { + id: data.remove_identifier("$id")?, + owner_id: data.remove_identifier("$owner_id")?, + properties: Default::default(), + revision: data.remove_optional_integer("$revision")?, + created_at: data.remove_optional_integer("$created_at")?, + updated_at: data.remove_optional_integer("$updated_at")?, + }; + + data.replace_at_paths( + self.identifier_paths.iter().map(|s| s.as_str()), + ReplacementType::Identifier, + )?; + + data.replace_at_paths( + self.binary_paths.iter().map(|s| s.as_str()), + ReplacementType::BinaryBytes, + )?; + + document.properties = data + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?; + + Ok(document) + } + pub fn from_platform_value( data_contract_id: Identifier, name: &str, @@ -273,11 +310,15 @@ impl DocumentType { let index_structure = IndexLevel::from(indices.as_slice()); + let (identifier_paths, binary_paths) = + Self::find_identifier_and_binary_paths(&document_properties); Ok(DocumentType { name: String::from(name), indices, index_structure, properties: document_properties, + identifier_paths, + binary_paths, required_fields, documents_keep_history, documents_mutable, @@ -355,6 +396,72 @@ impl DocumentType { None } } + + pub(crate) fn find_identifier_and_binary_paths( + properties: &BTreeMap, + ) -> (BTreeSet, BTreeSet) { + Self::find_identifier_and_binary_paths_inner(properties, "") + } + fn find_identifier_and_binary_paths_inner( + properties: &BTreeMap, + current_path: &str, + ) -> (BTreeSet, BTreeSet) { + let mut identifier_paths = BTreeSet::new(); + let mut binary_paths = BTreeSet::new(); + + for (key, value) in properties.iter() { + let new_path = if current_path.is_empty() { + key.clone() + } else { + format!("{}.{}", current_path, key) + }; + + match &value.document_type { + DocumentFieldType::Identifier => { + identifier_paths.insert(new_path); + } + DocumentFieldType::ByteArray(_, _) => { + binary_paths.insert(new_path); + } + DocumentFieldType::Object(inner_properties) => { + let (inner_identifier_paths, inner_binary_paths) = + Self::find_identifier_and_binary_paths_inner(inner_properties, &new_path); + + identifier_paths.extend(inner_identifier_paths); + binary_paths.extend(inner_binary_paths); + } + DocumentFieldType::Array(array_field_type) => { + let new_path = format!("{}[]", new_path); + match array_field_type { + ArrayFieldType::Identifier => { + identifier_paths.insert(new_path.clone()); + } + ArrayFieldType::ByteArray(_, _) => { + binary_paths.insert(new_path.clone()); + } + _ => {} + } + } + DocumentFieldType::VariableTypeArray(array_field_types) => { + for (i, array_field_type) in array_field_types.iter().enumerate() { + let new_path = format!("{}[{}]", new_path, i); + match array_field_type { + ArrayFieldType::Identifier => { + identifier_paths.insert(new_path.clone()); + } + ArrayFieldType::ByteArray(_, _) => { + binary_paths.insert(new_path.clone()); + } + _ => {} + } + } + } + _ => {} + } + } + + (identifier_paths, binary_paths) + } } pub fn string_to_field_type(field_type_name: &str) -> Option { diff --git a/packages/rs-dpp/src/data_contract/document_type/random_document_type.rs b/packages/rs-dpp/src/data_contract/document_type/random_document_type.rs index 9b0bee0b717..a22ad294e7f 100644 --- a/packages/rs-dpp/src/data_contract/document_type/random_document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/random_document_type.rs @@ -223,11 +223,15 @@ impl DocumentType { let documents_mutable = rng.gen_bool(parameters.documents_mutable_chance); let index_structure = IndexLevel::from(indices.as_slice()); + let (identifier_paths, binary_paths) = + DocumentType::find_identifier_and_binary_paths(&properties); Ok(DocumentType { name: format!("doc_type_{}", rng.gen::()), indices, index_structure, properties, + identifier_paths, + binary_paths, required_fields, documents_keep_history, documents_mutable, diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index 928ad245f18..55ee6cb5662 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -1,19 +1,19 @@ +use crate::data_contract::document_type::DocumentType; use crate::data_contract::errors::StructureError; use crate::document::Document; +use crate::prelude::DataContract; use crate::util::cbor_value::cbor_value_into_json_value; use crate::util::serializer::serializable_value_to_cbor; use crate::ProtocolError; +use crate::ProtocolError::ValueError; use ciborium::Value; +use platform_value::Identifier; use std::collections::BTreeMap; use std::convert::TryInto; use std::fs::File; use std::io::BufReader; use std::iter::FromIterator; use std::path::Path; -use platform_value::Identifier; -use crate::data_contract::document_type::DocumentType; -use crate::prelude::DataContract; -use crate::ProtocolError::ValueError; pub fn cbor_map_into_btree_map( cbor_map: Vec<(Value, Value)>, @@ -262,7 +262,9 @@ pub fn bytes_for_system_value_from_tree_map( } /// Reads a JSON file and converts it to serde_value. -pub fn json_document_to_json_value(path: impl AsRef) -> Result { +pub fn json_document_to_json_value( + path: impl AsRef, +) -> Result { let file = File::open(path.as_ref()).map_err(|_| { ProtocolError::FileNotFound(format!( "file not found at path {}", @@ -276,7 +278,9 @@ pub fn json_document_to_json_value(path: impl AsRef) -> Result) -> Result { +pub fn json_document_to_platform_value( + path: impl AsRef, +) -> Result { let file = File::open(path.as_ref()).map_err(|_| { ProtocolError::FileNotFound(format!( "file not found at path {}", @@ -299,24 +303,19 @@ pub fn json_document_to_cbor( } /// Reads a JSON file and converts it a document. -pub fn json_document_to_document(path: impl AsRef, owner_id: Option) -> Result { +pub fn json_document_to_document( + path: impl AsRef, + owner_id: Option, + document_type: &DocumentType, +) -> Result { + let mut value = json_document_to_platform_value(path)?; if let Some(owner_id) = owner_id { - let mut value = json_document_to_platform_value(path)?; - dbg!(&value); - value.set_value("$ownerId", platform_value::Value::Identifier(owner_id.into_buffer()))?; - platform_value::from_value(value).map_err(ValueError) - } else { - let file = File::open(path.as_ref()).map_err(|_| { - ProtocolError::FileNotFound(format!( - "file not found at path {}", - path.as_ref().to_str().unwrap() - )) - })?; - - let reader = BufReader::new(file); - serde_json::from_reader(reader) - .map_err(|e| ProtocolError::DecodingError(format!("error decoding document from json document {e}"))) + value.set_value( + "$ownerId", + platform_value::Value::Identifier(owner_id.into_buffer()), + )?; } + document_type.convert_value_to_document(value) } /// Make sure the protocol version is correct. diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index e266ff5b8ab..2ac6d2d380e 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize}; use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::document::extended_document::{property_names, ExtendedDocument}; +use crate::data_contract::document_type::DocumentType; use crate::data_contract::DriveContractExt; use crate::document::document_transition::INITIAL_REVISION; use crate::document::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 91edef7780b..b05567e14d6 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 @@ -375,8 +375,6 @@ mod tests { ) .expect("expected to get cbor contract"); - - drive_operations.push(DocumentOperation(AddDocumentForContract { document_and_contract_info: DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { From 322b60a61a2402795c981552674079d408e75579 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 22 Apr 2023 22:31:44 +0700 Subject: [PATCH 04/50] clean up of data contract --- packages/rs-dpp/Cargo.toml | 5 +- .../rs-dpp/src/data_contract/data_contract.rs | 58 +++- .../document_type/document_field.rs | 10 +- .../rs-dpp/src/data_contract/extra/common.rs | 260 ++---------------- .../src/data_contract/extra/drive_api.rs | 8 +- packages/rs-drive/src/query/mod.rs | 28 +- 6 files changed, 105 insertions(+), 264 deletions(-) diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index ffd3b816900..03b6499ed98 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -15,7 +15,7 @@ chrono = { version = "0.4.20", default-features = false, features = [ "wasmbind", "clock", ] } -ciborium = { git = "https://github.com/qrayven/ciborium", branch = "feat-ser-null-as-undefined" } +ciborium = { git = "https://github.com/qrayven/ciborium", branch = "feat-ser-null-as-undefined" , optional = true} dashcore = { git = "https://github.com/dashpay/rust-dashcore", features = [ "std", "secp-recovery", @@ -59,5 +59,6 @@ tokio = { version = "1.17", features = ["full"] } pretty_assertions = { version = "1.3.0" } [features] -default = ["fixtures-and-mocks"] +default = ["fixtures-and-mocks", "cbor"] +cbor = ["ciborium"] fixtures-and-mocks = ["mockall"] diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 7bca040eb7d..fe0097a6fc2 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -95,36 +95,51 @@ impl Convertible for DataContract { } } +/// `DataContract` represents a data contract in a decentralized platform. +/// +/// It contains information about the contract, such as its protocol version, unique identifier, +/// schema, version, and owner identifier. The struct also includes details about the document +/// types, metadata, configuration, and document schemas associated with the contract. +/// +/// Additionally, `DataContract` holds definitions for JSON schemas, entropy, and binary properties +/// of the documents. #[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)] -#[serde(rename_all = "camelCase")] #[serde(try_from = "DataContractInner")] pub struct DataContract { + /// The version of the protocol this contract adheres to. pub protocol_version: u32, - #[serde(rename = "$id")] + + /// A unique identifier for the data contract. pub id: Identifier, - #[serde(rename = "$schema")] + + /// A reference to the JSON schema that defines the contract. pub schema: String, + + /// The version of this data contract. pub version: u32, + + /// The identifier of the contract owner. pub owner_id: Identifier, - #[serde(skip)] + + /// A mapping of document names to their corresponding document types. pub document_types: BTreeMap, - #[serde(skip)] + + /// Optional metadata associated with the contract. pub metadata: Option, - #[serde(skip)] + + /// Internal configuration for the contract. pub(crate) config: ContractConfig, - #[serde(rename = "documents")] + /// A mapping of document names to their corresponding JSON schemas. pub documents: BTreeMap, - // TODO we may ensure in compile time that defs are not empty if we define a type for it - #[serde(rename = "$defs", default)] + /// Optional mapping of definition names to their corresponding JSON schemas. pub defs: Option>, - //todo: we should remove entropy - #[serde(skip)] + /// A randomly generated value used for creating unique identifiers within the contract. pub entropy: Bytes32, - #[serde(skip)] + /// A nested mapping of document names and property paths to their binary values. pub binary_properties: BTreeMap>, } @@ -153,17 +168,36 @@ impl<'a> BorrowDecode<'a> for DataContract { } } +// Standalone default_protocol_version function +fn default_protocol_version() -> u32 { + 1 +} + #[derive(Serialize, Deserialize, Encode, Decode)] #[serde(rename_all = "camelCase")] pub struct DataContractInner { + /// The version of the protocol this contract adheres to, with a default value if not provided. + #[serde(default = "default_protocol_version")] pub protocol_version: u32, + + /// A unique identifier for the data contract. #[serde(rename = "$id")] pub id: Identifier, + + /// A reference to the JSON schema that defines the contract. #[serde(rename = "$schema")] pub schema: String, + + /// The version of this data contract. pub version: u32, + + /// The identifier of the contract owner. pub owner_id: Identifier, + + /// A mapping of document names to their corresponding JSON values. pub documents: BTreeMap, + + /// Optional mapping of definition names to their corresponding JSON values. #[serde(rename = "$defs", default)] pub defs: Option>, } 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 ab260791063..f89a653407f 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 @@ -386,13 +386,9 @@ impl DocumentFieldType { Ok(Some(Value::Map(values))) } } - DocumentFieldType::Array(_array_field_type) => { - Err(ProtocolError::DataContractError( - DataContractError::Unsupported("serialization of arrays not yet supported"), - )) - // cbor_inner_array_value(value.as_array().ok_or_else(get_field_type_matching_error)) - // let array = value.as_array().ok_or_else(get_field_type_matching_error)?; - } + DocumentFieldType::Array(_array_field_type) => Err(ProtocolError::DataContractError( + DataContractError::Unsupported("serialization of arrays not yet supported"), + )), DocumentFieldType::VariableTypeArray(_) => Err(ProtocolError::DataContractError( DataContractError::Unsupported("serialization of arrays not yet supported"), )), diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index 55ee6cb5662..d590d90288c 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -15,69 +15,6 @@ use std::io::BufReader; use std::iter::FromIterator; use std::path::Path; -pub fn cbor_map_into_btree_map( - cbor_map: Vec<(Value, Value)>, -) -> Result, ProtocolError> { - cbor_map - .into_iter() - .map(|(key, value)| { - let key = key.into_text().map_err(|_| { - ProtocolError::StructureError(StructureError::KeyWrongType( - "expected key to be string", - )) - })?; - Ok((key, value)) - }) - .collect::, ProtocolError>>() -} - -//todo remove this function -pub fn cbor_map_into_serde_btree_map( - cbor_map: Vec<(Value, Value)>, -) -> Result, ProtocolError> { - cbor_map - .into_iter() - .map(|(key, value)| { - let key = key.into_text().map_err(|_| { - ProtocolError::StructureError(StructureError::KeyWrongType( - "expected key to be string", - )) - })?; - let value = cbor_value_into_json_value(value)?; - Ok((key, value)) - }) - .collect::, ProtocolError>>() -} - -/// Converts a CBOR map to a BTree map. -pub fn cbor_map_to_btree_map(cbor_map: &[(Value, Value)]) -> BTreeMap { - cbor_map - .iter() - .filter_map(|(key, value)| key.as_text().map(|key| (key.to_string(), value))) - .collect::>() -} - -/// Gets the inner bool value from cbor map -pub fn cbor_inner_bool_value(document_type: &[(Value, Value)], key: &str) -> Option { - let key_value = get_key_from_cbor_map(document_type, key)?; - if let Value::Bool(bool_value) = key_value { - return Some(*bool_value); - } - None -} - -/// Gets the inner array value from cbor map -pub fn cbor_inner_array_value<'a>( - document_type: &'a [(Value, Value)], - key: &'a str, -) -> Option<&'a Vec> { - let key_value = get_key_from_cbor_map(document_type, key)?; - if let Value::Array(key_value) = key_value { - return Some(key_value); - } - None -} - pub fn get_key_from_cbor_map<'a>( cbor_map: &'a [(Value, Value)], key: &'a str, @@ -94,173 +31,6 @@ pub fn get_key_from_cbor_map<'a>( None } -/// Retrieves the value of a key from a CBOR map if it's an array of strings. -pub fn cbor_inner_array_of_strings<'a, I: FromIterator>( - document_type: &'a [(Value, Value)], - key: &'a str, -) -> Option { - let key_value = get_key_from_cbor_map(document_type, key)?; - if let Value::Array(key_value) = key_value { - Some( - key_value - .iter() - .filter_map(|v| { - if let Value::Text(text) = v { - Some(text.clone()) - } else { - None - } - }) - .collect(), - ) - } else { - None - } -} -// -// pub fn cbor_inner_map_value<'a>( -// document_type: &'a [(Value, Value)], -// key: &'a str, -// ) -> Option<&'a Vec<(Value, Value)>> { -// let key_value = get_key_from_cbor_map(document_type, key)?; -// if let Value::Map(map_value) = key_value { -// return Some(map_value); -// } -// None -// } -// -/// Retrieves the value of a key from a CBOR map, and if it's a map itself, -/// returns it as a B-tree map. -pub fn cbor_inner_btree_map<'a>( - document_type: &'a [(Value, Value)], - key: &'a str, -) -> Option> { - let key_value = get_key_from_cbor_map(document_type, key)?; - if let Value::Map(map_value) = key_value { - return Some(cbor_map_to_btree_map(map_value)); - } - None -} -// -/// Retrieves the value of a key from a B-tree map, and if it's a map itself, -/// returns it as a B-tree map. -pub fn btree_map_inner_btree_map<'a>( - document_type: &'a BTreeMap, - key: &'a str, -) -> Option> { - let key_value = document_type.get(key)?; - if let Value::Map(map_value) = key_value { - return Some(cbor_map_to_btree_map(map_value)); - } - None -} - -/// Retrieves the value of a key from a B-tree map if it's a map itself. -pub fn btree_map_inner_map_value<'a>( - document_type: &'a BTreeMap, - key: &'a str, -) -> Option<&'a Vec<(Value, Value)>> { - let key_value = document_type.get(key)?; - if let Value::Map(map_value) = key_value { - return Some(map_value); - } - None -} - -/// Retrieves the value of a key from a CBOR map if it's a string. -pub fn cbor_inner_text_value<'a>( - document_type: &'a [(Value, Value)], - key: &'a str, -) -> Result, ProtocolError> { - match get_key_from_cbor_map(document_type, key) { - None => Ok(None), - Some(key_value) => { - if let Value::Text(string_value) = key_value { - Ok(Some(string_value)) - } else { - Err(ProtocolError::StructureError( - StructureError::ValueWrongType("expected a string for the value"), - )) - } - } - } -} - -/// Retrieves the value of a key from a CBOR map if it's a byte array. -pub fn cbor_inner_bytes_value<'a>( - document_type: &'a [(Value, Value)], - key: &'a str, -) -> Result>, ProtocolError> { - match get_key_from_cbor_map(document_type, key) { - None => Ok(None), - Some(key_value) => match key_value { - Value::Bytes(bytes) => Ok(Some(bytes.clone())), - Value::Array(array) => array - .iter() - .map(|byte| match byte { - Value::Integer(int) => { - let value_as_u8: u8 = (*int).try_into().map_err(|_| { - ProtocolError::StructureError(StructureError::ValueWrongType( - "expected u8 value", - )) - })?; - Ok(value_as_u8) - } - _ => Err(ProtocolError::StructureError( - StructureError::ValueWrongType("not an array of integers"), - )), - }) - .collect::, ProtocolError>>() - .map(Some), - _ => Err(ProtocolError::StructureError( - StructureError::ValueWrongType("value should be a byte array"), - )), - }, - } -} - -/// Takes a value (should be a system value) and returns it as a byte array if possible. -pub fn bytes_for_system_value(value: &Value) -> Result>, ProtocolError> { - match value { - Value::Bytes(bytes) => Ok(Some(bytes.clone())), - Value::Text(text) => match bs58::decode(text).into_vec() { - Ok(data) => Ok(Some(data)), - Err(_) => Ok(None), - }, - Value::Array(array) => array - .iter() - .map(|byte| match byte { - Value::Integer(int) => { - let value_as_u8: u8 = (*int).try_into().map_err(|_| { - ProtocolError::StructureError(StructureError::ValueWrongType( - "expected u8 value", - )) - })?; - Ok(Some(value_as_u8)) - } - _ => Err(ProtocolError::StructureError( - StructureError::ValueWrongType("not an array of integers"), - )), - }) - .collect::>, ProtocolError>>(), - _ => Err(ProtocolError::StructureError( - StructureError::ValueWrongType("system value is incorrect type"), - )), - } -} - -pub fn bytes_for_system_value_from_tree_map( - document: &BTreeMap, - key: &str, -) -> Result>, ProtocolError> { - let value = document.get(key); - if let Some(value) = value { - bytes_for_system_value(value) - } else { - Ok(None) - } -} - /// Reads a JSON file and converts it to serde_value. pub fn json_document_to_json_value( path: impl AsRef, @@ -302,6 +72,36 @@ pub fn json_document_to_cbor( serializable_value_to_cbor(&json, protocol_version) } +/// Reads a JSON file and converts it a contract. +pub fn json_document_to_contract(path: impl AsRef) -> Result { + let file = File::open(path.as_ref()).map_err(|_| { + ProtocolError::FileNotFound(format!( + "file not found at path {}", + path.as_ref().to_str().unwrap() + )) + })?; + + let reader = BufReader::new(file); + serde_json::from_reader(reader).map_err(|e| { + ProtocolError::DecodingError(format!("error decoding contract from document {e}")) + }) +} + +/// Reads a JSON file and converts it a document. +pub fn json_document_to_contract_with_owner_id( + path: impl AsRef, + owner_id: Option, +) -> Result { + let mut value = json_document_to_platform_value(path)?; + if let Some(owner_id) = owner_id { + value.set_value( + "$ownerId", + platform_value::Value::Identifier(owner_id.into_buffer()), + )?; + } + DataContract::from_raw_object(value) +} + /// Reads a JSON file and converts it a document. pub fn json_document_to_document( path: impl AsRef, 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 b0aa8669ef0..9ae7a463a59 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -197,6 +197,7 @@ impl DriveContractExt for DataContract { mod test { use crate::data_contract::contract_config::ContractConfig; + use crate::data_contract::extra::common::json_document_to_contract; use crate::{ data_contract::extra::common::json_document_to_cbor, data_contract::DataContract, util::json_schema::JsonSchemaExt, @@ -349,10 +350,9 @@ mod test { #[test] fn should_drive_api_methods_contain_contract_data() { - let dashpay_cbor = - json_document_to_cbor("src/tests/payloads/contract/dashpay-contract.json", Some(1)) - .expect("expected to get cbor document"); - let contract = DataContract::from_cbor(dashpay_cbor).unwrap(); + let contract = + json_document_to_contract("src/tests/payloads/contract/dashpay-contract.json") + .expect("expected to get a contract"); assert!(contract.documents_mutable_contract_default()); assert!(!contract.keeps_history()); diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 1ba63c5e217..1e9d1064235 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -97,8 +97,6 @@ use crate::fee::op::LowLevelDriveOperation; #[cfg(feature = "full")] use crate::drive::contract::paths::ContractPaths; -#[cfg(any(feature = "full", feature = "verify"))] -use dpp::data_contract::extra::common::bytes_for_system_value; #[cfg(any(feature = "full", feature = "verify"))] use dpp::document::Document; @@ -577,13 +575,25 @@ impl<'a> DriveQuery<'a> { let internal_clauses = InternalClauses::extract_from_clauses(all_where_clauses)?; - let start_at_option = None; - let start_at_included = true; - let start_at: Option> = if start_at_option.is_some() { - bytes_for_system_value(start_at_option.unwrap())? - } else { - None - }; + let start_at_option = None; //todo + let start_after_option = None; //todo + let mut start_at_included = true; + let mut start_option: Option = None; + + if start_after_option.is_some() { + start_option = start_after_option; + start_at_included = false; + } else if start_at_option.is_some() { + start_option = start_at_option; + start_at_included = true; + } + + let start_at: Option> = start_option + .map(|v| { + v.into_identifier_bytes() + .map_err(|e| Error::Protocol(ProtocolError::ValueError(e))) + }) + .transpose()?; Ok(DriveQuery { contract, From 71b8e80692cb112244160230b36b04b51b3fce58 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 22 Apr 2023 22:47:02 +0700 Subject: [PATCH 05/50] more work --- packages/rs-dpp/Cargo.toml | 2 +- .../document_type/document_field.rs | 2 +- .../document_type/document_type.rs | 4 +- .../rs-dpp/src/data_contract/extra/common.rs | 52 ------------------- .../src/data_contract/extra/drive_api.rs | 2 +- .../src/data_contract/serialization/cbor.rs | 3 +- .../src/data_contract/serialization/mod.rs | 1 + .../src/decode_protocol_entity_factory.rs | 1 + packages/rs-dpp/src/document/document.rs | 1 + .../rs-dpp/src/document/extended_document.rs | 13 +++-- packages/rs-dpp/src/document/serialize.rs | 3 ++ .../documents_batch_transition/mod.rs | 3 ++ packages/rs-dpp/src/identity/identity.rs | 6 ++- .../identity/identity_public_key/key_type.rs | 1 + .../src/identity/identity_public_key/mod.rs | 4 ++ .../identity/identity_public_key/purpose.rs | 1 + .../identity_public_key/security_level.rs | 1 + .../instant/instant_asset_lock_proof.rs | 4 +- .../identity_public_key_transitions/mod.rs | 3 ++ .../abstract_state_transition.rs | 1 - packages/rs-dpp/src/util/mod.rs | 1 + .../src/validation/validation_result.rs | 1 - 22 files changed, 43 insertions(+), 67 deletions(-) diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 03b6499ed98..162a2ea5810 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -59,6 +59,6 @@ tokio = { version = "1.17", features = ["full"] } pretty_assertions = { version = "1.3.0" } [features] -default = ["fixtures-and-mocks", "cbor"] +default = ["fixtures-and-mocks"] cbor = ["ciborium"] fixtures-and-mocks = ["mockall"] 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 f89a653407f..01e37a4906d 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 @@ -9,7 +9,7 @@ use crate::prelude::TimestampMillis; use crate::ProtocolError; use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use integer_encoding::{VarInt, VarIntReader}; -use platform_value::{Identifier, Value}; +use platform_value::Value; use rand::distributions::{Alphanumeric, Standard}; use rand::rngs::StdRng; use rand::Rng; 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 b6031ae131b..03618b8cccb 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 @@ -1,4 +1,4 @@ -use std::collections::{BTreeMap, BTreeSet, HashSet}; +use std::collections::{BTreeMap, BTreeSet}; use std::convert::TryInto; use super::{ @@ -13,7 +13,7 @@ use crate::document::Document; use crate::prelude::Revision; use crate::ProtocolError; use platform_value::btreemap_extensions::{ - BTreeValueMapHelper, BTreeValueMapReplacementPathHelper, BTreeValueRemoveFromMapHelper, + BTreeValueMapHelper, BTreeValueRemoveFromMapHelper, }; use platform_value::{Identifier, ReplacementType, Value}; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index d590d90288c..1a1408dc2f8 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -1,36 +1,14 @@ use crate::data_contract::document_type::DocumentType; -use crate::data_contract::errors::StructureError; use crate::document::Document; use crate::prelude::DataContract; -use crate::util::cbor_value::cbor_value_into_json_value; use crate::util::serializer::serializable_value_to_cbor; use crate::ProtocolError; use crate::ProtocolError::ValueError; -use ciborium::Value; -use platform_value::Identifier; -use std::collections::BTreeMap; use std::convert::TryInto; use std::fs::File; use std::io::BufReader; -use std::iter::FromIterator; use std::path::Path; -pub fn get_key_from_cbor_map<'a>( - cbor_map: &'a [(Value, Value)], - key: &'a str, -) -> Option<&'a Value> { - for (cbor_key, cbor_value) in cbor_map.iter() { - if !cbor_key.is_text() { - continue; - } - - if cbor_key.as_text().expect("confirmed as text") == key { - return Some(cbor_value); - } - } - None -} - /// Reads a JSON file and converts it to serde_value. pub fn json_document_to_json_value( path: impl AsRef, @@ -136,33 +114,3 @@ pub fn check_protocol_version_bytes(version_bytes: &[u8]) -> bool { check_protocol_version(version) } } - -pub fn reduced_value_string_representation(value: &Value) -> String { - match value { - Value::Integer(integer) => { - let i: i128 = (*integer).try_into().unwrap(); - format!("{}", i) - } - Value::Bytes(bytes) => hex::encode(bytes), - Value::Float(float) => { - format!("{}", 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) - } else { - text.clone() - } - } - Value::Bool(b) => { - format!("{}", b) - } - Value::Null => "None".to_string(), - Value::Tag(_, _) => "Tag".to_string(), - Value::Array(_) => "Array".to_string(), - Value::Map(_) => "Map".to_string(), - _ => "".to_string(), - } -} 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 9ae7a463a59..f1fbd820218 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -358,7 +358,7 @@ mod test { assert!(!contract.keeps_history()); assert!(!contract.readonly()); // the contract shouldn't be readonly assert!(!contract.documents_keep_history_contract_default()); - assert_eq!(contract.document_types().len(), 3); + assert_eq!(contract.document_types.len(), 3); assert!(contract.document_types().get("profile").is_some()); assert!( contract diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index 837e194b32e..9794423a9d7 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -1,10 +1,11 @@ use crate::data_contract::{property_names, DataContract}; use crate::prelude::Identifier; use crate::util::cbor_value::CborCanonicalMap; +use ciborium::Value as CborValue; 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::{Bytes32, Value}; diff --git a/packages/rs-dpp/src/data_contract/serialization/mod.rs b/packages/rs-dpp/src/data_contract/serialization/mod.rs index 823c250fd03..4f638470e9b 100644 --- a/packages/rs-dpp/src/data_contract/serialization/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialization/mod.rs @@ -1,2 +1,3 @@ pub mod bincode; +#[cfg(feature = "cbor")] pub mod cbor; diff --git a/packages/rs-dpp/src/decode_protocol_entity_factory.rs b/packages/rs-dpp/src/decode_protocol_entity_factory.rs index 5266d568d8a..6b935e1754c 100644 --- a/packages/rs-dpp/src/decode_protocol_entity_factory.rs +++ b/packages/rs-dpp/src/decode_protocol_entity_factory.rs @@ -1,4 +1,5 @@ use anyhow::anyhow; +#[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; use std::convert::TryInto; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 9e0dc970f4b..9e80d03ebed 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -37,6 +37,7 @@ use std::collections::{BTreeMap, HashSet}; use std::convert::TryInto; use std::fmt; +#[cfg(feature = "cbor")] use ciborium::Value as CborValue; use serde_json::{json, Value as JsonValue}; diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 18d84a06e27..d20491b0182 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -2,12 +2,14 @@ use crate::data_contract::{DataContract, DriveContractExt}; use crate::metadata::Metadata; use crate::prelude::Identifier; use crate::prelude::{Revision, TimestampMillis}; +#[cfg(feature = "cbor")] use crate::util::cbor_value::CborCanonicalMap; +#[cfg(feature = "cbor")] +use ciborium::Value as CborValue; use crate::util::deserializer; use crate::util::deserializer::{ProtocolVersion, SplitProtocolVersionOutcome}; use crate::util::hash::hash_to_vec; use crate::ProtocolError; -use ciborium::Value as CborValue; use integer_encoding::VarInt; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; @@ -261,7 +263,8 @@ impl ExtendedDocument { Ok(value) } - pub fn from_buffer(cbor_bytes: impl AsRef<[u8]>) -> Result { + #[cfg(feature = "cbor")] + pub fn from_cbor_buffer(cbor_bytes: impl AsRef<[u8]>) -> Result { let SplitProtocolVersionOutcome { protocol_version, main_message_bytes: document_cbor_bytes, @@ -574,7 +577,7 @@ mod test { let init_doc = new_example_document(); let buffer_document = init_doc.to_buffer().expect("no errors"); - let doc = ExtendedDocument::from_buffer(buffer_document) + let doc = ExtendedDocument::from_cbor_buffer(buffer_document) .expect("document should be created from buffer"); assert_eq!(init_doc.created_at(), doc.created_at()); @@ -631,7 +634,7 @@ mod test { fn deserialize_js_cpp_cbor() -> Result<()> { let document_cbor = document_cbor_bytes(); - let document = ExtendedDocument::from_buffer(document_cbor)?; + let document = ExtendedDocument::from_cbor_buffer(document_cbor)?; assert_eq!(document.protocol_version, 1); assert_eq!( @@ -666,7 +669,7 @@ mod test { #[test] fn to_buffer_serialize_to_the_same_format_as_js_dpp() -> Result<()> { let document_cbor = document_cbor_bytes(); - let document = ExtendedDocument::from_buffer(&document_cbor)?; + let document = ExtendedDocument::from_cbor_buffer(&document_cbor)?; let buffer = document.to_buffer()?; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 50c6a1ecc60..75ef5054e71 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -14,6 +14,7 @@ use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::ProtocolError; use byteorder::{BigEndian, ReadBytesExt}; +#[cfg(feature = "cbor")] use ciborium::Value as CborValue; use integer_encoding::VarIntWriter; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; @@ -325,6 +326,7 @@ impl Document { /// 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. + #[cfg(feature = "cbor")] pub fn from_cbor( document_cbor: &[u8], document_id: Option<[u8; 32]>, @@ -387,6 +389,7 @@ impl Document { } /// Serializes the Document to CBOR. + #[cfg(feature = "cbor")] pub fn to_cbor(&self) -> Result, ProtocolError> { let mut buffer: Vec = Vec::new(); buffer.write_varint(PROTOCOL_VERSION).map_err(|_| { 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 0964f03c008..7df88d8621a 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 @@ -3,6 +3,7 @@ use std::collections::{BTreeMap, HashMap}; use std::convert::{TryFrom, TryInto}; use anyhow::{anyhow, Context}; +#[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; use integer_encoding::VarInt; use platform_value::btreemap_extensions::BTreeValueMapHelper; @@ -16,6 +17,7 @@ use crate::data_contract::DataContract; use crate::document::document_transition::DocumentTransitionObjectLike; use crate::prelude::{DocumentTransition, Identifier}; +#[cfg(feature = "cbor")] use crate::util::cbor_value::{CborCanonicalMap, FieldType, ReplacePaths, ValuesCollection}; use crate::util::json_value::JsonValueExt; use crate::version::LATEST_VERSION; @@ -401,6 +403,7 @@ impl StateTransitionConvert for DocumentsBatchTransition { Ok(object) } + #[cfg(feature = "cbor")] fn to_cbor_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { let mut result_buf = self.protocol_version.encode_var_vec(); let value: CborValue = self.to_object(skip_signature)?.try_into()?; diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 0f289fb63b0..417b81f9cd6 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::convert::{TryFrom, TryInto}; use std::hash::{Hash, Hasher}; -use ciborium::value::Value as CborValue; + use integer_encoding::VarInt; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; @@ -11,7 +11,10 @@ use serde_json::Value as JsonValue; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; use crate::identity::{identity_public_key, KeyType, Purpose, SecurityLevel}; use crate::prelude::Revision; +#[cfg(feature = "cbor")] use crate::util::cbor_value::{CborBTreeMapHelper, CborCanonicalMap}; +#[cfg(feature = "cbor")] +use ciborium::value::Value as CborValue; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::{ @@ -295,6 +298,7 @@ impl Identity { Self::from_cbor(b.as_ref()) } + #[cfg(feature = "cbor")] pub fn from_cbor(identity_cbor: &[u8]) -> Result { let SplitProtocolVersionOutcome { protocol_version, diff --git a/packages/rs-dpp/src/identity/identity_public_key/key_type.rs b/packages/rs-dpp/src/identity/identity_public_key/key_type.rs index 50f2c6a1a45..52b2fd72187 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/key_type.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/key_type.rs @@ -1,6 +1,7 @@ use crate::util::hash::ripemd160_sha256; use anyhow::bail; use bincode::{Decode, Encode}; +#[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; use dashcore::secp256k1::rand::rngs::StdRng as EcdsaRng; use dashcore::secp256k1::rand::SeedableRng; 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 71efda21675..fd19ea51df8 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -9,6 +9,7 @@ pub mod serialize; use std::convert::{TryFrom, TryInto}; use anyhow::anyhow; +#[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; use dashcore::PublicKey as ECDSAPublicKey; use platform_value::{BinaryData, ReplacementType, Value, ValueMapHelper}; @@ -19,6 +20,7 @@ use crate::errors::{InvalidVectorSizeError, ProtocolError}; pub use crate::identity::key_type::KeyType; pub use crate::identity::purpose::Purpose; pub use crate::identity::security_level::SecurityLevel; +#[cfg(feature = "cbor")] use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; use crate::util::hash::ripemd160_sha256; use crate::util::{serializer, vec}; @@ -202,6 +204,7 @@ impl IdentityPublicKey { }) } + #[cfg(feature = "cbor")] pub fn to_cbor_value(&self) -> CborValue { let mut pk_map = CborCanonicalMap::new(); @@ -219,6 +222,7 @@ impl IdentityPublicKey { } } +#[cfg(feature = "cbor")] impl Into for &IdentityPublicKey { fn into(self) -> CborValue { self.to_cbor_value() diff --git a/packages/rs-dpp/src/identity/identity_public_key/purpose.rs b/packages/rs-dpp/src/identity/identity_public_key/purpose.rs index a818c92843f..f66d17e3541 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/purpose.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/purpose.rs @@ -1,6 +1,7 @@ use crate::identity::Purpose::{AUTHENTICATION, DECRYPTION, ENCRYPTION, SYSTEM, WITHDRAW}; use anyhow::bail; use bincode::{Decode, Encode}; +#[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; use serde_repr::{Deserialize_repr, Serialize_repr}; use std::convert::TryFrom; diff --git a/packages/rs-dpp/src/identity/identity_public_key/security_level.rs b/packages/rs-dpp/src/identity/identity_public_key/security_level.rs index 5737e1cb217..84752224a67 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/security_level.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/security_level.rs @@ -1,6 +1,7 @@ use super::purpose::Purpose; use anyhow::bail; use bincode::{Decode, Encode}; +#[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; use lazy_static::lazy_static; use serde_repr::{Deserialize_repr, Serialize_repr}; 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 ada37c54d95..fb273e7b9d7 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 @@ -9,6 +9,7 @@ use serde::ser::Error as SerError; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use crate::prelude::Identifier; +#[cfg(feature = "cbor")] use crate::util::cbor_value::CborCanonicalMap; use crate::util::hash::hash_to_vec; use crate::util::vec::vec_to_array; @@ -126,7 +127,8 @@ impl InstantAssetLockProof { Ok(Identifier::new(vec_to_array(&buffer)?)) } - pub fn to_buffer(&self) -> Result, ProtocolError> { + #[cfg(feature = "cbor")] + pub fn to_cbor_buffer(&self) -> Result, ProtocolError> { let mut map = CborCanonicalMap::new(); let mut is_lock_buffer = Vec::::new(); let mut transaction_buffer = Vec::::new(); diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs index af98b977101..7ec0ecfcce1 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs @@ -1,5 +1,6 @@ mod serialize; use crate::identity::{IdentityPublicKey, KeyID, KeyType, Purpose, SecurityLevel}; +#[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; use dashcore::signer; use std::collections::BTreeMap; @@ -18,6 +19,7 @@ use crate::consensus::ConsensusError; use crate::errors::ProtocolError; use crate::identity::signer::Signer; use crate::state_transition::errors::InvalidIdentityPublicKeyTypeError; +#[cfg(feature = "cbor")] use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; use crate::util::vec; use crate::validation::SimpleConsensusValidationResult; @@ -323,6 +325,7 @@ impl IdentityPublicKeyInCreationWithWitness { }) } + #[cfg(feature = "cbor")] pub fn to_cbor_value(&self) -> CborValue { let mut pk_map = CborCanonicalMap::new(); 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 47048c98feb..8d32bf613d1 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -8,7 +8,6 @@ use serde_json::Value as JsonValue; use crate::consensus::ConsensusError; use crate::errors::consensus::signature::SignatureError; -use crate::identity::signer::Signer; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, StateTransitionIsNotSignedError, diff --git a/packages/rs-dpp/src/util/mod.rs b/packages/rs-dpp/src/util/mod.rs index 23269436dc4..2f518f11724 100644 --- a/packages/rs-dpp/src/util/mod.rs +++ b/packages/rs-dpp/src/util/mod.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "cbor")] pub mod cbor_value; pub mod deserializer; pub mod entropy_generator; diff --git a/packages/rs-dpp/src/validation/validation_result.rs b/packages/rs-dpp/src/validation/validation_result.rs index e65a6dbd07b..15707f3ed3e 100644 --- a/packages/rs-dpp/src/validation/validation_result.rs +++ b/packages/rs-dpp/src/validation/validation_result.rs @@ -1,6 +1,5 @@ use crate::errors::consensus::ConsensusError; use crate::ProtocolError; -use futures::StreamExt; use std::fmt::Debug; pub type SimpleConsensusValidationResult = ConsensusValidationResult<()>; From 1808f710c73e99deaeb9e85aea290f4c8f185455 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 22 Apr 2023 23:09:47 +0700 Subject: [PATCH 06/50] removed DriveContractExt --- packages/rs-dpp/Cargo.toml | 2 +- .../rs-dpp/src/data_contract/data_contract.rs | 19 ++ .../rs-dpp/src/data_contract/extra/common.rs | 1 + .../src/data_contract/extra/drive_api.rs | 226 ++---------------- packages/rs-dpp/src/data_contract/mod.rs | 1 - .../src/data_contract/serialization/cbor.rs | 26 +- packages/rs-dpp/src/document/document.rs | 18 +- .../rs-dpp/src/document/document_factory.rs | 2 +- .../rs-dpp/src/document/document_validator.rs | 2 +- .../rs-dpp/src/document/extended_document.rs | 2 +- .../basic/find_duplicates_by_indices.rs | 2 +- .../tests/fixtures/get_documents_fixture.rs | 2 +- .../src/drive/contract/estimation_costs.rs | 6 +- packages/rs-drive/src/drive/contract/mod.rs | 26 +- .../rs-drive/src/drive/document/delete.rs | 4 +- packages/rs-drive/src/query/mod.rs | 2 +- packages/rs-drive/tests/query_tests.rs | 104 ++++---- .../rs-drive/tests/query_tests_history.rs | 56 ++--- 18 files changed, 178 insertions(+), 323 deletions(-) diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 162a2ea5810..03b6499ed98 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -59,6 +59,6 @@ tokio = { version = "1.17", features = ["full"] } pretty_assertions = { version = "1.3.0" } [features] -default = ["fixtures-and-mocks"] +default = ["fixtures-and-mocks", "cbor"] cbor = ["ciborium"] fixtures-and-mocks = ["mockall"] diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index fe0097a6fc2..e947f31760a 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -481,6 +481,25 @@ impl DataContract { }) .unwrap_or_default()) } + + pub fn optional_document_type_for_name(&self, document_type_name: &str) -> Option<&DocumentType> { + self.document_types.get(document_type_name) + } + + pub fn document_type_for_name( + &self, + document_type_name: &str, + ) -> Result<&DocumentType, ProtocolError> { + self.document_types.get(document_type_name).ok_or({ + ProtocolError::DataContractError(DataContractError::DocumentTypeNotFound( + "can not get document type from contract", + )) + }) + } + + pub fn has_document_type_for_name(&self, document_type_name: &str) -> bool { + self.document_types.get(document_type_name).is_some() + } } impl TryFrom for DataContract { diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index 1a1408dc2f8..a60dd22d145 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -8,6 +8,7 @@ use std::convert::TryInto; use std::fs::File; use std::io::BufReader; use std::path::Path; +use platform_value::Identifier; /// Reads a JSON file and converts it to serde_value. pub fn json_document_to_json_value( 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 f1fbd820218..8ad7cead638 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -9,189 +9,6 @@ use crate::ProtocolError; use crate::data_contract::contract_config; use crate::data_contract::errors::DataContractError; -pub enum DriveEncoding { - DriveCbor, - DriveProtobuf, -} - -/// The traits provides method specific for RS-Drive -pub trait DriveContractExt { - fn id(&self) -> &[u8; 32]; - - fn document_types(&self) -> &BTreeMap; - fn document_types_mut(&mut self) -> &mut BTreeMap; - fn set_document_types(&mut self, document_types: BTreeMap); - - fn keeps_history(&self) -> bool; - fn set_keeps_history(&mut self, value: bool); - - fn can_be_deleted(&self) -> bool; - fn set_can_be_deleted(&mut self, can_be_deleted: bool); - - fn readonly(&self) -> bool; - fn set_readonly(&mut self, is_read_only: bool); - - fn documents_keep_history_contract_default(&self) -> bool; - fn set_documents_keep_history_contract_default(&mut self, value: bool); - - fn documents_mutable_contract_default(&self) -> bool; - fn set_documents_mutable_contract_default(&mut self, value: bool); - - fn deserialize( - serialized_contract: &[u8], - contract_id: Option<[u8; 32]>, - encoding: DriveEncoding, - ) -> Result - where - Self: Sized; - - fn from_cbor( - contract_cbor: &[u8], - contract_id: Option<[u8; 32]>, - ) -> Result - where - Self: Sized; - - fn to_cbor(&self) -> Result, ProtocolError>; - fn optional_document_type_for_name(&self, document_type_name: &str) -> Option<&DocumentType>; - - fn document_type_for_name( - &self, - document_type_name: &str, - ) -> Result<&DocumentType, ProtocolError>; - fn has_document_type_for_name(&self, document_type_name: &str) -> bool; -} - -impl DriveContractExt for DataContract { - fn id(&self) -> &[u8; 32] { - &self.id.0 .0 - } - fn document_types(&self) -> &BTreeMap { - &self.document_types - } - fn document_types_mut(&mut self) -> &mut BTreeMap { - &mut self.document_types - } - fn set_document_types(&mut self, document_types: BTreeMap) { - self.document_types = document_types - } - - fn keeps_history(&self) -> bool { - self.config.keeps_history - } - - fn set_keeps_history(&mut self, value: bool) { - self.config.keeps_history = value - } - - fn can_be_deleted(&self) -> bool { - self.config.can_be_deleted - } - fn set_can_be_deleted(&mut self, can_be_deleted: bool) { - self.config.can_be_deleted = can_be_deleted; - } - - fn readonly(&self) -> bool { - self.config.readonly - } - fn set_readonly(&mut self, is_read_only: bool) { - self.config.readonly = is_read_only; - } - - fn documents_keep_history_contract_default(&self) -> bool { - self.config.documents_keep_history_contract_default - } - fn set_documents_keep_history_contract_default(&mut self, value: bool) { - self.config.documents_keep_history_contract_default = value; - } - - fn documents_mutable_contract_default(&self) -> bool { - self.config.documents_mutable_contract_default - } - fn set_documents_mutable_contract_default(&mut self, value: bool) { - self.config.documents_mutable_contract_default = value - } - - fn deserialize( - serialized_contract: &[u8], - contract_id: Option<[u8; 32]>, - encoding: DriveEncoding, - ) -> Result - where - Self: Sized, - { - let mut data_contract = match encoding { - DriveEncoding::DriveCbor => DataContract::from_cbor(serialized_contract)?, - DriveEncoding::DriveProtobuf => { - todo!() - } - }; - if let Some(id) = contract_id { - data_contract.id = Identifier::new(id) - } - Ok(data_contract) - } - - fn from_cbor(contract_cbor: &[u8], contract_id: Option<[u8; 32]>) -> Result - where - Self: Sized, - { - let mut data_contract = DataContract::from_cbor(contract_cbor)?; - if let Some(id) = contract_id { - data_contract.id = Identifier::from(id) - } - - Ok(data_contract) - } - - /// `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 contract_cbor_map = self.to_cbor_canonical_map()?; - - contract_cbor_map.insert(contract_config::property::READONLY, self.readonly()); - contract_cbor_map.insert( - contract_config::property::KEEPS_HISTORY, - self.keeps_history(), - ); - contract_cbor_map.insert( - contract_config::property::DOCUMENTS_KEEP_HISTORY_CONTRACT_DEFAULT, - self.documents_keep_history_contract_default(), - ); - contract_cbor_map.insert( - contract_config::property::DOCUMENTS_MUTABLE_CONTRACT_DEFAULT, - self.documents_mutable_contract_default(), - ); - - let mut contract_buf = contract_cbor_map - .to_bytes() - .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - - buf.append(&mut contract_buf); - Ok(buf) - } - - fn optional_document_type_for_name(&self, document_type_name: &str) -> Option<&DocumentType> { - self.document_types.get(document_type_name) - } - - fn document_type_for_name( - &self, - document_type_name: &str, - ) -> Result<&DocumentType, ProtocolError> { - self.document_types.get(document_type_name).ok_or({ - ProtocolError::DataContractError(DataContractError::DocumentTypeNotFound( - "can not get document type from contract", - )) - }) - } - - fn has_document_type_for_name(&self, document_type_name: &str) -> bool { - self.document_types.get(document_type_name).is_some() - } -} #[cfg(test)] mod test { @@ -354,39 +171,39 @@ mod test { json_document_to_contract("src/tests/payloads/contract/dashpay-contract.json") .expect("expected to get a contract"); - assert!(contract.documents_mutable_contract_default()); - assert!(!contract.keeps_history()); - assert!(!contract.readonly()); // the contract shouldn't be readonly - assert!(!contract.documents_keep_history_contract_default()); + assert!(contract.config.documents_mutable_contract_default); + assert!(!contract.config.keeps_history); + assert!(!contract.config.readonly); // the contract shouldn't be readonly + assert!(!contract.config.documents_keep_history_contract_default); assert_eq!(contract.document_types.len(), 3); - assert!(contract.document_types().get("profile").is_some()); + assert!(contract.document_types.get("profile").is_some()); assert!( contract - .document_types() + .document_types .get("profile") .unwrap() .documents_mutable ); - assert!(contract.document_types().get("contactInfo").is_some()); + assert!(contract.document_types.get("contactInfo").is_some()); assert!( contract - .document_types() + .document_types .get("contactInfo") .unwrap() .documents_mutable ); - assert!(contract.document_types().get("contactRequest").is_some()); + assert!(contract.document_types.get("contactRequest").is_some()); assert!( !contract - .document_types() + .document_types .get("contactRequest") .unwrap() .documents_mutable ); - assert!(contract.document_types().get("non_existent_key").is_none()); + assert!(contract.document_types.get("non_existent_key").is_none()); let contact_info_indices = &contract - .document_types() + .document_types .get("contactInfo") .unwrap() .indices; @@ -415,18 +232,17 @@ mod test { .expect("expected to get a cbor document"); let mut contract = DataContract::from_cbor(dashpay_cbor).unwrap(); - assert!(!contract.readonly()); - assert!(!contract.keeps_history()); - assert!(contract.documents_mutable_contract_default()); - assert!(!contract.documents_keep_history_contract_default()); + assert!(!contract.config.readonly); + assert!(!contract.config.keeps_history); + assert!(contract.config.documents_mutable_contract_default); + assert!(!contract.config.documents_keep_history_contract_default); - contract.set_readonly(true); - contract.set_keeps_history(true); - contract.set_documents_mutable_contract_default(false); - contract.set_documents_keep_history_contract_default(true); + contract.config.readonly = true; + contract.config.keeps_history = true; + contract.config.documents_mutable_contract_default = false; + contract.config.documents_keep_history_contract_default = true; - let contract_cbor = - DriveContractExt::to_cbor(&contract).expect("serialization shouldn't fail"); + let contract_cbor = contract.to_cbor().expect("serialization shouldn't fail"); let deserialized_contract = DataContract::from_cbor(contract_cbor).expect("deserialization shouldn't fail"); diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index 21dc7073e5a..5f591a1ee60 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -7,7 +7,6 @@ pub mod errors; pub mod extra; mod data_contract_facade; -pub use extra::drive_api::DriveContractExt; pub mod contract_config; mod data_contract_factory; diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index 9794423a9d7..bbc4a8ed6cb 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -1,4 +1,4 @@ -use crate::data_contract::{property_names, DataContract}; +use crate::data_contract::{property_names, DataContract, contract_config}; use crate::prelude::Identifier; use crate::util::cbor_value::CborCanonicalMap; use ciborium::Value as CborValue; @@ -13,6 +13,13 @@ use serde_json::Value as JsonValue; use std::collections::BTreeMap; impl DataContract { + pub fn from_cbor_with_id(cbor_bytes: impl AsRef<[u8]>, contract_id: Option) -> Result { + let mut data_contract = Self::from_cbor(cbor_bytes)?; + if let Some(id) = contract_id { + data_contract.id = id; + } + Ok(data_contract) + } pub fn from_cbor(cbor_bytes: impl AsRef<[u8]>) -> Result { let SplitProtocolVersionOutcome { protocol_version, @@ -80,7 +87,22 @@ impl DataContract { 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_cbor_map = self.to_cbor_canonical_map()?; + + contract_cbor_map.insert(contract_config::property::READONLY, self.config.readonly); + contract_cbor_map.insert( + contract_config::property::KEEPS_HISTORY, + self.config.keeps_history, + ); + contract_cbor_map.insert( + contract_config::property::DOCUMENTS_KEEP_HISTORY_CONTRACT_DEFAULT, + self.config.documents_keep_history_contract_default, + ); + contract_cbor_map.insert( + contract_config::property::DOCUMENTS_MUTABLE_CONTRACT_DEFAULT, + self.config.documents_mutable_contract_default, + ); + let mut contract_buf = contract_cbor_map .to_bytes() .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 9e80d03ebed..e295a447394 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -41,7 +41,7 @@ use std::fmt; use ciborium::Value as CborValue; use serde_json::{json, Value as JsonValue}; -use crate::data_contract::{DataContract, DriveContractExt}; +use crate::data_contract::DataContract; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; @@ -138,7 +138,7 @@ impl Document { contract: &DataContract, owner_id: Option<[u8; 32]>, ) -> Result>, ProtocolError> { - let document_type = contract.document_types().get(document_type_name).ok_or({ + let document_type = contract.document_types.get(document_type_name).ok_or({ ProtocolError::DataContractError(DataContractError::DocumentTypeNotFound( "document type should exist for name", )) @@ -433,7 +433,7 @@ impl fmt::Display for Document { mod tests { use super::*; use crate::data_contract::document_type::random_document::CreateRandomDocument; - use crate::data_contract::extra::common::json_document_to_cbor; + use crate::data_contract::extra::common::{json_document_to_cbor, json_document_to_contract}; use regex::Regex; #[test] @@ -443,7 +443,7 @@ mod tests { Some(1), ) .expect("expected to get cbor contract"); - let contract = ::from_cbor(&dashpay_cbor, None).unwrap(); + let contract = DataContract::from_cbor(&dashpay_cbor).unwrap(); let document_type = contract .document_type_for_name("contactRequest") @@ -476,7 +476,7 @@ mod tests { Some(1), ) .expect("expected to get cbor contract"); - let contract = ::from_cbor(&dashpay_cbor, None).unwrap(); + let contract = DataContract::from_cbor(&dashpay_cbor).unwrap(); let document_type = contract .document_type_for_name("profile") @@ -493,12 +493,10 @@ mod tests { #[test] fn test_document_display() { - let dashpay_cbor = json_document_to_cbor( - "../rs-dpp/src/tests/payloads/contract/dashpay-contract.json", - Some(1), + let contract = json_document_to_contract( + "../rs-dpp/src/tests/payloads/contract/dashpay-contract.json" ) - .expect("expected to get cbor contract"); - let contract = ::from_cbor(&dashpay_cbor, None).unwrap(); + .expect("expected to get contract"); let document_type = contract .document_type_for_name("profile") diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 2ac6d2d380e..19d63b2d185 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -13,7 +13,7 @@ use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::document::extended_document::{property_names, ExtendedDocument}; use crate::data_contract::document_type::DocumentType; -use crate::data_contract::DriveContractExt; + use crate::document::document_transition::INITIAL_REVISION; use crate::document::Document; use crate::identity::TimestampMillis; diff --git a/packages/rs-dpp/src/document/document_validator.rs b/packages/rs-dpp/src/document/document_validator.rs index 3fac04cfe28..35fa416a193 100644 --- a/packages/rs-dpp/src/document/document_validator.rs +++ b/packages/rs-dpp/src/document/document_validator.rs @@ -7,7 +7,7 @@ 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::validation::SimpleConsensusValidationResult; use crate::{ consensus::basic::BasicError, diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index d20491b0182..09c21efc261 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, DriveContractExt}; +use crate::data_contract::DataContract; use crate::metadata::Metadata; use crate::prelude::Identifier; use crate::prelude::{Revision, TimestampMillis}; 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 4cdcff92d33..e705b44e754 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 @@ -3,7 +3,7 @@ use platform_value::{Value, ValueMap}; use std::collections::btree_map::Entry; use std::collections::BTreeMap; -use crate::data_contract::DriveContractExt; + use crate::{ document::document_transition::DocumentTransition, prelude::DataContract, util::json_schema::Index, ProtocolError, 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 895e9e3af3b..cced0e230aa 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_documents_fixture.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use platform_value::{platform_value, Value}; use crate::contracts::withdrawals_contract::document_types; -use crate::data_contract::DriveContractExt; + use crate::document::Document; use crate::{ document::{ diff --git a/packages/rs-drive/src/drive/contract/estimation_costs.rs b/packages/rs-drive/src/drive/contract/estimation_costs.rs index dfd7f0a7839..bdd456672ca 100644 --- a/packages/rs-drive/src/drive/contract/estimation_costs.rs +++ b/packages/rs-drive/src/drive/contract/estimation_costs.rs @@ -27,13 +27,13 @@ impl Drive { ); // we only store the owner_id storage - let storage_flags = if contract.can_be_deleted() || !contract.readonly() { + let storage_flags = if contract.can_be_deleted() || !contract.config.readonly { Some(StorageFlags::approximate_size(true, None)) } else { None }; - for document_type_name in contract.document_types().keys() { + for document_type_name in contract.document_types.keys() { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(contract_document_type_path( contract.id.as_bytes(), @@ -51,7 +51,7 @@ impl Drive { ); } - if contract.keeps_history() { + if contract.config.keeps_history { // we are dealing with a sibling reference // sibling reference serialized size is going to be the encoded time size // (DEFAULT_FLOAT_SIZE) plus 1 byte for reference type and 1 byte for the space of diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 0be3e88846e..3108fd5d958 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -152,7 +152,7 @@ impl Drive { insert_operations: &mut Vec, ) -> Result<(), Error> { let contract_root_path = paths::contract_root_path(contract.id.as_bytes()); - if contract.keeps_history() { + if contract.config.keeps_history { let element_flags = contract_element.get_flags().clone(); let storage_flags = StorageFlags::map_cow_some_element_flags_ref(contract_element.get_flags())?; @@ -229,7 +229,7 @@ impl Drive { let contract = ::from_cbor(&contract_cbor, contract_id)?; - let storage_flags = if contract.can_be_deleted() || !contract.readonly() { + let storage_flags = if contract.can_be_deleted() || !contract.config.readonly { Some(StorageFlags::new_single_epoch( block_info.epoch.index, Some(contract.owner_id.to_buffer()), @@ -354,7 +354,7 @@ impl Drive { // toDo: change this to be a reference by index let contract_documents_path = contract_documents_path(contract.id.as_bytes()); - for (type_key, document_type) in contract.document_types() { + for (type_key, document_type) in contract.document_types { self.batch_insert_empty_tree( contract_documents_path, KeyRef(type_key.as_bytes()), @@ -452,7 +452,7 @@ impl Drive { "contract should exist", )))?; - if original_contract_fetch_info.contract.readonly() { + if original_contract_fetch_info.contract.config.readonly { return Err(Error::Drive(DriveError::UpdatingReadOnlyImmutableContract( "original contract is readonly", ))); @@ -554,26 +554,26 @@ impl Drive { transaction: TransactionArg, ) -> Result, Error> { let mut batch_operations: Vec = vec![]; - if original_contract.readonly() { + if original_contract.config.readonly { return Err(Error::Drive(DriveError::UpdatingReadOnlyImmutableContract( "contract is readonly", ))); } - if contract.readonly() { + if contract.config.readonly { return Err(Error::Drive(DriveError::ChangingContractToReadOnly( "contract can not be changed to readonly", ))); } - if contract.keeps_history() ^ original_contract.keeps_history() { + if contract.config.keeps_history ^ original_contract.config.keeps_history { return Err(Error::Drive(DriveError::ChangingContractKeepsHistory( "contract can not change whether it keeps history", ))); } - if contract.documents_keep_history_contract_default() - ^ original_contract.documents_keep_history_contract_default() + if contract.config.documents_keep_history_contract_default + ^ original_contract.config.documents_keep_history_contract_default { return Err(Error::Drive( DriveError::ChangingContractDocumentsKeepsHistoryDefault( @@ -582,8 +582,8 @@ impl Drive { )); } - if contract.documents_mutable_contract_default() - ^ original_contract.documents_mutable_contract_default() + if contract.config.documents_mutable_contract_default + ^ original_contract.config.documents_mutable_contract_default { return Err(Error::Drive( DriveError::ChangingContractDocumentsMutabilityDefault( @@ -606,8 +606,8 @@ impl Drive { let storage_flags = StorageFlags::map_cow_some_element_flags_ref(&element_flags)?; let contract_documents_path = contract_documents_path(contract.id.as_bytes()); - for (type_key, document_type) in contract.document_types() { - let original_document_type = &original_contract.document_types().get(type_key); + for (type_key, document_type) in contract.document_types { + let original_document_type = &original_contract.document_types.get(type_key); if let Some(original_document_type) = original_document_type { if original_document_type.documents_mutable ^ document_type.documents_mutable { return Err(Error::Drive(DriveError::ChangingDocumentTypeMutability( diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 8c99d79d7f3..9968d7d9f80 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -1736,7 +1736,7 @@ mod tests { let (results, _, _) = drive .query_documents_cbor_from_contract( &contract, - contract.document_types().get("niceDocument").unwrap(), + contract.document_types.get("niceDocument").unwrap(), query_cbor.as_slice(), None, None, @@ -1771,7 +1771,7 @@ mod tests { let (results, _, _) = drive .query_documents_cbor_from_contract( &contract, - contract.document_types().get("niceDocument").unwrap(), + contract.document_types.get("niceDocument").unwrap(), query_cbor.as_slice(), None, Some(&db_transaction), diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 1e9d1064235..7312fdc0f22 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -547,7 +547,7 @@ impl<'a> DriveQuery<'a> { let document_type = contract - .document_types() + .document_types .get(document_type_name) .ok_or(Error::Query(QueryError::DocumentTypeNotFound( "document type not found in contract", diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index c572995ee3d..99bd26949cd 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -715,7 +715,7 @@ fn test_reference_proof_single_index() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -757,7 +757,7 @@ fn test_non_existence_reference_proof_single_index() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -819,7 +819,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -862,7 +862,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -902,7 +902,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -958,7 +958,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1001,7 +1001,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1052,7 +1052,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1092,7 +1092,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1134,7 +1134,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1186,7 +1186,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1233,7 +1233,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1281,7 +1281,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1337,7 +1337,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1381,7 +1381,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1437,7 +1437,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1492,7 +1492,7 @@ fn test_family_basic_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1674,7 +1674,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1717,7 +1717,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1757,7 +1757,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1793,7 +1793,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1820,7 +1820,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1861,7 +1861,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1891,7 +1891,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1957,7 +1957,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1987,7 +1987,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -2017,7 +2017,7 @@ fn test_family_basic_queries() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -2099,7 +2099,7 @@ fn test_family_starts_at_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -2154,7 +2154,7 @@ fn test_family_starts_at_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -2203,7 +2203,7 @@ fn test_family_starts_at_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -2258,7 +2258,7 @@ fn test_family_starts_at_queries() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -2303,7 +2303,7 @@ fn test_family_sql_query() { // produce the correct result set let (_, contract) = setup_family_tests(10, 73509); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -2485,7 +2485,7 @@ fn test_family_with_nulls_query() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -2662,7 +2662,7 @@ fn test_dpns_query() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -2709,7 +2709,7 @@ fn test_dpns_query() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -2784,7 +2784,7 @@ fn test_dpns_query() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -2838,7 +2838,7 @@ fn test_dpns_query() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -2909,7 +2909,7 @@ fn test_dpns_query() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -2961,7 +2961,7 @@ fn test_dpns_query() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -3005,7 +3005,7 @@ fn test_dpns_query() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -3040,7 +3040,7 @@ fn test_dpns_insertion_no_aliases() { .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); @@ -3093,7 +3093,7 @@ fn test_dpns_insertion_with_aliases() { .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); @@ -3182,7 +3182,7 @@ fn test_dpns_query_start_at() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -3270,7 +3270,7 @@ fn test_dpns_query_start_after() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -3358,7 +3358,7 @@ fn test_dpns_query_start_at_desc() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -3446,7 +3446,7 @@ fn test_dpns_query_start_after_desc() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -3641,7 +3641,7 @@ fn test_dpns_query_start_at_with_null_id() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -3846,7 +3846,7 @@ fn test_dpns_query_start_after_with_null_id() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -4063,7 +4063,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -4112,7 +4112,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -4161,7 +4161,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract - .document_types() + .document_types .get("domain") .expect("contract should have a domain document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, domain_document_type) @@ -4312,7 +4312,7 @@ fn test_query_a_b_c_d_e_contract() { .query_documents_cbor_from_contract( &contract, contract - .document_types() + .document_types .get(&document_type) .expect("should have this document type"), &query_cbor, diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 870b3f4f8f4..3fa86d11d9e 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -322,7 +322,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -360,7 +360,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -389,7 +389,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -433,7 +433,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -464,7 +464,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -503,7 +503,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -531,7 +531,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -561,7 +561,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -607,7 +607,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -649,7 +649,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -725,7 +725,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -775,7 +775,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -819,7 +819,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -857,7 +857,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -928,7 +928,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -978,7 +978,7 @@ fn test_query_historical() { let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); let query = DriveQuery::from_cbor(where_cbor.as_slice(), &contract, person_document_type) @@ -1156,7 +1156,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1182,7 +1182,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1209,7 +1209,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1238,7 +1238,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1279,7 +1279,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1316,7 +1316,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1343,7 +1343,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1395,7 +1395,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1449,7 +1449,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1479,7 +1479,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1546,7 +1546,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); @@ -1576,7 +1576,7 @@ fn test_query_historical() { .expect("expected to serialize to cbor"); let person_document_type = contract - .document_types() + .document_types .get("person") .expect("contract should have a person document type"); From fd14239e1b8f17e566fe5c000d0f9845f1e18698 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 22 Apr 2023 23:34:35 +0700 Subject: [PATCH 07/50] more cleanup --- .../rs-dpp/src/data_contract/data_contract.rs | 7 +- .../document_type/document_type.rs | 4 +- .../rs-dpp/src/data_contract/extra/common.rs | 8 +- .../src/data_contract/extra/drive_api.rs | 7 +- .../src/data_contract/serialization/cbor.rs | 19 +++-- packages/rs-dpp/src/document/document.rs | 12 +-- .../rs-dpp/src/document/extended_document.rs | 4 +- .../basic/find_duplicates_by_indices.rs | 1 - packages/rs-dpp/src/identity/identity.rs | 5 +- packages/rs-drive-abci/src/abci/handlers.rs | 2 +- .../src/contracts/reward_shares.rs | 1 - .../data_trigger/dpns_triggers/mod.rs | 2 +- .../reward_share_data_triggers/mod.rs | 1 - .../withdrawals_data_triggers/mod.rs | 2 +- .../src/identity_credit_withdrawal/mod.rs | 7 +- .../src/platform/state_repository.rs | 1 - packages/rs-drive-abci/src/state/genesis.rs | 1 - .../src/test/helpers/fee_pools.rs | 1 - .../fetch_documents.rs | 2 +- ...lidate_documents_batch_transition_state.rs | 2 +- .../tests/strategy_tests/main.rs | 74 ++++++------------- packages/rs-drive/benches/benchmarks.rs | 21 ++---- packages/rs-drive/src/common/mod.rs | 23 ++---- .../drive/batch/drive_op_batch/contract.rs | 9 ++- .../drive/batch/drive_op_batch/document.rs | 21 +++--- .../src/drive/batch/drive_op_batch/mod.rs | 31 +++----- .../document/document_create_transition.rs | 2 +- .../src/drive/contract/estimation_costs.rs | 4 +- packages/rs-drive/src/drive/contract/mod.rs | 34 +++++---- .../rs-drive/src/drive/document/delete.rs | 6 +- .../src/drive/document/estimation_costs.rs | 3 +- .../rs-drive/src/drive/document/insert.rs | 8 +- .../rs-drive/src/drive/document/update.rs | 16 ++-- .../rs-drive/src/drive/estimation_costs.rs | 4 +- .../drive/identity/withdrawals/documents.rs | 6 +- packages/rs-drive/src/drive/mod.rs | 3 - packages/rs-drive/src/drive/query/mod.rs | 4 +- packages/rs-drive/src/query/mod.rs | 17 ++--- .../rs-drive/tests/deterministic_root_hash.rs | 2 - packages/rs-drive/tests/query_tests.rs | 2 +- .../rs-drive/tests/query_tests_history.rs | 2 - packages/wasm-dpp/src/document/mod.rs | 2 +- 42 files changed, 159 insertions(+), 224 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index e947f31760a..2f42c96eba5 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -128,7 +128,7 @@ pub struct DataContract { pub metadata: Option, /// Internal configuration for the contract. - pub(crate) config: ContractConfig, + pub config: ContractConfig, /// A mapping of document names to their corresponding JSON schemas. pub documents: BTreeMap, @@ -482,7 +482,10 @@ impl DataContract { .unwrap_or_default()) } - pub fn optional_document_type_for_name(&self, document_type_name: &str) -> Option<&DocumentType> { + pub fn optional_document_type_for_name( + &self, + document_type_name: &str, + ) -> Option<&DocumentType> { self.document_types.get(document_type_name) } 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 03618b8cccb..45994c9a934 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 @@ -12,9 +12,7 @@ use crate::document::document_transition::INITIAL_REVISION; use crate::document::Document; use crate::prelude::Revision; use crate::ProtocolError; -use platform_value::btreemap_extensions::{ - BTreeValueMapHelper, BTreeValueRemoveFromMapHelper, -}; +use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; use platform_value::{Identifier, ReplacementType, Value}; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index a60dd22d145..72122231321 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -4,11 +4,11 @@ use crate::prelude::DataContract; use crate::util::serializer::serializable_value_to_cbor; use crate::ProtocolError; use crate::ProtocolError::ValueError; +use platform_value::Identifier; use std::convert::TryInto; use std::fs::File; use std::io::BufReader; use std::path::Path; -use platform_value::Identifier; /// Reads a JSON file and converts it to serde_value. pub fn json_document_to_json_value( @@ -67,11 +67,15 @@ pub fn json_document_to_contract(path: impl AsRef) -> Result, + id: Option, owner_id: Option, ) -> Result { let mut value = json_document_to_platform_value(path)?; + if let Some(id) = id { + value.set_value("$id", platform_value::Value::Identifier(id.into_buffer()))?; + } if let Some(owner_id) = owner_id { value.set_value( "$ownerId", 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 8ad7cead638..7d2f52651d9 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -9,7 +9,6 @@ use crate::ProtocolError; use crate::data_contract::contract_config; use crate::data_contract::errors::DataContractError; - #[cfg(test)] mod test { use crate::data_contract::contract_config::ContractConfig; @@ -202,11 +201,7 @@ mod test { ); assert!(contract.document_types.get("non_existent_key").is_none()); - let contact_info_indices = &contract - .document_types - .get("contactInfo") - .unwrap() - .indices; + let contact_info_indices = &contract.document_types.get("contactInfo").unwrap().indices; assert_eq!(contact_info_indices.len(), 2); assert!(contact_info_indices[0].unique); assert!(!contact_info_indices[1].unique); diff --git a/packages/rs-dpp/src/data_contract/serialization/cbor.rs b/packages/rs-dpp/src/data_contract/serialization/cbor.rs index bbc4a8ed6cb..bab9293e26a 100644 --- a/packages/rs-dpp/src/data_contract/serialization/cbor.rs +++ b/packages/rs-dpp/src/data_contract/serialization/cbor.rs @@ -1,10 +1,10 @@ -use crate::data_contract::{property_names, DataContract, contract_config}; +use crate::data_contract::{contract_config, property_names, DataContract}; use crate::prelude::Identifier; use crate::util::cbor_value::CborCanonicalMap; -use ciborium::Value as CborValue; 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; @@ -13,13 +13,16 @@ use serde_json::Value as JsonValue; use std::collections::BTreeMap; impl DataContract { - pub fn from_cbor_with_id(cbor_bytes: impl AsRef<[u8]>, contract_id: Option) -> Result { - let mut data_contract = Self::from_cbor(cbor_bytes)?; - if let Some(id) = contract_id { - data_contract.id = id; - } - Ok(data_contract) + pub fn from_cbor_with_id( + cbor_bytes: impl AsRef<[u8]>, + contract_id: Option, + ) -> Result { + let mut data_contract = Self::from_cbor(cbor_bytes)?; + if let Some(id) = contract_id { + data_contract.id = id; } + Ok(data_contract) + } pub fn from_cbor(cbor_bytes: impl AsRef<[u8]>) -> Result { let SplitProtocolVersionOutcome { protocol_version, diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index e295a447394..a9e606d2579 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -438,12 +438,10 @@ mod tests { #[test] fn test_serialization() { - let dashpay_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "../rs-dpp/src/tests/payloads/contract/dashpay-contract.json", - Some(1), ) - .expect("expected to get cbor contract"); - let contract = DataContract::from_cbor(&dashpay_cbor).unwrap(); + .expect("expected to get dashpay contract"); let document_type = contract .document_type_for_name("contactRequest") @@ -471,12 +469,10 @@ mod tests { #[test] fn test_document_cbor_serialization() { - let dashpay_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "../rs-dpp/src/tests/payloads/contract/dashpay-contract.json", - Some(1), ) .expect("expected to get cbor contract"); - let contract = DataContract::from_cbor(&dashpay_cbor).unwrap(); let document_type = contract .document_type_for_name("profile") @@ -494,7 +490,7 @@ mod tests { #[test] fn test_document_display() { let contract = json_document_to_contract( - "../rs-dpp/src/tests/payloads/contract/dashpay-contract.json" + "../rs-dpp/src/tests/payloads/contract/dashpay-contract.json", ) .expect("expected to get contract"); diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 09c21efc261..62e9facca76 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -4,12 +4,12 @@ use crate::prelude::Identifier; use crate::prelude::{Revision, TimestampMillis}; #[cfg(feature = "cbor")] use crate::util::cbor_value::CborCanonicalMap; -#[cfg(feature = "cbor")] -use ciborium::Value as CborValue; use crate::util::deserializer; use crate::util::deserializer::{ProtocolVersion, SplitProtocolVersionOutcome}; use crate::util::hash::hash_to_vec; use crate::ProtocolError; +#[cfg(feature = "cbor")] +use ciborium::Value as CborValue; use integer_encoding::VarInt; use crate::data_contract::document_type::document_type::PROTOCOL_VERSION; 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 e705b44e754..41bbd80bd89 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 @@ -3,7 +3,6 @@ use platform_value::{Value, ValueMap}; use std::collections::btree_map::Entry; use std::collections::BTreeMap; - use crate::{ document::document_transition::DocumentTransition, prelude::DataContract, util::json_schema::Index, ProtocolError, diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 417b81f9cd6..5ae9e046f7d 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -2,7 +2,6 @@ use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::convert::{TryFrom, TryInto}; use std::hash::{Hash, Hasher}; - use integer_encoding::VarInt; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; @@ -13,14 +12,14 @@ use crate::identity::{identity_public_key, KeyType, Purpose, SecurityLevel}; use crate::prelude::Revision; #[cfg(feature = "cbor")] use crate::util::cbor_value::{CborBTreeMapHelper, CborCanonicalMap}; -#[cfg(feature = "cbor")] -use ciborium::value::Value as CborValue; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::{ errors::ProtocolError, identifier::Identifier, metadata::Metadata, util::hash, Convertible, }; use bincode::{Decode, Encode}; +#[cfg(feature = "cbor")] +use ciborium::value::Value as CborValue; use super::{IdentityPublicKey, KeyID}; diff --git a/packages/rs-drive-abci/src/abci/handlers.rs b/packages/rs-drive-abci/src/abci/handlers.rs index 4fbca1aac69..d73f47fcb23 100644 --- a/packages/rs-drive-abci/src/abci/handlers.rs +++ b/packages/rs-drive-abci/src/abci/handlers.rs @@ -467,7 +467,7 @@ where // use dashcore::hashes::hex::FromHex; // 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}; diff --git a/packages/rs-drive-abci/src/contracts/reward_shares.rs b/packages/rs-drive-abci/src/contracts/reward_shares.rs index 65e99a8e003..30b24674f5b 100644 --- a/packages/rs-drive-abci/src/contracts/reward_shares.rs +++ b/packages/rs-drive-abci/src/contracts/reward_shares.rs @@ -41,7 +41,6 @@ use crate::error::Error; use crate::platform::Platform; use dpp::block::block_info::BlockInfo; use drive::contract::Contract; -use drive::dpp::data_contract::DriveContractExt; use drive::dpp::document::Document; use drive::dpp::util::serializer; use drive::drive::flags::StorageFlags; diff --git a/packages/rs-drive-abci/src/execution/data_trigger/dpns_triggers/mod.rs b/packages/rs-drive-abci/src/execution/data_trigger/dpns_triggers/mod.rs index 952f334ae4a..9bec30a138a 100644 --- a/packages/rs-drive-abci/src/execution/data_trigger/dpns_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/data_trigger/dpns_triggers/mod.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use crate::error::execution::ExecutionError; use crate::error::Error; -use dpp::data_contract::DriveContractExt; + use dpp::document::document_transition::DocumentTransitionAction; use dpp::platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueMapPathHelper}; use dpp::platform_value::Value; diff --git a/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs index 4e08666410a..b6b7caaf2d8 100644 --- a/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs @@ -1,4 +1,3 @@ -use dpp::data_contract::DriveContractExt; use dpp::document::document_transition::DocumentTransitionAction; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; diff --git a/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs index 159f458177e..647f7135c9d 100644 --- a/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs @@ -1,7 +1,7 @@ use crate::error::execution::ExecutionError; use crate::error::Error; use dpp::contracts::withdrawals_contract; -use dpp::data_contract::DriveContractExt; + use dpp::document::document_transition::DocumentTransitionAction; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::{Identifier, Value}; 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 34a2bbf23f5..ac77178f80d 100644 --- a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs @@ -14,7 +14,6 @@ use dpp::block::epoch::Epoch; 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; use drive::dpp::identity::convert_credits_to_satoshi; use drive::dpp::util::hash; @@ -565,7 +564,7 @@ mod tests { use dpp::identity::core_script::CoreScript; use dpp::platform_value::platform_value; use dpp::{ - data_contract::{DataContract, DriveContractExt}, + data_contract::DataContract, prelude::Identifier, system_data_contracts::{load_system_data_contract, SystemDataContract}, }; @@ -769,7 +768,7 @@ mod tests { } mod pool_withdrawals_into_transactions { - 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; @@ -991,7 +990,7 @@ mod tests { mod build_withdrawal_transactions_from_documents { use dpp::block::block_info::BlockInfo; - 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; diff --git a/packages/rs-drive-abci/src/platform/state_repository.rs b/packages/rs-drive-abci/src/platform/state_repository.rs index 13faecaf5a9..99a04f63146 100644 --- a/packages/rs-drive-abci/src/platform/state_repository.rs +++ b/packages/rs-drive-abci/src/platform/state_repository.rs @@ -3,7 +3,6 @@ // use dashcore::anyhow::Result; // use dashcore::InstantLock; // use dpp::async_trait::async_trait; -// use dpp::data_contract::{DataContract, DriveContractExt}; // use dpp::document::{Document, ExtendedDocument}; // use dpp::identifier::Identifier; // use dpp::identity::{Identity, IdentityPublicKey, KeyID}; diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index dbeb995a2dd..858abaefbf4 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -34,7 +34,6 @@ use crate::platform::Platform; use dpp::platform_value::{platform_value, BinaryData}; use dpp::ProtocolError; use drive::contract::DataContract; -use drive::dpp::data_contract::DriveContractExt; use drive::dpp::document::Document; use drive::dpp::identity::{ Identity, IdentityPublicKey, KeyType, Purpose, SecurityLevel, TimestampMillis, 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 b6aeae112bd..c67bdbe567a 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -45,7 +45,6 @@ use rand::{Rng, SeedableRng}; use dpp::block::block_info::BlockInfo; 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; use drive::drive::flags::StorageFlags; use drive::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; diff --git a/packages/rs-drive-abci/src/validation/state_transition/document_state_validation/fetch_documents.rs b/packages/rs-drive-abci/src/validation/state_transition/document_state_validation/fetch_documents.rs index 594144eecf1..d8734682751 100644 --- a/packages/rs-drive-abci/src/validation/state_transition/document_state_validation/fetch_documents.rs +++ b/packages/rs-drive-abci/src/validation/state_transition/document_state_validation/fetch_documents.rs @@ -6,7 +6,7 @@ use crate::platform::PlatformStateRef; use dpp::consensus::basic::document::InvalidDocumentTypeError; use dpp::consensus::basic::BasicError; use dpp::data_contract::document_type::DocumentType; -use dpp::data_contract::DriveContractExt; + use dpp::document::Document; use dpp::get_from_transition; use dpp::platform_value::{Identifier, Value}; diff --git a/packages/rs-drive-abci/src/validation/state_transition/document_state_validation/validate_documents_batch_transition_state.rs b/packages/rs-drive-abci/src/validation/state_transition/document_state_validation/validate_documents_batch_transition_state.rs index b67c6bc8281..2abf9cc6f70 100644 --- a/packages/rs-drive-abci/src/validation/state_transition/document_state_validation/validate_documents_batch_transition_state.rs +++ b/packages/rs-drive-abci/src/validation/state_transition/document_state_validation/validate_documents_batch_transition_state.rs @@ -8,7 +8,7 @@ use crate::validation::state_transition::document_state_validation::execute_data use crate::validation::state_transition::document_state_validation::fetch_documents::fetch_documents_for_transitions_knowing_contract_and_document_type; use dpp::consensus::basic::BasicError; use dpp::data_contract::document_type::DocumentType; -use dpp::data_contract::{DataContract, DriveContractExt}; +use dpp::data_contract::DataContract; use dpp::document::document_transition::{ DocumentCreateTransitionAction, DocumentDeleteTransitionAction, DocumentReplaceTransition, DocumentReplaceTransitionAction, DocumentTransitionAction, diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 38e307862d1..72de61f0e69 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -1665,8 +1665,8 @@ mod tests { use dashcore_rpc::dashcore_rpc_json::{ Bip9SoftforkInfo, Bip9SoftforkStatus, ExtendedQuorumDetails, }; + use dpp::data_contract::extra::common::json_document_to_contract; use drive::dpp::data_contract::extra::common::json_document_to_cbor; - use drive::dpp::data_contract::DriveContractExt; use drive_abci::config::PlatformTestConfig; use drive_abci::rpc::core::QuorumListExtendedInfo; use tenderdash_abci::proto::types::CoreChainLock; @@ -2296,13 +2296,10 @@ mod tests { #[test] fn run_chain_insert_one_new_identity_and_a_contract() { - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); let strategy = Strategy { contracts_with_updates: vec![(contract, None)], @@ -2369,34 +2366,23 @@ mod tests { #[test] fn run_chain_insert_one_new_identity_and_a_contract_with_updates() { - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); - let contract_cbor_update_1 = json_document_to_cbor( + let mut contract_update_1 = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable-update-1.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let mut contract_update_1 = - ::from_cbor(&contract_cbor_update_1, None) - .expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); //todo: versions should start at 0 (so this should be 1) contract_update_1.version = 2; - let contract_cbor_update_2 = json_document_to_cbor( + let mut contract_update_2 = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable-update-2.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let mut contract_update_2 = - ::from_cbor(&contract_cbor_update_2, None) - .expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); contract_update_2.version = 3; @@ -2471,13 +2457,10 @@ mod tests { #[test] fn run_chain_insert_one_new_identity_per_block_and_one_new_document() { - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); let document_op = DocumentOp { contract: contract.clone(), @@ -2539,13 +2522,10 @@ mod tests { #[test] fn run_chain_insert_one_new_identity_per_block_and_a_document_with_epoch_change() { - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); let document_op = DocumentOp { contract: contract.clone(), @@ -2617,13 +2597,10 @@ mod tests { #[test] fn run_chain_insert_one_new_identity_per_block_document_insertions_and_deletions_with_epoch_change( ) { - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); let document_insertion_op = DocumentOp { contract: contract.clone(), @@ -2713,13 +2690,10 @@ mod tests { #[test] fn run_chain_insert_one_new_identity_per_block_many_document_insertions_and_deletions_with_epoch_change( ) { - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); let document_insertion_op = DocumentOp { contract: contract.clone(), @@ -2810,13 +2784,10 @@ mod tests { #[test] fn run_chain_insert_many_new_identity_per_block_many_document_insertions_and_deletions_with_epoch_change( ) { - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); let document_insertion_op = DocumentOp { contract: contract.clone(), @@ -2909,13 +2880,10 @@ mod tests { #[test] fn run_chain_insert_many_new_identity_per_block_many_document_insertions_updates_and_deletions_with_epoch_change( ) { - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(PROTOCOL_VERSION), ) - .expect("expected to get cbor from a json document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); + .expect("expected to get contract from a json document"); let document_insertion_op = DocumentOp { contract: contract.clone(), diff --git a/packages/rs-drive/benches/benchmarks.rs b/packages/rs-drive/benches/benchmarks.rs index 099a53cf048..7c19879669d 100644 --- a/packages/rs-drive/benches/benchmarks.rs +++ b/packages/rs-drive/benches/benchmarks.rs @@ -33,9 +33,8 @@ //! use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; -use dpp::data_contract::extra::common::json_document_to_cbor; +use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_contract}; -use dpp::data_contract::DriveContractExt; use dpp::document::Document; use drive::contract::Contract; use drive::contract::CreateRandomDocument; @@ -47,12 +46,9 @@ criterion_group!(deserialization, test_drive_10_deserialization); /// Benchmarks the `DDSR 10`, `CBOR 10`, and `DDSR Consume 10` serialization functions /// using 10 Dashpay `contactRequest` documents with random data. fn test_drive_10_serialization(c: &mut Criterion) { - let dashpay_cbor = json_document_to_cbor( - "tests/supporting_files/contract/dashpay/dashpay-contract.json", - Some(1), - ) - .expect("expected to get cbor contract"); - let contract = ::from_cbor(&dashpay_cbor, None).unwrap(); + let contract = + json_document_to_contract("tests/supporting_files/contract/dashpay/dashpay-contract.json") + .expect("expected to get contract"); let document_type = contract .document_type_for_name("contactRequest") @@ -102,12 +98,9 @@ fn test_drive_10_serialization(c: &mut Criterion) { /// Benchmarks the `DDSR 10` and `CBOR 10` deserialization functions /// using 10 serialized Dashpay `contactRequest` documents with random data. fn test_drive_10_deserialization(c: &mut Criterion) { - let dashpay_cbor = json_document_to_cbor( - "tests/supporting_files/contract/dashpay/dashpay-contract.json", - Some(1), - ) - .expect("expected to get cbor contract"); - let contract = ::from_cbor(&dashpay_cbor, None).unwrap(); + let contract = + json_document_to_contract("tests/supporting_files/contract/dashpay/dashpay-contract.json") + .expect("expected to get contract"); let document_type = contract .document_type_for_name("contactRequest") diff --git a/packages/rs-drive/src/common/mod.rs b/packages/rs-drive/src/common/mod.rs index 82dbd28e67a..927a3f2b1a7 100644 --- a/packages/rs-drive/src/common/mod.rs +++ b/packages/rs-drive/src/common/mod.rs @@ -51,8 +51,7 @@ use std::path::Path; #[cfg(feature = "full")] use ciborium::value::Value; -#[cfg(feature = "full")] -use dpp::data_contract::DriveContractExt; + #[cfg(feature = "full")] use grovedb::TransactionArg; @@ -66,6 +65,8 @@ use dpp::data_contract::extra::common::json_document_to_cbor; #[cfg(feature = "full")] use dpp::block::block_info::BlockInfo; +use dpp::data_contract::extra::common::json_document_to_contract_with_ids; +use dpp::prelude::Identifier; #[cfg(feature = "full")] /// Serializes to CBOR and applies to Drive a JSON contract from the file system. @@ -75,22 +76,12 @@ pub fn setup_contract( contract_id: Option<[u8; 32]>, transaction: TransactionArg, ) -> Contract { - let contract_cbor = json_document_to_cbor(path, Some(crate::drive::defaults::PROTOCOL_VERSION)) - .expect("expected to get cbor contract"); - let contract = ::from_cbor(&contract_cbor, contract_id) - .expect("contract should be deserialized"); - let contract_cbor = - DriveContractExt::to_cbor(&contract).expect("contract should be serialized"); + let contract = + json_document_to_contract_with_ids(path, contract_id.map(|i| Identifier::from(i)), None) + .expect("expected to get cbor contract"); drive - .apply_contract_cbor( - contract_cbor, - contract_id, - BlockInfo::default(), - true, - None, - transaction, - ) + .apply_contract(&contract, BlockInfo::default(), true, None, transaction) .expect("contract should be applied"); contract } diff --git a/packages/rs-drive/src/drive/batch/drive_op_batch/contract.rs b/packages/rs-drive/src/drive/batch/drive_op_batch/contract.rs index f7a7e032c5e..83cefe9b813 100644 --- a/packages/rs-drive/src/drive/batch/drive_op_batch/contract.rs +++ b/packages/rs-drive/src/drive/batch/drive_op_batch/contract.rs @@ -4,7 +4,8 @@ use crate::drive::Drive; use crate::error::Error; use crate::fee::op::LowLevelDriveOperation; use dpp::block::block_info::BlockInfo; -use dpp::data_contract::{DataContract as Contract, DriveContractExt}; +use dpp::data_contract::DataContract as Contract; +use dpp::platform_value::Identifier; use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; use std::borrow::{Borrow, Cow}; @@ -63,8 +64,10 @@ impl DriveLowLevelOperationConverter for ContractOperationType<'_> { storage_flags, } => { // first we need to deserialize the contract - let contract = - ::from_cbor(&contract_cbor, contract_id)?; + let contract = Contract::from_cbor_with_id( + &contract_cbor, + contract_id.map(|bytes| Identifier::from(bytes)), + )?; drive.apply_contract_with_serialization_operations( &contract, 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 d3ef134bb8c..f3dc494e4ad 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::LowLevelDriveOperation; use dpp::block::block_info::BlockInfo; use dpp::data_contract::document_type::DocumentType; -use dpp::data_contract::{DataContract as Contract, DriveContractExt}; +use dpp::data_contract::DataContract; use dpp::document::Document; use dpp::prelude::Identifier; use grovedb::batch::KeyInfoPath; @@ -38,7 +38,7 @@ pub struct DocumentOperationsForContractDocumentType<'a> { /// Document info pub operations: Vec>, /// Contract - pub contract: &'a Contract, + pub contract: &'a DataContract, /// Document type pub document_type: &'a DocumentType, } @@ -66,7 +66,7 @@ pub enum DocumentOperationType<'a> { /// The serialized document serialized_document: &'a [u8], /// The contract - contract: &'a Contract, + contract: &'a DataContract, /// The name of the document type document_type_name: &'a str, /// The owner id, if none is specified will try to recover from serialized document @@ -120,7 +120,7 @@ pub enum DocumentOperationType<'a> { /// The document id document_id: [u8; 32], /// The contract - contract: &'a Contract, + contract: &'a DataContract, /// The name of the document type document_type_name: &'a str, /// The owner id, if none is specified will try to recover from serialized document @@ -131,7 +131,7 @@ pub enum DocumentOperationType<'a> { /// The document id document_id: [u8; 32], /// The contract - contract: &'a Contract, + contract: &'a DataContract, /// The name of the document type document_type: &'a DocumentType, /// The owner id, if none is specified will try to recover from serialized document @@ -167,7 +167,7 @@ pub enum DocumentOperationType<'a> { /// The serialized document serialized_document: &'a [u8], /// The contract - contract: &'a Contract, + contract: &'a DataContract, /// The name of the document type document_type_name: &'a str, /// The owner id, if none is specified will try to recover from serialized document @@ -191,7 +191,7 @@ pub enum DocumentOperationType<'a> { /// The document in pre-serialized form serialized_document: &'a [u8], /// The contract - contract: &'a Contract, + contract: &'a DataContract, /// The name of the document type document_type_name: &'a str, /// The owner id, if none is specified will try to recover from serialized document @@ -220,8 +220,7 @@ impl DriveLowLevelOperationConverter for DocumentOperationType<'_> { override_document, storage_flags, } => { - let contract = - ::from_cbor(serialized_contract, None)?; + let contract = DataContract::from_cbor(serialized_contract)?; let document = Document::from_cbor(serialized_document, None, owner_id)?; @@ -399,7 +398,7 @@ impl DriveLowLevelOperationConverter for DocumentOperationType<'_> { document_type_name, owner_id, } => { - let contract = ::from_cbor(contract_cbor, None)?; + let contract = DataContract::from_cbor(contract_cbor)?; drive.delete_document_for_contract_with_named_type_operations( document_id, &contract, @@ -417,7 +416,7 @@ impl DriveLowLevelOperationConverter for DocumentOperationType<'_> { owner_id, storage_flags, } => { - let contract = ::from_cbor(contract_cbor, None)?; + let contract = DataContract::from_cbor(contract_cbor)?; let document = Document::from_cbor(serialized_document, None, owner_id)?; 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 b05567e14d6..f6e82f8f5ae 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 @@ -212,8 +212,10 @@ mod tests { use super::*; - use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_document}; - use dpp::data_contract::DriveContractExt; + use dpp::data_contract::extra::common::{ + json_document_to_cbor, json_document_to_contract, json_document_to_document, + }; + use dpp::document::Document; use dpp::util::serializer; use rand::Rng; @@ -232,6 +234,7 @@ mod tests { use crate::drive::batch::drive_op_batch::document::{ DocumentOperationsForContractDocumentType, UpdateOperationInfo, }; + use crate::drive::batch::ContractOperationType::ApplyContract; use crate::drive::batch::DocumentOperationType::AddDocumentForContract; use crate::drive::batch::DriveOperation::{ContractOperation, DocumentOperation}; use crate::drive::config::DriveConfig; @@ -255,23 +258,17 @@ mod tests { .create_initial_state_structure(Some(&db_transaction)) .expect("expected to create root tree successfully"); - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(crate::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to get cbor contract"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); - let serialized_contract = - DriveContractExt::to_cbor(&contract).expect("contract should be serialized"); let document_type = contract .document_type_for_name("contactRequest") .expect("expected to get document type"); - drive_operations.push(ContractOperation(ApplyContractWithSerialization { + drive_operations.push(ContractOperation(ApplyContract { contract: Cow::Borrowed(&contract), - serialized_contract: serialized_contract.clone(), storage_flags: None, })); @@ -348,23 +345,17 @@ mod tests { .create_initial_state_structure(Some(&db_transaction)) .expect("expected to create root tree successfully"); - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(crate::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to get cbor contract"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); - let serialized_contract = - DriveContractExt::to_cbor(&contract).expect("contract should be serialized"); - let _document_type = contract + let document_type = contract .document_type_for_name("contactRequest") .expect("expected to get document type"); - drive_operations.push(ContractOperation(ApplyContractWithSerialization { + drive_operations.push(ContractOperation(ApplyContract { contract: Cow::Borrowed(&contract), - serialized_contract, storage_flags: None, })); let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); @@ -372,6 +363,7 @@ mod tests { let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor contract"); @@ -392,6 +384,7 @@ mod tests { let dashpay_cr_1_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request1.json", Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor contract"); diff --git a/packages/rs-drive/src/drive/batch/transitions/document/document_create_transition.rs b/packages/rs-drive/src/drive/batch/transitions/document/document_create_transition.rs index 4ea2158d3b8..f193038275c 100644 --- a/packages/rs-drive/src/drive/batch/transitions/document/document_create_transition.rs +++ b/packages/rs-drive/src/drive/batch/transitions/document/document_create_transition.rs @@ -6,7 +6,7 @@ use crate::drive::object_size_info::DocumentInfo::DocumentWithoutSerialization; use crate::drive::object_size_info::OwnedDocumentInfo; use crate::error::Error; use dpp::block::epoch::Epoch; -use dpp::data_contract::DriveContractExt; + use dpp::document::document_transition::{ DocumentBaseTransitionAction, DocumentCreateTransitionAction, }; diff --git a/packages/rs-drive/src/drive/contract/estimation_costs.rs b/packages/rs-drive/src/drive/contract/estimation_costs.rs index bdd456672ca..d3156dc95ad 100644 --- a/packages/rs-drive/src/drive/contract/estimation_costs.rs +++ b/packages/rs-drive/src/drive/contract/estimation_costs.rs @@ -7,7 +7,7 @@ use crate::drive::document::contract_document_type_path; use crate::drive::flags::StorageFlags; use crate::drive::Drive; -use dpp::data_contract::{DataContract, DriveContractExt}; +use dpp::data_contract::DataContract; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel}; use grovedb::EstimatedLayerInformation; @@ -27,7 +27,7 @@ impl Drive { ); // we only store the owner_id storage - let storage_flags = if contract.can_be_deleted() || !contract.config.readonly { + let storage_flags = if contract.config.can_be_deleted || !contract.config.readonly { Some(StorageFlags::approximate_size(true, None)) } else { None diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 3108fd5d958..17a311d5612 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -63,9 +63,7 @@ use grovedb::batch::KeyInfoPath; #[cfg(feature = "full")] use grovedb::reference_path::ReferencePathType::SiblingReference; -#[cfg(feature = "full")] -use dpp::data_contract::DriveContractExt; -use dpp::platform_value::{platform_value, Value}; +use dpp::platform_value::{platform_value, Identifier, Value}; use dpp::Convertible; #[cfg(feature = "full")] use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; @@ -227,9 +225,12 @@ impl Drive { ) -> Result { let mut drive_operations: Vec = vec![]; - let contract = ::from_cbor(&contract_cbor, contract_id)?; + let contract = DataContract::from_cbor_with_id( + &contract_cbor, + contract_id.map(|identifier| Identifier::from(identifier)), + )?; - let storage_flags = if contract.can_be_deleted() || !contract.config.readonly { + let storage_flags = if contract.config.can_be_deleted || !contract.config.readonly { Some(StorageFlags::new_single_epoch( block_info.epoch.index, Some(contract.owner_id.to_buffer()), @@ -354,7 +355,7 @@ impl Drive { // toDo: change this to be a reference by index let contract_documents_path = contract_documents_path(contract.id.as_bytes()); - for (type_key, document_type) in contract.document_types { + for (type_key, document_type) in contract.document_types.iter() { self.batch_insert_empty_tree( contract_documents_path, KeyRef(type_key.as_bytes()), @@ -425,7 +426,10 @@ impl Drive { } let mut drive_operations: Vec = vec![]; - let contract = ::from_cbor(&contract_cbor, contract_id)?; + let contract = DataContract::from_cbor_with_id( + &contract_cbor, + contract_id.map(|identifier| Identifier::from(identifier)), + )?; let contract_id = contract_id.unwrap_or_else(|| *contract.id.as_bytes()); @@ -573,7 +577,9 @@ impl Drive { } if contract.config.documents_keep_history_contract_default - ^ original_contract.config.documents_keep_history_contract_default + ^ original_contract + .config + .documents_keep_history_contract_default { return Err(Error::Drive( DriveError::ChangingContractDocumentsKeepsHistoryDefault( @@ -606,7 +612,7 @@ impl Drive { let storage_flags = StorageFlags::map_cow_some_element_flags_ref(&element_flags)?; let contract_documents_path = contract_documents_path(contract.id.as_bytes()); - for (type_key, document_type) in contract.document_types { + for (type_key, document_type) in contract.document_types.iter() { let original_document_type = &original_contract.document_types.get(type_key); if let Some(original_document_type) = original_document_type { if original_document_type.documents_mutable ^ document_type.documents_mutable { @@ -714,7 +720,10 @@ impl Drive { transaction: TransactionArg, ) -> Result { // first we need to deserialize the contract - let contract = ::from_cbor(&contract_cbor, contract_id)?; + let contract = DataContract::from_cbor_with_id( + &contract_cbor, + contract_id.map(|identifier| Identifier::from(identifier)), + )?; self.apply_contract_with_serialization( &contract, @@ -1095,10 +1104,7 @@ impl Drive { if already_exists { if !original_contract_stored_data.is_empty() { - let original_contract = ::from_cbor( - &original_contract_stored_data, - None, - )?; + let original_contract = Contract::from_cbor(&original_contract_stored_data)?; // if the contract is not mutable update_contract will return an error self.update_contract_add_operations( contract_element, diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 9968d7d9f80..e4bf58f9e89 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -40,7 +40,7 @@ use grovedb::EstimatedLayerSizes::{AllItems, AllReference, AllSubtrees}; use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; use dpp::data_contract::document_type::{DocumentType, IndexLevel}; -use dpp::data_contract::DriveContractExt; + use grovedb::EstimatedSumTrees::NoSumTrees; use std::collections::HashMap; @@ -121,7 +121,7 @@ impl Drive { apply: bool, transaction: TransactionArg, ) -> Result { - let contract = ::from_cbor(contract_cbor, None)?; + let contract = Contract::from_cbor(contract_cbor)?; self.delete_document_for_contract( document_id, &contract, @@ -511,7 +511,7 @@ impl Drive { let index_level = &document_type.index_structure; let contract = document_and_contract_info.contract; let event_id = unique_event_id(); - let storage_flags = if document_type.documents_mutable || contract.can_be_deleted() { + let storage_flags = if document_type.documents_mutable || contract.config.can_be_deleted { document_and_contract_info .owned_document_info .document_info diff --git a/packages/rs-drive/src/drive/document/estimation_costs.rs b/packages/rs-drive/src/drive/document/estimation_costs.rs index 7ef0a0d59fe..b91050449d3 100644 --- a/packages/rs-drive/src/drive/document/estimation_costs.rs +++ b/packages/rs-drive/src/drive/document/estimation_costs.rs @@ -41,7 +41,6 @@ use crate::drive::Drive; use crate::error::fee::FeeError; use crate::error::Error; -use dpp::data_contract::DriveContractExt; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees, Mix}; @@ -72,7 +71,7 @@ impl Drive { if document_type.documents_keep_history { // if we keep history this level has trees // we only keep flags if the contract can be deleted - let average_flags_size = if contract.can_be_deleted() { + let average_flags_size = if contract.config.can_be_deleted { // the trees flags will never change let flags_size = StorageFlags::approximate_size(true, None); Some(flags_size) diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 89110501d52..a12d8125abc 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -33,7 +33,7 @@ //! use dpp::data_contract::document_type::{encode_unsigned_integer, IndexLevel}; -use dpp::data_contract::DriveContractExt; + use grovedb::batch::key_info::KeyInfo; use grovedb::batch::key_info::KeyInfo::KnownKey; use grovedb::batch::KeyInfoPath; @@ -134,7 +134,7 @@ impl Drive { StorageFlags::optional_default_as_ref(), ) } else { - let inserted_storage_flags = if contract.can_be_deleted() { + let inserted_storage_flags = if contract.config.can_be_deleted { document_and_contract_info .owned_document_info .document_info @@ -488,7 +488,7 @@ impl Drive { storage_flags: Option>, transaction: TransactionArg, ) -> Result { - let contract = ::from_cbor(serialized_contract, None)?; + let contract = Contract::from_cbor(serialized_contract)?; let document = Document::from_cbor(serialized_document, None, owner_id)?; @@ -1022,7 +1022,7 @@ impl Drive { let contract = document_and_contract_info.contract; let event_id = unique_event_id(); let document_type = document_and_contract_info.document_type; - let storage_flags = if document_type.documents_mutable || contract.can_be_deleted() { + let storage_flags = if document_type.documents_mutable || contract.config.can_be_deleted { document_and_contract_info .owned_document_info .document_info diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 228ef3b82a1..1df8e58dfa0 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -36,7 +36,7 @@ use std::borrow::Cow; use std::collections::{HashMap, HashSet}; use dpp::data_contract::document_type::DocumentType; -use dpp::data_contract::DriveContractExt; + use grovedb::batch::key_info::KeyInfo; use grovedb::batch::key_info::KeyInfo::KnownKey; use grovedb::batch::KeyInfoPath; @@ -94,7 +94,7 @@ impl Drive { storage_flags: Option>, transaction: TransactionArg, ) -> Result { - let contract = ::from_cbor(contract_cbor, None)?; + let contract = Contract::from_cbor(contract_cbor)?; let document = Document::from_cbor(serialized_document, None, owner_id)?; @@ -773,8 +773,8 @@ mod tests { let contract_cbor = hex::decode("01a5632469645820b0248cd9a27f86d05badf475dd9ff574d63219cd60c52e2be1e540c2fdd713336724736368656d61783468747470733a2f2f736368656d612e646173682e6f72672f6470702d302d342d302f6d6574612f646174612d636f6e7472616374676f776e6572496458204c9bf0db6ae315c85465e9ef26e6a006de9673731d08d14881945ddef1b5c5f26776657273696f6e0169646f63756d656e7473a267636f6e74616374a56474797065666f626a65637467696e646963657381a3646e616d656f6f6e7765724964546f55736572496466756e69717565f56a70726f7065727469657382a168246f776e6572496463617363a168746f557365724964636173636872657175697265648268746f557365724964697075626c69634b65796a70726f70657274696573a268746f557365724964a56474797065656172726179686d61784974656d731820686d696e4974656d73182069627974654172726179f570636f6e74656e744d656469615479706578216170706c69636174696f6e2f782e646173682e6470702e6964656e746966696572697075626c69634b6579a36474797065656172726179686d61784974656d73182169627974654172726179f5746164646974696f6e616c50726f70657274696573f46770726f66696c65a56474797065666f626a65637467696e646963657381a3646e616d65676f776e6572496466756e69717565f56a70726f7065727469657381a168246f776e6572496463617363687265717569726564826961766174617255726c6561626f75746a70726f70657274696573a26561626f7574a2647479706566737472696e67696d61784c656e67746818ff6961766174617255726ca3647479706566737472696e6766666f726d61746375726c696d61784c656e67746818ff746164646974696f6e616c50726f70657274696573f4").unwrap(); - let contract = ::from_cbor(contract_cbor.as_slice(), None) - .expect("expected to create contract"); + let contract = + Contract::from_cbor(contract_cbor.as_slice()).expect("expected to create contract"); drive .apply_contract_cbor( contract_cbor.clone(), @@ -866,8 +866,8 @@ mod tests { let contract_cbor = hex::decode("01a5632469645820b0248cd9a27f86d05badf475dd9ff574d63219cd60c52e2be1e540c2fdd713336724736368656d61783468747470733a2f2f736368656d612e646173682e6f72672f6470702d302d342d302f6d6574612f646174612d636f6e7472616374676f776e6572496458204c9bf0db6ae315c85465e9ef26e6a006de9673731d08d14881945ddef1b5c5f26776657273696f6e0169646f63756d656e7473a267636f6e74616374a56474797065666f626a65637467696e646963657381a3646e616d656f6f6e7765724964546f55736572496466756e69717565f56a70726f7065727469657382a168246f776e6572496463617363a168746f557365724964636173636872657175697265648268746f557365724964697075626c69634b65796a70726f70657274696573a268746f557365724964a56474797065656172726179686d61784974656d731820686d696e4974656d73182069627974654172726179f570636f6e74656e744d656469615479706578216170706c69636174696f6e2f782e646173682e6470702e6964656e746966696572697075626c69634b6579a36474797065656172726179686d61784974656d73182169627974654172726179f5746164646974696f6e616c50726f70657274696573f46770726f66696c65a56474797065666f626a65637467696e646963657381a3646e616d65676f776e6572496466756e69717565f56a70726f7065727469657381a168246f776e6572496463617363687265717569726564826961766174617255726c6561626f75746a70726f70657274696573a26561626f7574a2647479706566737472696e67696d61784c656e67746818ff6961766174617255726ca3647479706566737472696e6766666f726d61746375726c696d61784c656e67746818ff746164646974696f6e616c50726f70657274696573f4").unwrap(); - let contract = ::from_cbor(contract_cbor.as_slice(), None) - .expect("expected to create contract"); + let contract = + Contract::from_cbor(contract_cbor.as_slice()).expect("expected to create contract"); drive .apply_contract_cbor( contract_cbor.clone(), @@ -979,8 +979,8 @@ mod tests { let contract_cbor = hex::decode("01a5632469645820b0248cd9a27f86d05badf475dd9ff574d63219cd60c52e2be1e540c2fdd713336724736368656d61783468747470733a2f2f736368656d612e646173682e6f72672f6470702d302d342d302f6d6574612f646174612d636f6e7472616374676f776e6572496458204c9bf0db6ae315c85465e9ef26e6a006de9673731d08d14881945ddef1b5c5f26776657273696f6e0169646f63756d656e7473a267636f6e74616374a56474797065666f626a65637467696e646963657381a3646e616d656f6f6e7765724964546f55736572496466756e69717565f56a70726f7065727469657382a168246f776e6572496463617363a168746f557365724964636173636872657175697265648268746f557365724964697075626c69634b65796a70726f70657274696573a268746f557365724964a56474797065656172726179686d61784974656d731820686d696e4974656d73182069627974654172726179f570636f6e74656e744d656469615479706578216170706c69636174696f6e2f782e646173682e6470702e6964656e746966696572697075626c69634b6579a36474797065656172726179686d61784974656d73182169627974654172726179f5746164646974696f6e616c50726f70657274696573f46770726f66696c65a56474797065666f626a65637467696e646963657381a3646e616d65676f776e6572496466756e69717565f56a70726f7065727469657381a168246f776e6572496463617363687265717569726564826961766174617255726c6561626f75746a70726f70657274696573a26561626f7574a2647479706566737472696e67696d61784c656e67746818ff6961766174617255726ca3647479706566737472696e6766666f726d61746375726c696d61784c656e67746818ff746164646974696f6e616c50726f70657274696573f4").unwrap(); - let contract = ::from_cbor(contract_cbor.as_slice(), None) - .expect("expected to create contract"); + let contract = + Contract::from_cbor(contract_cbor.as_slice()).expect("expected to create contract"); drive .apply_contract_cbor( contract_cbor.clone(), diff --git a/packages/rs-drive/src/drive/estimation_costs.rs b/packages/rs-drive/src/drive/estimation_costs.rs index 7d0d0564df7..c7f71f259c0 100644 --- a/packages/rs-drive/src/drive/estimation_costs.rs +++ b/packages/rs-drive/src/drive/estimation_costs.rs @@ -32,7 +32,7 @@ use crate::drive::defaults::{DEFAULT_HASH_SIZE_U8, ESTIMATED_AVERAGE_DOCUMENT_TY use crate::drive::flags::StorageFlags; use crate::drive::{contract_documents_path, Drive}; -use dpp::data_contract::{DataContract, DriveContractExt}; +use dpp::data_contract::DataContract; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerInformation; @@ -80,7 +80,7 @@ impl Drive { let document_type_count = contract.documents.len() as u32; // we only store the owner_id storage - let storage_flags = if contract.can_be_deleted() { + let storage_flags = if contract.config.can_be_deleted { Some(StorageFlags::approximate_size(true, None)) } else { None diff --git a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs index c17b22a93ad..d58c1f4174d 100644 --- a/packages/rs-drive/src/drive/identity/withdrawals/documents.rs +++ b/packages/rs-drive/src/drive/identity/withdrawals/documents.rs @@ -1,9 +1,9 @@ use std::collections::BTreeMap; +use dpp::contracts::withdrawals_contract; 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 grovedb::TransactionArg; use indexmap::IndexMap; use lazy_static::__Deref; @@ -195,7 +195,7 @@ mod tests { use crate::tests::helpers::setup::{setup_document, setup_system_data_contract}; 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; @@ -296,7 +296,7 @@ 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}; diff --git a/packages/rs-drive/src/drive/mod.rs b/packages/rs-drive/src/drive/mod.rs index ccc25597971..4e346aa4e04 100644 --- a/packages/rs-drive/src/drive/mod.rs +++ b/packages/rs-drive/src/drive/mod.rs @@ -36,9 +36,6 @@ use std::path::Path; #[cfg(any(feature = "full", feature = "verify"))] use std::sync::RwLock; -#[cfg(feature = "full")] -use dpp::data_contract::DriveContractExt; - #[cfg(feature = "full")] use grovedb::batch::KeyInfoPath; use grovedb::batch::{GroveDbOp, OpsByLevelPath}; diff --git a/packages/rs-drive/src/drive/query/mod.rs b/packages/rs-drive/src/drive/query/mod.rs index 4a136e1cbde..5e43d0d923f 100644 --- a/packages/rs-drive/src/drive/query/mod.rs +++ b/packages/rs-drive/src/drive/query/mod.rs @@ -44,7 +44,7 @@ use crate::fee::calculate_fee; use crate::fee::op::LowLevelDriveOperation; use crate::query::DriveQuery; use dpp::data_contract::document_type::DocumentType; -use dpp::data_contract::DriveContractExt; + use dpp::document::Document; use dpp::platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use dpp::platform_value::Value; @@ -331,7 +331,7 @@ impl Drive { transaction: TransactionArg, ) -> Result<(Vec>, u16, u64), Error> { let mut drive_operations: Vec = vec![]; - let contract = ::from_cbor(contract_cbor, None)?; + let contract = Contract::from_cbor(contract_cbor)?; //todo cbor cost let document_type = contract.document_type_for_name(document_type_name.as_str())?; diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 7312fdc0f22..a4b991a5d9c 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -70,7 +70,7 @@ use dpp::data_contract::document_type::DocumentType; #[cfg(feature = "full")] use dpp::data_contract::document_type::{Index, IndexProperty}; #[cfg(any(feature = "full", feature = "verify"))] -use dpp::data_contract::DriveContractExt; + /// Import ordering #[cfg(any(feature = "full", feature = "verify"))] pub use ordering::OrderClause; @@ -545,13 +545,12 @@ impl<'a> DriveQuery<'a> { "Issue parsing sql: invalid from value", )))?; - let document_type = - contract - .document_types - .get(document_type_name) - .ok_or(Error::Query(QueryError::DocumentTypeNotFound( - "document type not found in contract", - )))?; + let document_type = contract + .document_types + .get(document_type_name) + .ok_or(Error::Query(QueryError::DocumentTypeNotFound( + "document type not found in contract", + )))?; // Restrictions // only binary where clauses are supported @@ -1531,7 +1530,7 @@ mod tests { use crate::query::DriveQuery; use dpp::data_contract::document_type::DocumentType; use dpp::data_contract::extra::common::json_document_to_cbor; - use dpp::data_contract::DriveContractExt; + use dpp::util::serializer; use serde_json::Value::Null; diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index 9418705b693..cc6d2a5d107 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -35,8 +35,6 @@ use std::borrow::Cow; #[cfg(feature = "full")] use std::option::Option::None; -#[cfg(feature = "full")] -use dpp::data_contract::DriveContractExt; #[cfg(feature = "full")] use dpp::document::Document; #[cfg(feature = "full")] diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 99bd26949cd..696d1ca33e2 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -47,7 +47,7 @@ use std::option::Option::None; use std::sync::Arc; #[cfg(feature = "full")] -use dpp::data_contract::{DataContractFactory, DriveContractExt}; +use dpp::data_contract::DataContractFactory; #[cfg(feature = "full")] use rand::seq::SliceRandom; #[cfg(feature = "full")] diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 3fa86d11d9e..b7f16358dce 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -39,8 +39,6 @@ use std::fmt::{Debug, Formatter}; #[cfg(feature = "full")] use std::option::Option::None; -#[cfg(feature = "full")] -use dpp::data_contract::DriveContractExt; #[cfg(feature = "full")] use dpp::document::Document; #[cfg(feature = "full")] diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index 07f55c36bb5..e79811baf33 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -27,7 +27,7 @@ pub mod state_transition; mod validator; pub use document_batch_transition::DocumentsBatchTransitionWasm; -use dpp::data_contract::DriveContractExt; + use dpp::document::{Document, EXTENDED_DOCUMENT_IDENTIFIER_FIELDS, IDENTIFIER_FIELDS}; pub use extended_document::ExtendedDocumentWasm; From e84ed04d184b0a1e4c0ff89ca07a2f84c6e6cb1a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 22 Apr 2023 23:40:10 +0700 Subject: [PATCH 08/50] more work --- packages/rs-dpp/Cargo.toml | 2 +- packages/rs-dpp/src/data_contract/data_contract.rs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 03b6499ed98..162a2ea5810 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -59,6 +59,6 @@ tokio = { version = "1.17", features = ["full"] } pretty_assertions = { version = "1.3.0" } [features] -default = ["fixtures-and-mocks", "cbor"] +default = ["fixtures-and-mocks"] cbor = ["ciborium"] fixtures-and-mocks = ["mockall"] diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 2f42c96eba5..e34d1018ebe 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -319,7 +319,8 @@ impl DataContract { Self::from_raw_object(value) } - pub fn from_buffer(b: impl AsRef<[u8]>) -> Result { + #[cfg(feature = "cbor")] + pub fn from_cbor_buffer(b: impl AsRef<[u8]>) -> Result { Self::from_cbor(b) } @@ -685,7 +686,7 @@ mod test { let data_contract_bytes = data_contract .to_buffer() .expect("data contract should be converted into the bytes"); - let data_contract_restored = DataContract::from_buffer(data_contract_bytes) + let data_contract_restored = DataContract::from_cbor_buffer(data_contract_bytes) .expect("data contract should be created from bytes"); assert_eq!( @@ -717,7 +718,7 @@ mod test { .to_buffer() .expect("data contract should be converted into the bytes"); - let data_contract_restored = DataContract::from_buffer(data_contract_bytes) + let data_contract_restored = DataContract::from_cbor_buffer(data_contract_bytes) .expect("data contract should be created from bytes"); assert_eq!( @@ -759,7 +760,7 @@ mod test { high_protocol_version_bytes.extend_from_slice(contract_cbor_bytes); - let data_contract_restored = DataContract::from_buffer(&high_protocol_version_bytes) + let data_contract_restored = DataContract::from_cbor_buffer(&high_protocol_version_bytes) .expect("data contract should be created from bytes"); assert_eq!(u32::MAX, data_contract_restored.protocol_version); @@ -872,7 +873,7 @@ mod test { fn deserialize_dpp_cbor() { let data_contract_cbor = get_data_contract_cbor_bytes(); - let data_contract = DataContract::from_buffer(data_contract_cbor).unwrap(); + let data_contract = DataContract::from_cbor_buffer(data_contract_cbor).unwrap(); assert_eq!(data_contract.version, 1); assert_eq!(data_contract.protocol_version, 1); @@ -900,7 +901,7 @@ mod test { fn serialize_deterministically_serialize_to_cbor() { let data_contract_cbor = get_data_contract_cbor_bytes(); - let data_contract = DataContract::from_buffer(&data_contract_cbor).unwrap(); + let data_contract = DataContract::from_cbor_buffer(&data_contract_cbor).unwrap(); let serialized = data_contract.to_buffer().unwrap(); From 0e101a76387b13af232c5c63a7aff6f15a9bd48e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 02:36:23 +0700 Subject: [PATCH 09/50] more work on serialization/deserialization --- Cargo.lock | 11 ++ Cargo.toml | 1 + packages/rs-dpp/Cargo.toml | 5 +- packages/rs-dpp/src/convertible.rs | 3 +- .../rs-dpp/src/data_contract/data_contract.rs | 23 ++- .../data_contract/data_contract_factory.rs | 2 +- .../rs-dpp/src/data_contract/extra/common.rs | 4 +- .../data_contract_create_transition/mod.rs | 1 + .../serialize_for_signing.rs | 36 ++++ .../data_contract_update_transition/mod.rs | 2 + .../serialize_for_signing.rs | 34 ++++ packages/rs-dpp/src/document/document.rs | 1 + .../rs-dpp/src/document/extended_document.rs | 10 +- packages/rs-dpp/src/document/serialize.rs | 3 +- packages/rs-dpp/src/identity/identity.rs | 7 +- .../identity/identity_public_key/key_type.rs | 1 + .../src/identity/identity_public_key/mod.rs | 10 +- .../identity/identity_public_key/purpose.rs | 1 + .../identity_public_key/security_level.rs | 1 + .../identity_public_key_transitions/mod.rs | 23 ++- packages/rs-dpp/src/lib.rs | 1 + .../abstract_state_transition.rs | 15 +- packages/rs-dpp/src/state_transition/mod.rs | 26 --- .../{serializer.rs => cbor_serializer.rs} | 0 packages/rs-dpp/src/util/mod.rs | 5 +- .../src/contracts/reward_shares.rs | 4 +- .../src/drive/batch/drive_op_batch/mod.rs | 20 +-- packages/rs-drive/src/drive/contract/mod.rs | 46 ++---- .../rs-drive/src/drive/document/delete.rs | 6 +- .../rs-drive/src/drive/document/update.rs | 32 ++-- packages/rs-drive/src/query/mod.rs | 30 ++-- packages/rs-drive/src/query/test_index.rs | 8 +- .../rs-drive/tests/deterministic_root_hash.rs | 4 +- packages/rs-drive/tests/query_tests.rs | 154 +++++++++--------- .../rs-drive/tests/query_tests_history.rs | 66 ++++---- packages/rs-platform-serialization/Cargo.toml | 17 ++ .../rs-platform-serialization/src/error.rs | 11 ++ packages/rs-platform-serialization/src/lib.rs | 25 +++ packages/rs-platform-value/Cargo.toml | 1 + .../src/data_contract/data_contract.rs | 2 +- .../src/document/extended_document.rs | 2 +- packages/wasm-dpp/src/identity/mod.rs | 2 +- 42 files changed, 398 insertions(+), 258 deletions(-) create mode 100644 packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs create mode 100644 packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs rename packages/rs-dpp/src/util/{serializer.rs => cbor_serializer.rs} (100%) create mode 100644 packages/rs-platform-serialization/Cargo.toml create mode 100644 packages/rs-platform-serialization/src/error.rs create mode 100644 packages/rs-platform-serialization/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 0c9d25b350a..f818271416b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1120,6 +1120,7 @@ dependencies = [ "log", "mockall", "num_enum", + "platform-serialization", "platform-value", "pretty_assertions", "rand", @@ -2461,6 +2462,16 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +[[package]] +name = "platform-serialization" +version = "0.1.0" +dependencies = [ + "bincode 2.0.0-rc.3", + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "platform-value" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 0353b5edae1..60270d33794 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "packages/wasm-dpp", "packages/rs-drive", "packages/rs-platform-value", + "packages/rs-platform-serialization", "packages/rs-drive-abci", "packages/dashpay-contract", "packages/withdrawals-contract", diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 162a2ea5810..8876766d9bd 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -2,7 +2,7 @@ name = "dpp" version = "0.1.0" edition = "2018" -authors = ["Anton Suprunchuk "] +authors = ["Anton Suprunchuk ", "Samuel Westrich ", "Ivan Shumkov ", "Djavid Gabibiyan "] [dependencies] anyhow = { version = "1.0.70" } @@ -50,6 +50,7 @@ thiserror = { version = "1.0" } mockall = { version = "0.11.3", optional = true } data-contracts = { path = "../data-contracts" } platform-value = { path = "../rs-platform-value" } +platform-serialization = { path = "../rs-platform-serialization" } derive_more = "0.99.17" ed25519-dalek = {version = "2.0.0-rc.2", features = ["rand_core"] } @@ -59,6 +60,6 @@ tokio = { version = "1.17", features = ["full"] } pretty_assertions = { version = "1.3.0" } [features] -default = ["fixtures-and-mocks"] +default = ["fixtures-and-mocks", "cbor"] cbor = ["ciborium"] fixtures-and-mocks = ["mockall"] diff --git a/packages/rs-dpp/src/convertible.rs b/packages/rs-dpp/src/convertible.rs index 8313dceb7d0..c7995ae44b1 100644 --- a/packages/rs-dpp/src/convertible.rs +++ b/packages/rs-dpp/src/convertible.rs @@ -18,5 +18,6 @@ pub trait Convertible { fn to_json(&self) -> Result; /// 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>; + #[cfg(feature = "cbor")] + fn to_cbor_buffer(&self) -> Result, ProtocolError>; } diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index e34d1018ebe..9a56bc63018 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -24,11 +24,9 @@ use crate::data_contract::contract_config::{ use crate::data_contract::get_binary_properties_from_schema::get_binary_properties; -use crate::{ - errors::ProtocolError, - metadata::Metadata, - util::{hash::hash_to_vec, serializer}, -}; +#[cfg(feature = "cbor")] +use crate::util::cbor_serializer; +use crate::{errors::ProtocolError, metadata::Metadata, util::hash::hash_to_vec}; use crate::{identifier, Convertible}; use platform_value::string_encoding::Encoding; @@ -78,7 +76,8 @@ impl Convertible for DataContract { } /// Returns Data Contract as a Buffer - fn to_buffer(&self) -> Result, ProtocolError> { + #[cfg(feature = "cbor")] + fn to_cbor_buffer(&self) -> Result, ProtocolError> { let protocol_version = self.protocol_version; let mut object = self.to_object()?; @@ -91,7 +90,7 @@ impl Convertible for DataContract { .unwrap() .sort_by_lexicographical_byte_ordering_keys_and_inner_maps(); - serializer::serializable_value_to_cbor(&object, Some(protocol_version)) + cbor_serializer::serializable_value_to_cbor(&object, Some(protocol_version)) } } @@ -326,7 +325,7 @@ impl DataContract { // Returns hash from Data Contract pub fn hash(&self) -> Result, ProtocolError> { - Ok(hash_to_vec(self.to_buffer()?)) + Ok(hash_to_vec(self.serialize()?)) } /// Increments version of Data Contract @@ -684,7 +683,7 @@ mod test { let data_contract = get_data_contract_fixture(None); let data_contract_bytes = data_contract - .to_buffer() + .to_cbor_buffer() .expect("data contract should be converted into the bytes"); let data_contract_restored = DataContract::from_cbor_buffer(data_contract_bytes) .expect("data contract should be created from bytes"); @@ -715,7 +714,7 @@ mod test { data_contract.protocol_version = 10000; let data_contract_bytes = data_contract - .to_buffer() + .to_cbor_buffer() .expect("data contract should be converted into the bytes"); let data_contract_restored = DataContract::from_cbor_buffer(data_contract_bytes) @@ -746,7 +745,7 @@ mod test { let data_contract = get_data_contract_fixture(None); let data_contract_bytes = data_contract - .to_buffer() + .to_cbor_buffer() .expect("data contract should be converted into the bytes"); let mut high_protocol_version_bytes = u64::MAX.encode_var_vec(); @@ -903,7 +902,7 @@ mod test { let data_contract = DataContract::from_cbor_buffer(&data_contract_cbor).unwrap(); - let serialized = data_contract.to_buffer().unwrap(); + let serialized = data_contract.to_cbor_buffer().unwrap(); assert_eq!(hex::encode(data_contract_cbor), hex::encode(serialized)); } 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 5b8b9a6a0eb..4fee02db3e5 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -305,7 +305,7 @@ mod tests { .. } = get_test_data(); let serialized_data_contract = data_contract - .to_buffer() + .to_cbor_buffer() .expect("should be serialized to buffer"); let result = factory .create_from_buffer(serialized_data_contract, false) diff --git a/packages/rs-dpp/src/data_contract/extra/common.rs b/packages/rs-dpp/src/data_contract/extra/common.rs index 72122231321..c8a2eea642f 100644 --- a/packages/rs-dpp/src/data_contract/extra/common.rs +++ b/packages/rs-dpp/src/data_contract/extra/common.rs @@ -1,7 +1,8 @@ use crate::data_contract::document_type::DocumentType; use crate::document::Document; use crate::prelude::DataContract; -use crate::util::serializer::serializable_value_to_cbor; +#[cfg(feature = "cbor")] +use crate::util::cbor_serializer::serializable_value_to_cbor; use crate::ProtocolError; use crate::ProtocolError::ValueError; use platform_value::Identifier; @@ -43,6 +44,7 @@ pub fn json_document_to_platform_value( } /// Reads a JSON file and converts it to CBOR. +#[cfg(feature = "cbor")] pub fn json_document_to_cbor( path: impl AsRef, protocol_version: Option, 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 06be8113179..676b7679900 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 @@ -25,6 +25,7 @@ use bincode::{Decode, Encode}; mod action; pub mod apply_data_contract_create_transition_factory; pub mod builder; +mod serialize_for_signing; pub mod validation; pub use action::{ diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs new file mode 100644 index 00000000000..0407734b973 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs @@ -0,0 +1,36 @@ +use crate::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; +use crate::data_contract::{DataContract, DataContractInner}; +use crate::state_transition::StateTransitionType; +use crate::util::hash::{hash, hash_to_vec}; +use crate::ProtocolError; +use bincode::config; +use platform_value::Bytes32; +// use platform_serialization::PlatformSerialize; + +#[derive(Debug, Clone, PartialEq)] +pub struct TempDataContractCreateTransitionWithoutWitness<'a> { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub data_contract: &'a DataContract, + pub entropy: &'a Bytes32, +} + +impl<'a> From<&'a DataContractCreateTransition> + for TempDataContractCreateTransitionWithoutWitness<'a> +{ + fn from(value: &'a DataContractCreateTransition) -> Self { + let DataContractCreateTransition { + protocol_version, + transition_type, + data_contract, + entropy, + .. + } = value; + TempDataContractCreateTransitionWithoutWitness { + protocol_version: *protocol_version, + transition_type: *transition_type, + data_contract, + entropy, + } + } +} 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 1ae5b2fe03f..efb096c32b9 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 @@ -23,7 +23,9 @@ use super::property_names::*; mod action; pub mod apply_data_contract_update_transition_factory; +mod serialize_for_signing; pub mod validation; + pub use action::{ DataContractUpdateTransitionAction, DATA_CONTRACT_UPDATE_TRANSITION_ACTION_VERSION, }; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs new file mode 100644 index 00000000000..45def59be2e --- /dev/null +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs @@ -0,0 +1,34 @@ +use crate::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; +use crate::data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition; +use crate::data_contract::{DataContract, DataContractInner}; +use crate::state_transition::StateTransitionType; +use crate::util::hash::{hash, hash_to_vec}; +use crate::ProtocolError; +use bincode::config; +use platform_serialization::PlatformSerialize; +use platform_value::Bytes32; + +#[derive(Debug, Clone, PartialEq)] +pub struct TempDataContractUpdateTransitionWithoutWitness<'a> { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub data_contract: &'a DataContract, +} + +impl<'a> From<&'a DataContractUpdateTransition> + for TempDataContractUpdateTransitionWithoutWitness<'a> +{ + fn from(value: &'a DataContractUpdateTransition) -> Self { + let DataContractUpdateTransition { + protocol_version, + transition_type, + data_contract, + .. + } = value; + TempDataContractUpdateTransitionWithoutWitness { + protocol_version: *protocol_version, + transition_type: *transition_type, + data_contract, + } + } +} diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index a9e606d2579..4545f0efef4 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -340,6 +340,7 @@ impl Document { Ok(self.to_map_value()?.into()) } + #[cfg(feature = "cbor")] pub fn to_cbor_value(&self) -> Result { self.to_object() .map(|v| v.try_into().map_err(ProtocolError::ValueError))? diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index 62e9facca76..a3703853faa 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -352,7 +352,8 @@ impl ExtendedDocument { .map_err(ProtocolError::ValueError) } - pub fn to_buffer(&self) -> Result, ProtocolError> { + #[cfg(feature = "cbor")] + pub fn to_cbor_buffer(&self) -> Result, ProtocolError> { let mut result_buf = self.protocol_version.encode_var_vec(); let mut cbor_value = self.document.to_cbor_value()?; @@ -379,8 +380,9 @@ impl ExtendedDocument { Ok(result_buf) } + #[cfg(feature = "cbor")] pub fn hash(&self) -> Result, ProtocolError> { - Ok(hash_to_vec(self.to_buffer()?)) + Ok(hash_to_vec(self.to_cbor_buffer()?)) } /// Set the value under given path. @@ -575,7 +577,7 @@ mod test { fn test_buffer_serialize_deserialize() { init(); let init_doc = new_example_document(); - let buffer_document = init_doc.to_buffer().expect("no errors"); + let buffer_document = init_doc.to_cbor_buffer().expect("no errors"); let doc = ExtendedDocument::from_cbor_buffer(buffer_document) .expect("document should be created from buffer"); @@ -671,7 +673,7 @@ mod test { let document_cbor = document_cbor_bytes(); let document = ExtendedDocument::from_cbor_buffer(&document_cbor)?; - let buffer = document.to_buffer()?; + let buffer = document.to_cbor_buffer()?; assert_eq!(hex::encode(document_cbor), hex::encode(buffer)); Ok(()) diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 75ef5054e71..f9ec0cbe9c2 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -24,7 +24,7 @@ use std::collections::BTreeMap; use std::convert::TryFrom; use std::io::{BufReader, Read}; -//todo: delete in later PR +#[cfg(feature = "cbor")] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] pub struct DocumentForCbor { /// The unique document ID. @@ -49,6 +49,7 @@ pub struct DocumentForCbor { pub updated_at: Option, } +#[cfg(feature = "cbor")] impl TryFrom for DocumentForCbor { type Error = ProtocolError; diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 5ae9e046f7d..98f5dbb9a89 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -137,7 +137,8 @@ impl Convertible for Identity { .map_err(ProtocolError::ValueError) } - fn to_buffer(&self) -> Result, ProtocolError> { + #[cfg(feature = "cbor")] + fn to_cbor_buffer(&self) -> Result, ProtocolError> { self.to_cbor() } } @@ -268,6 +269,7 @@ impl Identity { } /// Converts the identity to a cbor buffer + #[cfg(feature = "cbor")] pub fn to_cbor(&self) -> Result, ProtocolError> { // Prepend protocol version to the result let mut buf = self.get_protocol_version().encode_var_vec(); @@ -293,6 +295,7 @@ impl Identity { Ok(buf) } + #[cfg(feature = "cbor")] pub fn from_buffer(b: impl AsRef<[u8]>) -> Result { Self::from_cbor(b.as_ref()) } @@ -370,7 +373,7 @@ impl Identity { /// Computes the hash of an identity pub fn hash(&self) -> Result, ProtocolError> { - Ok(hash::hash_to_vec(self.to_buffer()?)) + Ok(hash::hash_to_vec(self.serialize()?)) } /// Convenience method to get Partial Identity Info diff --git a/packages/rs-dpp/src/identity/identity_public_key/key_type.rs b/packages/rs-dpp/src/identity/identity_public_key/key_type.rs index 52b2fd72187..86d3705d94a 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/key_type.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/key_type.rs @@ -165,6 +165,7 @@ impl TryFrom for KeyType { } } +#[cfg(feature = "cbor")] impl Into for KeyType { fn into(self) -> CborValue { CborValue::from(self as u128) 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 fd19ea51df8..926e0f19dda 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -21,13 +21,15 @@ pub use crate::identity::key_type::KeyType; pub use crate::identity::purpose::Purpose; pub use crate::identity::security_level::SecurityLevel; #[cfg(feature = "cbor")] +use crate::util::cbor_serializer; +#[cfg(feature = "cbor")] use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; use crate::util::hash::ripemd160_sha256; -use crate::util::{serializer, vec}; use crate::Convertible; use bincode::{Decode, Encode}; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyInCreationWithWitness; +use crate::util::vec; pub type KeyID = u32; pub type TimestampMillis = u64; @@ -95,14 +97,15 @@ impl Convertible for IdentityPublicKey { .map_err(ProtocolError::ValueError) } - fn to_buffer(&self) -> Result, ProtocolError> { + #[cfg(feature = "cbor")] + fn to_cbor_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) + cbor_serializer::serializable_value_to_cbor(&object, None) } } @@ -173,6 +176,7 @@ impl IdentityPublicKey { Self::from_value(value) } + #[cfg(feature = "cbor")] 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/identity_public_key/purpose.rs b/packages/rs-dpp/src/identity/identity_public_key/purpose.rs index f66d17e3541..cfcf02f62e1 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/purpose.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/purpose.rs @@ -48,6 +48,7 @@ impl TryFrom for Purpose { } } +#[cfg(feature = "cbor")] impl Into for Purpose { fn into(self) -> CborValue { CborValue::from(self as u128) diff --git a/packages/rs-dpp/src/identity/identity_public_key/security_level.rs b/packages/rs-dpp/src/identity/identity_public_key/security_level.rs index 84752224a67..9cada729471 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/security_level.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/security_level.rs @@ -30,6 +30,7 @@ pub enum SecurityLevel { MEDIUM = 3, } +#[cfg(feature = "cbor")] impl Into for SecurityLevel { fn into(self) -> CborValue { CborValue::from(self as u128) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs index 7ec0ecfcce1..a4fbbf1763a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs @@ -21,7 +21,7 @@ use crate::identity::signer::Signer; use crate::state_transition::errors::InvalidIdentityPublicKeyTypeError; #[cfg(feature = "cbor")] use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; -use crate::util::vec; +use crate::util::{cbor_serializer, vec}; use crate::validation::SimpleConsensusValidationResult; use crate::{BlsModule, Convertible, InvalidVectorSizeError, SerdeParsingError}; @@ -97,14 +97,20 @@ impl Convertible for IdentityPublicKeyInCreationWithWitness { .try_into() .map_err(ProtocolError::ValueError) } + #[cfg(feature = "cbor")] + fn to_cbor_buffer(&self) -> Result, ProtocolError> { + let mut object = self.to_object()?; - fn to_buffer(&self) -> Result, ProtocolError> { - let without_witness: IdentityPublicKeyInCreationWithoutWitness = self.clone().into(); - without_witness.serialize() + cbor_serializer::serializable_value_to_cbor(&object, None) } } impl IdentityPublicKeyInCreationWithWitness { + fn serialize_without_witness(&self) -> Result, ProtocolError> { + let without_witness: IdentityPublicKeyInCreationWithoutWitness = self.clone().into(); + without_witness.serialize() + } + pub fn to_identity_public_key(self) -> IdentityPublicKey { let Self { id, @@ -147,7 +153,7 @@ impl IdentityPublicKeyInCreationWithWitness { ) -> Result { let mut public_key_with_witness: IdentityPublicKeyInCreationWithWitness = public_key.clone().into(); - let data = public_key_with_witness.to_buffer()?; + let data = public_key_with_witness.serialize_without_witness()?; match public_key.key_type { KeyType::ECDSA_SECP256K1 | KeyType::BLS12_381 => { public_key_with_witness.signature = signer.sign(&public_key, data.as_slice())?; @@ -167,7 +173,7 @@ impl IdentityPublicKeyInCreationWithWitness { key_type: KeyType, bls: &impl BlsModule, ) -> Result<(), ProtocolError> { - let data = self.to_buffer()?; + let data = self.serialize_without_witness()?; match key_type { KeyType::BLS12_381 => self.signature = bls.sign(&data, private_key)?.into(), @@ -294,6 +300,7 @@ impl IdentityPublicKeyInCreationWithWitness { }) } + #[cfg(feature = "cbor")] pub fn from_cbor_value(cbor_value: &CborValue) -> Result { let key_value_map = cbor_value.as_map().ok_or_else(|| { ProtocolError::DecodingError(String::from( @@ -346,7 +353,7 @@ impl IdentityPublicKeyInCreationWithWitness { pub fn verify_signature(&self) -> Result { match self.key_type { KeyType::ECDSA_SECP256K1 => { - let signable_data = self.to_buffer()?; + let signable_data = self.serialize_without_witness()?; if let Err(e) = signer::verify_data_signature( &signable_data, self.signature.as_slice(), @@ -363,7 +370,7 @@ impl IdentityPublicKeyInCreationWithWitness { } } KeyType::BLS12_381 => { - let signable_data = self.to_buffer()?; + let signable_data = self.serialize_without_witness()?; let public_key = match bls_signatures::PublicKey::from_bytes(self.data.as_slice()) { Ok(public_key) => public_key, Err(e) => { diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index c8e5e1977a7..3ed0d81b2ec 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -68,4 +68,5 @@ pub use bincode; pub use bls_signatures; pub use ed25519_dalek; pub use jsonschema; +pub use platform_serialization; pub use platform_value; 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 8d32bf613d1..ea537614e97 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -12,10 +12,12 @@ use crate::errors::consensus::signature::SignatureError; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, StateTransitionIsNotSignedError, }; +#[cfg(feature = "cbor")] +use crate::util::cbor_serializer; use crate::{ identity::KeyType, prelude::{Identifier, ProtocolError}, - util::{hash, serializer}, + util::hash, BlsModule, }; @@ -235,12 +237,21 @@ pub trait StateTransitionConvert: Serialize { state_transition_helpers::to_json(self, skip_signature_paths) } + // Returns the cbor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version + fn to_bincode_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { + let mut value = self.to_canonical_cleaned_object(skip_signature)?; + let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; + + cbor_serializer::serializable_value_to_cbor(&value, Some(protocol_version)) + } + + #[cfg(feature = "cbor")] // Returns the cbor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_cbor_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { 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)) + cbor_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 0401f9a4c9a..005833c4622 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -92,32 +92,6 @@ pub enum StateTransition { } impl StateTransition { - // pub fn from_value(value: Value) -> Result { - // let state_transition_type = value.get_integer("type")? as StateTransitionType; - // Ok(match state_transition_type { - // StateTransitionType::DataContractCreate => { - // DataContractCreateTransition::from_raw_object(value)?.into() - // } - // StateTransitionType::DocumentsBatch => { - // DocumentsBatchTransition::from_raw_object_with_contracts(value)?.into() - // } - // StateTransitionType::IdentityCreate => { - // IdentityCreateTransition::from_raw_object(value)?.into() - // } - // StateTransitionType::IdentityTopUp => { - // IdentityTopUpTransition::from_raw_object(value)?.into() - // } - // StateTransitionType::DataContractUpdate => { - // DataContractUpdateTransition::from_raw_object(value)?.into() - // } - // StateTransitionType::IdentityUpdate => { - // IdentityUpdateTransition::from_raw_object(value)?.into() - // } - // StateTransitionType::IdentityCreditWithdrawal => { - // IdentityCreditWithdrawalTransition::from_raw_object(value)?.into() - // } - // }) - // } fn signature_property_paths(&self) -> Vec<&'static str> { call_static_method!(self, signature_property_paths) } diff --git a/packages/rs-dpp/src/util/serializer.rs b/packages/rs-dpp/src/util/cbor_serializer.rs similarity index 100% rename from packages/rs-dpp/src/util/serializer.rs rename to packages/rs-dpp/src/util/cbor_serializer.rs diff --git a/packages/rs-dpp/src/util/mod.rs b/packages/rs-dpp/src/util/mod.rs index 2f518f11724..5eb2bd022da 100644 --- a/packages/rs-dpp/src/util/mod.rs +++ b/packages/rs-dpp/src/util/mod.rs @@ -1,5 +1,8 @@ #[cfg(feature = "cbor")] +pub mod cbor_serializer; +#[cfg(feature = "cbor")] pub mod cbor_value; + pub mod deserializer; pub mod entropy_generator; pub mod hash; @@ -8,5 +11,5 @@ pub mod json_path; pub mod json_schema; pub mod json_value; pub mod protocol_data; -pub mod serializer; + pub mod vec; diff --git a/packages/rs-drive-abci/src/contracts/reward_shares.rs b/packages/rs-drive-abci/src/contracts/reward_shares.rs index 30b24674f5b..149cd23a877 100644 --- a/packages/rs-drive-abci/src/contracts/reward_shares.rs +++ b/packages/rs-drive-abci/src/contracts/reward_shares.rs @@ -42,7 +42,7 @@ use crate::platform::Platform; use dpp::block::block_info::BlockInfo; use drive::contract::Contract; use drive::dpp::document::Document; -use drive::dpp::util::serializer; +use drive::dpp::util::cbor_serializer; use drive::drive::flags::StorageFlags; use drive::drive::query::QuerySerializedDocumentsOutcome; use drive::grovedb::TransactionArg; @@ -71,7 +71,7 @@ impl Platform { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_json, None) .expect("expected to serialize to cbor"); let QuerySerializedDocumentsOutcome { items, .. } = 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 f6e82f8f5ae..f9da3d4bc9b 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 @@ -217,7 +217,7 @@ mod tests { }; use dpp::document::Document; - use dpp::util::serializer; + use dpp::util::cbor_serializer; use rand::Rng; use serde_json::json; use tempfile::TempDir; @@ -318,7 +318,7 @@ mod tests { ["$ownerId", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive @@ -544,7 +544,7 @@ mod tests { ["$ownerId", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive @@ -672,7 +672,7 @@ mod tests { ["$ownerId", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive @@ -865,7 +865,7 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive @@ -888,7 +888,7 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive @@ -911,7 +911,7 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive @@ -1105,7 +1105,7 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive @@ -1128,7 +1128,7 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive @@ -1151,7 +1151,7 @@ mod tests { ["age", "asc"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (docs, _, _) = drive diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 17a311d5612..4d7f00615e9 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -214,22 +214,16 @@ impl Drive { Ok(()) } - /// Insert a contract CBOR. - pub fn insert_contract_cbor( + /// Insert a contract. + pub fn insert_contract( &self, - contract_cbor: Vec, - contract_id: Option<[u8; 32]>, + contract: &DataContract, block_info: BlockInfo, apply: bool, transaction: TransactionArg, ) -> Result { let mut drive_operations: Vec = vec![]; - let contract = DataContract::from_cbor_with_id( - &contract_cbor, - contract_id.map(|identifier| Identifier::from(identifier)), - )?; - let storage_flags = if contract.config.can_be_deleted || !contract.config.readonly { Some(StorageFlags::new_single_epoch( block_info.epoch.index, @@ -240,13 +234,13 @@ impl Drive { }; let contract_element = Element::Item( - contract_cbor, + contract.serialize()?, StorageFlags::map_to_some_element_flags(storage_flags.as_ref()), ); self.insert_contract_element( contract_element, - &contract, + contract, &block_info, apply, transaction, @@ -406,32 +400,20 @@ impl Drive { Ok(batch_operations) } - /// Insert a contract CBOR. - pub fn update_contract_cbor( + /// Update a data contract + pub fn update_contract( &self, - contract_cbor: Vec, - contract_id: Option<[u8; 32]>, + contract: &DataContract, block_info: BlockInfo, apply: bool, transaction: TransactionArg, ) -> Result { if !apply { - return self.insert_contract_cbor( - contract_cbor, - contract_id, - block_info, - false, - transaction, - ); + return self.insert_contract(contract, block_info, false, transaction); } let mut drive_operations: Vec = vec![]; - let contract = DataContract::from_cbor_with_id( - &contract_cbor, - contract_id.map(|identifier| Identifier::from(identifier)), - )?; - - let contract_id = contract_id.unwrap_or_else(|| *contract.id.as_bytes()); + let contract_bytes = contract.serialize()?; // Since we can update the contract by definition it already has storage flags let storage_flags = Some(StorageFlags::new_single_epoch( @@ -440,13 +422,13 @@ impl Drive { )); let contract_element = Element::Item( - contract_cbor, + contract_bytes, StorageFlags::map_to_some_element_flags(storage_flags.as_ref()), ); let original_contract_fetch_info = self .get_contract_with_fetch_info_and_add_to_operations( - contract_id, + contract.id.to_buffer(), Some(&block_info.epoch), true, transaction, @@ -474,7 +456,7 @@ impl Drive { // Update Data Contracts cache with the new contract let updated_contract_fetch_info = self .fetch_contract_and_add_operations( - contract_id, + contract.id.to_buffer(), Some(&block_info.epoch), transaction, &mut drive_operations, @@ -1466,7 +1448,7 @@ mod tests { contract.increment_version(); - let updated_contract_cbor = contract.to_buffer().expect("should serialize a contract"); + let updated_contract_bytes = contract.serialize().expect("should serialize a contract"); drive .update_contract_cbor( diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index e4bf58f9e89..d0c9a1de986 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -826,7 +826,7 @@ mod tests { use crate::query::DriveQuery; use dpp::block::epoch::Epoch; use dpp::document::Document; - use dpp::util::serializer; + use dpp::util::cbor_serializer; #[test] fn test_add_and_remove_family_one_document_no_transaction() { @@ -1724,7 +1724,7 @@ mod tests { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_json, None) .expect("expected to serialize to cbor"); drive @@ -1765,7 +1765,7 @@ mod tests { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_json, None) .expect("expected to serialize to cbor"); let (results, _, _) = drive diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 1df8e58dfa0..70ab60fdd31 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -682,7 +682,7 @@ mod tests { use dpp::platform_value::{platform_value, Value}; use dpp::prelude::DataContract; - use dpp::util::serializer; + use dpp::util::cbor_serializer; use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; use rand::Rng; use serde::{Deserialize, Serialize}; @@ -1138,9 +1138,11 @@ mod tests { }, }); - let contract = - serializer::serializable_value_to_cbor(&contract, Some(defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let contract = cbor_serializer::serializable_value_to_cbor( + &contract, + Some(defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); drive .apply_contract_cbor( @@ -1168,9 +1170,11 @@ mod tests { "$updatedAt":1647535750329_u64, }); - let serialized_document = - serializer::serializable_value_to_cbor(&document, Some(defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let serialized_document = cbor_serializer::serializable_value_to_cbor( + &document, + Some(defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); drive .add_serialized_document_for_serialized_contract( @@ -1201,9 +1205,11 @@ mod tests { "$updatedAt":1647535754556_u64, }); - let serialized_document = - serializer::serializable_value_to_cbor(&document, Some(defaults::PROTOCOL_VERSION)) - .expect("expected to serialize to cbor"); + let serialized_document = cbor_serializer::serializable_value_to_cbor( + &document, + Some(defaults::PROTOCOL_VERSION), + ) + .expect("expected to serialize to cbor"); drive .update_document_for_contract_cbor( @@ -2102,7 +2108,7 @@ mod tests { ) -> FeeResult { let value = serde_json::to_value(person).expect("serialized person"); let document_cbor = - serializer::serializable_value_to_cbor(&value, Some(defaults::PROTOCOL_VERSION)) + 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"); @@ -2405,7 +2411,7 @@ mod tests { ) .expect("should create a document"); - let document_cbor = document.to_buffer().expect("should encode to buffer"); + let document_cbor = document.to_cbor_buffer().expect("should encode to buffer"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpochOwned( 0, @@ -2434,7 +2440,7 @@ mod tests { .set("name", Value::Text("Ivaaaaaaaaaan!".to_string())) .expect("should change name"); - let document_cbor = document.to_buffer().expect("should encode to buffer"); + let document_cbor = document.to_cbor_buffer().expect("should encode to buffer"); let block_info = BlockInfo::default_with_time(10000); diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index a4b991a5d9c..f7fff6b9ec3 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -1531,7 +1531,7 @@ mod tests { use dpp::data_contract::document_type::DocumentType; use dpp::data_contract::extra::common::json_document_to_cbor; - use dpp::util::serializer; + use dpp::util::cbor_serializer; use serde_json::Value::Null; use dpp::block::block_info::BlockInfo; @@ -1614,7 +1614,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1636,7 +1636,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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...)", @@ -1660,7 +1660,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1683,7 +1683,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1705,7 +1705,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1731,7 +1731,7 @@ mod tests { ], }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1813,7 +1813,7 @@ mod tests { ], }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1840,7 +1840,7 @@ mod tests { ], }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1872,7 +1872,7 @@ mod tests { ], }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1900,7 +1900,7 @@ mod tests { ], }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); // The is actually valid, however executing it is not @@ -1929,7 +1929,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1950,7 +1950,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1971,7 +1971,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -1992,7 +1992,7 @@ mod tests { let contract = Contract::default(); let document_type = DocumentType::default(); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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 f6261ef64e6..66993668a09 100644 --- a/packages/rs-drive/src/query/test_index.rs +++ b/packages/rs-drive/src/query/test_index.rs @@ -3,7 +3,7 @@ mod tests { use dpp::data_contract::document_type::{DocumentType, Index, IndexProperty}; use dpp::platform_value::Identifier; - use dpp::util::serializer; + use dpp::util::cbor_serializer; use serde_json::json; use crate::contract::Contract; @@ -82,7 +82,7 @@ mod tests { ["b", "==", "2"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -94,7 +94,7 @@ mod tests { ["a", "==", "1"], ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); @@ -112,7 +112,7 @@ mod tests { ["c", "==", "1"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = 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"); diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index cc6d2a5d107..4ac19b946c2 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -38,7 +38,7 @@ use std::option::Option::None; #[cfg(feature = "full")] use dpp::document::Document; #[cfg(feature = "full")] -use dpp::util::serializer; +use dpp::util::cbor_serializer; #[cfg(feature = "full")] use drive::common; @@ -140,7 +140,7 @@ 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::serializable_value_to_cbor( + let document_cbor = cbor_serializer::serializable_value_to_cbor( &value, Some(drive::drive::defaults::PROTOCOL_VERSION), ) diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 696d1ca33e2..0458135d29c 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -99,7 +99,7 @@ use dpp::block::block_info::BlockInfo; use dpp::prelude::DataContract; use dpp::prelude::Revision; #[cfg(feature = "full")] -use dpp::util::serializer; +use dpp::util::cbor_serializer; #[cfg(feature = "full")] use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; #[cfg(feature = "full")] @@ -235,7 +235,7 @@ pub fn setup_family_tests(count: u32, seed: u64) -> (Drive, Contract) { 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::serializable_value_to_cbor( + let document_cbor = cbor_serializer::serializable_value_to_cbor( &value, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -308,7 +308,7 @@ pub fn setup_family_tests_with_nulls(count: u32, seed: u64) -> (Drive, Contract) 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::serializable_value_to_cbor( + let document_cbor = cbor_serializer::serializable_value_to_cbor( &value, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -380,7 +380,7 @@ pub fn setup_family_tests_only_first_name_index(count: u32, 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::serializable_value_to_cbor( + let document_cbor = cbor_serializer::serializable_value_to_cbor( &value, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -494,7 +494,7 @@ 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::serializable_value_to_cbor( + let document_cbor = cbor_serializer::serializable_value_to_cbor( &value, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -593,7 +593,7 @@ 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::serializable_value_to_cbor( + let domain_cbor = cbor_serializer::serializable_value_to_cbor( &domain_json, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -648,7 +648,7 @@ 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::serializable_value_to_cbor( + let document_cbor = cbor_serializer::serializable_value_to_cbor( &value, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -712,7 +712,7 @@ fn test_reference_proof_single_index() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -754,7 +754,7 @@ fn test_non_existence_reference_proof_single_index() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -816,7 +816,7 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -858,7 +858,7 @@ fn test_family_basic_queries() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -898,7 +898,7 @@ fn test_family_basic_queries() { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -954,7 +954,7 @@ fn test_family_basic_queries() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -997,7 +997,7 @@ fn test_family_basic_queries() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1048,7 +1048,7 @@ fn test_family_basic_queries() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1088,7 +1088,7 @@ fn test_family_basic_queries() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1131,7 +1131,7 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1183,7 +1183,7 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1230,7 +1230,7 @@ fn test_family_basic_queries() { ["firstName", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1278,7 +1278,7 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1334,7 +1334,7 @@ fn test_family_basic_queries() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1378,7 +1378,7 @@ fn test_family_basic_queries() { ["firstName", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1434,7 +1434,7 @@ fn test_family_basic_queries() { ["age", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1489,7 +1489,7 @@ fn test_family_basic_queries() { ["age", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1579,7 +1579,7 @@ 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::serializable_value_to_cbor( + let person_cbor = cbor_serializer::serializable_value_to_cbor( &serialized_person, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -1629,7 +1629,7 @@ 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::serializable_value_to_cbor( + let person_cbor = cbor_serializer::serializable_value_to_cbor( &serialized_person, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -1670,7 +1670,7 @@ fn test_family_basic_queries() { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1713,7 +1713,7 @@ fn test_family_basic_queries() { "orderBy": [["$id", "asc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1753,7 +1753,7 @@ fn test_family_basic_queries() { "orderBy": [["$id", "desc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1789,7 +1789,7 @@ fn test_family_basic_queries() { // let query_value = json!({}); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1816,7 +1816,7 @@ fn test_family_basic_queries() { "orderBy": [["$id", "desc"]] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1857,7 +1857,7 @@ fn test_family_basic_queries() { "orderBy": [["$ownerId", "desc"]] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1887,7 +1887,7 @@ fn test_family_basic_queries() { "orderBy": [["$ownerId", "asc"]] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1929,7 +1929,7 @@ fn test_family_basic_queries() { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (results, _, _) = drive @@ -1953,7 +1953,7 @@ fn test_family_basic_queries() { "orderBy": [["$id", "asc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1983,7 +1983,7 @@ fn test_family_basic_queries() { "orderBy": [["$id", "asc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -2013,7 +2013,7 @@ fn test_family_basic_queries() { "orderBy": [["$id", "asc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -2096,7 +2096,7 @@ fn test_family_starts_at_queries() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -2151,7 +2151,7 @@ fn test_family_starts_at_queries() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -2200,7 +2200,7 @@ fn test_family_starts_at_queries() { ["firstName", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -2255,7 +2255,7 @@ fn test_family_starts_at_queries() { ["firstName", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -2308,7 +2308,7 @@ fn test_family_sql_query() { .expect("contract should have a person document type"); // Empty where clause - let query_cbor = serializer::serializable_value_to_cbor( + let query_cbor = cbor_serializer::serializable_value_to_cbor( &json!({ "where": [], "limit": 100, @@ -2328,7 +2328,7 @@ fn test_family_sql_query() { assert_eq!(query1, query2); // Equality clause - let query_cbor = serializer::serializable_value_to_cbor( + let query_cbor = cbor_serializer::serializable_value_to_cbor( &json!({ "where": [ ["firstName", "==", "Chris"] @@ -2346,7 +2346,7 @@ fn test_family_sql_query() { assert_eq!(query1, query2); // Less than - let query_cbor = serializer::serializable_value_to_cbor( + let query_cbor = cbor_serializer::serializable_value_to_cbor( &json!({ "where": [ ["firstName", "<", "Chris"] @@ -2369,7 +2369,7 @@ fn test_family_sql_query() { assert_eq!(query1, query2); // Starts with - let query_cbor = serializer::serializable_value_to_cbor( + let query_cbor = cbor_serializer::serializable_value_to_cbor( &json!({ "where": [ ["firstName", "StartsWith", "C"] @@ -2392,7 +2392,7 @@ fn test_family_sql_query() { assert_eq!(query1, query2); // Range combination - let query_cbor = serializer::serializable_value_to_cbor( + let query_cbor = cbor_serializer::serializable_value_to_cbor( &json!({ "where": [ ["firstName", ">", "Chris"], @@ -2416,7 +2416,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( + let query_cbor = cbor_serializer::serializable_value_to_cbor( &json!({ "where": [ ["firstName", "in", names] @@ -2482,7 +2482,7 @@ fn test_family_with_nulls_query() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -2592,7 +2592,7 @@ fn test_query_with_cached_contract() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let QuerySerializedDocumentsOutcome { items, .. } = drive @@ -2659,7 +2659,7 @@ fn test_dpns_query() { ["normalizedLabel", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -2706,7 +2706,7 @@ fn test_dpns_query() { ["normalizedLabel", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -2781,7 +2781,7 @@ fn test_dpns_query() { ["normalizedLabel", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -2835,7 +2835,7 @@ fn test_dpns_query() { ["normalizedLabel", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -2906,7 +2906,7 @@ fn test_dpns_query() { ["records.dashUniqueIdentityId", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -2958,7 +2958,7 @@ fn test_dpns_query() { ["records.dashUniqueIdentityId", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -3002,7 +3002,7 @@ fn test_dpns_query() { ["records.dashUniqueIdentityId", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -3036,7 +3036,7 @@ fn test_dpns_insertion_no_aliases() { "orderBy": [["records.dashUniqueIdentityId", "desc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract @@ -3089,7 +3089,7 @@ fn test_dpns_insertion_with_aliases() { "orderBy": [["records.dashUniqueIdentityId", "desc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract @@ -3179,7 +3179,7 @@ fn test_dpns_query_start_at() { ["normalizedLabel", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -3267,7 +3267,7 @@ fn test_dpns_query_start_after() { ["normalizedLabel", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -3355,7 +3355,7 @@ fn test_dpns_query_start_at_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -3443,7 +3443,7 @@ fn test_dpns_query_start_after_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -3512,7 +3512,7 @@ fn test_dpns_query_start_at_with_null_id() { }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); - let document_cbor0 = serializer::serializable_value_to_cbor( + let document_cbor0 = cbor_serializer::serializable_value_to_cbor( &value0, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -3559,7 +3559,7 @@ fn test_dpns_query_start_at_with_null_id() { }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); - let document_cbor1 = serializer::serializable_value_to_cbor( + let document_cbor1 = cbor_serializer::serializable_value_to_cbor( &value1, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -3638,7 +3638,7 @@ fn test_dpns_query_start_at_with_null_id() { ["normalizedLabel", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -3716,7 +3716,7 @@ fn test_dpns_query_start_after_with_null_id() { }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); - let document_cbor0 = serializer::serializable_value_to_cbor( + let document_cbor0 = cbor_serializer::serializable_value_to_cbor( &value0, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -3763,7 +3763,7 @@ fn test_dpns_query_start_after_with_null_id() { }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); - let document_cbor1 = serializer::serializable_value_to_cbor( + let document_cbor1 = cbor_serializer::serializable_value_to_cbor( &value1, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -3843,7 +3843,7 @@ fn test_dpns_query_start_after_with_null_id() { ["normalizedLabel", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -3923,7 +3923,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); - let document_cbor0 = serializer::serializable_value_to_cbor( + let document_cbor0 = cbor_serializer::serializable_value_to_cbor( &value0, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -3970,7 +3970,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); - let document_cbor1 = serializer::serializable_value_to_cbor( + let document_cbor1 = cbor_serializer::serializable_value_to_cbor( &value1, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -4060,7 +4060,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -4109,7 +4109,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -4158,7 +4158,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { ["normalizedLabel", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let domain_document_type = contract .document_types @@ -4305,7 +4305,7 @@ fn test_query_a_b_c_d_e_contract() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_json, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_json, None) .expect("expected to serialize to cbor"); drive @@ -4361,7 +4361,7 @@ fn test_query_documents_by_created_at() { }); let contract_cbor = - serializer::serializable_value_to_cbor(&contract, Some(defaults::PROTOCOL_VERSION)) + cbor_serializer::serializable_value_to_cbor(&contract, Some(defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); let contract = @@ -4396,7 +4396,7 @@ fn test_query_documents_by_created_at() { }); let serialized_document = - serializer::serializable_value_to_cbor(&document, Some(defaults::PROTOCOL_VERSION)) + cbor_serializer::serializable_value_to_cbor(&document, Some(defaults::PROTOCOL_VERSION)) .expect("expected to serialize to cbor"); drive @@ -4422,7 +4422,7 @@ fn test_query_documents_by_created_at() { }) .expect("should create cbor"); - let query_bytes = serializer::serializable_value_to_cbor(&query_cbor, None) + let query_bytes = cbor_serializer::serializable_value_to_cbor(&query_cbor, None) .expect("should serialize cbor value to bytes"); let document_type = contract diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index b7f16358dce..68929572a62 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -42,7 +42,7 @@ use std::option::Option::None; #[cfg(feature = "full")] use dpp::document::Document; #[cfg(feature = "full")] -use dpp::util::serializer; +use dpp::util::cbor_serializer; #[cfg(feature = "full")] use rand::seq::SliceRandom; #[cfg(feature = "full")] @@ -219,7 +219,7 @@ pub fn setup( } } let value = serde_json::to_value(person).expect("serialized person"); - let document_cbor = serializer::serializable_value_to_cbor( + let document_cbor = cbor_serializer::serializable_value_to_cbor( &value, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -317,7 +317,7 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -354,7 +354,7 @@ fn test_query_historical() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -383,7 +383,7 @@ fn test_query_historical() { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -427,7 +427,7 @@ fn test_query_historical() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -458,7 +458,7 @@ fn test_query_historical() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -497,7 +497,7 @@ fn test_query_historical() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -525,7 +525,7 @@ fn test_query_historical() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -556,7 +556,7 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -602,7 +602,7 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -644,7 +644,7 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -720,7 +720,7 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -770,7 +770,7 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -814,7 +814,7 @@ fn test_query_historical() { ["firstName", "asc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -852,7 +852,7 @@ fn test_query_historical() { ["firstName", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -923,7 +923,7 @@ fn test_query_historical() { ["age", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -973,7 +973,7 @@ fn test_query_historical() { ["age", "desc"] ] }); - let where_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract .document_types @@ -1058,7 +1058,7 @@ 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::serializable_value_to_cbor( + let person_cbor = cbor_serializer::serializable_value_to_cbor( &serialized_person, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -1109,7 +1109,7 @@ 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::serializable_value_to_cbor( + let person_cbor = cbor_serializer::serializable_value_to_cbor( &serialized_person, Some(drive::drive::defaults::PROTOCOL_VERSION), ) @@ -1150,7 +1150,7 @@ fn test_query_historical() { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1176,7 +1176,7 @@ fn test_query_historical() { ] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1203,7 +1203,7 @@ fn test_query_historical() { "blockTime": 300 }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1232,7 +1232,7 @@ fn test_query_historical() { "orderBy": [["$id", "asc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1273,7 +1273,7 @@ fn test_query_historical() { "orderBy": [["$id", "desc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1310,7 +1310,7 @@ fn test_query_historical() { // let query_value = json!({}); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1337,7 +1337,7 @@ fn test_query_historical() { "orderBy": [["$id", "desc"]] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1389,7 +1389,7 @@ fn test_query_historical() { "blockTime": 300 }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1443,7 +1443,7 @@ fn test_query_historical() { "orderBy": [["$ownerId", "desc"]] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1473,7 +1473,7 @@ fn test_query_historical() { "orderBy": [["$ownerId", "asc"]] }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1515,7 +1515,7 @@ fn test_query_historical() { ], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let (results, _, _) = drive @@ -1540,7 +1540,7 @@ fn test_query_historical() { "orderBy": [["$id", "asc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract @@ -1570,7 +1570,7 @@ fn test_query_historical() { "orderBy": [["$id", "asc"]], }); - let query_cbor = serializer::serializable_value_to_cbor(&query_value, None) + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); let person_document_type = contract diff --git a/packages/rs-platform-serialization/Cargo.toml b/packages/rs-platform-serialization/Cargo.toml new file mode 100644 index 00000000000..893319d9a64 --- /dev/null +++ b/packages/rs-platform-serialization/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "platform-serialization" +authors = ["Samuel Westrich "] +description = "Bincode serialization and deserialization derivations" +version = "0.1.0" +edition = "2021" +license = "MIT" +private = true + +[lib] +proc-macro = true + +[dependencies] +bincode = { version = "2.0.0-rc.3", features = ["serde"] } +proc-macro2 = "1.0.56" +quote = "1.0.26" +syn = "2.0.15" diff --git a/packages/rs-platform-serialization/src/error.rs b/packages/rs-platform-serialization/src/error.rs new file mode 100644 index 00000000000..986251a2ecc --- /dev/null +++ b/packages/rs-platform-serialization/src/error.rs @@ -0,0 +1,11 @@ +/// Errors +#[derive(Debug, thiserror::Error)] +pub enum Error { + /// A serialization Error. + #[error("serialization error: {0}")] + SerializationError(String), + + /// A deserialization Error. + #[error("deserialization error: {0}")] + DeserializationError(String), +} \ No newline at end of file diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs new file mode 100644 index 00000000000..54b13b6147e --- /dev/null +++ b/packages/rs-platform-serialization/src/lib.rs @@ -0,0 +1,25 @@ +extern crate proc_macro; + +use bincode; +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +#[proc_macro_derive(PlatformSerialize)] +pub fn derive_serialize_data_contract(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = &input.ident; + + let expanded = quote! { + impl #name { + pub fn serialize(&self) -> Result, Error> { + let config = config::standard().with_big_endian().with_no_limit(); + bincode::encode_to_vec(self, config).map_err(|e| { + Error::SerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) + }) + } + } + }; + + TokenStream::from(expanded) +} diff --git a/packages/rs-platform-value/Cargo.toml b/packages/rs-platform-value/Cargo.toml index e6700efb3f4..89963a05abd 100644 --- a/packages/rs-platform-value/Cargo.toml +++ b/packages/rs-platform-value/Cargo.toml @@ -1,5 +1,6 @@ [package] name = "platform-value" +authors = ["Samuel Westrich "] description = "A simple value module" version = "0.1.0" edition = "2021" diff --git a/packages/wasm-dpp/src/data_contract/data_contract.rs b/packages/wasm-dpp/src/data_contract/data_contract.rs index fd22177cfa1..6d44bbda575 100644 --- a/packages/wasm-dpp/src/data_contract/data_contract.rs +++ b/packages/wasm-dpp/src/data_contract/data_contract.rs @@ -294,7 +294,7 @@ impl DataContractWasm { #[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_buffer().with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } diff --git a/packages/wasm-dpp/src/document/extended_document.rs b/packages/wasm-dpp/src/document/extended_document.rs index 724bf1db2c0..cba8141c806 100644 --- a/packages/wasm-dpp/src/document/extended_document.rs +++ b/packages/wasm-dpp/src/document/extended_document.rs @@ -299,7 +299,7 @@ impl ExtendedDocumentWasm { #[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_buffer().with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } diff --git a/packages/wasm-dpp/src/identity/mod.rs b/packages/wasm-dpp/src/identity/mod.rs index e34af93ec89..b9189dc0115 100644 --- a/packages/wasm-dpp/src/identity/mod.rs +++ b/packages/wasm-dpp/src/identity/mod.rs @@ -204,7 +204,7 @@ impl IdentityWasm { #[wasm_bindgen(js_name=toBuffer)] pub fn to_buffer(&self) -> Vec { - self.0.to_buffer().unwrap() + self.0.to_cbor_buffer().unwrap() } #[wasm_bindgen] From e0d76c7b3e9b80e2a03af524b6b26c5bb6d2bf8e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 03:10:08 +0700 Subject: [PATCH 10/50] derive macro for serialization --- Cargo.lock | 1 + .../serialize_for_signing.rs | 4 +- packages/rs-dpp/src/errors/errors.rs | 8 +++ packages/rs-platform-serialization/Cargo.toml | 1 + .../rs-platform-serialization/src/error.rs | 11 ---- packages/rs-platform-serialization/src/lib.rs | 66 ++++++++++++++++--- 6 files changed, 70 insertions(+), 21 deletions(-) delete mode 100644 packages/rs-platform-serialization/src/error.rs diff --git a/Cargo.lock b/Cargo.lock index f818271416b..5a56f356228 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2470,6 +2470,7 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.15", + "thiserror", ] [[package]] diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs index 45def59be2e..44205112ec6 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs @@ -5,10 +5,12 @@ use crate::state_transition::StateTransitionType; use crate::util::hash::{hash, hash_to_vec}; use crate::ProtocolError; use bincode::config; +use bincode::Encode; use platform_serialization::PlatformSerialize; use platform_value::Bytes32; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Encode, PlatformSerialize)] +#[platform_serialize_error_type(ProtocolError)] pub struct TempDataContractUpdateTransitionWithoutWitness<'a> { pub protocol_version: u32, pub transition_type: StateTransitionType, diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index 2e6bb1e6864..eb5c7ae979e 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -131,6 +131,14 @@ pub enum ProtocolError { #[error("value error: {0}")] ValueError(#[from] ValueError), + /// Value error + #[error("platform serialization error: {0}")] + PlatformSerializationError(String), + + /// Value error + #[error("platform deserialization error: {0}")] + PlatformDeserializationError(String), + /// Dash core error #[error("dash core error: {0}")] DashCoreError(#[from] DashCoreError), diff --git a/packages/rs-platform-serialization/Cargo.toml b/packages/rs-platform-serialization/Cargo.toml index 893319d9a64..ea37e29e6fc 100644 --- a/packages/rs-platform-serialization/Cargo.toml +++ b/packages/rs-platform-serialization/Cargo.toml @@ -11,6 +11,7 @@ private = true proc-macro = true [dependencies] +thiserror = { version = "1.0" } bincode = { version = "2.0.0-rc.3", features = ["serde"] } proc-macro2 = "1.0.56" quote = "1.0.26" diff --git a/packages/rs-platform-serialization/src/error.rs b/packages/rs-platform-serialization/src/error.rs deleted file mode 100644 index 986251a2ecc..00000000000 --- a/packages/rs-platform-serialization/src/error.rs +++ /dev/null @@ -1,11 +0,0 @@ -/// Errors -#[derive(Debug, thiserror::Error)] -pub enum Error { - /// A serialization Error. - #[error("serialization error: {0}")] - SerializationError(String), - - /// A deserialization Error. - #[error("deserialization error: {0}")] - DeserializationError(String), -} \ No newline at end of file diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 54b13b6147e..15462653468 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -5,18 +5,66 @@ use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput}; -#[proc_macro_derive(PlatformSerialize)] -pub fn derive_serialize_data_contract(input: TokenStream) -> TokenStream { +#[proc_macro_derive( + PlatformSerialize, + attributes(platform_serialize_error_type, platform_serialize_limit) +)] +pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; - let expanded = quote! { - impl #name { - pub fn serialize(&self) -> Result, Error> { - let config = config::standard().with_big_endian().with_no_limit(); - bincode::encode_to_vec(self, config).map_err(|e| { - Error::SerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) - }) + // Extract the error type from the attribute. + let error_type = input + .attrs + .iter() + .find_map(|attr| { + if attr.path().is_ident("platform_serialize_error_type") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }) + .expect("Missing platform_serialize_error_type attribute"); + + // Extract the serialization limit from the attribute, if it exists. + let limit = input.attrs.iter().find_map(|attr| { + if attr.path().is_ident("platform_serialize_limit") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }); + + // Extract the generics. + let generics = &input.generics; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let expanded = if let Some(limit) = limit { + quote! { + impl #impl_generics #name #ty_generics #where_clause + where + Self: bincode::Encode + { + pub fn serialize(&self) -> Result, #error_type> { + let config = config::standard().with_big_endian().with_limit(#limit); + bincode::encode_to_vec(self, config).map_err(|e| { + #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) + }) + } + } + } + } else { + quote! { + impl #impl_generics #name #ty_generics #where_clause + where + Self: bincode::Encode + { + pub fn serialize(&self) -> Result, #error_type> { + let config = config::standard().with_big_endian().with_no_limit(); + bincode::encode_to_vec(self, config).map_err(|e| { + #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) + }) + } } } }; From ae7ca277a3502f9e2fe30dbd76d96bd4cecdb412 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 03:48:55 +0700 Subject: [PATCH 11/50] derive macro for deserialization --- packages/rs-platform-serialization/src/lib.rs | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 15462653468..b7dcda89bab 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -71,3 +71,56 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } + +#[proc_macro_derive(PlatformDeserialize, attributes(platform_deserialize_error_type, platform_deserialize_limit))] +pub fn derive_platform_deserialize(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = &input.ident; + + // Extract the generics. + let generics = &input.generics; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + // Extract the platform_deserialize_error_type attribute, if provided. + let platform_deserialize_error_type = input + .attrs + .iter() + .find_map(|attr| { + if attr.path().is_ident("platform_deserialize_error_type") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }) + .unwrap_or_else(|| syn::parse_str("Error").unwrap()); + + // Extract the platform_deserialize_limit attribute, if provided. + let platform_deserialize_limit: Option = input + .attrs + .iter() + .find_map(|attr| { + if attr.path().is_ident("platform_deserialize_limit") { + Some(attr.parse_args::().unwrap().base10_parse().unwrap()) + } else { + None + } + }); + + let config = match platform_deserialize_limit { + Some(limit) => quote! { config::standard().with_big_endian().with_limit(#limit) }, + None => quote! { config::standard().with_big_endian().with_no_limit() }, + }; + + let expanded = quote! { + impl #impl_generics #name #ty_generics #where_clause { + pub fn deserialize(data: &[u8]) -> Result { + let config = #config; + bincode::decode_from_slice(data, config).map_err(|e| { + #platform_deserialize_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + }) + } + } + }; + + TokenStream::from(expanded) +} \ No newline at end of file From 75e9c714c3d1b1cd5ba962fb571a59e6f0aff20b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 04:58:41 +0700 Subject: [PATCH 12/50] more work on macros --- packages/rs-dpp/src/block/block_info.rs | 28 +--- .../rs-dpp/src/data_contract/data_contract.rs | 12 +- .../data_contract/serialization/bincode.rs | 32 ----- .../data_contract_create_transition/mod.rs | 1 + .../serialize_for_signing.rs | 2 +- packages/rs-dpp/src/identity/identity.rs | 20 ++- packages/rs-dpp/src/identity/mod.rs | 1 - packages/rs-dpp/src/identity/serialize.rs | 24 ---- packages/rs-platform-serialization/src/lib.rs | 133 ++++++++++++++---- 9 files changed, 141 insertions(+), 112 deletions(-) delete mode 100644 packages/rs-dpp/src/identity/serialize.rs diff --git a/packages/rs-dpp/src/block/block_info.rs b/packages/rs-dpp/src/block/block_info.rs index 4d1d49742d1..88f2c28dec3 100644 --- a/packages/rs-dpp/src/block/block_info.rs +++ b/packages/rs-dpp/src/block/block_info.rs @@ -2,9 +2,12 @@ use crate::block::epoch::Epoch; use crate::ProtocolError; use bincode::config; use bincode::{Decode, Encode}; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; /// Block information -#[derive(Clone, Default, Encode, Decode)] +#[derive(Clone, Default, Encode, Decode, PlatformSerialize, PlatformDeserialize)] +#[platform_error_type(ProtocolError)] +#[platform_deserialize_limit(15000)] pub struct BlockInfo { /// Block time in milliseconds pub time_ms: u64, @@ -42,27 +45,4 @@ impl BlockInfo { ..Default::default() } } - - /// Serialize block info - pub fn serialize(&self) -> Result, ProtocolError> { - let config = config::standard().with_big_endian().with_no_limit(); - bincode::encode_to_vec(self, config).map_err(|e| { - ProtocolError::EncodingError(format!("unable to serialize data contract {e}")) - }) - } - - /// The size of serialized block info - pub fn serialized_size(&self) -> Result { - self.serialize().map(|a| a.len()) - } - - /// Deserialization of block info - pub fn deserialize(bytes: &[u8]) -> Result { - let config = config::standard().with_big_endian().with_limit::<15000>(); - bincode::decode_from_slice(bytes, config) - .map_err(|e| { - ProtocolError::EncodingError(format!("unable to deserialize block info {}", e)) - }) - .map(|(a, _)| a) - } } diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 9a56bc63018..aed9796a227 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -1,3 +1,4 @@ +use bincode::config; use bincode::de::{BorrowDecoder, Decoder}; use bincode::enc::Encoder; use bincode::error::{DecodeError, EncodeError}; @@ -30,6 +31,8 @@ use crate::{errors::ProtocolError, metadata::Metadata, util::hash::hash_to_vec}; use crate::{identifier, Convertible}; use platform_value::string_encoding::Encoding; +use platform_serialization::{PlatformDeserialize, PlatformDeserializeNoLimit, PlatformSerialize}; + use super::document_type::DocumentType; use super::errors::*; @@ -102,7 +105,14 @@ impl Convertible for DataContract { /// /// Additionally, `DataContract` holds definitions for JSON schemas, entropy, and binary properties /// of the documents. -#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq)] +#[derive( + Serialize, Deserialize, Debug, Clone, Default, PartialEq, PlatformSerialize, PlatformDeserialize, +)] // , PlatformDeserializeNoLimit +#[platform_error_type(ProtocolError)] +#[platform_deserialize_limit(15000)] +#[platform_serialize_limit(15000)] +#[platform_serialize_into(DataContractInner)] +#[platform_deserialize_from(DataContractInner)] #[serde(try_from = "DataContractInner")] pub struct DataContract { /// The version of the protocol this contract adheres to. diff --git a/packages/rs-dpp/src/data_contract/serialization/bincode.rs b/packages/rs-dpp/src/data_contract/serialization/bincode.rs index 8fa873c5cf2..89026a23058 100644 --- a/packages/rs-dpp/src/data_contract/serialization/bincode.rs +++ b/packages/rs-dpp/src/data_contract/serialization/bincode.rs @@ -4,14 +4,6 @@ use bincode::config; use std::convert::TryInto; impl DataContract { - pub fn serialize(&self) -> Result, ProtocolError> { - let config = config::standard().with_big_endian().with_no_limit(); - let inner: DataContractInner = self.clone().into(); - bincode::encode_to_vec(inner, config).map_err(|e| { - ProtocolError::EncodingError(format!("unable to serialize data contract {e}")) - }) - } - pub fn serialize_consume(self) -> Result, ProtocolError> { let config = config::standard().with_big_endian().with_no_limit(); let inner: DataContractInner = self.into(); @@ -19,30 +11,6 @@ impl DataContract { ProtocolError::EncodingError(format!("unable to serialize data contract {e}")) }) } - - pub fn serialized_size(&self) -> Result { - self.serialize().map(|a| a.len()) - } - - pub fn deserialize(bytes: &[u8]) -> Result { - let config = config::standard().with_big_endian(); - let inner: DataContractInner = bincode::decode_from_slice(bytes, config) - .map_err(|e| { - ProtocolError::EncodingError(format!("unable to deserialize data contract {}", e)) - }) - .map(|(a, _)| a)?; - inner.try_into() - } - - pub fn deserialize_with_limit(bytes: &[u8]) -> Result { - let config = config::standard().with_big_endian().with_limit::<20000>(); - let inner: DataContractInner = bincode::decode_from_slice(bytes, config) - .map_err(|e| { - ProtocolError::EncodingError(format!("unable to deserialize data contract {}", e)) - }) - .map(|(a, _)| a)?; - inner.try_into() - } } #[cfg(test)] 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 676b7679900..98bbc9468e7 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,6 +1,7 @@ use std::collections::BTreeMap; use std::convert::TryInto; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::{BinaryData, Bytes32, IntegerReplacementType, ReplacementType, Value}; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs index 44205112ec6..581939061d1 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs @@ -10,7 +10,7 @@ use platform_serialization::PlatformSerialize; use platform_value::Bytes32; #[derive(Debug, Clone, PartialEq, Encode, PlatformSerialize)] -#[platform_serialize_error_type(ProtocolError)] +#[platform_error_type(ProtocolError)] pub struct TempDataContractUpdateTransitionWithoutWitness<'a> { pub protocol_version: u32, pub transition_type: StateTransitionType, diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 98f5dbb9a89..de90728c8ca 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -17,9 +17,10 @@ use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::{ errors::ProtocolError, identifier::Identifier, metadata::Metadata, util::hash, Convertible, }; -use bincode::{Decode, Encode}; +use bincode::{config, Decode, Encode}; #[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; use super::{IdentityPublicKey, KeyID}; @@ -36,7 +37,22 @@ pub const IDENTIFIER_FIELDS_RAW_OBJECT: [&str; 1] = [property_names::ID_RAW_OBJE /// Implement the Identity. Identity is a low-level construct that provides the foundation /// for user-facing functionality on the platform -#[derive(Default, Debug, Serialize, Deserialize, Encode, Decode, Clone, Eq, PartialEq)] +#[derive( + Default, + Debug, + Serialize, + Deserialize, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + Clone, + Eq, + PartialEq, +)] +#[platform_error_type(ProtocolError)] +#[platform_deserialize_limit(15000)] +#[platform_serialize_limit(15000)] #[serde(rename_all = "camelCase")] pub struct Identity { pub protocol_version: u32, diff --git a/packages/rs-dpp/src/identity/mod.rs b/packages/rs-dpp/src/identity/mod.rs index 0cf2fb81791..1a7dfbbfefa 100644 --- a/packages/rs-dpp/src/identity/mod.rs +++ b/packages/rs-dpp/src/identity/mod.rs @@ -17,5 +17,4 @@ pub mod validation; mod credits_converter; pub mod errors; pub mod factory; -pub mod serialize; pub mod signer; diff --git a/packages/rs-dpp/src/identity/serialize.rs b/packages/rs-dpp/src/identity/serialize.rs deleted file mode 100644 index 4883ffae42c..00000000000 --- a/packages/rs-dpp/src/identity/serialize.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::prelude::Identity; -use crate::ProtocolError; -use bincode::config; - -impl Identity { - pub fn serialize(&self) -> Result, ProtocolError> { - let config = config::standard().with_big_endian().with_limit::<15000>(); - bincode::encode_to_vec(self, config) - .map_err(|_| ProtocolError::EncodingError(String::from("unable to serialize identity"))) - } - - pub fn serialized_size(&self) -> Result { - self.serialize().map(|a| a.len()) - } - - pub fn deserialize(bytes: &[u8]) -> Result { - let config = config::standard().with_big_endian().with_limit::<15000>(); - bincode::decode_from_slice(bytes, config) - .map_err(|e| { - ProtocolError::EncodingError(format!("unable to deserialize identity {}", e)) - }) - .map(|(a, _)| a) - } -} diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index b7dcda89bab..1012a73bf03 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -7,7 +7,7 @@ use syn::{parse_macro_input, DeriveInput}; #[proc_macro_derive( PlatformSerialize, - attributes(platform_serialize_error_type, platform_serialize_limit) + attributes(platform_error_type, platform_serialize_limit, platform_serialize_into) )] pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); @@ -18,13 +18,13 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { .attrs .iter() .find_map(|attr| { - if attr.path().is_ident("platform_serialize_error_type") { + if attr.path().is_ident("platform_error_type") { Some(attr.parse_args::().unwrap()) } else { None } }) - .expect("Missing platform_serialize_error_type attribute"); + .expect("Missing platform_error_type attribute"); // Extract the serialization limit from the attribute, if it exists. let limit = input.attrs.iter().find_map(|attr| { @@ -35,19 +35,35 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { } }); + let platform_serialize_into: Option = input.attrs.iter().find_map(|attr| { + if attr.path().is_ident("platform_serialize_into") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }); + // Extract the generics. let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let serialize_into = match platform_serialize_into { + Some(inner) => quote! { + let inner: #inner = self.clone().into(); + bincode::encode_to_vec(inner, config) + }, + None => quote! { + bincode::encode_to_vec(self, config) + }, + }; + let expanded = if let Some(limit) = limit { quote! { impl #impl_generics #name #ty_generics #where_clause - where - Self: bincode::Encode { pub fn serialize(&self) -> Result, #error_type> { let config = config::standard().with_big_endian().with_limit(#limit); - bincode::encode_to_vec(self, config).map_err(|e| { + #serialize_into.map_err(|e| { #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) }) } @@ -56,12 +72,10 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { } else { quote! { impl #impl_generics #name #ty_generics #where_clause - where - Self: bincode::Encode { pub fn serialize(&self) -> Result, #error_type> { let config = config::standard().with_big_endian().with_no_limit(); - bincode::encode_to_vec(self, config).map_err(|e| { + #serialize_into.map_err(|e| { #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) }) } @@ -72,7 +86,14 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } -#[proc_macro_derive(PlatformDeserialize, attributes(platform_deserialize_error_type, platform_deserialize_limit))] +#[proc_macro_derive( + PlatformDeserialize, + attributes( + platform_error_type, + platform_deserialize_limit, + platform_deserialize_from + ) +)] pub fn derive_platform_deserialize(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; @@ -81,12 +102,12 @@ pub fn derive_platform_deserialize(input: TokenStream) -> TokenStream { let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - // Extract the platform_deserialize_error_type attribute, if provided. - let platform_deserialize_error_type = input + // Extract the platform_error_type attribute, if provided. + let platform_error_type = input .attrs .iter() .find_map(|attr| { - if attr.path().is_ident("platform_deserialize_error_type") { + if attr.path().is_ident("platform_error_type") { Some(attr.parse_args::().unwrap()) } else { None @@ -95,16 +116,38 @@ pub fn derive_platform_deserialize(input: TokenStream) -> TokenStream { .unwrap_or_else(|| syn::parse_str("Error").unwrap()); // Extract the platform_deserialize_limit attribute, if provided. - let platform_deserialize_limit: Option = input - .attrs - .iter() - .find_map(|attr| { - if attr.path().is_ident("platform_deserialize_limit") { - Some(attr.parse_args::().unwrap().base10_parse().unwrap()) - } else { - None - } - }); + let platform_deserialize_limit: Option = input.attrs.iter().find_map(|attr| { + if attr.path().is_ident("platform_deserialize_limit") { + Some( + attr.parse_args::() + .unwrap() + .base10_parse() + .unwrap(), + ) + } else { + None + } + }); + + let platform_deserialize_from: Option = input.attrs.iter().find_map(|attr| { + if attr.path().is_ident("platform_deserialize_from") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }); + + let deserialize_from_inner = match platform_deserialize_from { + Some(inner) => quote! { + let inner: #inner = bincode::decode_from_slice(data, config)?; + inner.try_into().map_err(|e: #platform_error_type| { + #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + }) + }, + None => quote! { + bincode::decode_from_slice(data, config) + }, + }; let config = match platform_deserialize_limit { Some(limit) => quote! { config::standard().with_big_endian().with_limit(#limit) }, @@ -113,14 +156,50 @@ pub fn derive_platform_deserialize(input: TokenStream) -> TokenStream { let expanded = quote! { impl #impl_generics #name #ty_generics #where_clause { - pub fn deserialize(data: &[u8]) -> Result { + pub fn deserialize(data: &[u8]) -> Result { let config = #config; - bincode::decode_from_slice(data, config).map_err(|e| { - #platform_deserialize_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + #deserialize_from_inner.map_err(|e| { + #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) }) } } }; TokenStream::from(expanded) -} \ No newline at end of file +} + +#[proc_macro_derive(PlatformDeserializeNoLimit, attributes(platform_error_type))] +pub fn derive_platform_deserialize_no_limit(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = &input.ident; + + // Extract the generics. + let generics = &input.generics; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + // Extract the platform_error_type attribute, if provided. + let platform_error_type = input + .attrs + .iter() + .find_map(|attr| { + if attr.path().is_ident("platform_error_type") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }) + .unwrap_or_else(|| syn::parse_str("Error").unwrap()); + + let deserialize_impl = quote! { + impl #impl_generics #name #ty_generics #where_clause { + pub fn deserialize_no_limit(data: &[u8]) -> Result { + let config = config::standard().with_big_endian().with_no_limit(); + bincode::decode_from_slice(data, config).map_err(|e| { + #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + }).map(|(a, _)| a) + } + } + }; + + TokenStream::from(deserialize_impl) +} From 7590c87100dc0eee3b954938e341dff14e5b4a2b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 05:26:03 +0700 Subject: [PATCH 13/50] more work on macros --- .../rs-dpp/src/data_contract/data_contract.rs | 10 ++- .../data_contract/serialization/bincode.rs | 15 ---- packages/rs-platform-serialization/src/lib.rs | 69 ++++++++++++++++--- 3 files changed, 67 insertions(+), 27 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index aed9796a227..9d4c1c761ef 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -106,7 +106,15 @@ impl Convertible for DataContract { /// Additionally, `DataContract` holds definitions for JSON schemas, entropy, and binary properties /// of the documents. #[derive( - Serialize, Deserialize, Debug, Clone, Default, PartialEq, PlatformSerialize, PlatformDeserialize, + Serialize, + Deserialize, + Debug, + Clone, + Default, + PartialEq, + PlatformSerialize, + PlatformDeserialize, + PlatformDeserializeNoLimit, )] // , PlatformDeserializeNoLimit #[platform_error_type(ProtocolError)] #[platform_deserialize_limit(15000)] diff --git a/packages/rs-dpp/src/data_contract/serialization/bincode.rs b/packages/rs-dpp/src/data_contract/serialization/bincode.rs index 89026a23058..6681b904799 100644 --- a/packages/rs-dpp/src/data_contract/serialization/bincode.rs +++ b/packages/rs-dpp/src/data_contract/serialization/bincode.rs @@ -1,18 +1,3 @@ -use crate::data_contract::{DataContract, DataContractInner}; -use crate::ProtocolError; -use bincode::config; -use std::convert::TryInto; - -impl DataContract { - pub fn serialize_consume(self) -> Result, ProtocolError> { - let config = config::standard().with_big_endian().with_no_limit(); - let inner: DataContractInner = self.into(); - bincode::encode_to_vec(inner, config).map_err(|e| { - ProtocolError::EncodingError(format!("unable to serialize data contract {e}")) - }) - } -} - #[cfg(test)] mod tests { use crate::data_contract::DataContract; diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 1012a73bf03..8f98173ee13 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -4,7 +4,6 @@ use bincode; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput}; - #[proc_macro_derive( PlatformSerialize, attributes(platform_error_type, platform_serialize_limit, platform_serialize_into) @@ -47,7 +46,7 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let serialize_into = match platform_serialize_into { + let serialize_into = match platform_serialize_into.clone() { Some(inner) => quote! { let inner: #inner = self.clone().into(); bincode::encode_to_vec(inner, config) @@ -57,16 +56,33 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { }, }; + let serialize_into_consume = match platform_serialize_into { + Some(inner) => quote! { + let inner: #inner = self.into(); + bincode::encode_to_vec(inner, config) + }, + None => quote! { + bincode::encode_to_vec(self, config) + }, + }; + let expanded = if let Some(limit) = limit { quote! { impl #impl_generics #name #ty_generics #where_clause { pub fn serialize(&self) -> Result, #error_type> { - let config = config::standard().with_big_endian().with_limit(#limit); + let config = config::standard().with_big_endian().with_limit::<{ #limit }>(); #serialize_into.map_err(|e| { #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) }) } + + pub fn serialize_consume(self) -> Result, #error_type> { + let config = config::standard().with_big_endian().with_limit::<{ #limit }>(); + #serialize_into_consume.map_err(|e| { + #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) + }) + } } } } else { @@ -139,18 +155,22 @@ pub fn derive_platform_deserialize(input: TokenStream) -> TokenStream { let deserialize_from_inner = match platform_deserialize_from { Some(inner) => quote! { - let inner: #inner = bincode::decode_from_slice(data, config)?; + let inner: #inner = bincode::decode_from_slice(data, config).map_err(|e| { + #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + }).map(|(a, _)| a)?; inner.try_into().map_err(|e: #platform_error_type| { #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) }) }, None => quote! { - bincode::decode_from_slice(data, config) + bincode::decode_from_slice(data, config).map(|(a, _)| a).map_err(|e| { + #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + }) }, }; let config = match platform_deserialize_limit { - Some(limit) => quote! { config::standard().with_big_endian().with_limit(#limit) }, + Some(limit) => quote! { config::standard().with_big_endian().with_limit::<{ #limit }>() }, None => quote! { config::standard().with_big_endian().with_no_limit() }, }; @@ -168,7 +188,10 @@ pub fn derive_platform_deserialize(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } -#[proc_macro_derive(PlatformDeserializeNoLimit, attributes(platform_error_type))] +#[proc_macro_derive( + PlatformDeserializeNoLimit, + attributes(platform_error_type, platform_deserialize_from) +)] pub fn derive_platform_deserialize_no_limit(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; @@ -190,16 +213,40 @@ pub fn derive_platform_deserialize_no_limit(input: TokenStream) -> TokenStream { }) .unwrap_or_else(|| syn::parse_str("Error").unwrap()); - let deserialize_impl = quote! { + let platform_deserialize_from: Option = input.attrs.iter().find_map(|attr| { + if attr.path().is_ident("platform_deserialize_from") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }); + + let deserialize_from_inner = match platform_deserialize_from { + Some(inner) => quote! { + let inner: #inner = bincode::decode_from_slice(data, config).map_err(|e| { + #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + }).map(|(a, _)| a)?; + inner.try_into().map_err(|e: #platform_error_type| { + #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + }) + }, + None => quote! { + bincode::decode_from_slice(data, config).map(|(a, _)| a).map_err(|e| { + #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) + }) + }, + }; + + let expanded = quote! { impl #impl_generics #name #ty_generics #where_clause { pub fn deserialize_no_limit(data: &[u8]) -> Result { let config = config::standard().with_big_endian().with_no_limit(); - bincode::decode_from_slice(data, config).map_err(|e| { + #deserialize_from_inner.map_err(|e| { #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) - }).map(|(a, _)| a) + }) } } }; - TokenStream::from(deserialize_impl) + TokenStream::from(expanded) } From eeea9ee78c71e422d573c422d651990bfd52af63 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 05:39:52 +0700 Subject: [PATCH 14/50] more work on deserialization --- .../src/identity/identity_public_key/mod.rs | 35 ++++++++++++++++-- .../identity/identity_public_key/serialize.rs | 37 ------------------- .../identity_public_key_transitions/mod.rs | 9 +++-- .../serialize.rs | 24 ------------ packages/rs-dpp/src/state_transition/mod.rs | 19 +++++++++- .../src/state_transition/serialization.rs | 23 ------------ 6 files changed, 55 insertions(+), 92 deletions(-) delete mode 100644 packages/rs-dpp/src/identity/identity_public_key/serialize.rs delete mode 100644 packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/serialize.rs 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 926e0f19dda..db2ded5edc0 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -4,7 +4,6 @@ pub mod factory; pub mod key_type; pub mod purpose; pub mod security_level; -pub mod serialize; use std::convert::{TryFrom, TryInto}; @@ -26,10 +25,11 @@ use crate::util::cbor_serializer; use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; use crate::util::hash::ripemd160_sha256; use crate::Convertible; -use bincode::{Decode, Encode}; +use bincode::{config, Decode, Encode}; use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyInCreationWithWitness; use crate::util::vec; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; pub type KeyID = u32; pub type TimestampMillis = u64; @@ -37,9 +37,24 @@ pub type TimestampMillis = u64; pub const BINARY_DATA_FIELDS: [&str; 1] = ["data"]; #[derive( - Debug, Serialize, Deserialize, Encode, Decode, Clone, PartialEq, Eq, Ord, PartialOrd, Hash, + Debug, + Serialize, + Deserialize, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + Clone, + PartialEq, + Eq, + Ord, + PartialOrd, + Hash, )] #[serde(rename_all = "camelCase")] +#[platform_error_type(ProtocolError)] +#[platform_deserialize_limit(2000)] +#[platform_serialize_limit(2000)] pub struct IdentityPublicKey { pub id: KeyID, pub purpose: Purpose, @@ -281,3 +296,17 @@ where { serializer.serialize_str(&base64::encode(buffer)) } + +#[cfg(test)] +mod tests { + use crate::identity::IdentityPublicKey; + + #[test] + fn test_identity_key_serialization_deserialization() { + let key = IdentityPublicKey::random_key(1, Some(500)); + let serialized = key.serialize().expect("expected to serialize key"); + let unserialized = IdentityPublicKey::deserialize(serialized.as_slice()) + .expect("expected to deserialize key"); + assert_eq!(key, unserialized) + } +} diff --git a/packages/rs-dpp/src/identity/identity_public_key/serialize.rs b/packages/rs-dpp/src/identity/identity_public_key/serialize.rs deleted file mode 100644 index 981539ef24e..00000000000 --- a/packages/rs-dpp/src/identity/identity_public_key/serialize.rs +++ /dev/null @@ -1,37 +0,0 @@ -use crate::identity::IdentityPublicKey; -use crate::ProtocolError; -use bincode::config; - -impl IdentityPublicKey { - pub fn serialize(&self) -> Result, ProtocolError> { - let config = config::standard().with_big_endian().with_limit::<2000>(); - bincode::encode_to_vec(self, config).map_err(|_| { - ProtocolError::EncodingError(String::from("unable to serialize identity public key")) - }) - } - - pub fn serialized_size(&self) -> Result { - self.serialize().map(|a| a.len()) - } - - pub fn deserialize(bytes: &[u8]) -> Result { - let config = config::standard().with_big_endian().with_limit::<2000>(); - bincode::decode_from_slice(bytes, config) - .map_err(|e| ProtocolError::EncodingError(format!("unable to deserialize key {}", e))) - .map(|(a, _)| a) - } -} - -#[cfg(test)] -mod tests { - use crate::identity::IdentityPublicKey; - - #[test] - fn test_identity_key_serialization_deserialization() { - let key = IdentityPublicKey::random_key(1, Some(500)); - let serialized = key.serialize().expect("expected to serialize key"); - let unserialized = IdentityPublicKey::deserialize(serialized.as_slice()) - .expect("expected to deserialize key"); - assert_eq!(key, unserialized) - } -} diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs index a4fbbf1763a..5c51a0a8ee1 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs @@ -1,4 +1,3 @@ -mod serialize; use crate::identity::{IdentityPublicKey, KeyID, KeyType, Purpose, SecurityLevel}; #[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; @@ -6,7 +5,7 @@ use dashcore::signer; use std::collections::BTreeMap; use std::convert::{TryFrom, TryInto}; -use bincode::{Decode, Encode}; +use bincode::{config, Decode, Encode}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; @@ -18,6 +17,7 @@ use crate::consensus::signature::SignatureError; use crate::consensus::ConsensusError; use crate::errors::ProtocolError; use crate::identity::signer::Signer; +use crate::platform_serialization::{PlatformDeserialize, PlatformSerialize}; use crate::state_transition::errors::InvalidIdentityPublicKeyTypeError; #[cfg(feature = "cbor")] use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; @@ -41,7 +41,10 @@ pub struct IdentityPublicKeyInCreationWithWitness { pub signature: BinaryData, } -#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq)] +#[derive(Debug, Encode, Decode, PlatformDeserialize, PlatformSerialize, Clone, PartialEq, Eq)] +#[platform_error_type(ProtocolError)] +#[platform_deserialize_limit(2000)] +#[platform_serialize_limit(2000)] pub struct IdentityPublicKeyInCreationWithoutWitness { pub id: KeyID, pub key_type: KeyType, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/serialize.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/serialize.rs deleted file mode 100644 index 86636c28054..00000000000 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/serialize.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::identity::state_transition::identity_public_key_transitions::IdentityPublicKeyInCreationWithoutWitness; - -use crate::ProtocolError; -use bincode::config; - -impl IdentityPublicKeyInCreationWithoutWitness { - pub fn serialize(&self) -> Result, ProtocolError> { - let config = config::standard().with_big_endian().with_limit::<2000>(); - bincode::encode_to_vec(self, config).map_err(|_| { - ProtocolError::EncodingError(String::from("unable to serialize identity public key")) - }) - } - - pub fn serialized_size(&self) -> Result { - self.serialize().map(|a| a.len()) - } - - pub fn deserialize(bytes: &[u8]) -> Result { - let config = config::standard().with_big_endian().with_limit::<2000>(); - bincode::decode_from_slice(bytes, config) - .map_err(|e| ProtocolError::EncodingError(format!("unable to deserialize key {}", e))) - .map(|(a, _)| a) - } -} diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 005833c4622..790c1041364 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -17,7 +17,8 @@ use crate::identity::state_transition::identity_credit_withdrawal_transition::Id use crate::identity::state_transition::identity_topup_transition::IdentityTopUpTransition; use crate::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; use crate::prelude::Identifier; -use bincode::{Decode, Encode}; +use bincode::{config, Decode, Encode}; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; mod abstract_state_transition; mod abstract_state_transition_identity_signed; @@ -80,7 +81,21 @@ macro_rules! call_static_method { }; } -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, From, PartialEq)] +#[derive( + Debug, + Clone, + Serialize, + Deserialize, + Encode, + Decode, + PlatformSerialize, + PlatformDeserialize, + From, + PartialEq, +)] +#[platform_error_type(ProtocolError)] +#[platform_deserialize_limit(100000)] +#[platform_serialize_limit(100000)] pub enum StateTransition { DataContractCreate(DataContractCreateTransition), DataContractUpdate(DataContractUpdateTransition), diff --git a/packages/rs-dpp/src/state_transition/serialization.rs b/packages/rs-dpp/src/state_transition/serialization.rs index 91bc51f50fc..f8921427d07 100644 --- a/packages/rs-dpp/src/state_transition/serialization.rs +++ b/packages/rs-dpp/src/state_transition/serialization.rs @@ -3,29 +3,6 @@ use crate::ProtocolError; use bincode::config; impl StateTransition { - pub fn serialize(&self) -> Result, ProtocolError> { - let config = config::standard().with_big_endian().with_no_limit(); - bincode::encode_to_vec(self, config).map_err(|e| { - ProtocolError::EncodingError(format!("unable to serialize state transition {e}")) - }) - } - - pub fn serialized_size(&self) -> Result { - self.serialize().map(|a| a.len()) - } - - pub fn deserialize(bytes: &[u8]) -> Result { - let config = config::standard().with_big_endian().with_limit::<100000>(); - bincode::decode_from_slice(bytes, config) - .map_err(|e| { - ProtocolError::EncodingError(format!( - "unable to deserialize state transition {}", - e - )) - }) - .map(|(a, _)| a) - } - pub fn deserialize_many( raw_state_transitions: &Vec>, ) -> Result, ProtocolError> { From 5209661c18e34331606ac12631d7d1b1cae14fca Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 06:17:04 +0700 Subject: [PATCH 15/50] dpp tests passing --- .../rs-dpp/src/data_contract/data_contract.rs | 12 +++- .../src/drive/batch/drive_op_batch/mod.rs | 68 +++++++++---------- packages/rs-drive/src/drive/contract/mod.rs | 25 ++----- 3 files changed, 48 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 9d4c1c761ef..d40ffd380bf 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -115,21 +115,24 @@ impl Convertible for DataContract { PlatformSerialize, PlatformDeserialize, PlatformDeserializeNoLimit, -)] // , PlatformDeserializeNoLimit +)] #[platform_error_type(ProtocolError)] #[platform_deserialize_limit(15000)] #[platform_serialize_limit(15000)] #[platform_serialize_into(DataContractInner)] #[platform_deserialize_from(DataContractInner)] #[serde(try_from = "DataContractInner")] +#[serde(rename_all = "camelCase")] pub struct DataContract { /// The version of the protocol this contract adheres to. pub protocol_version: u32, /// A unique identifier for the data contract. + #[serde(rename = "$id")] pub id: Identifier, /// A reference to the JSON schema that defines the contract. + #[serde(rename = "$schema")] pub schema: String, /// The version of this data contract. @@ -139,24 +142,30 @@ pub struct DataContract { pub owner_id: Identifier, /// A mapping of document names to their corresponding document types. + #[serde(skip)] pub document_types: BTreeMap, /// Optional metadata associated with the contract. + #[serde(skip)] pub metadata: Option, /// Internal configuration for the contract. + #[serde(skip)] pub config: ContractConfig, /// A mapping of document names to their corresponding JSON schemas. pub documents: BTreeMap, /// Optional mapping of definition names to their corresponding JSON schemas. + #[serde(rename = "$defs", default)] pub defs: Option>, /// A randomly generated value used for creating unique identifiers within the contract. + #[serde(skip)] pub entropy: Bytes32, /// A nested mapping of document names and property paths to their binary values. + #[serde(skip)] pub binary_properties: BTreeMap>, } @@ -842,6 +851,7 @@ mod test { let data_contract: DataContract = serde_json::from_str(&string_contract)?; let raw_data_contract = data_contract.to_json_object()?; + dbg!(&raw_data_contract); for path in IDENTIFIER_FIELDS { assert!(raw_data_contract .get(path) 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 f9da3d4bc9b..3e8e2ab7e36 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 @@ -308,7 +308,15 @@ mod tests { .unwrap() .expect("expected to get contract back"); - assert_eq!(element, Element::Item(serialized_contract, None)); + assert_eq!( + element, + Element::Item( + contract + .serialize() + .expect("expected to serialize contract"), + None + ) + ); let query_value = json!({ "where": [ @@ -431,54 +439,42 @@ mod tests { .create_initial_state_structure(Some(&db_transaction)) .expect("expected to create root tree successfully"); - let contract_cbor = json_document_to_cbor( + let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", - Some(crate::drive::defaults::PROTOCOL_VERSION), ) .expect("expected to get cbor contract"); - let contract = - Contract::from_cbor(&contract_cbor).expect("contract should be deserialized"); - let serialized_contract = - DriveContractExt::to_cbor(&contract).expect("contract should be serialized"); let document_type = contract .document_type_for_name("contactRequest") .expect("expected to get document type"); - drive_operations.push(ContractOperation(ApplyContractWithSerialization { + drive_operations.push(ContractOperation(ApplyContract { contract: Cow::Borrowed(&contract), - serialized_contract: serialized_contract.clone(), storage_flags: None, })); - let dashpay_cr_serialized_document0 = json_document_to_cbor( + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let document0 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) - .expect("expected to get cbor contract"); + .expect("expected to get document 0"); - let dashpay_cr_serialized_document1 = json_document_to_cbor( + let document1 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request1.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) - .expect("expected to get cbor contract"); - - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + .expect("expected to get document 1"); let mut operations = vec![]; - let document0 = Document::from_cbor( - dashpay_cr_serialized_document0.as_slice(), - None, - Some(random_owner_id), - ) - .expect("expected to deserialize contact request"); - operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( + document_info: DocumentRefWithoutSerialization(( &document0, - dashpay_cr_serialized_document0.as_slice(), StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id), @@ -486,18 +482,10 @@ mod tests { override_document: false, }); - let document1 = Document::from_cbor( - dashpay_cr_serialized_document1.as_slice(), - None, - Some(random_owner_id), - ) - .expect("expected to deserialize contact request"); - operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( + document_info: DocumentRefWithoutSerialization(( &document1, - dashpay_cr_serialized_document1.as_slice(), StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id), @@ -534,7 +522,15 @@ mod tests { .unwrap() .expect("expected to get contract back"); - assert_eq!(element, Element::Item(serialized_contract, None)); + assert_eq!( + element, + Element::Item( + contract + .serialize() + .expect("expected to serialize contract"), + None + ) + ); let query_value = json!({ "where": [ diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 4d7f00615e9..9b2a618bae9 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -1126,7 +1126,7 @@ mod tests { DocumentAndContractInfo, DocumentInfo, OwnedDocumentInfo, }; use crate::drive::Drive; - use dpp::data_contract::extra::common::json_document_to_cbor; + use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_contract}; use crate::tests::helpers::setup::setup_drive_with_initial_state_structure; @@ -1406,16 +1406,13 @@ mod tests { let contract_path = "tests/supporting_files/contract/references/references.json"; // let's construct the grovedb structure for the dashpay data contract - let contract_cbor = - json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); let contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + json_document_to_contract(contract_path).expect("expected to get cbor document"); // Create a contract first drive - .apply_contract_with_serialization( + .apply_contract( &contract, - contract_cbor.clone(), BlockInfo::default(), true, StorageFlags::optional_default_as_cow(), @@ -1425,13 +1422,7 @@ mod tests { // Update existing contract drive - .update_contract_cbor( - contract_cbor, - Some(contract.id.to_buffer()), - BlockInfo::default(), - false, - None, - ) + .update_contract(&contract, BlockInfo::default(), false, None) .expect("expected to apply contract successfully"); } @@ -1451,13 +1442,7 @@ mod tests { let updated_contract_bytes = contract.serialize().expect("should serialize a contract"); drive - .update_contract_cbor( - updated_contract_cbor, - None, - BlockInfo::default(), - true, - Some(&transaction), - ) + .update_contract(&contract, BlockInfo::default(), true, Some(&transaction)) .expect("should update contract"); let fetch_info_from_database = drive From 620b422bf6500cd5d896c36d634d2b6e579b4bef Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 06:22:25 +0700 Subject: [PATCH 16/50] more work --- packages/rs-dpp/src/data_contract/data_contract.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index d40ffd380bf..8f51d6b2d64 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -31,6 +31,7 @@ use crate::{errors::ProtocolError, metadata::Metadata, util::hash::hash_to_vec}; use crate::{identifier, Convertible}; use platform_value::string_encoding::Encoding; +use crate::version::LATEST_VERSION; use platform_serialization::{PlatformDeserialize, PlatformDeserializeNoLimit, PlatformSerialize}; use super::document_type::DocumentType; @@ -125,6 +126,7 @@ impl Convertible for DataContract { #[serde(rename_all = "camelCase")] pub struct DataContract { /// The version of the protocol this contract adheres to. + #[serde(default = "default_protocol_version")] pub protocol_version: u32, /// A unique identifier for the data contract. @@ -291,8 +293,9 @@ impl DataContract { mutability.documents_mutable_contract_default, )?; - let protocol_version = - data_contract_map.remove_integer(property_names::PROTOCOL_VERSION)?; + let protocol_version = data_contract_map + .remove_optional_integer(property_names::PROTOCOL_VERSION)? + .unwrap_or(LATEST_VERSION); let documents = data_contract_map .remove(property_names::DOCUMENTS) From b7da50428719936ab100f622b059242e37e3b1e0 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 07:56:53 +0700 Subject: [PATCH 17/50] more trials --- .../data_contract_create_transition/mod.rs | 18 ++++- .../serialize_for_signing.rs | 8 +-- packages/rs-platform-serialization/src/lib.rs | 70 +++++++++++++++++++ 3 files changed, 90 insertions(+), 6 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 98bbc9468e7..c4b81a31bc9 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,7 @@ use std::collections::BTreeMap; use std::convert::TryInto; -use platform_serialization::{PlatformDeserialize, PlatformSerialize}; +use platform_serialization::{PlatformSignable}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::{BinaryData, Bytes32, IntegerReplacementType, ReplacementType, Value}; @@ -21,7 +21,7 @@ use crate::{ use super::property_names::*; -use bincode::{Decode, Encode}; +use bincode::{Decode, Encode, config}; mod action; pub mod apply_data_contract_create_transition_factory; @@ -32,6 +32,7 @@ pub mod validation; pub use action::{ DataContractCreateTransitionAction, DATA_CONTRACT_CREATE_TRANSITION_ACTION_VERSION, }; +use crate::data_contract::state_transition::data_contract_create_transition::serialize_for_signing::TempDataContractCreateTransitionWithoutWitness; pub mod property_names { pub const PROTOCOL_VERSION: &str = "protocolVersion"; @@ -59,15 +60,28 @@ pub const U32_FIELDS: [&str; 2] = [ property_names::DATA_CONTRACT_PROTOCOL_VERSION, ]; +#[derive(Encode, Decode, PlatformSignable)] +#[platform_error_type(ProtocolError)] +pub struct Test12 { + test: u32, + #[exclude_from_sig_hash] + signature_public_key_id: KeyID, + #[exclude_from_sig_hash] + signature: BinaryData, +} + #[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq)] #[serde(rename_all = "camelCase")] +#[platform_error_type(ProtocolError)] pub struct DataContractCreateTransition { pub protocol_version: u32, #[serde(rename = "type")] pub transition_type: StateTransitionType, pub data_contract: DataContract, pub entropy: Bytes32, + #[exclude_from_sig_hash] pub signature_public_key_id: KeyID, + #[exclude_from_sig_hash] pub signature: BinaryData, } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs index 0407734b973..28065fd81ce 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs @@ -5,9 +5,10 @@ use crate::util::hash::{hash, hash_to_vec}; use crate::ProtocolError; use bincode::config; use platform_value::Bytes32; -// use platform_serialization::PlatformSerialize; -#[derive(Debug, Clone, PartialEq)] +use bincode::{Decode, Encode}; + +#[derive(Debug, Clone, PartialEq, Encode, Decode)] pub struct TempDataContractCreateTransitionWithoutWitness<'a> { pub protocol_version: u32, pub transition_type: StateTransitionType, @@ -21,14 +22,13 @@ impl<'a> From<&'a DataContractCreateTransition> fn from(value: &'a DataContractCreateTransition) -> Self { let DataContractCreateTransition { protocol_version, - transition_type, data_contract, entropy, .. } = value; TempDataContractCreateTransitionWithoutWitness { protocol_version: *protocol_version, - transition_type: *transition_type, + transition_type: StateTransitionType::DataContractCreate, data_contract, entropy, } diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 8f98173ee13..39c1348688a 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -250,3 +250,73 @@ pub fn derive_platform_deserialize_no_limit(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } + +#[proc_macro_derive( +PlatformSignable, +attributes(platform_error_type, exclude_from_sig_hash) +)] +pub fn derive_platform_signable(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = &input.ident; + + // Extract the error type from the attribute. + let error_type = input + .attrs + .iter() + .find_map(|attr| { + if attr.path().is_ident("platform_error_type") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }) + .expect("Missing platform_error_type attribute"); + + // Extract the fields of the struct. + let fields = match &input.data { + syn::Data::Struct(data) => &data.fields, + _ => panic!("PlatformSignable can only be derived for structs"), + }; + + // Filter out the fields with the `exclude_from_sig_hash` attribute. + let filtered_fields: Vec<&syn::Field> = fields + .iter() + .filter(|field| { + !field.attrs.iter().any(|attr| attr.path().is_ident("exclude_from_sig_hash")) + }) + .collect(); + + // Construct the intermediate structure. + let intermediate_name = syn::Ident::new(&format!("{}Intermediate", name), name.span()); + let intermediate_fields = filtered_fields.iter().map(|field| { + let ident = &field.ident; + let ty = &field.ty; + quote! { #ident: #ty } + }); + + // Extract the generics. + let generics = &input.generics; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let expanded = quote! { + struct #intermediate_name #generics { + #( #intermediate_fields, )* + } + + impl #impl_generics #name #ty_generics #where_clause { + pub fn sig_hash(&self) -> Result, #error_type> { + let config = config::standard().with_big_endian(); + + let intermediate = #intermediate_name { + #( #filtered_fields: self.#filtered_fields.clone(), )* + }; + + bincode::encode_to_vec(&intermediate, config).map_err(|e| { + #error_type::PlatformSerializationError(format!("unable to serialize to produce sig hash {}: {}", stringify!(#name), e)) + }) + } + } + }; + + TokenStream::from(expanded) +} \ No newline at end of file From 7c4ffc7161a8f90621123f0eebf1536878616d6c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 08:00:00 +0700 Subject: [PATCH 18/50] trial --- packages/rs-platform-serialization/src/lib.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 39c1348688a..2190014ccd6 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -298,6 +298,12 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + // Create a list of field access expressions. + let field_access = filtered_fields.iter().map(|field| { + let ident = field.ident.as_ref().expect("Expected named field"); + quote! { self.#ident.clone() } + }); + let expanded = quote! { struct #intermediate_name #generics { #( #intermediate_fields, )* @@ -308,7 +314,7 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let config = config::standard().with_big_endian(); let intermediate = #intermediate_name { - #( #filtered_fields: self.#filtered_fields.clone(), )* + #( #filtered_fields: #field_access, )* }; bincode::encode_to_vec(&intermediate, config).map_err(|e| { From cac2e79e54f5911f7d50c24edce16060b87f9c33 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 08:08:19 +0700 Subject: [PATCH 19/50] making progress --- .../data_contract_create_transition/mod.rs | 12 +----------- .../serialize_for_signing.rs | 2 +- packages/rs-platform-serialization/src/lib.rs | 7 +++---- 3 files changed, 5 insertions(+), 16 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 c4b81a31bc9..ab926084162 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 @@ -60,17 +60,7 @@ pub const U32_FIELDS: [&str; 2] = [ property_names::DATA_CONTRACT_PROTOCOL_VERSION, ]; -#[derive(Encode, Decode, PlatformSignable)] -#[platform_error_type(ProtocolError)] -pub struct Test12 { - test: u32, - #[exclude_from_sig_hash] - signature_public_key_id: KeyID, - #[exclude_from_sig_hash] - signature: BinaryData, -} - -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq, PlatformSignable)] #[serde(rename_all = "camelCase")] #[platform_error_type(ProtocolError)] pub struct DataContractCreateTransition { diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs index 28065fd81ce..d592c80d9d2 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/serialize_for_signing.rs @@ -8,7 +8,7 @@ use platform_value::Bytes32; use bincode::{Decode, Encode}; -#[derive(Debug, Clone, PartialEq, Encode, Decode)] +#[derive(Debug, Clone, PartialEq)] pub struct TempDataContractCreateTransitionWithoutWitness<'a> { pub protocol_version: u32, pub transition_type: StateTransitionType, diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 2190014ccd6..894a30514a7 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -298,10 +298,9 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - // Create a list of field access expressions. - let field_access = filtered_fields.iter().map(|field| { + let field_mapping = filtered_fields.iter().map(|field| { let ident = field.ident.as_ref().expect("Expected named field"); - quote! { self.#ident.clone() } + quote! { #ident: self.#ident.clone() } }); let expanded = quote! { @@ -314,7 +313,7 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let config = config::standard().with_big_endian(); let intermediate = #intermediate_name { - #( #filtered_fields: #field_access, )* + #( #field_mapping, )* }; bincode::encode_to_vec(&intermediate, config).map_err(|e| { From adbbc21202f852d5b3bb2cac4575dedb72c91fcf Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 09:10:24 +0700 Subject: [PATCH 20/50] trial --- .../data_contract_create_transition/mod.rs | 55 ++++++++++++++++-- packages/rs-platform-serialization/src/lib.rs | 57 ++++++++++++------- 2 files changed, 87 insertions(+), 25 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 ab926084162..aa412c38e1f 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 @@ -22,6 +22,8 @@ use crate::{ use super::property_names::*; use bincode::{Decode, Encode, config}; +use bincode::enc::Encoder; +use bincode::error::EncodeError; mod action; pub mod apply_data_contract_create_transition_factory; @@ -59,19 +61,62 @@ pub const U32_FIELDS: [&str; 2] = [ property_names::PROTOCOL_VERSION, property_names::DATA_CONTRACT_PROTOCOL_VERSION, ]; - -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq, PlatformSignable)] +// +// // #[derive(Encode, Decode, PlatformSignable)] +// // #[platform_error_type(ProtocolError)] +// // pub struct Test12 { +// // test: u32, +// // #[exclude_from_sig_hash] +// // signature_public_key_id: KeyID, +// // #[exclude_from_sig_hash] +// // signature: BinaryData, +// // } +// +// struct Test12Intermediate { test : u32, } +// impl bincode :: Encode for +// Test12Intermediate +// { +// fn encode < E > (& self, encoder : & mut E) -> Result < (), bincode :: +// error :: EncodeError > where E : bincode::, +// { +// encoder. +// encoder.encode_field(& self.test : self.test.clone().clone()) ? ; +// Ok(()) +// } +// } +// +// impl Test12 +// { +// pub fn sig_hash(& self) -> Result < Vec < u8 >, ProtocolError > +// { +// let config = config :: standard().with_big_endian() ; let intermediate +// = Test12Intermediate { test : self.test.clone().clone(), } ; bincode +// :: +// encode_to_vec(& intermediate, +// config).map_err(| e | +// { +// ProtocolError :: +// PlatformSerializationError(format! +// ("unable to serialize to produce sig hash {}: {}", stringify! +// (Test12), e)) +// }) +// } +// } + + + +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq)] #[serde(rename_all = "camelCase")] -#[platform_error_type(ProtocolError)] +// #[platform_error_type(ProtocolError)] pub struct DataContractCreateTransition { pub protocol_version: u32, #[serde(rename = "type")] pub transition_type: StateTransitionType, pub data_contract: DataContract, pub entropy: Bytes32, - #[exclude_from_sig_hash] + // #[exclude_from_sig_hash] pub signature_public_key_id: KeyID, - #[exclude_from_sig_hash] + // #[exclude_from_sig_hash] pub signature: BinaryData, } diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 894a30514a7..24a4fd78e2e 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -259,7 +259,6 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = &input.ident; - // Extract the error type from the attribute. let error_type = input .attrs .iter() @@ -272,13 +271,11 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { }) .expect("Missing platform_error_type attribute"); - // Extract the fields of the struct. let fields = match &input.data { syn::Data::Struct(data) => &data.fields, _ => panic!("PlatformSignable can only be derived for structs"), }; - // Filter out the fields with the `exclude_from_sig_hash` attribute. let filtered_fields: Vec<&syn::Field> = fields .iter() .filter(|field| { @@ -286,15 +283,13 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { }) .collect(); - // Construct the intermediate structure. let intermediate_name = syn::Ident::new(&format!("{}Intermediate", name), name.span()); - let intermediate_fields = filtered_fields.iter().map(|field| { + let intermediate_fields: Vec<_> = filtered_fields.iter().map(|field| { let ident = &field.ident; let ty = &field.ty; quote! { #ident: #ty } - }); + }).collect(); - // Extract the generics. let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); @@ -303,25 +298,47 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { quote! { #ident: self.#ident.clone() } }); + let field_mapping_clone = field_mapping.clone(); + let expanded = quote! { - struct #intermediate_name #generics { - #( #intermediate_fields, )* + struct #intermediate_name #impl_generics { + #( #intermediate_fields, )* + } + + // impl #impl_generics Clone for #intermediate_name #ty_generics #where_clause { + // fn clone(&self) -> Self { + // #intermediate_name { + // #( #field_mapping_clone.clone(), )* + // } + // } + // } + + impl #impl_generics bincode::Encode for #intermediate_name #ty_generics #where_clause { + fn encode(&self, encoder: &mut E) -> Result<(), bincode::error::EncodeError> + where + E: bincode::Encoder, + { + #( encoder.encode_field(&self.#field_mapping_clone.clone())?; )* + Ok(()) } + } - impl #impl_generics #name #ty_generics #where_clause { - pub fn sig_hash(&self) -> Result, #error_type> { - let config = config::standard().with_big_endian(); + impl #impl_generics #name #ty_generics #where_clause { + pub fn sig_hash(&self) -> Result, #error_type> { + let config = config::standard().with_big_endian(); - let intermediate = #intermediate_name { - #( #field_mapping, )* - }; + let intermediate = #intermediate_name { + #( #field_mapping.clone(), )* + }; - bincode::encode_to_vec(&intermediate, config).map_err(|e| { - #error_type::PlatformSerializationError(format!("unable to serialize to produce sig hash {}: {}", stringify!(#name), e)) - }) - } + bincode::encode_to_vec(&intermediate, config).map_err(|e| { + #error_type::PlatformSerializationError(format!("unable to serialize to produce sig hash {}: {}", stringify!(#name), e)) + }) } - }; + } +}; + + println!("Expanded code: {}", expanded.to_string()); TokenStream::from(expanded) } \ No newline at end of file From 3fd482781cd459388b9084170676997a04b2b441 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 09:37:35 +0700 Subject: [PATCH 21/50] working --- .../data_contract_create_transition/mod.rs | 57 ++---------- packages/rs-platform-serialization/src/lib.rs | 88 ++++++++++--------- 2 files changed, 54 insertions(+), 91 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 aa412c38e1f..349db406785 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,7 @@ use std::collections::BTreeMap; use std::convert::TryInto; -use platform_serialization::{PlatformSignable}; +use platform_serialization::PlatformSignable; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::{BinaryData, Bytes32, IntegerReplacementType, ReplacementType, Value}; @@ -21,9 +21,9 @@ use crate::{ use super::property_names::*; -use bincode::{Decode, Encode, config}; use bincode::enc::Encoder; use bincode::error::EncodeError; +use bincode::{config, Decode, Encode}; mod action; pub mod apply_data_contract_create_transition_factory; @@ -61,62 +61,19 @@ pub const U32_FIELDS: [&str; 2] = [ property_names::PROTOCOL_VERSION, property_names::DATA_CONTRACT_PROTOCOL_VERSION, ]; -// -// // #[derive(Encode, Decode, PlatformSignable)] -// // #[platform_error_type(ProtocolError)] -// // pub struct Test12 { -// // test: u32, -// // #[exclude_from_sig_hash] -// // signature_public_key_id: KeyID, -// // #[exclude_from_sig_hash] -// // signature: BinaryData, -// // } -// -// struct Test12Intermediate { test : u32, } -// impl bincode :: Encode for -// Test12Intermediate -// { -// fn encode < E > (& self, encoder : & mut E) -> Result < (), bincode :: -// error :: EncodeError > where E : bincode::, -// { -// encoder. -// encoder.encode_field(& self.test : self.test.clone().clone()) ? ; -// Ok(()) -// } -// } -// -// impl Test12 -// { -// pub fn sig_hash(& self) -> Result < Vec < u8 >, ProtocolError > -// { -// let config = config :: standard().with_big_endian() ; let intermediate -// = Test12Intermediate { test : self.test.clone().clone(), } ; bincode -// :: -// encode_to_vec(& intermediate, -// config).map_err(| e | -// { -// ProtocolError :: -// PlatformSerializationError(format! -// ("unable to serialize to produce sig hash {}: {}", stringify! -// (Test12), e)) -// }) -// } -// } - - - -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq)] + +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq, PlatformSignable)] #[serde(rename_all = "camelCase")] -// #[platform_error_type(ProtocolError)] +#[platform_error_type(ProtocolError)] pub struct DataContractCreateTransition { pub protocol_version: u32, #[serde(rename = "type")] pub transition_type: StateTransitionType, pub data_contract: DataContract, pub entropy: Bytes32, - // #[exclude_from_sig_hash] + #[exclude_from_sig_hash] pub signature_public_key_id: KeyID, - // #[exclude_from_sig_hash] + #[exclude_from_sig_hash] pub signature: BinaryData, } diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 24a4fd78e2e..1a93369ef9b 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -252,8 +252,8 @@ pub fn derive_platform_deserialize_no_limit(input: TokenStream) -> TokenStream { } #[proc_macro_derive( -PlatformSignable, -attributes(platform_error_type, exclude_from_sig_hash) + PlatformSignable, + attributes(platform_error_type, exclude_from_sig_hash) )] pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); @@ -279,16 +279,22 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let filtered_fields: Vec<&syn::Field> = fields .iter() .filter(|field| { - !field.attrs.iter().any(|attr| attr.path().is_ident("exclude_from_sig_hash")) + !field + .attrs + .iter() + .any(|attr| attr.path().is_ident("exclude_from_sig_hash")) }) .collect(); let intermediate_name = syn::Ident::new(&format!("{}Intermediate", name), name.span()); - let intermediate_fields: Vec<_> = filtered_fields.iter().map(|field| { - let ident = &field.ident; - let ty = &field.ty; - quote! { #ident: #ty } - }).collect(); + let intermediate_fields: Vec<_> = filtered_fields + .iter() + .map(|field| { + let ident = &field.ident; + let ty = &field.ty; + quote! { #ident: #ty } + }) + .collect(); let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); @@ -298,47 +304,47 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { quote! { #ident: self.#ident.clone() } }); - let field_mapping_clone = field_mapping.clone(); + let field_mapping_2 = filtered_fields.iter().map(|field| { + let ident = field.ident.as_ref().expect("Expected named field"); + quote! { #ident } + }); let expanded = quote! { - struct #intermediate_name #impl_generics { - #( #intermediate_fields, )* - } - - // impl #impl_generics Clone for #intermediate_name #ty_generics #where_clause { - // fn clone(&self) -> Self { - // #intermediate_name { - // #( #field_mapping_clone.clone(), )* - // } - // } - // } - - impl #impl_generics bincode::Encode for #intermediate_name #ty_generics #where_clause { - fn encode(&self, encoder: &mut E) -> Result<(), bincode::error::EncodeError> - where - E: bincode::Encoder, - { - #( encoder.encode_field(&self.#field_mapping_clone.clone())?; )* - Ok(()) + struct #intermediate_name #impl_generics { + #( #intermediate_fields, )* } - } - impl #impl_generics #name #ty_generics #where_clause { - pub fn sig_hash(&self) -> Result, #error_type> { - let config = config::standard().with_big_endian(); + // impl #impl_generics Clone for #intermediate_name #ty_generics #where_clause { + // fn clone(&self) -> Self { + // #intermediate_name { + // #( #field_mapping_clone.clone(), )* + // } + // } + // } + + impl #impl_generics bincode::Encode for #intermediate_name #ty_generics #where_clause { + fn encode(&self, encoder: &mut E) -> Result<(), bincode::error::EncodeError> + where + E: bincode::enc::Encoder, + { + + #(self.#field_mapping_2.encode(encoder)?; )* + Ok(()) + } + } - let intermediate = #intermediate_name { - #( #field_mapping.clone(), )* - }; + impl #impl_generics #intermediate_name #ty_generics #where_clause { + pub fn sig_hash(&self) -> Result, #error_type> { + let config = config::standard().with_big_endian(); - bincode::encode_to_vec(&intermediate, config).map_err(|e| { - #error_type::PlatformSerializationError(format!("unable to serialize to produce sig hash {}: {}", stringify!(#name), e)) - }) + bincode::encode_to_vec(self, config).map_err(|e| { + #error_type::PlatformSerializationError(format!("unable to serialize to produce sig hash {}: {}", stringify!(#name), e)) + }) + } } - } -}; + }; println!("Expanded code: {}", expanded.to_string()); TokenStream::from(expanded) -} \ No newline at end of file +} From 7e26c7ae798cae03347749ca2f59137fd4fb9374 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 10:24:22 +0700 Subject: [PATCH 22/50] more work --- Cargo.lock | 2 -- .../data_contract_create_transition/mod.rs | 1 + .../data_contract_update_transition/mod.rs | 9 +++++-- .../documents_batch_transition/mod.rs | 9 +++++-- .../identity_create_transition.rs | 9 ++++++- .../mod.rs | 9 +++++-- .../identity_topup_transition.rs | 8 +++++-- .../identity_update_transition.rs | 21 +++++++++------- packages/rs-dpp/src/lib.rs | 1 + packages/rs-dpp/src/signable.rs | 5 ++++ .../abstract_state_transition.rs | 5 ++-- .../rs-dpp/src/state_transition/example.rs | 12 ++++++++-- packages/rs-dpp/src/state_transition/mod.rs | 7 ++++++ packages/rs-platform-serialization/Cargo.toml | 2 -- packages/rs-platform-serialization/src/lib.rs | 24 ++++--------------- 15 files changed, 80 insertions(+), 44 deletions(-) create mode 100644 packages/rs-dpp/src/signable.rs diff --git a/Cargo.lock b/Cargo.lock index 5a56f356228..432f30eb452 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2466,11 +2466,9 @@ checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" name = "platform-serialization" version = "0.1.0" dependencies = [ - "bincode 2.0.0-rc.3", "proc-macro2", "quote", "syn 2.0.15", - "thiserror", ] [[package]] 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 349db406785..b92461f8831 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 @@ -21,6 +21,7 @@ use crate::{ use super::property_names::*; +use crate::signable::Signable; use bincode::enc::Encoder; use bincode::error::EncodeError; use bincode::{config, Decode, Encode}; 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 efb096c32b9..2e8833310fd 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 @@ -6,7 +6,9 @@ use serde_json::Value as JsonValue; use std::collections::BTreeMap; use std::convert::TryInto; -use bincode::{Decode, Encode}; +use crate::platform_serialization::PlatformSignable; +use crate::signable::Signable; +use bincode::{config, Decode, Encode}; use crate::{ data_contract::DataContract, @@ -54,14 +56,17 @@ pub const U32_FIELDS: [&str; 2] = [ property_names::DATA_CONTRACT_PROTOCOL_VERSION, ]; -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq, PlatformSignable)] #[serde(rename_all = "camelCase")] +#[platform_error_type(ProtocolError)] pub struct DataContractUpdateTransition { pub protocol_version: u32, #[serde(rename = "type")] pub transition_type: StateTransitionType, pub data_contract: DataContract, + #[exclude_from_sig_hash] pub signature_public_key_id: KeyID, + #[exclude_from_sig_hash] pub signature: BinaryData, } 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 7df88d8621a..6f11385e50f 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,6 @@ -use bincode::{Decode, Encode}; +use crate::platform_serialization::PlatformSignable; +use crate::signable::Signable; +use bincode::{config, Decode, Encode}; use std::collections::{BTreeMap, HashMap}; use std::convert::{TryFrom, TryInto}; @@ -66,8 +68,9 @@ pub const U32_FIELDS: [&str; 1] = [property_names::PROTOCOL_VERSION]; const DEFAULT_SECURITY_LEVEL: SecurityLevel = SecurityLevel::HIGH; const EMPTY_VEC: Vec = vec![]; -#[derive(Debug, Serialize, Deserialize, Encode, Decode, Clone, PartialEq)] +#[derive(Debug, Serialize, Deserialize, Encode, Decode, Clone, PartialEq, PlatformSignable)] #[serde(rename_all = "camelCase")] +#[platform_error_type(ProtocolError)] pub struct DocumentsBatchTransition { pub protocol_version: u32, #[serde(rename = "type")] @@ -78,9 +81,11 @@ pub struct DocumentsBatchTransition { pub transitions: Vec, #[serde(default, skip_serializing_if = "Option::is_none")] + #[exclude_from_sig_hash] pub signature_public_key_id: Option, #[serde(default, skip_serializing_if = "Option::is_none")] + #[exclude_from_sig_hash] pub signature: Option, } 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 65e33f83c49..9f326553565 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,5 +1,9 @@ use std::convert::{TryFrom, TryInto}; +use crate::platform_serialization::PlatformSignable; +use crate::signable::Signable; +use bincode::{config, Decode, Encode}; + use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::{BinaryData, IntegerReplacementType, ReplacementType, Value}; use serde::{Deserialize, Serialize}; @@ -41,9 +45,10 @@ pub struct SerializationOptions { pub into_validating_json: bool, } -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Encode, Decode, PlatformSignable)] #[serde(rename_all = "camelCase")] #[serde(try_from = "IdentityCreateTransitionInner")] +#[platform_error_type(ProtocolError)] pub struct IdentityCreateTransition { #[serde(rename = "type")] pub transition_type: StateTransitionType, @@ -52,8 +57,10 @@ pub struct IdentityCreateTransition { pub asset_lock_proof: AssetLockProof, // Generic identity ST fields pub protocol_version: u32, + #[exclude_from_sig_hash] pub signature: BinaryData, #[serde(skip)] + #[exclude_from_sig_hash] pub identity_id: Identifier, } 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 c8fb3f5ed7c..94f7115f4e9 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,4 +1,6 @@ -use bincode::{Decode, Encode}; +use crate::platform_serialization::PlatformSignable; +use crate::signable::Signable; +use bincode::{config, Decode, Encode}; use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -45,8 +47,9 @@ impl std::default::Default for Pooling { } } -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PlatformSignable, PartialEq)] #[serde(rename_all = "camelCase")] +#[platform_error_type(ProtocolError)] pub struct IdentityCreditWithdrawalTransition { pub protocol_version: u32, #[serde(rename = "type")] @@ -58,7 +61,9 @@ pub struct IdentityCreditWithdrawalTransition { #[bincode(with_serde)] pub output_script: CoreScript, pub revision: Revision, + #[exclude_from_sig_hash] pub signature_public_key_id: KeyID, + #[exclude_from_sig_hash] pub signature: BinaryData, } 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 b698c4b7723..8566336c89e 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,4 +1,6 @@ -use bincode::{Decode, Encode}; +use crate::platform_serialization::PlatformSignable; +use crate::signable::Signable; +use bincode::{config, Decode, Encode}; use std::convert::{TryFrom, TryInto}; use platform_value::{BinaryData, Value}; @@ -23,8 +25,9 @@ mod property_names { pub const IDENTITY_ID: &str = "identityId"; } -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PlatformSignable, PartialEq)] #[serde(rename_all = "camelCase")] +#[platform_error_type(ProtocolError)] pub struct IdentityTopUpTransition { #[serde(rename = "type")] pub transition_type: StateTransitionType, @@ -33,6 +36,7 @@ pub struct IdentityTopUpTransition { pub identity_id: Identifier, // Generic identity ST fields pub protocol_version: u32, + #[exclude_from_sig_hash] pub signature: BinaryData, } 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 f6471963855..49835477096 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,6 @@ -use bincode::{Decode, Encode}; +use crate::platform_serialization::PlatformSignable; +use crate::signable::Signable; +use bincode::{config, Decode, Encode}; use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; @@ -45,19 +47,14 @@ pub const BINARY_FIELDS: [&str; 3] = [ property_names::SIGNATURE, ]; -#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq)] +#[derive(Serialize, Deserialize, Encode, Decode, PlatformSignable, Debug, Clone, PartialEq)] #[serde(rename_all = "camelCase")] +#[platform_error_type(ProtocolError)] pub struct IdentityUpdateTransition { pub protocol_version: u32, #[serde(rename = "type")] pub transition_type: StateTransitionType, - /// Cryptographic signature of the State Transition - pub signature: BinaryData, - - /// The ID of the public key used to sing the State Transition - pub signature_public_key_id: KeyID, - /// Unique identifier of the identity to be updated pub identity_id: Identifier, @@ -75,6 +72,14 @@ pub struct IdentityUpdateTransition { /// Timestamp when keys were disabled pub public_keys_disabled_at: Option, + + /// Cryptographic signature of the State Transition + #[exclude_from_sig_hash] + pub signature: BinaryData, + + /// The ID of the public key used to sing the State Transition + #[exclude_from_sig_hash] + pub signature_public_key_id: KeyID, } impl Default for IdentityUpdateTransition { diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 3ed0d81b2ec..8e50baeca80 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -43,6 +43,7 @@ mod bls; pub mod tests; pub mod block; +pub mod signable; pub mod system_data_contracts; pub use async_trait; diff --git a/packages/rs-dpp/src/signable.rs b/packages/rs-dpp/src/signable.rs new file mode 100644 index 00000000000..430f2fecd8c --- /dev/null +++ b/packages/rs-dpp/src/signable.rs @@ -0,0 +1,5 @@ +use crate::ProtocolError; + +pub trait Signable { + fn signable_bytes(&self) -> Result, ProtocolError>; +} 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 ea537614e97..92f404632d3 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -9,6 +9,7 @@ use serde_json::Value as JsonValue; use crate::consensus::ConsensusError; use crate::errors::consensus::signature::SignatureError; +use crate::signable::Signable; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, StateTransitionIsNotSignedError, }; @@ -43,7 +44,7 @@ pub const DATA_CONTRACT_TRANSITION_TYPES: [StateTransitionType; 2] = [ /// The StateTransitionLike represents set of methods that are shared for all types of State Transition. /// Every type of state transition should also implement Debug, Clone, and support conversion to compounded [`StateTransition`] pub trait StateTransitionLike: - StateTransitionConvert + Clone + Debug + Into + StateTransitionConvert + Clone + Debug + Into + Signable { /// returns the protocol version fn get_protocol_version(&self) -> u32; @@ -63,7 +64,7 @@ pub trait StateTransitionLike: key_type: KeyType, bls: &impl BlsModule, ) -> Result<(), ProtocolError> { - let data = self.to_cbor_buffer(true)?; + let data = self.signable_bytes()?; match key_type { KeyType::BLS12_381 => self.set_signature(bls.sign(&data, private_key)?.into()), diff --git a/packages/rs-dpp/src/state_transition/example.rs b/packages/rs-dpp/src/state_transition/example.rs index 45f0be3ef04..e12858ee79e 100644 --- a/packages/rs-dpp/src/state_transition/example.rs +++ b/packages/rs-dpp/src/state_transition/example.rs @@ -1,6 +1,11 @@ +use crate::ProtocolError; use platform_value::BinaryData; use serde::{Deserialize, Serialize}; +use crate::platform_serialization::PlatformSignable; +use crate::signable::Signable; +use bincode::{config, Decode, Encode}; + use super::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, StateTransitionConvert, StateTransitionLike, StateTransitionType, @@ -10,14 +15,17 @@ const PROPERTY_SIGNATURE: &str = "signature"; const PROPERTY_PROTOCOL_VERSION: &str = "protocolVersion"; // The example implementation of generic state transition: -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PlatformSignable)] #[serde(rename_all = "camelCase")] +#[platform_error_type(ProtocolError)] struct ExampleStateTransition { pub protocol_version: u32, - pub signature: BinaryData, pub transition_type: StateTransitionType, #[serde(skip)] + #[exclude_from_sig_hash] pub execution_context: StateTransitionExecutionContext, + #[exclude_from_sig_hash] + pub signature: BinaryData, } 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 790c1041364..2ad00ff6b5c 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -39,6 +39,7 @@ mod example; mod serialization; mod state_transition_action; +use crate::signable::Signable; pub use state_transition_action::StateTransitionAction; macro_rules! call_method { ($state_transition:expr, $method:ident, $args:tt ) => { @@ -161,6 +162,12 @@ impl StateTransitionConvert for StateTransition { } } +impl Signable for StateTransition { + fn signable_bytes(&self) -> Result, ProtocolError> { + call_method!(self, signable_bytes) + } +} + impl StateTransitionLike for StateTransition { fn get_protocol_version(&self) -> u32 { call_method!(self, get_protocol_version) diff --git a/packages/rs-platform-serialization/Cargo.toml b/packages/rs-platform-serialization/Cargo.toml index ea37e29e6fc..c88fb5b6c6b 100644 --- a/packages/rs-platform-serialization/Cargo.toml +++ b/packages/rs-platform-serialization/Cargo.toml @@ -11,8 +11,6 @@ private = true proc-macro = true [dependencies] -thiserror = { version = "1.0" } -bincode = { version = "2.0.0-rc.3", features = ["serde"] } proc-macro2 = "1.0.56" quote = "1.0.26" syn = "2.0.15" diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 1a93369ef9b..2660a5304ec 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -1,6 +1,5 @@ extern crate proc_macro; -use bincode; use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, DeriveInput}; @@ -300,11 +299,6 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let field_mapping = filtered_fields.iter().map(|field| { - let ident = field.ident.as_ref().expect("Expected named field"); - quote! { #ident: self.#ident.clone() } - }); - - let field_mapping_2 = filtered_fields.iter().map(|field| { let ident = field.ident.as_ref().expect("Expected named field"); quote! { #ident } }); @@ -314,29 +308,23 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { #( #intermediate_fields, )* } - // impl #impl_generics Clone for #intermediate_name #ty_generics #where_clause { - // fn clone(&self) -> Self { - // #intermediate_name { - // #( #field_mapping_clone.clone(), )* - // } - // } - // } - impl #impl_generics bincode::Encode for #intermediate_name #ty_generics #where_clause { fn encode(&self, encoder: &mut E) -> Result<(), bincode::error::EncodeError> where E: bincode::enc::Encoder, { - #(self.#field_mapping_2.encode(encoder)?; )* + #(self.#field_mapping.encode(encoder)?; )* Ok(()) } } - impl #impl_generics #intermediate_name #ty_generics #where_clause { - pub fn sig_hash(&self) -> Result, #error_type> { + impl #impl_generics Signable for #name #ty_generics #where_clause { + fn signable_bytes(&self) -> Result, #error_type> { let config = config::standard().with_big_endian(); + let intermediate : #intermediate_name = self.into(); + bincode::encode_to_vec(self, config).map_err(|e| { #error_type::PlatformSerializationError(format!("unable to serialize to produce sig hash {}: {}", stringify!(#name), e)) }) @@ -344,7 +332,5 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { } }; - println!("Expanded code: {}", expanded.to_string()); - TokenStream::from(expanded) } From 389a075b6fc8741c2f1106c1b861a1cd557aa3e4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 11:12:34 +0700 Subject: [PATCH 23/50] more work --- Cargo.lock | 18 ++--- packages/rs-dpp/src/identity/core_script.rs | 72 +++++++++++++++++++ .../mod.rs | 1 - .../identity_update_transition.rs | 7 +- .../rs-dpp/src/state_transition/example.rs | 13 ++-- ...ate_state_transition_identity_signature.rs | 4 +- packages/rs-platform-serialization/src/lib.rs | 10 +++ 7 files changed, 103 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 432f30eb452..6dc4d79e265 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -430,9 +430,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "bytecheck" @@ -968,7 +968,7 @@ dependencies = [ [[package]] name = "dashcore" version = "0.29.1" -source = "git+https://github.com/dashpay/rust-dashcore?branch=feat/addons#b6d2233595193218f3c91565e36a16d229f2fa30" +source = "git+https://github.com/dashpay/rust-dashcore?branch=feat/addons#8a36b955c3c05beb66622795ae2c42e399aef6ef" dependencies = [ "anyhow", "bech32", @@ -2002,9 +2002,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b085a4f2cde5781fc4b1717f2e86c62f5cda49de7ba99a7c2eae02b61c9064c" +checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "lock_api" @@ -2991,9 +2991,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.13" +version = "0.37.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79bef90eb6d984c72722595b5b1348ab39275a5e5123faca6863bf07d75a4e0" +checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" dependencies = [ "bitflags", "errno", @@ -3703,9 +3703,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", diff --git a/packages/rs-dpp/src/identity/core_script.rs b/packages/rs-dpp/src/identity/core_script.rs index 541d7c3842e..f384c846a3d 100644 --- a/packages/rs-dpp/src/identity/core_script.rs +++ b/packages/rs-dpp/src/identity/core_script.rs @@ -1,5 +1,10 @@ +use bincode::de::{BorrowDecoder, Decoder}; +use bincode::enc::Encoder; +use bincode::error::{DecodeError, EncodeError}; +use bincode::{BorrowDecode, Decode, Encode}; use dashcore::blockdata::opcodes; use std::fmt; +use std::io::{Read, Write}; use std::ops::Deref; use dashcore::Script as DashcoreScript; @@ -11,6 +16,7 @@ use serde::de::Visitor; use serde::{Deserialize, Serialize}; use crate::ProtocolError; +use bincode::de::read::Reader; #[derive(Clone, Debug, Eq, PartialEq, Default)] pub struct CoreScript(DashcoreScript); @@ -71,6 +77,72 @@ impl Deref for CoreScript { } } +// Implement the bincode::Encode trait for CoreScript +impl Encode for CoreScript { + fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { + self.0.as_bytes().encode(encoder) + } +} + +// Implement the bincode::Decode trait for CoreScript +impl Decode for CoreScript { + fn decode(decoder: &mut D) -> Result { + // Read the serialized bytes from the decoder into a Vec + let mut bytes = Vec::new(); + loop { + let mut buf = [0u8; 1]; + match decoder.reader().read(&mut buf) { + Ok(()) => bytes.push(buf[0]), + Err(DecodeError::Io { inner, additional }) + if inner.kind() == std::io::ErrorKind::UnexpectedEof => + { + if additional > 0 { + return Err(DecodeError::Io { inner, additional }); + } else { + break; + } + } + Err(e) => return Err(e), + } + } + + // Convert Vec to Box<[u8]> and create a DashCoreScript instance + let dash_core_script = DashcoreScript(bytes.into_boxed_slice()); + + // Create a CoreScript instance using the decoded DashCoreScript + Ok(CoreScript(dash_core_script)) + } +} + +impl<'de> BorrowDecode<'de> for CoreScript { + fn borrow_decode>(decoder: &mut D) -> Result { + // Read the serialized bytes from the decoder into a Vec + let mut bytes = Vec::new(); + loop { + let mut buf = [0u8; 1]; + match decoder.reader().read(&mut buf) { + Ok(()) => bytes.push(buf[0]), + Err(DecodeError::Io { inner, additional }) + if inner.kind() == std::io::ErrorKind::UnexpectedEof => + { + if additional > 0 { + return Err(DecodeError::Io { inner, additional }); + } else { + break; + } + } + Err(e) => return Err(e), + } + } + + // Convert Vec to Box<[u8]> and create a DashCoreScript instance + let dash_core_script = DashcoreScript(bytes.into_boxed_slice()); + + // Create a CoreScript instance using the decoded DashCoreScript + Ok(CoreScript(dash_core_script)) + } +} + impl Serialize for CoreScript { fn serialize(&self, serializer: S) -> Result where 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 94f7115f4e9..3a6cc238416 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 @@ -58,7 +58,6 @@ pub struct IdentityCreditWithdrawalTransition { pub amount: u64, pub core_fee_per_byte: u32, pub pooling: Pooling, - #[bincode(with_serde)] pub output_script: CoreScript, pub revision: Revision, #[exclude_from_sig_hash] 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 49835477096..6edeff74b96 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 @@ -73,13 +73,12 @@ pub struct IdentityUpdateTransition { /// Timestamp when keys were disabled pub public_keys_disabled_at: Option, - /// Cryptographic signature of the State Transition - #[exclude_from_sig_hash] - pub signature: BinaryData, - /// The ID of the public key used to sing the State Transition #[exclude_from_sig_hash] pub signature_public_key_id: KeyID, + /// Cryptographic signature of the State Transition + #[exclude_from_sig_hash] + pub signature: BinaryData, } impl Default for IdentityUpdateTransition { diff --git a/packages/rs-dpp/src/state_transition/example.rs b/packages/rs-dpp/src/state_transition/example.rs index e12858ee79e..f6840d0df7c 100644 --- a/packages/rs-dpp/src/state_transition/example.rs +++ b/packages/rs-dpp/src/state_transition/example.rs @@ -2,9 +2,7 @@ use crate::ProtocolError; use platform_value::BinaryData; use serde::{Deserialize, Serialize}; -use crate::platform_serialization::PlatformSignable; use crate::signable::Signable; -use bincode::{config, Decode, Encode}; use super::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, @@ -15,16 +13,13 @@ const PROPERTY_SIGNATURE: &str = "signature"; const PROPERTY_PROTOCOL_VERSION: &str = "protocolVersion"; // The example implementation of generic state transition: -#[derive(Debug, Clone, Serialize, Deserialize, PlatformSignable)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -#[platform_error_type(ProtocolError)] struct ExampleStateTransition { pub protocol_version: u32, pub transition_type: StateTransitionType, #[serde(skip)] - #[exclude_from_sig_hash] pub execution_context: StateTransitionExecutionContext, - #[exclude_from_sig_hash] pub signature: BinaryData, } @@ -34,6 +29,12 @@ impl From for StateTransition { } } +impl Signable for ExampleStateTransition { + fn signable_bytes(&self) -> Result, ProtocolError> { + Ok(vec![]) + } +} + impl StateTransitionLike for ExampleStateTransition { fn get_protocol_version(&self) -> u32 { self.protocol_version 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 6321b63bba3..a3af1d25bda 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 @@ -171,14 +171,14 @@ mod test { #[serde(rename_all = "camelCase")] struct ExampleStateTransition { pub protocol_version: u32, - pub signature: BinaryData, - pub signature_public_key_id: KeyID, pub transition_type: StateTransitionType, pub owner_id: Identifier, pub return_error: Option, #[serde(skip)] pub execution_context: StateTransitionExecutionContext, + pub signature_public_key_id: KeyID, + pub signature: BinaryData, } impl StateTransitionConvert for ExampleStateTransition { diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 2660a5304ec..712b77882fa 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -303,6 +303,8 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { quote! { #ident } }); + let cloned_field_mapping = field_mapping.clone(); + let expanded = quote! { struct #intermediate_name #impl_generics { #( #intermediate_fields, )* @@ -319,6 +321,14 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { } } + impl #impl_generics From<&#name #ty_generics> for #intermediate_name #ty_generics #where_clause { + fn from(original: &#name #ty_generics) -> Self { + #intermediate_name { + #( #cloned_field_mapping: original.#cloned_field_mapping, )* + } + } + } + impl #impl_generics Signable for #name #ty_generics #where_clause { fn signable_bytes(&self) -> Result, #error_type> { let config = config::standard().with_big_endian(); From 042fe8c7d018d2c762fc1775fd2e080022c6cc62 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 11:40:36 +0700 Subject: [PATCH 24/50] more work --- packages/rs-platform-serialization/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 712b77882fa..6037c71b242 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -1,6 +1,7 @@ extern crate proc_macro; use proc_macro::TokenStream; +use proc_macro2::Span; use quote::quote; use syn::{parse_macro_input, DeriveInput}; #[proc_macro_derive( @@ -249,7 +250,6 @@ pub fn derive_platform_deserialize_no_limit(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } - #[proc_macro_derive( PlatformSignable, attributes(platform_error_type, exclude_from_sig_hash) @@ -291,7 +291,7 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { .map(|field| { let ident = &field.ident; let ty = &field.ty; - quote! { #ident: #ty } + quote! { #ident: &'a #ty } }) .collect(); @@ -306,7 +306,7 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let cloned_field_mapping = field_mapping.clone(); let expanded = quote! { - struct #intermediate_name #impl_generics { + struct #intermediate_name<'a> #impl_generics { #( #intermediate_fields, )* } @@ -321,10 +321,10 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { } } - impl #impl_generics From<&#name #ty_generics> for #intermediate_name #ty_generics #where_clause { - fn from(original: &#name #ty_generics) -> Self { + impl #impl_generics <'a> From<&'a #name #ty_generics> for #intermediate_name<'a> #ty_generics #where_clause { + fn from(original: &'a #name #ty_generics) -> Self { #intermediate_name { - #( #cloned_field_mapping: original.#cloned_field_mapping, )* + #( #cloned_field_mapping: &original.#cloned_field_mapping, )* } } } @@ -341,6 +341,6 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { } } }; - + println!("{}", expanded.to_string()); TokenStream::from(expanded) } From 6f7094823439bd829f10d3899c8a632b4ace03a8 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 19:27:19 +0700 Subject: [PATCH 25/50] Platform signable is done --- packages/rs-platform-serialization/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 6037c71b242..5134c08632d 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -250,6 +250,7 @@ pub fn derive_platform_deserialize_no_limit(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } + #[proc_macro_derive( PlatformSignable, attributes(platform_error_type, exclude_from_sig_hash) @@ -291,7 +292,7 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { .map(|field| { let ident = &field.ident; let ty = &field.ty; - quote! { #ident: &'a #ty } + quote! { #ident: std::borrow::Cow<'a, #ty> } }) .collect(); @@ -310,7 +311,7 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { #( #intermediate_fields, )* } - impl #impl_generics bincode::Encode for #intermediate_name #ty_generics #where_clause { + impl #impl_generics <'a> bincode::Encode for #intermediate_name<'a> #ty_generics #where_clause { fn encode(&self, encoder: &mut E) -> Result<(), bincode::error::EncodeError> where E: bincode::enc::Encoder, @@ -324,7 +325,7 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { impl #impl_generics <'a> From<&'a #name #ty_generics> for #intermediate_name<'a> #ty_generics #where_clause { fn from(original: &'a #name #ty_generics) -> Self { #intermediate_name { - #( #cloned_field_mapping: &original.#cloned_field_mapping, )* + #( #cloned_field_mapping: std::borrow::Cow::Borrowed(&original.#cloned_field_mapping), )* } } } @@ -335,12 +336,11 @@ pub fn derive_platform_signable(input: TokenStream) -> TokenStream { let intermediate : #intermediate_name = self.into(); - bincode::encode_to_vec(self, config).map_err(|e| { + bincode::encode_to_vec(intermediate, config).map_err(|e| { #error_type::PlatformSerializationError(format!("unable to serialize to produce sig hash {}: {}", stringify!(#name), e)) }) } } }; - println!("{}", expanded.to_string()); TokenStream::from(expanded) } From aa101c75edff935d96f06dd72ecb76dfd4ee8649 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 23 Apr 2023 21:54:18 +0700 Subject: [PATCH 26/50] more work --- packages/rs-dpp/Cargo.toml | 2 +- packages/rs-dpp/src/block/block_info.rs | 1 + .../rs-dpp/src/data_contract/data_contract.rs | 2 ++ .../data_contract/data_contract_factory.rs | 2 +- .../builder.rs | 5 ++-- .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- .../src/decode_protocol_entity_factory.rs | 28 +++++++++++++++++-- .../rs-dpp/src/document/document_factory.rs | 2 +- .../documents_batch_transition/mod.rs | 2 +- packages/rs-dpp/src/errors/errors.rs | 2 +- packages/rs-dpp/src/identity/factory.rs | 2 +- packages/rs-dpp/src/identity/identity.rs | 1 + .../src/identity/identity_public_key/mod.rs | 1 + .../identity_create_transition.rs | 2 +- .../mod.rs | 2 +- .../identity_public_key_transitions/mod.rs | 5 +++- .../identity_topup_transition.rs | 2 +- .../identity_update_transition.rs | 2 +- packages/rs-dpp/src/lib.rs | 2 +- packages/rs-dpp/src/serialization_traits.rs | 9 ++++++ packages/rs-dpp/src/signable.rs | 5 ---- .../abstract_state_transition.rs | 14 ++-------- ...stract_state_transition_identity_signed.rs | 2 +- .../rs-dpp/src/state_transition/example.rs | 2 +- packages/rs-dpp/src/state_transition/mod.rs | 3 +- .../state_transition_factory.rs | 2 +- .../validate_state_transition_basic.rs | 6 ++-- packages/rs-dpp/src/util/cbor_serializer.rs | 2 +- packages/rs-platform-serialization/src/lib.rs | 16 +++++++---- .../wasm-dpp/src/decode_protocol_entity.rs | 2 +- 31 files changed, 82 insertions(+), 50 deletions(-) create mode 100644 packages/rs-dpp/src/serialization_traits.rs delete mode 100644 packages/rs-dpp/src/signable.rs diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 8876766d9bd..5b09d1149f9 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -60,6 +60,6 @@ tokio = { version = "1.17", features = ["full"] } pretty_assertions = { version = "1.3.0" } [features] -default = ["fixtures-and-mocks", "cbor"] +default = ["fixtures-and-mocks"] cbor = ["ciborium"] fixtures-and-mocks = ["mockall"] diff --git a/packages/rs-dpp/src/block/block_info.rs b/packages/rs-dpp/src/block/block_info.rs index 88f2c28dec3..f310f013b70 100644 --- a/packages/rs-dpp/src/block/block_info.rs +++ b/packages/rs-dpp/src/block/block_info.rs @@ -3,6 +3,7 @@ use crate::ProtocolError; use bincode::config; use bincode::{Decode, Encode}; use platform_serialization::{PlatformDeserialize, PlatformSerialize}; +use crate::serialization_traits::PlatformDeserializable; /// Block information #[derive(Clone, Default, Encode, Decode, PlatformSerialize, PlatformDeserialize)] diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 8f51d6b2d64..f0cc4c22f79 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -15,6 +15,8 @@ use serde::de::Error; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use crate::serialization_traits::PlatformDeserializable; + use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::data_contract::contract_config; use crate::data_contract::contract_config::{ 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 4fee02db3e5..3a3e2e2b2e5 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -163,7 +163,7 @@ impl DataContractFactory { skip_validation: bool, ) -> Result { let (protocol_version, mut raw_data_contract) = - DecodeProtocolEntity::decode_protocol_entity(buffer)?; + DecodeProtocolEntity::decode_protocol_entity_to_value::(buffer)?; raw_data_contract.set_value("protocolVersion", Value::U32(protocol_version))?; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/builder.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/builder.rs index 996fa16a15a..86bb3163b3f 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/builder.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/builder.rs @@ -8,6 +8,7 @@ use crate::state_transition::StateTransitionConvert; use crate::state_transition::StateTransitionType::{DataContractCreate, DataContractUpdate}; use crate::version::LATEST_VERSION; use crate::{NonConsensusError, ProtocolError}; +use crate::serialization_traits::{Signable, PlatformDeserializable}; impl DataContractCreateTransition { pub fn new_from_data_contract( @@ -26,7 +27,7 @@ impl DataContractCreateTransition { signature_public_key_id: key_id, signature: Default::default(), }; - let value = transition.to_cbor_buffer(true)?; + let value = transition.signable_bytes()?; let public_key = identity .loaded_public_keys @@ -55,7 +56,7 @@ impl DataContractUpdateTransition { signature_public_key_id: key_id, signature: Default::default(), }; - let value = transition.to_cbor_buffer(true)?; + let value = transition.signable_bytes()?; let public_key = identity .loaded_public_keys 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 b92461f8831..42275057a22 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 @@ -21,7 +21,7 @@ use crate::{ use super::property_names::*; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use bincode::enc::Encoder; use bincode::error::EncodeError; use bincode::{config, Decode, Encode}; 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 2e8833310fd..79830a3fbb5 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 @@ -7,7 +7,7 @@ use std::collections::BTreeMap; use std::convert::TryInto; use crate::platform_serialization::PlatformSignable; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use bincode::{config, Decode, Encode}; use crate::{ diff --git a/packages/rs-dpp/src/decode_protocol_entity_factory.rs b/packages/rs-dpp/src/decode_protocol_entity_factory.rs index 6b935e1754c..408c91d1eb1 100644 --- a/packages/rs-dpp/src/decode_protocol_entity_factory.rs +++ b/packages/rs-dpp/src/decode_protocol_entity_factory.rs @@ -8,19 +8,41 @@ use platform_value::Value; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::{errors::consensus::ConsensusError, errors::ProtocolError}; +use crate::serialization_traits::PlatformDeserializable; +use crate::state_transition::{StateTransition, StateTransitionConvert}; #[derive(Default, Clone, Copy)] pub struct DecodeProtocolEntity {} impl DecodeProtocolEntity { - pub fn decode_protocol_entity(buffer: impl AsRef<[u8]>) -> Result<(u32, Value), ProtocolError> { + pub fn decode_protocol_entity(buffer: impl AsRef<[u8]>) -> Result<(u32, T), ProtocolError> { let SplitProtocolVersionOutcome { protocol_version, main_message_bytes: document_bytes, .. } = deserializer::split_protocol_version(buffer.as_ref())?; - let cbor_value: CborValue = ciborium::de::from_reader(document_bytes).map_err(|e| { + let protocol_entity = T::deserialize(document_bytes).map_err(|e| { + ConsensusError::SerializedObjectParsingError { + parsing_error: anyhow!("Decode protocol entity: {:#?}", e), + } + })?; + + //todo deal with version + + Ok(( + protocol_version, + protocol_entity, + )) + } + pub fn decode_protocol_entity_to_value(buffer: impl AsRef<[u8]>) -> Result<(u32, Value), ProtocolError> { + let SplitProtocolVersionOutcome { + protocol_version, + main_message_bytes: document_bytes, + .. + } = deserializer::split_protocol_version(buffer.as_ref())?; + + let protocol_entity = T::deserialize(document_bytes).map_err(|e| { ConsensusError::SerializedObjectParsingError { parsing_error: anyhow!("Decode protocol entity: {:#?}", e), } @@ -28,7 +50,7 @@ impl DecodeProtocolEntity { Ok(( protocol_version, - cbor_value.try_into().map_err(ProtocolError::ValueError)?, + protocol_entity.to_object(false)?, )) } } diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index 19d63b2d185..c0ed28ac035 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -274,7 +274,7 @@ where buffer: impl AsRef<[u8]>, options: FactoryOptions, ) -> Result { - let result = DecodeProtocolEntity::decode_protocol_entity(buffer); + let result = DecodeProtocolEntity::decode_protocol_entity_to_value::(buffer); match result { Err(ProtocolError::AbstractConsensusError(err)) => { 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 6f11385e50f..39f4193b817 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,5 +1,5 @@ use crate::platform_serialization::PlatformSignable; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use bincode::{config, Decode, Encode}; use std::collections::{BTreeMap, HashMap}; use std::convert::{TryFrom, TryInto}; diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index eb5c7ae979e..ad5c9923240 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -31,8 +31,8 @@ pub enum ProtocolError { EmptyPublicKeyDataError, #[error("Payload reached a {max_size_kbytes}KB limit")] MaxEncodedBytesReachedError { - payload: Vec, max_size_kbytes: usize, + size_hit: usize, }, #[error("Encoding Error - {0}")] EncodingError(String), diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index 39f700570db..dcbd2a07f66 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -204,7 +204,7 @@ where skip_validation: bool, ) -> Result { let (protocol_version, mut raw_identity) = - DecodeProtocolEntity::decode_protocol_entity(buffer)?; + DecodeProtocolEntity::decode_protocol_entity_to_value(buffer)?; raw_identity .set_value("protocolVersion", Value::U32(protocol_version)) .map_err(ProtocolError::ValueError)?; diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index de90728c8ca..6994079dcc4 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -6,6 +6,7 @@ use integer_encoding::VarInt; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +use crate::serialization_traits::PlatformDeserializable; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; use crate::identity::{identity_public_key, KeyType, Purpose, SecurityLevel}; 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 db2ded5edc0..38a7142d49c 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -14,6 +14,7 @@ use dashcore::PublicKey as ECDSAPublicKey; use platform_value::{BinaryData, ReplacementType, Value, ValueMapHelper}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; +use crate::serialization_traits::PlatformDeserializable; use crate::errors::{InvalidVectorSizeError, ProtocolError}; pub use crate::identity::key_type::KeyType; 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 9f326553565..c54f0358880 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 crate::platform_serialization::PlatformSignable; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use bincode::{config, Decode, Encode}; use platform_value::btreemap_extensions::BTreeValueMapHelper; 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 3a6cc238416..ceff3eae633 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,5 @@ use crate::platform_serialization::PlatformSignable; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use bincode::{config, Decode, Encode}; use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs index 5c51a0a8ee1..e7be7224c5d 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs @@ -18,10 +18,13 @@ use crate::consensus::ConsensusError; use crate::errors::ProtocolError; use crate::identity::signer::Signer; use crate::platform_serialization::{PlatformDeserialize, PlatformSerialize}; +use crate::serialization_traits::PlatformDeserializable; use crate::state_transition::errors::InvalidIdentityPublicKeyTypeError; #[cfg(feature = "cbor")] use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; -use crate::util::{cbor_serializer, vec}; +#[cfg(feature = "cbor")] +use crate::util::cbor_serializer; +use crate::util::vec; use crate::validation::SimpleConsensusValidationResult; use crate::{BlsModule, Convertible, InvalidVectorSizeError, SerdeParsingError}; 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 8566336c89e..c54efd70abc 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,5 +1,5 @@ use crate::platform_serialization::PlatformSignable; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use bincode::{config, Decode, Encode}; use std::convert::{TryFrom, TryInto}; 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 6edeff74b96..fd2f5d58558 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,5 +1,5 @@ use crate::platform_serialization::PlatformSignable; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use bincode::{config, Decode, Encode}; use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 8e50baeca80..e741dbfbb87 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -43,7 +43,7 @@ mod bls; pub mod tests; pub mod block; -pub mod signable; +pub mod serialization_traits; pub mod system_data_contracts; pub use async_trait; diff --git a/packages/rs-dpp/src/serialization_traits.rs b/packages/rs-dpp/src/serialization_traits.rs new file mode 100644 index 00000000000..161523d226a --- /dev/null +++ b/packages/rs-dpp/src/serialization_traits.rs @@ -0,0 +1,9 @@ +use crate::ProtocolError; + +pub trait Signable { + fn signable_bytes(&self) -> Result, ProtocolError>; +} + +pub trait PlatformDeserializable { + fn deserialize(data: &[u8]) -> Result where Self: Sized; +} diff --git a/packages/rs-dpp/src/signable.rs b/packages/rs-dpp/src/signable.rs deleted file mode 100644 index 430f2fecd8c..00000000000 --- a/packages/rs-dpp/src/signable.rs +++ /dev/null @@ -1,5 +0,0 @@ -use crate::ProtocolError; - -pub trait Signable { - fn signable_bytes(&self) -> Result, ProtocolError>; -} 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 92f404632d3..1ede0f39b96 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -9,7 +9,7 @@ use serde_json::Value as JsonValue; use crate::consensus::ConsensusError; use crate::errors::consensus::signature::SignatureError; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, StateTransitionIsNotSignedError, }; @@ -131,7 +131,7 @@ pub trait StateTransitionLike: StateTransitionIsNotSignedError::new(self.clone().into()), )); } - let data = self.to_cbor_buffer(true)?; + let data = self.signable_bytes()?; signer::verify_data_signature(&data, self.get_signature().as_slice(), public_key).map_err( |_| { ProtocolError::from(ConsensusError::SignatureError( @@ -153,7 +153,7 @@ pub trait StateTransitionLike: )); } - let data = self.to_cbor_buffer(true)?; + let data = self.signable_bytes()?; bls.verify_signature(self.get_signature().as_slice(), &data, public_key) .map(|_| ()) @@ -238,14 +238,6 @@ pub trait StateTransitionConvert: Serialize { state_transition_helpers::to_json(self, skip_signature_paths) } - // Returns the cbor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version - fn to_bincode_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { - let mut value = self.to_canonical_cleaned_object(skip_signature)?; - let protocol_version = value.remove_integer(PROPERTY_PROTOCOL_VERSION)?; - - cbor_serializer::serializable_value_to_cbor(&value, Some(protocol_version)) - } - #[cfg(feature = "cbor")] // Returns the cbor-encoded bytes representation of the object. The data is prefixed by 4 bytes containing the Protocol Version fn to_cbor_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { 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 aff18564950..ebaad834726 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 @@ -33,7 +33,7 @@ where ) -> Result<(), ProtocolError> { self.verify_public_key_level_and_purpose(identity_public_key)?; self.verify_public_key_is_enabled(identity_public_key)?; - let data = self.to_cbor_buffer(true)?; + let data = self.signable_bytes()?; self.set_signature(signer.sign(identity_public_key, data.as_slice())?); self.set_signature_public_key_id(identity_public_key.id); Ok(()) diff --git a/packages/rs-dpp/src/state_transition/example.rs b/packages/rs-dpp/src/state_transition/example.rs index f6840d0df7c..6e059136f58 100644 --- a/packages/rs-dpp/src/state_transition/example.rs +++ b/packages/rs-dpp/src/state_transition/example.rs @@ -2,7 +2,7 @@ use crate::ProtocolError; use platform_value::BinaryData; use serde::{Deserialize, Serialize}; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; use super::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 2ad00ff6b5c..c6ab60a689b 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -39,7 +39,7 @@ mod example; mod serialization; mod state_transition_action; -use crate::signable::Signable; +use crate::serialization_traits::{Signable, PlatformDeserializable}; pub use state_transition_action::StateTransitionAction; macro_rules! call_method { ($state_transition:expr, $method:ident, $args:tt ) => { @@ -130,6 +130,7 @@ impl StateTransitionConvert for StateTransition { call_method!(self, hash, skip_signature) } + #[cfg(feature = "cbor")] fn to_cbor_buffer(&self, _skip_signature: bool) -> Result, crate::ProtocolError> { call_method!(self, to_cbor_buffer, true) } 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 4ec895300c9..53213277e7c 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -107,7 +107,7 @@ where options: Option, ) -> Result { let (protocol_version, mut raw_state_transition) = - DecodeProtocolEntity::decode_protocol_entity(state_transition_buffer)?; + DecodeProtocolEntity::decode_protocol_entity_to_value(state_transition_buffer)?; match raw_state_transition { Value::Map(ref mut m) => m.insert_string_key_value( 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 d6e66d7f86f..3cee6eb4819 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 @@ -100,11 +100,11 @@ where if let Err(ProtocolError::MaxEncodedBytesReachedError { max_size_kbytes, - payload, - }) = state_transition.to_cbor_buffer(false) + size_hit, + }) = state_transition.serialize() { result.add_error(BasicError::StateTransitionMaxSizeExceededError( - StateTransitionMaxSizeExceededError::new(payload.len() / 1024, max_size_kbytes), + StateTransitionMaxSizeExceededError::new(size_hit / 1024, max_size_kbytes), )); } diff --git a/packages/rs-dpp/src/util/cbor_serializer.rs b/packages/rs-dpp/src/util/cbor_serializer.rs index 1f9cd4dddd0..8b89d93812b 100644 --- a/packages/rs-dpp/src/util/cbor_serializer.rs +++ b/packages/rs-dpp/src/util/cbor_serializer.rs @@ -24,7 +24,7 @@ pub fn serializable_value_to_cbor( if (buffer.len() - size_with_protocol) >= MAX_ENCODED_KBYTE_LENGTH * 1024 { return Err(ProtocolError::MaxEncodedBytesReachedError { - payload: buffer, + size_hit: buffer.len(), max_size_kbytes: MAX_ENCODED_KBYTE_LENGTH, }); } diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 5134c08632d..614e441f193 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -73,15 +73,19 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { pub fn serialize(&self) -> Result, #error_type> { let config = config::standard().with_big_endian().with_limit::<{ #limit }>(); #serialize_into.map_err(|e| { - #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) - }) + match e { + bincode::error::EncodeError::Io{inner, index} => #error_type::MaxEncodedBytesReachedError{max_size_kbytes: #limit, size_hit: index}, + _ => #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)), + }}) } pub fn serialize_consume(self) -> Result, #error_type> { let config = config::standard().with_big_endian().with_limit::<{ #limit }>(); #serialize_into_consume.map_err(|e| { - #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) - }) + match e { + bincode::error::EncodeError::Io{inner, index} => #error_type::MaxEncodedBytesReachedError{max_size_kbytes: #limit, size_hit: index}, + _ => #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)), + }}) } } } @@ -175,8 +179,8 @@ pub fn derive_platform_deserialize(input: TokenStream) -> TokenStream { }; let expanded = quote! { - impl #impl_generics #name #ty_generics #where_clause { - pub fn deserialize(data: &[u8]) -> Result { + impl PlatformDeserializable for #impl_generics #name #ty_generics #where_clause { + fn deserialize(data: &[u8]) -> Result { let config = #config; #deserialize_from_inner.map_err(|e| { #platform_error_type::PlatformDeserializationError(format!("unable to deserialize {}: {}", stringify!(#name), e)) diff --git a/packages/wasm-dpp/src/decode_protocol_entity.rs b/packages/wasm-dpp/src/decode_protocol_entity.rs index b78efff6a27..9a1f2b51c60 100644 --- a/packages/wasm-dpp/src/decode_protocol_entity.rs +++ b/packages/wasm-dpp/src/decode_protocol_entity.rs @@ -10,7 +10,7 @@ use wasm_bindgen::JsValue; #[wasm_bindgen(js_name=decodeProtocolEntity)] pub fn decode_protocol_entity(buffer: Vec) -> Result { let (protocol_version, value) = - DecodeProtocolEntity::decode_protocol_entity(buffer).map_err(from_protocol_error)?; + DecodeProtocolEntity::decode_protocol_entity_to_value(buffer).map_err(from_protocol_error)?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_value = value From 131783a3e3e3a26f167ffe04475cb9a397ac1afb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 04:29:15 +0700 Subject: [PATCH 27/50] added a platform value convertible --- Cargo.toml | 1 + packages/rs-dpp/Cargo.toml | 1 + packages/rs-dpp/src/block/block_info.rs | 2 +- .../builder.rs | 2 +- .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- .../src/decode_protocol_entity_factory.rs | 28 ++-- .../rs-dpp/src/document/document_factory.rs | 3 +- .../rs-dpp/src/document/extended_document.rs | 57 +++++++- .../documents_batch_transition/mod.rs | 2 +- packages/rs-dpp/src/identity/identity.rs | 2 +- .../src/identity/identity_public_key/mod.rs | 2 +- .../identity_create_transition.rs | 2 +- .../mod.rs | 2 +- .../identity_public_key_transitions/mod.rs | 4 +- .../identity_topup_transition.rs | 2 +- .../identity_update_transition.rs | 2 +- packages/rs-dpp/src/serialization_traits.rs | 4 +- .../abstract_state_transition.rs | 2 +- .../rs-dpp/src/state_transition/example.rs | 2 +- packages/rs-dpp/src/state_transition/mod.rs | 2 +- .../state_transition_factory.rs | 4 +- packages/rs-platform-serialization/src/lib.rs | 7 + .../rs-platform-value-convertible/Cargo.toml | 16 +++ .../rs-platform-value-convertible/src/lib.rs | 127 ++++++++++++++++++ .../wasm-dpp/src/decode_protocol_entity.rs | 4 +- 26 files changed, 247 insertions(+), 37 deletions(-) create mode 100644 packages/rs-platform-value-convertible/Cargo.toml create mode 100644 packages/rs-platform-value-convertible/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 60270d33794..fd540e3fd56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "packages/rs-drive", "packages/rs-platform-value", "packages/rs-platform-serialization", + "packages/rs-platform-value-convertible", "packages/rs-drive-abci", "packages/dashpay-contract", "packages/withdrawals-contract", diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 5b09d1149f9..8f69a04f78f 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -50,6 +50,7 @@ thiserror = { version = "1.0" } mockall = { version = "0.11.3", optional = true } data-contracts = { path = "../data-contracts" } platform-value = { path = "../rs-platform-value" } +platform-value-convertible = { path = "../rs-platform-value-convertible" } platform-serialization = { path = "../rs-platform-serialization" } derive_more = "0.99.17" ed25519-dalek = {version = "2.0.0-rc.2", features = ["rand_core"] } diff --git a/packages/rs-dpp/src/block/block_info.rs b/packages/rs-dpp/src/block/block_info.rs index f310f013b70..c7d99b1e7be 100644 --- a/packages/rs-dpp/src/block/block_info.rs +++ b/packages/rs-dpp/src/block/block_info.rs @@ -1,9 +1,9 @@ use crate::block::epoch::Epoch; +use crate::serialization_traits::PlatformDeserializable; use crate::ProtocolError; use bincode::config; use bincode::{Decode, Encode}; use platform_serialization::{PlatformDeserialize, PlatformSerialize}; -use crate::serialization_traits::PlatformDeserializable; /// Block information #[derive(Clone, Default, Encode, Decode, PlatformSerialize, PlatformDeserialize)] diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/builder.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/builder.rs index 86bb3163b3f..f2bd4027210 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/builder.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/builder.rs @@ -4,11 +4,11 @@ use crate::data_contract::state_transition::data_contract_update_transition::Dat use crate::identity::signer::Signer; use crate::identity::{KeyID, PartialIdentity}; use crate::prelude::DataContract; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use crate::state_transition::StateTransitionConvert; use crate::state_transition::StateTransitionType::{DataContractCreate, DataContractUpdate}; use crate::version::LATEST_VERSION; use crate::{NonConsensusError, ProtocolError}; -use crate::serialization_traits::{Signable, PlatformDeserializable}; impl DataContractCreateTransition { pub fn new_from_data_contract( 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 42275057a22..dfb579e8813 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 @@ -21,7 +21,7 @@ use crate::{ use super::property_names::*; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::enc::Encoder; use bincode::error::EncodeError; use bincode::{config, Decode, Encode}; 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 79830a3fbb5..96e40e36652 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 @@ -7,7 +7,7 @@ use std::collections::BTreeMap; use std::convert::TryInto; use crate::platform_serialization::PlatformSignable; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::{config, Decode, Encode}; use crate::{ diff --git a/packages/rs-dpp/src/decode_protocol_entity_factory.rs b/packages/rs-dpp/src/decode_protocol_entity_factory.rs index 408c91d1eb1..21560c3bd32 100644 --- a/packages/rs-dpp/src/decode_protocol_entity_factory.rs +++ b/packages/rs-dpp/src/decode_protocol_entity_factory.rs @@ -5,24 +5,26 @@ use std::convert::TryInto; use platform_value::Value; -use crate::util::deserializer; -use crate::util::deserializer::SplitProtocolVersionOutcome; -use crate::{errors::consensus::ConsensusError, errors::ProtocolError}; use crate::serialization_traits::PlatformDeserializable; use crate::state_transition::{StateTransition, StateTransitionConvert}; +use crate::util::deserializer; +use crate::util::deserializer::SplitProtocolVersionOutcome; +use crate::{errors::consensus::ConsensusError, errors::ProtocolError, Convertible}; #[derive(Default, Clone, Copy)] pub struct DecodeProtocolEntity {} impl DecodeProtocolEntity { - pub fn decode_protocol_entity(buffer: impl AsRef<[u8]>) -> Result<(u32, T), ProtocolError> { + pub fn decode_protocol_entity( + buffer: impl AsRef<[u8]>, + ) -> Result<(u32, T), ProtocolError> { let SplitProtocolVersionOutcome { protocol_version, main_message_bytes: document_bytes, .. } = deserializer::split_protocol_version(buffer.as_ref())?; - let protocol_entity = T::deserialize(document_bytes).map_err(|e| { + let protocol_entity = T::deserialize(document_bytes).map_err(|e| { ConsensusError::SerializedObjectParsingError { parsing_error: anyhow!("Decode protocol entity: {:#?}", e), } @@ -30,27 +32,23 @@ impl DecodeProtocolEntity { //todo deal with version - Ok(( - protocol_version, - protocol_entity, - )) + Ok((protocol_version, protocol_entity)) } - pub fn decode_protocol_entity_to_value(buffer: impl AsRef<[u8]>) -> Result<(u32, Value), ProtocolError> { + pub fn decode_protocol_entity_to_value( + buffer: impl AsRef<[u8]>, + ) -> Result<(u32, Value), ProtocolError> { let SplitProtocolVersionOutcome { protocol_version, main_message_bytes: document_bytes, .. } = deserializer::split_protocol_version(buffer.as_ref())?; - let protocol_entity = T::deserialize(document_bytes).map_err(|e| { + let protocol_entity = T::deserialize(document_bytes).map_err(|e| { ConsensusError::SerializedObjectParsingError { parsing_error: anyhow!("Decode protocol entity: {:#?}", e), } })?; - Ok(( - protocol_version, - protocol_entity.to_object(false)?, - )) + Ok((protocol_version, protocol_entity.to_object()?)) } } diff --git a/packages/rs-dpp/src/document/document_factory.rs b/packages/rs-dpp/src/document/document_factory.rs index c0ed28ac035..458fb21dcb9 100644 --- a/packages/rs-dpp/src/document/document_factory.rs +++ b/packages/rs-dpp/src/document/document_factory.rs @@ -274,7 +274,8 @@ where buffer: impl AsRef<[u8]>, options: FactoryOptions, ) -> Result { - let result = DecodeProtocolEntity::decode_protocol_entity_to_value::(buffer); + let result = + DecodeProtocolEntity::decode_protocol_entity_to_value::(buffer); match result { Err(ProtocolError::AbstractConsensusError(err)) => { diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index a3703853faa..aebf0f0291b 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -15,6 +15,9 @@ 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 crate::serialization_traits::PlatformDeserializable; +use bincode::{Decode, Encode}; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; use platform_value::btreemap_extensions::BTreeValueMapInsertionPathHelper; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; @@ -44,7 +47,12 @@ 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)] +#[derive(Serialize, Deserialize, Debug, Clone, Default, PlatformSerialize, PlatformDeserialize)] +#[platform_error_type(ProtocolError)] +#[platform_deserialize_limit(2000)] +#[platform_serialize_limit(2000)] +#[platform_serialize_into(ExtendedDocumentInner)] +#[platform_deserialize_from(ExtendedDocumentInner)] pub struct ExtendedDocument { #[serde(rename = "$protocolVersion")] pub protocol_version: u32, @@ -63,6 +71,53 @@ pub struct ExtendedDocument { pub entropy: Bytes32, } +impl From for ExtendedDocument { + fn from(value: ExtendedDocumentInner) -> Self { + let ExtendedDocumentInner { + protocol_version, + document_type_name, + data_contract_id, + document, + } = value; + ExtendedDocument { + protocol_version, + document_type_name, + data_contract_id, + document, + data_contract: Default::default(), + metadata: None, + entropy: Default::default(), + } + } +} + +impl From for ExtendedDocumentInner { + fn from(value: ExtendedDocument) -> Self { + let ExtendedDocument { + protocol_version, + document_type_name, + data_contract_id, + document, + .. + } = value; + ExtendedDocumentInner { + protocol_version, + document_type_name, + data_contract_id, + document, + } + } +} + +/// The document object represents the data provided by the platform in response to a query. +#[derive(Debug, Clone, Default, Encode, Decode)] +pub struct ExtendedDocumentInner { + pub protocol_version: u32, + pub document_type_name: String, + pub data_contract_id: Identifier, + pub document: Document, +} + impl ExtendedDocument { fn properties_as_json_data(&self) -> Result { self.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 39f4193b817..77647174b65 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,5 +1,5 @@ use crate::platform_serialization::PlatformSignable; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::{config, Decode, Encode}; use std::collections::{BTreeMap, HashMap}; use std::convert::{TryFrom, TryInto}; diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 6994079dcc4..793449230f6 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -2,11 +2,11 @@ use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::convert::{TryFrom, TryInto}; use std::hash::{Hash, Hasher}; +use crate::serialization_traits::PlatformDeserializable; use integer_encoding::VarInt; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use crate::serialization_traits::PlatformDeserializable; use crate::identity::state_transition::asset_lock_proof::AssetLockProof; use crate::identity::{identity_public_key, KeyType, Purpose, SecurityLevel}; 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 38a7142d49c..0b2592be896 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -7,6 +7,7 @@ pub mod security_level; use std::convert::{TryFrom, TryInto}; +use crate::serialization_traits::PlatformDeserializable; use anyhow::anyhow; #[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; @@ -14,7 +15,6 @@ use dashcore::PublicKey as ECDSAPublicKey; use platform_value::{BinaryData, ReplacementType, Value, ValueMapHelper}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::Value as JsonValue; -use crate::serialization_traits::PlatformDeserializable; use crate::errors::{InvalidVectorSizeError, ProtocolError}; pub use crate::identity::key_type::KeyType; 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 c54f0358880..638919f0d03 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 crate::platform_serialization::PlatformSignable; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::{config, Decode, Encode}; use platform_value::btreemap_extensions::BTreeValueMapHelper; 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 ceff3eae633..9e81350fd39 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,5 @@ use crate::platform_serialization::PlatformSignable; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::{config, Decode, Encode}; use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs index e7be7224c5d..dfec6e57d0a 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs @@ -21,9 +21,9 @@ use crate::platform_serialization::{PlatformDeserialize, PlatformSerialize}; use crate::serialization_traits::PlatformDeserializable; use crate::state_transition::errors::InvalidIdentityPublicKeyTypeError; #[cfg(feature = "cbor")] -use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; -#[cfg(feature = "cbor")] use crate::util::cbor_serializer; +#[cfg(feature = "cbor")] +use crate::util::cbor_value::{CborCanonicalMap, CborMapExtension}; use crate::util::vec; use crate::validation::SimpleConsensusValidationResult; use crate::{BlsModule, Convertible, InvalidVectorSizeError, SerdeParsingError}; 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 c54efd70abc..028634eee41 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,5 +1,5 @@ use crate::platform_serialization::PlatformSignable; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::{config, Decode, Encode}; use std::convert::{TryFrom, TryInto}; 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 fd2f5d58558..7abf3df79ed 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,5 +1,5 @@ use crate::platform_serialization::PlatformSignable; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::{config, Decode, Encode}; use platform_value::{BinaryData, ReplacementType, Value}; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/serialization_traits.rs b/packages/rs-dpp/src/serialization_traits.rs index 161523d226a..47ab9b6e172 100644 --- a/packages/rs-dpp/src/serialization_traits.rs +++ b/packages/rs-dpp/src/serialization_traits.rs @@ -5,5 +5,7 @@ pub trait Signable { } pub trait PlatformDeserializable { - fn deserialize(data: &[u8]) -> Result where Self: Sized; + fn deserialize(data: &[u8]) -> Result + where + Self: Sized; } 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 1ede0f39b96..5f4561f4d16 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -9,7 +9,7 @@ use serde_json::Value as JsonValue; use crate::consensus::ConsensusError; use crate::errors::consensus::signature::SignatureError; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, StateTransitionIsNotSignedError, }; diff --git a/packages/rs-dpp/src/state_transition/example.rs b/packages/rs-dpp/src/state_transition/example.rs index 6e059136f58..a5683cb8e71 100644 --- a/packages/rs-dpp/src/state_transition/example.rs +++ b/packages/rs-dpp/src/state_transition/example.rs @@ -2,7 +2,7 @@ use crate::ProtocolError; use platform_value::BinaryData; use serde::{Deserialize, Serialize}; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; use super::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index c6ab60a689b..9a42245b904 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -39,7 +39,7 @@ mod example; mod serialization; mod state_transition_action; -use crate::serialization_traits::{Signable, PlatformDeserializable}; +use crate::serialization_traits::{PlatformDeserializable, Signable}; pub use state_transition_action::StateTransitionAction; macro_rules! call_method { ($state_transition:expr, $method:ident, $args:tt ) => { 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 53213277e7c..e63946d481e 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -107,7 +107,9 @@ where options: Option, ) -> Result { let (protocol_version, mut raw_state_transition) = - DecodeProtocolEntity::decode_protocol_entity_to_value(state_transition_buffer)?; + DecodeProtocolEntity::decode_protocol_entity_to_value::( + state_transition_buffer, + )?; match raw_state_transition { Value::Map(ref mut m) => m.insert_string_key_value( diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 614e441f193..793660d4677 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -99,6 +99,13 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) }) } + + pub fn serialize_consume(self) -> Result, #error_type> { + let config = config::standard().with_big_endian().with_no_limit(); + #serialize_into_consume.map_err(|e| { + #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) + }) + } } } }; diff --git a/packages/rs-platform-value-convertible/Cargo.toml b/packages/rs-platform-value-convertible/Cargo.toml new file mode 100644 index 00000000000..4404eef66ac --- /dev/null +++ b/packages/rs-platform-value-convertible/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "platform-value-convertible" +authors = ["Samuel Westrich "] +description = "Convertion to and from platform values" +version = "0.1.0" +edition = "2021" +license = "MIT" +private = true + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0.56" +quote = "1.0.26" +syn = "2.0.15" diff --git a/packages/rs-platform-value-convertible/src/lib.rs b/packages/rs-platform-value-convertible/src/lib.rs new file mode 100644 index 00000000000..84e4ed52e3d --- /dev/null +++ b/packages/rs-platform-value-convertible/src/lib.rs @@ -0,0 +1,127 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; +use proc_macro2::Span; +use quote::quote; +use syn::spanned::Spanned; +use syn::Error; +use syn::{parse_macro_input, Data, DeriveInput, Fields, Meta, NestedMeta}; + +#[proc_macro_derive( + PlatformValueConvert, + attributes(platform_error_type, platform_convert_into, platform_value) +)] +pub fn derive_platform_convert(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = &input.ident; + + // Extract the error type from the attribute. + let error_type = input + .attrs + .iter() + .find_map(|attr| { + if attr.path().is_ident("platform_error_type") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }) + .expect("Missing platform_error_type attribute"); + + let platform_convert_into: Option = input.attrs.iter().find_map(|attr| { + if attr.path().is_ident("platform_convert_into") { + Some(attr.parse_args::().unwrap()) + } else { + None + } + }); + + let fields = match &input.data { + Data::Struct(data_struct) => match &data_struct.fields { + Fields::Named(fields_named) => &fields_named.named, + _ => panic!("Only named fields are supported"), + }, + _ => panic!("Only structs are supported"), + }; + + let mut filtered_fields = vec![]; + for field in fields { + if !field.attrs.iter().any(|attr| { + attr.path.is_ident("platform_value") && attr.parse_args::().ok().map_or(false, |meta| { + matches!(meta, Meta::List(list) if list.nested.iter().any(|n| matches!(n, NestedMeta::Meta(Meta::Path(p)) if p.is_ident("skip")))) + }) + }) { + filtered_fields.push(field); + } + } + + let field_idents: Vec<_> = filtered_fields.iter().map(|f| &f.ident).collect(); + + // Extract the generics. + let generics = &input.generics; + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + + let convert_from_value = match &platform_convert_into { + Some(inner) => quote! { + #inner::from_object(value).map(Into::into) + }, + None => quote! { + Self::from_object(value) + }, + }; + + let convert_from_value_ref = match &platform_convert_into { + Some(inner) => quote! { + #inner::from_object_ref(value).map(Into::into) + }, + None => quote! { + Self::from_object_ref(value) + }, + }; + + let convert_into_value = match &platform_convert_into { + Some(inner) => quote! { + let inner: #inner = self.clone().into(); + inner.into_object() + }, + None => quote! { + self.into_object() + }, + }; + + let convert_to_object = match &platform_convert_into { + Some(inner) => quote! { + let inner: #inner = self.clone().into(); + inner.to_object() + }, + None => quote! { + platform_value::to_value_with_filter(self, |field_name| { + let field_names = vec![#(#field_idents),*]; + field_names.contains(&field_name) + }).map_err(#error_type::ValueError) + }, + }; + + let expanded = quote! { + impl #impl_generics ValueConvertible for #name #ty_generics #where_clause + { + fn to_object(&self) -> Result { + #convert_to_object + } + + fn into_object(self) -> Result { + #convert_into_value + } + + fn from_object(value: Value) -> Result { + #convert_from_value + } + + fn from_object_ref(value: &Value) -> Result { + #convert_from_value_ref + } + } + }; + + TokenStream::from(expanded) +} diff --git a/packages/wasm-dpp/src/decode_protocol_entity.rs b/packages/wasm-dpp/src/decode_protocol_entity.rs index 9a1f2b51c60..9d7db0d04aa 100644 --- a/packages/wasm-dpp/src/decode_protocol_entity.rs +++ b/packages/wasm-dpp/src/decode_protocol_entity.rs @@ -9,8 +9,8 @@ use wasm_bindgen::JsValue; #[wasm_bindgen(js_name=decodeProtocolEntity)] pub fn decode_protocol_entity(buffer: Vec) -> Result { - let (protocol_version, value) = - DecodeProtocolEntity::decode_protocol_entity_to_value(buffer).map_err(from_protocol_error)?; + let (protocol_version, value) = DecodeProtocolEntity::decode_protocol_entity_to_value(buffer) + .map_err(from_protocol_error)?; let serializer = serde_wasm_bindgen::Serializer::json_compatible(); let js_value = value From a06050aa53c885092a9e1a633a1a8a0b96939325 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 08:25:20 +0700 Subject: [PATCH 28/50] dpp compiling --- Cargo.lock | 10 ++ packages/rs-dpp/src/block/block_info.rs | 2 +- .../rs-dpp/src/data_contract/data_contract.rs | 5 +- .../data_contract/data_contract_factory.rs | 28 +++++- .../data_contract_create_transition/mod.rs | 16 +++- .../data_contract_update_transition/mod.rs | 15 ++- .../serialize_for_signing.rs | 1 + .../src/decode_protocol_entity_factory.rs | 5 +- .../rs-dpp/src/document/extended_document.rs | 96 +++++++------------ .../documents_batch_transition/mod.rs | 15 ++- packages/rs-dpp/src/identity/factory.rs | 34 +++++-- packages/rs-dpp/src/identity/identity.rs | 4 +- .../src/identity/identity_public_key/mod.rs | 2 +- .../identity_create_transition.rs | 15 ++- .../mod.rs | 15 ++- .../identity_public_key_transitions/mod.rs | 2 +- .../identity_topup_transition.rs | 15 ++- .../identity_update_transition.rs | 15 ++- packages/rs-dpp/src/serialization_traits.rs | 27 ++++++ .../abstract_state_transition.rs | 10 +- .../rs-dpp/src/state_transition/example.rs | 76 --------------- packages/rs-dpp/src/state_transition/mod.rs | 13 ++- .../src/state_transition/serialization.rs | 2 + .../state_transition_factory.rs | 42 ++++---- .../validate_state_transition_basic.rs | 1 + packages/rs-platform-serialization/src/lib.rs | 12 +-- .../rs-platform-value-convertible/src/lib.rs | 62 ++++++------ 27 files changed, 312 insertions(+), 228 deletions(-) delete mode 100644 packages/rs-dpp/src/state_transition/example.rs diff --git a/Cargo.lock b/Cargo.lock index 6dc4d79e265..cfc1d076046 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1122,6 +1122,7 @@ dependencies = [ "num_enum", "platform-serialization", "platform-value", + "platform-value-convertible", "pretty_assertions", "rand", "regex", @@ -2490,6 +2491,15 @@ dependencies = [ "treediff 4.0.2", ] +[[package]] +name = "platform-value-convertible" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "platforms" version = "3.0.2" diff --git a/packages/rs-dpp/src/block/block_info.rs b/packages/rs-dpp/src/block/block_info.rs index c7d99b1e7be..0203190f3be 100644 --- a/packages/rs-dpp/src/block/block_info.rs +++ b/packages/rs-dpp/src/block/block_info.rs @@ -1,5 +1,5 @@ use crate::block::epoch::Epoch; -use crate::serialization_traits::PlatformDeserializable; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; use crate::ProtocolError; use bincode::config; use bincode::{Decode, Encode}; diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index f0cc4c22f79..b1f84e1f81a 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -7,6 +7,7 @@ use futures::StreamExt; use std::collections::{BTreeMap, HashSet}; use std::convert::{TryFrom, TryInto}; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable, ValueConvertible}; use itertools::{Either, Itertools}; use platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueRemoveFromMapHelper}; use platform_value::{platform_value, Bytes32, Identifier}; @@ -15,8 +16,6 @@ use serde::de::Error; use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; -use crate::serialization_traits::PlatformDeserializable; - use crate::consensus::basic::document::InvalidDocumentTypeError; use crate::data_contract::contract_config; use crate::data_contract::contract_config::{ @@ -357,7 +356,7 @@ impl DataContract { // Returns hash from Data Contract pub fn hash(&self) -> Result, ProtocolError> { - Ok(hash_to_vec(self.serialize()?)) + Ok(hash_to_vec(PlatformSerializable::serialize(self)?)) } /// Increments version of 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 3a3e2e2b2e5..f3cbe387427 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -1,3 +1,4 @@ +use anyhow::anyhow; use serde_json::Value as JsonValue; use std::collections::BTreeMap; use std::convert::TryInto; @@ -11,13 +12,18 @@ use crate::data_contract::errors::InvalidDataContractError; use crate::data_contract::property_names::PROTOCOL_VERSION; +use crate::consensus::ConsensusError; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; use crate::state_transition::StateTransitionType; +use crate::util::deserializer; +use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::util::entropy_generator::{DefaultEntropyGenerator, EntropyGenerator}; use crate::{ data_contract::{self, generate_data_contract_id}, decode_protocol_entity_factory::DecodeProtocolEntity, errors::ProtocolError, prelude::Identifier, + Convertible, }; use super::state_transition::data_contract_create_transition::DataContractCreateTransition; @@ -162,13 +168,25 @@ impl DataContractFactory { buffer: Vec, skip_validation: bool, ) -> Result { - let (protocol_version, mut raw_data_contract) = - DecodeProtocolEntity::decode_protocol_entity_to_value::(buffer)?; + let SplitProtocolVersionOutcome { + protocol_version, + main_message_bytes: document_bytes, + .. + } = deserializer::split_protocol_version(buffer.as_ref())?; - raw_data_contract.set_value("protocolVersion", Value::U32(protocol_version))?; + let data_contract = DataContract::deserialize(document_bytes).map_err(|e| { + ConsensusError::SerializedObjectParsingError { + parsing_error: anyhow!("Decode protocol entity: {:#?}", e), + } + })?; - self.create_from_object(raw_data_contract, skip_validation) - .await + if !skip_validation { + let mut value = data_contract.to_object()?; + value.set_value("protocolVersion", Value::U32(protocol_version))?; + self.create_from_object(value, skip_validation).await + } else { + Ok(data_contract) + } } pub fn create_data_contract_create_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 dfb579e8813..2531bc250f8 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,10 @@ use std::collections::BTreeMap; use std::convert::TryInto; +use crate::serialization_traits::PlatformSerializable; use platform_serialization::PlatformSignable; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; + use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::{BinaryData, Bytes32, IntegerReplacementType, ReplacementType, Value}; @@ -63,7 +66,18 @@ pub const U32_FIELDS: [&str; 2] = [ property_names::DATA_CONTRACT_PROTOCOL_VERSION, ]; -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq, PlatformSignable)] +#[derive( + Debug, + Clone, + Serialize, + Deserialize, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PartialEq, + PlatformSignable, +)] #[serde(rename_all = "camelCase")] #[platform_error_type(ProtocolError)] pub struct 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 96e40e36652..9666a90d8f4 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 @@ -7,8 +7,10 @@ use std::collections::BTreeMap; use std::convert::TryInto; use crate::platform_serialization::PlatformSignable; +use crate::serialization_traits::PlatformSerializable; use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::{config, Decode, Encode}; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; use crate::{ data_contract::DataContract, @@ -56,7 +58,18 @@ pub const U32_FIELDS: [&str; 2] = [ property_names::DATA_CONTRACT_PROTOCOL_VERSION, ]; -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PartialEq, PlatformSignable)] +#[derive( + Debug, + Clone, + Serialize, + Deserialize, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PartialEq, + PlatformSignable, +)] #[serde(rename_all = "camelCase")] #[platform_error_type(ProtocolError)] pub struct DataContractUpdateTransition { diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs index 581939061d1..c61581cb375 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/serialize_for_signing.rs @@ -1,6 +1,7 @@ use crate::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; use crate::data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition; use crate::data_contract::{DataContract, DataContractInner}; +use crate::serialization_traits::PlatformSerializable; use crate::state_transition::StateTransitionType; use crate::util::hash::{hash, hash_to_vec}; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/decode_protocol_entity_factory.rs b/packages/rs-dpp/src/decode_protocol_entity_factory.rs index 21560c3bd32..5f79052025c 100644 --- a/packages/rs-dpp/src/decode_protocol_entity_factory.rs +++ b/packages/rs-dpp/src/decode_protocol_entity_factory.rs @@ -5,7 +5,7 @@ use std::convert::TryInto; use platform_value::Value; -use crate::serialization_traits::PlatformDeserializable; +use crate::serialization_traits::{PlatformDeserializable, ValueConvertible}; use crate::state_transition::{StateTransition, StateTransitionConvert}; use crate::util::deserializer; use crate::util::deserializer::SplitProtocolVersionOutcome; @@ -34,7 +34,8 @@ impl DecodeProtocolEntity { Ok((protocol_version, protocol_entity)) } - pub fn decode_protocol_entity_to_value( + + pub fn decode_protocol_entity_to_value( buffer: impl AsRef<[u8]>, ) -> Result<(u32, Value), ProtocolError> { let SplitProtocolVersionOutcome { diff --git a/packages/rs-dpp/src/document/extended_document.rs b/packages/rs-dpp/src/document/extended_document.rs index aebf0f0291b..6afe13481c6 100644 --- a/packages/rs-dpp/src/document/extended_document.rs +++ b/packages/rs-dpp/src/document/extended_document.rs @@ -15,8 +15,9 @@ 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 crate::serialization_traits::PlatformDeserializable; -use bincode::{Decode, Encode}; +use crate::serialization_traits::ValueConvertible; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; +use bincode::{config, Decode, Encode}; use platform_serialization::{PlatformDeserialize, PlatformSerialize}; use platform_value::btreemap_extensions::BTreeValueMapInsertionPathHelper; use platform_value::btreemap_extensions::BTreeValueMapPathHelper; @@ -24,9 +25,11 @@ use platform_value::btreemap_extensions::BTreeValueMapReplacementPathHelper; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::converter::serde_json::BTreeValueJsonConverter; use platform_value::{Bytes32, ReplacementType, Value}; +use platform_value_convertible::PlatformValueConvert; use serde::{Deserialize, Serialize}; use serde_json::{json, Value as JsonValue}; use std::collections::{BTreeMap, HashSet}; +use std::convert::TryFrom; use std::convert::TryInto; pub mod property_names { @@ -47,12 +50,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, PlatformSerialize, PlatformDeserialize)] -#[platform_error_type(ProtocolError)] -#[platform_deserialize_limit(2000)] -#[platform_serialize_limit(2000)] -#[platform_serialize_into(ExtendedDocumentInner)] -#[platform_deserialize_from(ExtendedDocumentInner)] +#[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct ExtendedDocument { #[serde(rename = "$protocolVersion")] pub protocol_version: u32, @@ -71,53 +69,6 @@ pub struct ExtendedDocument { pub entropy: Bytes32, } -impl From for ExtendedDocument { - fn from(value: ExtendedDocumentInner) -> Self { - let ExtendedDocumentInner { - protocol_version, - document_type_name, - data_contract_id, - document, - } = value; - ExtendedDocument { - protocol_version, - document_type_name, - data_contract_id, - document, - data_contract: Default::default(), - metadata: None, - entropy: Default::default(), - } - } -} - -impl From for ExtendedDocumentInner { - fn from(value: ExtendedDocument) -> Self { - let ExtendedDocument { - protocol_version, - document_type_name, - data_contract_id, - document, - .. - } = value; - ExtendedDocumentInner { - protocol_version, - document_type_name, - data_contract_id, - document, - } - } -} - -/// The document object represents the data provided by the platform in response to a query. -#[derive(Debug, Clone, Default, Encode, Decode)] -pub struct ExtendedDocumentInner { - pub protocol_version: u32, - pub document_type_name: String, - pub data_contract_id: Identifier, - pub document: Document, -} - impl ExtendedDocument { fn properties_as_json_data(&self) -> Result { self.document @@ -479,19 +430,36 @@ impl ExtendedDocument { } } -impl TryInto for ExtendedDocument { - type Error = ProtocolError; - - fn try_into(self) -> Result { - self.into_value() +impl PlatformDeserializable for ExtendedDocument { + fn deserialize(data: &[u8]) -> Result + where + Self: Sized, + { + todo!() } } -impl TryInto for &ExtendedDocument { - type Error = ProtocolError; +impl ValueConvertible for ExtendedDocument { + fn to_object(&self) -> Result { + todo!() + } + + fn into_object(self) -> Result { + todo!() + } + + fn from_object(value: Value) -> Result + where + Self: Sized, + { + todo!() + } - fn try_into(self) -> Result { - self.to_value() + fn from_object_ref(value: &Value) -> Result + where + Self: Sized, + { + todo!() } } 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 77647174b65..ab168a3156b 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 @@ -36,6 +36,8 @@ use platform_value::string_encoding::Encoding; use self::document_transition::{ document_base_transition, document_create_transition, DocumentTransitionExt, }; +use crate::serialization_traits::PlatformSerializable; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; mod action; pub mod apply_documents_batch_transition_factory; @@ -68,7 +70,18 @@ pub const U32_FIELDS: [&str; 1] = [property_names::PROTOCOL_VERSION]; const DEFAULT_SECURITY_LEVEL: SecurityLevel = SecurityLevel::HIGH; const EMPTY_VEC: Vec = vec![]; -#[derive(Debug, Serialize, Deserialize, Encode, Decode, Clone, PartialEq, PlatformSignable)] +#[derive( + Debug, + Serialize, + Deserialize, + Encode, + Decode, + Clone, + PartialEq, + PlatformDeserialize, + PlatformSerialize, + PlatformSignable, +)] #[serde(rename_all = "camelCase")] #[platform_error_type(ProtocolError)] pub struct DocumentsBatchTransition { diff --git a/packages/rs-dpp/src/identity/factory.rs b/packages/rs-dpp/src/identity/factory.rs index dcbd2a07f66..6b4be9b9915 100644 --- a/packages/rs-dpp/src/identity/factory.rs +++ b/packages/rs-dpp/src/identity/factory.rs @@ -10,7 +10,7 @@ use crate::identity::validation::{IdentityValidator, PublicKeysValidator}; use crate::identity::{Identity, IdentityPublicKey, KeyID, TimestampMillis}; use crate::prelude::Identifier; -use crate::{BlsModule, ProtocolError}; +use crate::{BlsModule, Convertible, ProtocolError}; use dashcore::{InstantLock, Transaction}; use rand::rngs::StdRng; @@ -19,6 +19,12 @@ use std::collections::BTreeMap; use std::convert::TryInto; use std::iter::FromIterator; +use crate::consensus::ConsensusError; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; +use crate::state_transition::StateTransition; +use crate::util::deserializer; +use crate::util::deserializer::SplitProtocolVersionOutcome; +use anyhow::anyhow; use platform_value::Value; use std::sync::Arc; @@ -203,15 +209,25 @@ where buffer: Vec, skip_validation: bool, ) -> Result { - let (protocol_version, mut raw_identity) = - DecodeProtocolEntity::decode_protocol_entity_to_value(buffer)?; - raw_identity - .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 + let SplitProtocolVersionOutcome { + protocol_version, + main_message_bytes: document_bytes, + .. + } = deserializer::split_protocol_version(buffer.as_ref())?; - self.create_from_object(raw_identity, skip_validation) + let identity = Identity::deserialize(document_bytes).map_err(|e| { + ConsensusError::SerializedObjectParsingError { + parsing_error: anyhow!("Decode protocol entity: {:#?}", e), + } + })?; + + if skip_validation { + Ok(identity) + } else { + let mut value = identity.to_object()?; + value.set_value("protocolVersion", Value::U32(protocol_version))?; + self.create_from_object(value, false) + } } pub fn create_instant_lock_proof( diff --git a/packages/rs-dpp/src/identity/identity.rs b/packages/rs-dpp/src/identity/identity.rs index 793449230f6..1099b5ee98d 100644 --- a/packages/rs-dpp/src/identity/identity.rs +++ b/packages/rs-dpp/src/identity/identity.rs @@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::convert::{TryFrom, TryInto}; use std::hash::{Hash, Hasher}; -use crate::serialization_traits::PlatformDeserializable; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; use integer_encoding::VarInt; use platform_value::{ReplacementType, Value}; use serde::{Deserialize, Serialize}; @@ -390,7 +390,7 @@ impl Identity { /// Computes the hash of an identity pub fn hash(&self) -> Result, ProtocolError> { - Ok(hash::hash_to_vec(self.serialize()?)) + Ok(hash::hash_to_vec(PlatformSerializable::serialize(self)?)) } /// Convenience method to get Partial Identity Info 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 0b2592be896..29ffaacef52 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -7,7 +7,7 @@ pub mod security_level; use std::convert::{TryFrom, TryInto}; -use crate::serialization_traits::PlatformDeserializable; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; use anyhow::anyhow; #[cfg(feature = "cbor")] use ciborium::value::Value as CborValue; 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 638919f0d03..255c7f368b0 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,8 +1,10 @@ use std::convert::{TryFrom, TryInto}; use crate::platform_serialization::PlatformSignable; +use crate::serialization_traits::PlatformSerializable; use crate::serialization_traits::{PlatformDeserializable, Signable}; use bincode::{config, Decode, Encode}; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::{BinaryData, IntegerReplacementType, ReplacementType, Value}; @@ -45,7 +47,18 @@ pub struct SerializationOptions { pub into_validating_json: bool, } -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Encode, Decode, PlatformSignable)] +#[derive( + Serialize, + Deserialize, + Debug, + Clone, + PartialEq, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PlatformSignable, +)] #[serde(rename_all = "camelCase")] #[serde(try_from = "IdentityCreateTransitionInner")] #[platform_error_type(ProtocolError)] 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 9e81350fd39..3f65d5c8283 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 @@ -22,6 +22,8 @@ use crate::{ use super::properties::{ PROPERTY_IDENTITY_ID, PROPERTY_SIGNATURE, PROPERTY_SIGNATURE_PUBLIC_KEY_ID, }; +use crate::serialization_traits::PlatformSerializable; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; mod action; pub mod apply_identity_credit_withdrawal_transition_factory; @@ -47,7 +49,18 @@ impl std::default::Default for Pooling { } } -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PlatformSignable, PartialEq)] +#[derive( + Debug, + Clone, + Serialize, + Deserialize, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PlatformSignable, + PartialEq, +)] #[serde(rename_all = "camelCase")] #[platform_error_type(ProtocolError)] pub struct IdentityCreditWithdrawalTransition { diff --git a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs index dfec6e57d0a..ae4ce7e9450 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_public_key_transitions/mod.rs @@ -18,7 +18,7 @@ use crate::consensus::ConsensusError; use crate::errors::ProtocolError; use crate::identity::signer::Signer; use crate::platform_serialization::{PlatformDeserialize, PlatformSerialize}; -use crate::serialization_traits::PlatformDeserializable; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; use crate::state_transition::errors::InvalidIdentityPublicKeyTypeError; #[cfg(feature = "cbor")] use crate::util::cbor_serializer; 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 028634eee41..45ae4f53b51 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,9 +13,11 @@ use crate::identity::Identity; use crate::identity::KeyType::ECDSA_HASH160; use crate::prelude::Identifier; +use crate::serialization_traits::PlatformSerializable; use crate::state_transition::{StateTransitionConvert, StateTransitionLike, StateTransitionType}; use crate::version::LATEST_VERSION; use crate::{BlsModule, NonConsensusError, ProtocolError}; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; mod property_names { pub const ASSET_LOCK_PROOF: &str = "assetLockProof"; @@ -25,7 +27,18 @@ mod property_names { pub const IDENTITY_ID: &str = "identityId"; } -#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, PlatformSignable, PartialEq)] +#[derive( + Debug, + Clone, + Serialize, + Deserialize, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PlatformSignable, + PartialEq, +)] #[serde(rename_all = "camelCase")] #[platform_error_type(ProtocolError)] pub struct 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 7abf3df79ed..bf0e62a3f18 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 @@ -15,6 +15,7 @@ use crate::consensus::ConsensusError; use crate::identity::signer::Signer; use crate::identity::{Identity, IdentityPublicKey}; +use crate::serialization_traits::PlatformSerializable; use crate::{ identity::{KeyID, SecurityLevel}, prelude::{Identifier, Revision, TimestampMillis}, @@ -25,6 +26,7 @@ use crate::{ version::LATEST_VERSION, ProtocolError, }; +use platform_serialization::{PlatformDeserialize, PlatformSerialize}; pub mod property_names { pub const PROTOCOL_VERSION: &str = "protocolVersion"; @@ -47,7 +49,18 @@ pub const BINARY_FIELDS: [&str; 3] = [ property_names::SIGNATURE, ]; -#[derive(Serialize, Deserialize, Encode, Decode, PlatformSignable, Debug, Clone, PartialEq)] +#[derive( + Serialize, + Deserialize, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PlatformSignable, + Debug, + Clone, + PartialEq, +)] #[serde(rename_all = "camelCase")] #[platform_error_type(ProtocolError)] pub struct IdentityUpdateTransition { diff --git a/packages/rs-dpp/src/serialization_traits.rs b/packages/rs-dpp/src/serialization_traits.rs index 47ab9b6e172..7256f9993a3 100644 --- a/packages/rs-dpp/src/serialization_traits.rs +++ b/packages/rs-dpp/src/serialization_traits.rs @@ -1,11 +1,38 @@ use crate::ProtocolError; +use platform_value::Value; pub trait Signable { fn signable_bytes(&self) -> Result, ProtocolError>; } +pub trait PlatformSerializable { + fn serialize(&self) -> Result, ProtocolError>; + + /// If the trait is not used just do a simple serialize + fn serialize_consume(self) -> Result, ProtocolError> + where + Self: Sized, + { + self.serialize() + } +} + pub trait PlatformDeserializable { fn deserialize(data: &[u8]) -> Result where Self: Sized; } + +pub trait ValueConvertible { + fn to_object(&self) -> Result; + + fn into_object(self) -> Result; + + fn from_object(value: Value) -> Result + where + Self: Sized; + + fn from_object_ref(value: &Value) -> Result + where + Self: Sized; +} 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 5f4561f4d16..f32225e4c0d 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -9,7 +9,7 @@ use serde_json::Value as JsonValue; use crate::consensus::ConsensusError; use crate::errors::consensus::signature::SignatureError; -use crate::serialization_traits::{PlatformDeserializable, Signable}; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable, Signable}; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, StateTransitionIsNotSignedError, }; @@ -181,7 +181,7 @@ pub trait StateTransitionLike: } /// The trait contains methods related to conversion of StateTransition into different formats -pub trait StateTransitionConvert: Serialize { +pub trait StateTransitionConvert: Serialize + Signable + PlatformSerializable { // TODO remove this as it is not necessary and can be hardcoded fn signature_property_paths() -> Vec<&'static str>; fn identifiers_property_paths() -> Vec<&'static str>; @@ -249,7 +249,11 @@ pub trait StateTransitionConvert: Serialize { // Returns the hash of cibor-encoded bytes representation of the object fn hash(&self, skip_signature: bool) -> Result, ProtocolError> { - Ok(hash::hash_to_vec(self.to_cbor_buffer(skip_signature)?)) + if skip_signature { + Ok(hash::hash_to_vec(self.signable_bytes()?)) + } else { + Ok(hash::hash_to_vec(PlatformSerializable::serialize(self)?)) + } } fn to_cleaned_object(&self, skip_signature: bool) -> Result { diff --git a/packages/rs-dpp/src/state_transition/example.rs b/packages/rs-dpp/src/state_transition/example.rs deleted file mode 100644 index a5683cb8e71..00000000000 --- a/packages/rs-dpp/src/state_transition/example.rs +++ /dev/null @@ -1,76 +0,0 @@ -use crate::ProtocolError; -use platform_value::BinaryData; -use serde::{Deserialize, Serialize}; - -use crate::serialization_traits::{PlatformDeserializable, Signable}; - -use super::{ - state_transition_execution_context::StateTransitionExecutionContext, StateTransition, - StateTransitionConvert, StateTransitionLike, StateTransitionType, -}; - -const PROPERTY_SIGNATURE: &str = "signature"; -const PROPERTY_PROTOCOL_VERSION: &str = "protocolVersion"; - -// The example implementation of generic state transition: -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -struct ExampleStateTransition { - pub protocol_version: u32, - pub transition_type: StateTransitionType, - #[serde(skip)] - pub execution_context: StateTransitionExecutionContext, - pub signature: BinaryData, -} - -impl From for StateTransition { - fn from(_: ExampleStateTransition) -> Self { - unimplemented!() - } -} - -impl Signable for ExampleStateTransition { - fn signable_bytes(&self) -> Result, ProtocolError> { - Ok(vec![]) - } -} - -impl StateTransitionLike for ExampleStateTransition { - fn get_protocol_version(&self) -> u32 { - self.protocol_version - } - - fn get_signature(&self) -> &BinaryData { - &self.signature - } - - fn get_type(&self) -> StateTransitionType { - self.transition_type - } - - 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_modified_data_ids(&self) -> Vec { - vec![] - } -} - -/// To implement the StateTransitionConvert is enough to implement the _property_paths methods -/// The rest of the methods will be automatically implemented as in the blanked implementation -impl StateTransitionConvert for ExampleStateTransition { - fn signature_property_paths() -> Vec<&'static str> { - vec![] - } - fn identifiers_property_paths() -> Vec<&'static str> { - vec![] - } - fn binary_property_paths() -> Vec<&'static str> { - vec![] - } -} diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 9a42245b904..87300950637 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -17,6 +17,7 @@ use crate::identity::state_transition::identity_credit_withdrawal_transition::Id use crate::identity::state_transition::identity_topup_transition::IdentityTopUpTransition; use crate::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; use crate::prelude::Identifier; +use crate::serialization_traits::PlatformSerializable; use bincode::{config, Decode, Encode}; use platform_serialization::{PlatformDeserialize, PlatformSerialize}; @@ -35,11 +36,11 @@ pub mod errors; pub mod fee; pub mod state_transition_execution_context; -mod example; mod serialization; mod state_transition_action; use crate::serialization_traits::{PlatformDeserializable, Signable}; +use crate::util::hash; pub use state_transition_action::StateTransitionAction; macro_rules! call_method { ($state_transition:expr, $method:ident, $args:tt ) => { @@ -101,7 +102,7 @@ pub enum StateTransition { DataContractCreate(DataContractCreateTransition), DataContractUpdate(DataContractUpdateTransition), DocumentsBatch(DocumentsBatchTransition), - IdentityCreate(#[bincode(with_serde)] IdentityCreateTransition), + IdentityCreate(IdentityCreateTransition), IdentityTopUp(IdentityTopUpTransition), IdentityCreditWithdrawal(IdentityCreditWithdrawalTransition), IdentityUpdate(IdentityUpdateTransition), @@ -126,8 +127,12 @@ impl StateTransition { } impl StateTransitionConvert for StateTransition { - fn hash(&self, skip_signature: bool) -> Result, crate::ProtocolError> { - call_method!(self, hash, skip_signature) + fn hash(&self, skip_signature: bool) -> Result, ProtocolError> { + if skip_signature { + Ok(hash::hash_to_vec(self.signable_bytes()?)) + } else { + Ok(hash::hash_to_vec(PlatformSerializable::serialize(self)?)) + } } #[cfg(feature = "cbor")] diff --git a/packages/rs-dpp/src/state_transition/serialization.rs b/packages/rs-dpp/src/state_transition/serialization.rs index f8921427d07..ed85bb6c301 100644 --- a/packages/rs-dpp/src/state_transition/serialization.rs +++ b/packages/rs-dpp/src/state_transition/serialization.rs @@ -1,3 +1,4 @@ +use crate::serialization_traits::PlatformDeserializable; use crate::state_transition::StateTransition; use crate::ProtocolError; use bincode::config; @@ -29,6 +30,7 @@ mod tests { use crate::identity::state_transition::identity_topup_transition::IdentityTopUpTransition; use crate::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; use crate::identity::Identity; + use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; use crate::state_transition::{StateTransition, StateTransitionLike, StateTransitionType}; use crate::tests::fixtures::{ get_data_contract_fixture, get_document_transitions_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 e63946d481e..ec80cbff39a 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -9,6 +9,10 @@ use crate::consensus::basic::state_transition::InvalidStateTransitionTypeError; use crate::data_contract::errors::DataContractNotPresentError; use crate::data_contract::state_transition::errors::MissingDataContractIdError; use crate::identity::state_transition::identity_update_transition::identity_update_transition::IdentityUpdateTransition; +use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; +use crate::state_transition::StateTransitionConvert; +use crate::util::deserializer; +use crate::util::deserializer::SplitProtocolVersionOutcome; use crate::{ consensus::{basic::BasicError, ConsensusError}, data_contract::{ @@ -106,25 +110,29 @@ where state_transition_buffer: &[u8], options: Option, ) -> Result { - let (protocol_version, mut raw_state_transition) = - DecodeProtocolEntity::decode_protocol_entity_to_value::( - state_transition_buffer, - )?; - - match raw_state_transition { - Value::Map(ref mut m) => m.insert_string_key_value( - "protocolVersion".to_string(), - Value::U32(protocol_version), - ), - _ => { - return Err(ConsensusError::SerializedObjectParsingError { - parsing_error: anyhow!("the '{:?}' is not a map", raw_state_transition), - } - .into()) + let SplitProtocolVersionOutcome { + protocol_version, + main_message_bytes: document_bytes, + .. + } = deserializer::split_protocol_version(state_transition_buffer.as_ref())?; + + let state_transition = StateTransition::deserialize(document_bytes).map_err(|e| { + ConsensusError::SerializedObjectParsingError { + parsing_error: anyhow!("Decode protocol entity: {:#?}", e), } - }; + })?; - self.create_from_object(raw_state_transition, options).await + if options + .as_ref() + .map(|options| options.skip_validation) + .unwrap_or_default() + { + Ok(state_transition) + } else { + let mut value = state_transition.to_object(false)?; + value.set_value("protocolVersion", Value::U32(protocol_version))?; + self.create_from_object(value, options).await + } } } 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 3cee6eb4819..ee8145a148e 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 @@ -6,6 +6,7 @@ use platform_value::Value; use crate::consensus::basic::state_transition::{ InvalidStateTransitionTypeError, StateTransitionMaxSizeExceededError, }; +use crate::serialization_traits::PlatformSerializable; use crate::{ consensus::{basic::BasicError, ConsensusError}, state_repository::StateRepositoryLike, diff --git a/packages/rs-platform-serialization/src/lib.rs b/packages/rs-platform-serialization/src/lib.rs index 793660d4677..7c9316eb995 100644 --- a/packages/rs-platform-serialization/src/lib.rs +++ b/packages/rs-platform-serialization/src/lib.rs @@ -68,9 +68,9 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { let expanded = if let Some(limit) = limit { quote! { - impl #impl_generics #name #ty_generics #where_clause + impl #impl_generics PlatformSerializable for #name #ty_generics #where_clause { - pub fn serialize(&self) -> Result, #error_type> { + fn serialize(&self) -> Result, #error_type> { let config = config::standard().with_big_endian().with_limit::<{ #limit }>(); #serialize_into.map_err(|e| { match e { @@ -79,7 +79,7 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { }}) } - pub fn serialize_consume(self) -> Result, #error_type> { + fn serialize_consume(self) -> Result, #error_type> { let config = config::standard().with_big_endian().with_limit::<{ #limit }>(); #serialize_into_consume.map_err(|e| { match e { @@ -91,16 +91,16 @@ pub fn derive_platform_serialize(input: TokenStream) -> TokenStream { } } else { quote! { - impl #impl_generics #name #ty_generics #where_clause + impl #impl_generics PlatformSerializable for #name #ty_generics #where_clause { - pub fn serialize(&self) -> Result, #error_type> { + fn serialize(&self) -> Result, #error_type> { let config = config::standard().with_big_endian().with_no_limit(); #serialize_into.map_err(|e| { #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) }) } - pub fn serialize_consume(self) -> Result, #error_type> { + fn serialize_consume(self) -> Result, #error_type> { let config = config::standard().with_big_endian().with_no_limit(); #serialize_into_consume.map_err(|e| { #error_type::PlatformSerializationError(format!("unable to serialize {}: {}", stringify!(#name), e)) diff --git a/packages/rs-platform-value-convertible/src/lib.rs b/packages/rs-platform-value-convertible/src/lib.rs index 84e4ed52e3d..1408c181ace 100644 --- a/packages/rs-platform-value-convertible/src/lib.rs +++ b/packages/rs-platform-value-convertible/src/lib.rs @@ -5,11 +5,11 @@ use proc_macro2::Span; use quote::quote; use syn::spanned::Spanned; use syn::Error; -use syn::{parse_macro_input, Data, DeriveInput, Fields, Meta, NestedMeta}; +use syn::{parse_macro_input, DeriveInput}; #[proc_macro_derive( PlatformValueConvert, - attributes(platform_error_type, platform_convert_into, platform_value) + attributes(platform_error_type, platform_convert_into) )] pub fn derive_platform_convert(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); @@ -36,27 +36,6 @@ pub fn derive_platform_convert(input: TokenStream) -> TokenStream { } }); - let fields = match &input.data { - Data::Struct(data_struct) => match &data_struct.fields { - Fields::Named(fields_named) => &fields_named.named, - _ => panic!("Only named fields are supported"), - }, - _ => panic!("Only structs are supported"), - }; - - let mut filtered_fields = vec![]; - for field in fields { - if !field.attrs.iter().any(|attr| { - attr.path.is_ident("platform_value") && attr.parse_args::().ok().map_or(false, |meta| { - matches!(meta, Meta::List(list) if list.nested.iter().any(|n| matches!(n, NestedMeta::Meta(Meta::Path(p)) if p.is_ident("skip")))) - }) - }) { - filtered_fields.push(field); - } - } - - let field_idents: Vec<_> = filtered_fields.iter().map(|f| &f.ident).collect(); - // Extract the generics. let generics = &input.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); @@ -95,10 +74,7 @@ pub fn derive_platform_convert(input: TokenStream) -> TokenStream { inner.to_object() }, None => quote! { - platform_value::to_value_with_filter(self, |field_name| { - let field_names = vec![#(#field_idents),*]; - field_names.contains(&field_name) - }).map_err(#error_type::ValueError) + self.to_object() }, }; @@ -121,6 +97,38 @@ pub fn derive_platform_convert(input: TokenStream) -> TokenStream { #convert_from_value_ref } } + + impl #impl_generics TryFrom<&Value> for #name #ty_generics #where_clause { + type Error = ProtocolError; + + fn try_from(value: &Value) -> Result { + Self::from_object_ref(value) + } + } + + impl #impl_generics TryFrom for #name #ty_generics #where_clause { + type Error = ProtocolError; + + fn try_from(value: Value) -> Result { + Self::from_object(value) + } + } + + impl #impl_generics TryFrom<#name> for Value #ty_generics #where_clause { + type Error = ProtocolError; + + fn try_from(value: #name) -> Result { + value.into_object() + } + } + + impl #impl_generics TryFrom<&#name> for Value #ty_generics #where_clause { + type Error = ProtocolError; + + fn try_from(value: &#name) -> Result { + value.to_object() + } + } }; TokenStream::from(expanded) From 78f8d53ccacfa3c2d5e05c35bd5307a5b959eb33 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 09:08:51 +0700 Subject: [PATCH 29/50] more work --- packages/rs-dpp/Cargo.toml | 2 +- .../src/data_contract/contract_config.rs | 3 +- .../rs-dpp/src/data_contract/data_contract.rs | 6 +++ .../data_contract/data_contract_factory.rs | 11 +---- .../src/data_contract/extra/drive_api.rs | 45 +++++++++++++++---- .../data_contract/serialization/bincode.rs | 1 + packages/rs-dpp/src/document/document.rs | 2 +- .../src/identity/identity_public_key/mod.rs | 1 + ...stract_state_transition_identity_signed.rs | 31 +++++++++---- ...ate_state_transition_identity_signature.rs | 23 ++++++++-- packages/rs-drive/benches/benchmarks.rs | 2 +- .../src/drive/batch/drive_op_batch/mod.rs | 2 +- packages/rs-drive/src/drive/contract/mod.rs | 2 +- .../rs-drive/src/drive/document/delete.rs | 34 ++++++++------ packages/rs-drive/src/drive/document/mod.rs | 16 +++---- .../rs-drive/src/drive/document/update.rs | 10 +++-- 16 files changed, 132 insertions(+), 59 deletions(-) diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index 8f69a04f78f..a0399a2626d 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -61,6 +61,6 @@ tokio = { version = "1.17", features = ["full"] } pretty_assertions = { version = "1.3.0" } [features] -default = ["fixtures-and-mocks"] +default = ["fixtures-and-mocks", "cbor"] cbor = ["ciborium"] fixtures-and-mocks = ["mockall"] diff --git a/packages/rs-dpp/src/data_contract/contract_config.rs b/packages/rs-dpp/src/data_contract/contract_config.rs index 2f685ea49d2..55a058310d1 100644 --- a/packages/rs-dpp/src/data_contract/contract_config.rs +++ b/packages/rs-dpp/src/data_contract/contract_config.rs @@ -1,3 +1,4 @@ +use bincode::{Decode, Encode}; use serde::{Deserialize, Serialize}; pub const DEFAULT_CONTRACT_KEEPS_HISTORY: bool = false; @@ -14,7 +15,7 @@ pub mod property { pub const DOCUMENTS_MUTABLE_CONTRACT_DEFAULT: &str = "documentsMutableContractDefault"; } -#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, Copy, PartialEq, Eq)] #[serde(rename_all = "camelCase", default)] pub struct ContractConfig { /// Can the contract ever be deleted diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index b1f84e1f81a..7b00d168210 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -213,6 +213,10 @@ pub struct DataContractInner { #[serde(rename = "$id")] pub id: Identifier, + /// Internal configuration for the contract. + #[serde(default)] + pub config: ContractConfig, + /// A reference to the JSON schema that defines the contract. #[serde(rename = "$schema")] pub schema: String, @@ -236,6 +240,7 @@ impl From for DataContractInner { let DataContract { protocol_version, id, + config, schema, version, owner_id, @@ -246,6 +251,7 @@ impl From for DataContractInner { DataContractInner { protocol_version, id, + config, schema, version, owner_id, 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 f3cbe387427..84c67388012 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -168,13 +168,7 @@ impl DataContractFactory { buffer: Vec, skip_validation: bool, ) -> Result { - let SplitProtocolVersionOutcome { - protocol_version, - main_message_bytes: document_bytes, - .. - } = deserializer::split_protocol_version(buffer.as_ref())?; - - let data_contract = DataContract::deserialize(document_bytes).map_err(|e| { + let data_contract = DataContract::deserialize(buffer.as_slice()).map_err(|e| { ConsensusError::SerializedObjectParsingError { parsing_error: anyhow!("Decode protocol entity: {:#?}", e), } @@ -182,7 +176,6 @@ impl DataContractFactory { if !skip_validation { let mut value = data_contract.to_object()?; - value.set_value("protocolVersion", Value::U32(protocol_version))?; self.create_from_object(value, skip_validation).await } else { Ok(data_contract) @@ -323,7 +316,7 @@ mod tests { .. } = get_test_data(); let serialized_data_contract = data_contract - .to_cbor_buffer() + .serialize() .expect("should be serialized to buffer"); let result = factory .create_from_buffer(serialized_data_contract, false) 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 7d2f52651d9..a3c83c281a8 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api.rs @@ -14,10 +14,8 @@ mod test { use crate::data_contract::contract_config::ContractConfig; use crate::data_contract::extra::common::json_document_to_contract; - use crate::{ - data_contract::extra::common::json_document_to_cbor, data_contract::DataContract, - util::json_schema::JsonSchemaExt, - }; + use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; + use crate::{data_contract::DataContract, util::json_schema::JsonSchemaExt}; use super::*; @@ -221,11 +219,10 @@ mod test { } #[test] - fn mutability_properties_should_be_stored_and_restored_during_serialization() { - let dashpay_cbor = - json_document_to_cbor("src/tests/payloads/contract/dashpay-contract.json", Some(1)) + fn mutability_properties_should_be_stored_and_restored_during_cbor_serialization() { + let mut contract = + json_document_to_contract("src/tests/payloads/contract/dashpay-contract.json") .expect("expected to get a cbor document"); - let mut contract = DataContract::from_cbor(dashpay_cbor).unwrap(); assert!(!contract.config.readonly); assert!(!contract.config.keeps_history); @@ -252,4 +249,36 @@ mod test { } )); } + + #[test] + fn mutability_properties_should_be_stored_and_restored_during_serialization() { + let mut contract = + json_document_to_contract("src/tests/payloads/contract/dashpay-contract.json") + .expect("expected to decode a contract"); + + assert!(!contract.config.readonly); + assert!(!contract.config.keeps_history); + assert!(contract.config.documents_mutable_contract_default); + assert!(!contract.config.documents_keep_history_contract_default); + + contract.config.readonly = true; + contract.config.keeps_history = true; + contract.config.documents_mutable_contract_default = false; + contract.config.documents_keep_history_contract_default = true; + + let contract = contract.serialize().expect("serialization shouldn't fail"); + let deserialized_contract = + DataContract::deserialize(contract.as_slice()).expect("deserialization shouldn't fail"); + + assert_eq!( + deserialized_contract.config, + ContractConfig { + can_be_deleted: false, + readonly: true, + keeps_history: true, + documents_mutable_contract_default: false, + documents_keep_history_contract_default: true, + } + ); + } } diff --git a/packages/rs-dpp/src/data_contract/serialization/bincode.rs b/packages/rs-dpp/src/data_contract/serialization/bincode.rs index 6681b904799..02cff560914 100644 --- a/packages/rs-dpp/src/data_contract/serialization/bincode.rs +++ b/packages/rs-dpp/src/data_contract/serialization/bincode.rs @@ -2,6 +2,7 @@ mod tests { use crate::data_contract::DataContract; use crate::identity::Identity; + use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; use crate::tests::fixtures::get_data_contract_fixture; use platform_value::Bytes32; diff --git a/packages/rs-dpp/src/document/document.rs b/packages/rs-dpp/src/document/document.rs index 4545f0efef4..6264ea4659f 100644 --- a/packages/rs-dpp/src/document/document.rs +++ b/packages/rs-dpp/src/document/document.rs @@ -434,7 +434,7 @@ impl fmt::Display for Document { mod tests { use super::*; use crate::data_contract::document_type::random_document::CreateRandomDocument; - use crate::data_contract::extra::common::{json_document_to_cbor, json_document_to_contract}; + use crate::data_contract::extra::common::json_document_to_contract; use regex::Regex; #[test] 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 29ffaacef52..51ab0e7d962 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/mod.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/mod.rs @@ -301,6 +301,7 @@ where #[cfg(test)] mod tests { use crate::identity::IdentityPublicKey; + use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; #[test] fn test_identity_key_serialization_deserialization() { 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 ebaad834726..534071b9ca3 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 @@ -218,17 +218,33 @@ mod test { use super::StateTransitionIdentitySigned; use super::*; - - #[derive(Debug, Clone, Serialize, Deserialize)] + use crate::serialization_traits::PlatformDeserializable; + use crate::serialization_traits::PlatformSerializable; + use crate::serialization_traits::Signable; + use bincode::{config, Decode, Encode}; + use platform_serialization::{PlatformDeserialize, PlatformSerialize, PlatformSignable}; + + #[derive( + Debug, + Clone, + Encode, + Decode, + Serialize, + Deserialize, + PlatformDeserialize, + PlatformSerialize, + PlatformSignable, + )] + #[platform_error_type(ProtocolError)] #[serde(rename_all = "camelCase")] struct ExampleStateTransition { pub protocol_version: u32, - pub signature: BinaryData, - pub signature_public_key_id: KeyID, pub transition_type: StateTransitionType, pub owner_id: Identifier, - #[serde(skip)] - pub execution_context: StateTransitionExecutionContext, + #[exclude_from_sig_hash] + pub signature: BinaryData, + #[exclude_from_sig_hash] + pub signature_public_key_id: KeyID, } impl StateTransitionConvert for ExampleStateTransition { @@ -306,7 +322,6 @@ mod test { signature: Default::default(), signature_public_key_id: 1, owner_id, - execution_context: Default::default(), } } @@ -408,7 +423,7 @@ mod test { let st = get_mock_state_transition(); let hash = st.hash(false).unwrap(); assert_eq!( - "208afc16722df887c6e2935d1a0c13c56c5a91318beec4089cad6919be18debc", + "39b9c5951e5d83668f98909bb73d390d49867c47bbfe043a42ac83de898142c0", hex::encode(hash) ) } 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 a3af1d25bda..780b2a70433 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 @@ -147,6 +147,9 @@ pub fn convert_to_consensus_signature_error( mod test { use super::*; use crate::consensus::signature::InvalidSignaturePublicKeySecurityLevelError; + use crate::serialization_traits::PlatformDeserializable; + use crate::serialization_traits::PlatformSerializable; + use crate::serialization_traits::Signable; use crate::state_transition::errors::{PublicKeyMismatchError, WrongPublicKeyPurposeError}; use crate::{ document::DocumentsBatchTransition, @@ -163,11 +166,24 @@ mod test { }, NativeBlsModule, }; + use bincode::{config, Decode, Encode}; + use platform_serialization::{PlatformDeserialize, PlatformSerialize, PlatformSignable}; use platform_value::BinaryData; use serde::{Deserialize, Serialize}; use std::vec; - #[derive(Debug, Clone, Serialize, Deserialize)] + #[derive( + Debug, + Clone, + Encode, + Decode, + Serialize, + Deserialize, + PlatformDeserialize, + PlatformSerialize, + PlatformSignable, + )] + #[platform_error_type(ProtocolError)] #[serde(rename_all = "camelCase")] struct ExampleStateTransition { pub protocol_version: u32, @@ -175,9 +191,9 @@ mod test { pub owner_id: Identifier, pub return_error: Option, - #[serde(skip)] - pub execution_context: StateTransitionExecutionContext, + #[exclude_from_sig_hash] pub signature_public_key_id: KeyID, + #[exclude_from_sig_hash] pub signature: BinaryData, } @@ -294,7 +310,6 @@ mod test { signature_public_key_id: 1, owner_id: generate_random_identifier_struct(), return_error: None, - execution_context: Default::default(), } } diff --git a/packages/rs-drive/benches/benchmarks.rs b/packages/rs-drive/benches/benchmarks.rs index 7c19879669d..0fa04e9f49b 100644 --- a/packages/rs-drive/benches/benchmarks.rs +++ b/packages/rs-drive/benches/benchmarks.rs @@ -33,7 +33,7 @@ //! use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; -use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_contract}; +use dpp::data_contract::extra::common::{json_document_to_contract}; use dpp::document::Document; use drive::contract::Contract; 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 3e8e2ab7e36..5f78adb0613 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 @@ -213,7 +213,7 @@ mod tests { use super::*; use dpp::data_contract::extra::common::{ - json_document_to_cbor, json_document_to_contract, json_document_to_document, + json_document_to_contract, json_document_to_document, }; use dpp::document::Document; diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 9b2a618bae9..b68c945afc4 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -1126,7 +1126,7 @@ mod tests { DocumentAndContractInfo, DocumentInfo, OwnedDocumentInfo, }; use crate::drive::Drive; - use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_contract}; + use dpp::data_contract::extra::common::{json_document_to_contract}; use crate::tests::helpers::setup::setup_drive_with_initial_state_structure; diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index d0c9a1de986..09a029fe375 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -804,7 +804,7 @@ impl Drive { #[cfg(feature = "full")] #[cfg(test)] mod tests { - use dpp::data_contract::extra::common::json_document_to_cbor; + use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_document}; use rand::Rng; use serde_json::json; use std::borrow::Cow; @@ -1447,25 +1447,33 @@ mod tests { #[test] fn test_delete_dashpay_documents_no_transaction() { - let (drive, dashpay_cbor) = setup_dashpay("delete", false); + let (drive, dashpay) = setup_dashpay("delete", false); - let dashpay_profile_serialized_document = json_document_to_cbor( + let document_type = dashpay.document_type_for_name("profile")?; + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + let dashpay_profile_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0.json", - Some(1), + Some(random_owner_id.into()), + document_type ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); drive - .add_serialized_document_for_serialized_contract( - &dashpay_profile_serialized_document, - &dashpay_cbor, - "profile", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_profile_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &dashpay, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), None, ) .expect("expected to insert a document successfully"); @@ -1478,9 +1486,9 @@ mod tests { .expect("this be 32 bytes"); drive - .delete_document_for_contract_cbor( + .delete_document_for_contract( document_id, - &dashpay_cbor, + &dashpay, "profile", Some(random_owner_id), BlockInfo::default(), diff --git a/packages/rs-drive/src/drive/document/mod.rs b/packages/rs-drive/src/drive/document/mod.rs index 6a59a04d8d9..d6590628c42 100644 --- a/packages/rs-drive/src/drive/document/mod.rs +++ b/packages/rs-drive/src/drive/document/mod.rs @@ -210,10 +210,11 @@ pub(crate) mod tests { use crate::drive::flags::StorageFlags; use crate::drive::Drive; use dpp::block::block_info::BlockInfo; - use dpp::data_contract::extra::common::json_document_to_cbor; + use dpp::data_contract::extra::common::json_document_to_contract; + use dpp::prelude::DataContract; /// Setup Dashpay - pub fn setup_dashpay(_prefix: &str, mutable_contact_requests: bool) -> (Drive, Vec) { + pub fn setup_dashpay(_prefix: &str, mutable_contact_requests: bool) -> (Drive, DataContract) { // Todo: make TempDir based on _prefix let tmp_dir = TempDir::new().unwrap(); let drive: Drive = Drive::open(tmp_dir, None).expect("expected to open Drive successfully"); @@ -229,12 +230,11 @@ pub(crate) mod tests { }; // let's construct the grovedb structure for the dashpay data contract - let dashpay_cbor = - json_document_to_cbor(dashpay_path, Some(1)).expect("expected to get cbor document"); + let dashpay = + json_document_to_contract(dashpay_path).expect("expected to get cbor document"); drive - .apply_contract_cbor( - dashpay_cbor.clone(), - None, + .apply_contract( + &dashpay, BlockInfo::default(), true, StorageFlags::optional_default_as_cow(), @@ -242,6 +242,6 @@ pub(crate) mod tests { ) .expect("expected to apply contract successfully"); - (drive, dashpay_cbor) + (drive, dashpay) } } diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 70ab60fdd31..e3ffe04f549 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -87,7 +87,7 @@ impl Drive { &self, serialized_document: &[u8], contract_cbor: &[u8], - document_type: &str, + document_type_name: &str, owner_id: Option<[u8; 32]>, block_info: BlockInfo, apply: bool, @@ -98,11 +98,15 @@ impl Drive { let document = Document::from_cbor(serialized_document, None, owner_id)?; + let document_type = contract.document_type_for_name(document_type_name)?; + + let reserialized_document = document.serialize(document_type)?; + self.update_document_for_contract( &document, - serialized_document, + reserialized_document.as_slice(), &contract, - document_type, + document_type_name, owner_id, block_info, apply, From bcfdd05275809b824e72a0ff8bb89f94f66ebada Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 10:55:18 +0700 Subject: [PATCH 30/50] more work --- packages/rs-dpp/src/identity/core_script.rs | 40 +-- .../mod.rs | 276 ++++++++++++++++++ .../identity_update_transition.rs | 1 - .../identity_update_transition_spec.rs | 9 +- packages/rs-drive/benches/benchmarks.rs | 2 +- .../src/drive/batch/drive_op_batch/mod.rs | 4 +- packages/rs-drive/src/drive/contract/mod.rs | 2 +- .../rs-drive/src/drive/document/delete.rs | 2 +- 8 files changed, 298 insertions(+), 38 deletions(-) diff --git a/packages/rs-dpp/src/identity/core_script.rs b/packages/rs-dpp/src/identity/core_script.rs index f384c846a3d..0cec89e5eb4 100644 --- a/packages/rs-dpp/src/identity/core_script.rs +++ b/packages/rs-dpp/src/identity/core_script.rs @@ -7,7 +7,7 @@ use std::fmt; use std::io::{Read, Write}; use std::ops::Deref; -use dashcore::Script as DashcoreScript; +use dashcore::{Script as DashcoreScript, Script}; use platform_value::string_encoding::{self, Encoding}; use rand::rngs::StdRng; use rand::Rng; @@ -87,30 +87,9 @@ impl Encode for CoreScript { // Implement the bincode::Decode trait for CoreScript impl Decode for CoreScript { fn decode(decoder: &mut D) -> Result { - // Read the serialized bytes from the decoder into a Vec - let mut bytes = Vec::new(); - loop { - let mut buf = [0u8; 1]; - match decoder.reader().read(&mut buf) { - Ok(()) => bytes.push(buf[0]), - Err(DecodeError::Io { inner, additional }) - if inner.kind() == std::io::ErrorKind::UnexpectedEof => - { - if additional > 0 { - return Err(DecodeError::Io { inner, additional }); - } else { - break; - } - } - Err(e) => return Err(e), - } - } - - // Convert Vec to Box<[u8]> and create a DashCoreScript instance - let dash_core_script = DashcoreScript(bytes.into_boxed_slice()); - + let bytes = Vec::::decode(decoder)?; // Create a CoreScript instance using the decoded DashCoreScript - Ok(CoreScript(dash_core_script)) + Ok(CoreScript(Script(bytes.into_boxed_slice()))) } } @@ -119,9 +98,16 @@ impl<'de> BorrowDecode<'de> for CoreScript { // Read the serialized bytes from the decoder into a Vec let mut bytes = Vec::new(); loop { - let mut buf = [0u8; 1]; - match decoder.reader().read(&mut buf) { - Ok(()) => bytes.push(buf[0]), + let mut buf = [0u8; 1024]; // Adjust the buffer size as needed + let mut temp = Vec::from(buf); + match decoder.reader().read(&mut temp) { + Ok(()) => { + let read_bytes = temp.iter().position(|&x| x == 0).unwrap_or(temp.len()); + bytes.extend_from_slice(&temp[..read_bytes]); + if read_bytes < buf.len() { + break; + } + } Err(DecodeError::Io { inner, additional }) if inner.kind() == std::io::ErrorKind::UnexpectedEof => { 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 3f65d5c8283..3f48503626f 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 @@ -218,3 +218,279 @@ impl StateTransitionConvert for IdentityCreditWithdrawalTransition { Ok(value) } } + +#[cfg(test)] +mod test { + use crate::identity::core_script::CoreScript; + use crate::identity::state_transition::identity_credit_withdrawal_transition::Pooling; + use crate::identity::KeyID; + use crate::prelude::Revision; + use crate::serialization_traits::{PlatformDeserializable, PlatformSerializable}; + use crate::state_transition::StateTransitionType; + use crate::ProtocolError; + use bincode::{config, Decode, Encode}; + use platform_serialization::{PlatformDeserialize, PlatformSerialize}; + use platform_value::{BinaryData, Identifier}; + use rand::Rng; + use std::fmt::Debug; + + // Structure with 1 property + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition1 { + pub protocol_version: u32, + } + + // Structure with 2 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition2 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + } + + // Structure with 3 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition3 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub identity_id: Identifier, + } + + // Structure with 4 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition4 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub identity_id: Identifier, + pub amount: u64, + } + + // Structure with 5 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition5 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub identity_id: Identifier, + pub amount: u64, + pub core_fee_per_byte: u32, + } + + // Structure with 6 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition6 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub identity_id: Identifier, + pub amount: u64, + pub core_fee_per_byte: u32, + pub pooling: Pooling, + } + + // Structure with 7 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition7 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub identity_id: Identifier, + pub amount: u64, + pub core_fee_per_byte: u32, + pub pooling: Pooling, + pub output_script: CoreScript, + } + + // Structure with 8 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition8 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub identity_id: Identifier, + pub amount: u64, + pub core_fee_per_byte: u32, + pub pooling: Pooling, + pub output_script: CoreScript, + pub revision: Revision, + } + + // Structure with 9 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition9 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub identity_id: Identifier, + pub amount: u64, + pub core_fee_per_byte: u32, + pub pooling: Pooling, + pub output_script: CoreScript, + pub revision: Revision, + pub signature_public_key_id: KeyID, + } + + // Structure with 10 properties + #[derive(Debug, Clone, Encode, Decode, PlatformDeserialize, PlatformSerialize, PartialEq)] + #[platform_error_type(ProtocolError)] + pub struct IdentityCreditWithdrawalTransition10 { + pub protocol_version: u32, + pub transition_type: StateTransitionType, + pub identity_id: Identifier, + pub amount: u64, + pub core_fee_per_byte: u32, + pub pooling: Pooling, + pub output_script: CoreScript, + pub revision: Revision, + pub signature_public_key_id: KeyID, + pub signature: BinaryData, + } + + fn test_identity_credit_withdrawal_transition< + T: PlatformSerializable + PlatformDeserializable + Debug + PartialEq, + >( + transition: T, + ) { + let serialized = T::serialize(&transition).expect("expected to serialize"); + let deserialized = T::deserialize(serialized.as_slice()).expect("expected to deserialize"); + assert_eq!(transition, deserialized); + } + + #[test] + fn test_identity_credit_withdrawal_transition_1() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition1 { + protocol_version: rng.gen(), + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_2() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition2 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, // Generate random value or choose from the available types + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_3() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition3 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, // Generate random value or choose from the available types + identity_id: Identifier::random(), // Generate a random Identifier + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_4() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition4 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, // Generate random value or choose from the available types + identity_id: Identifier::random(), // Generate a random Identifier + amount: rng.gen(), + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_5() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition5 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, // Generate random value or choose from the available types + identity_id: Identifier::random(), // Generate a random Identifier + amount: rng.gen(), + core_fee_per_byte: rng.gen(), + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_6() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition6 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, // Generate random value or choose from the available types + identity_id: Identifier::random(), // Generate a random Identifier + amount: rng.gen(), + core_fee_per_byte: rng.gen(), + pooling: Pooling::Standard, // Generate random value or choose from the available options + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_7() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition7 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, + identity_id: Identifier::random(), + amount: rng.gen(), + core_fee_per_byte: rng.gen(), + pooling: Pooling::Standard, + output_script: CoreScript::from_bytes((0..23).collect::>()), + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_8() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition8 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, + identity_id: Identifier::random(), + amount: rng.gen(), + core_fee_per_byte: rng.gen(), + pooling: Pooling::Standard, + output_script: CoreScript::from_bytes((0..23).collect::>()), + revision: rng.gen(), + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_9() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition9 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, + identity_id: Identifier::random(), + amount: rng.gen(), + core_fee_per_byte: rng.gen(), + pooling: Pooling::Standard, + output_script: CoreScript::from_bytes((0..23).collect::>()), + revision: rng.gen(), + signature_public_key_id: rng.gen(), + }; + test_identity_credit_withdrawal_transition(transition); + } + + #[test] + fn test_identity_credit_withdrawal_transition_10() { + let mut rng = rand::thread_rng(); + let transition = IdentityCreditWithdrawalTransition10 { + protocol_version: rng.gen(), + transition_type: StateTransitionType::IdentityCreditWithdrawal, + identity_id: Identifier::random(), + amount: rng.gen(), + core_fee_per_byte: rng.gen(), + pooling: Pooling::Standard, + output_script: CoreScript::from_bytes((0..23).collect::>()), + revision: rng.gen(), + signature_public_key_id: rng.gen(), + signature: [0; 65].to_vec().into(), + }; + test_identity_credit_withdrawal_transition(transition); + } +} 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 bf0e62a3f18..e409c3aabb5 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 @@ -336,7 +336,6 @@ impl StateTransitionConvert for IdentityUpdateTransition { fn to_object(&self, skip_signature: bool) -> Result { let mut value: Value = platform_value::to_value(self)?; - if skip_signature { value .remove_values_matching_paths(Self::signature_property_paths()) 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 b49b1e5f62d..cd1c2473217 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,8 +137,7 @@ fn to_object() { let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1u32, "type" : 5u8, - "signature" : BinaryData::new(vec![0u8;65]), - "signaturePublicKeyId": 0u32, + "identityId" : transition.identity_id, "revision": 0 as Revision, "addPublicKeys" : [ @@ -155,6 +154,8 @@ fn to_object() { ], "disablePublicKeys" : [0u32], "publicKeysDisabledAt" : 1234567u64, + "signaturePublicKeyId": 0u32, + "signature" : BinaryData::new(vec![0u8;65]), }); assert_eq!(expected_raw_state_transition, result); @@ -200,8 +201,6 @@ fn to_json() { let expected_raw_state_transition = platform_value!({ "protocolVersion" : 1u32, "type" : 5u8, - "signature" : BinaryData::new(vec![0u8;65]), - "signaturePublicKeyId": 0u32, "identityId" : transition.identity_id, "revision": 0 as Revision, "addPublicKeys" : [ @@ -218,6 +217,8 @@ fn to_json() { ], "disablePublicKeys" : [0u32], "publicKeysDisabledAt" : 1234567u64, + "signaturePublicKeyId": 0u32, + "signature" : BinaryData::new(vec![0u8;65]), }); assert_eq!(expected_raw_state_transition, result); diff --git a/packages/rs-drive/benches/benchmarks.rs b/packages/rs-drive/benches/benchmarks.rs index 0fa04e9f49b..60849693250 100644 --- a/packages/rs-drive/benches/benchmarks.rs +++ b/packages/rs-drive/benches/benchmarks.rs @@ -33,7 +33,7 @@ //! use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; -use dpp::data_contract::extra::common::{json_document_to_contract}; +use dpp::data_contract::extra::common::json_document_to_contract; use dpp::document::Document; use drive::contract::Contract; 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 5f78adb0613..064ae43e3a7 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 @@ -212,9 +212,7 @@ mod tests { use super::*; - use dpp::data_contract::extra::common::{ - json_document_to_contract, json_document_to_document, - }; + use dpp::data_contract::extra::common::{json_document_to_contract, json_document_to_document}; use dpp::document::Document; use dpp::util::cbor_serializer; diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index b68c945afc4..f036e28c7a6 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -1126,7 +1126,7 @@ mod tests { DocumentAndContractInfo, DocumentInfo, OwnedDocumentInfo, }; use crate::drive::Drive; - use dpp::data_contract::extra::common::{json_document_to_contract}; + use dpp::data_contract::extra::common::json_document_to_contract; use crate::tests::helpers::setup::setup_drive_with_initial_state_structure; diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 09a029fe375..1c1bcdf900d 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -1454,7 +1454,7 @@ mod tests { let dashpay_profile_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0.json", Some(random_owner_id.into()), - document_type + document_type, ) .expect("expected to get cbor document"); From c736f7378086b5411a160d44e394eb934be4c275 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 11:42:50 +0700 Subject: [PATCH 31/50] more work --- .../rs-dpp/src/data_contract/data_contract.rs | 94 +++++++++++++++++-- .../rs-drive/src/drive/identity/key/insert.rs | 1 + packages/rs-drive/src/drive/verify/mod.rs | 1 + 3 files changed, 87 insertions(+), 9 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 7b00d168210..9d692da9b8d 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -272,7 +272,66 @@ impl TryFrom for DataContract { type Error = ProtocolError; fn try_from(value: DataContractInner) -> Result { - DataContract::from_raw_object(platform_value!(value)) + let DataContractInner { + protocol_version, + id, + config, + schema, + version, + owner_id, + documents, + defs, + } = value; + + let document_types = get_document_types_from_value_array( + id, + &documents + .iter() + .map(|(key, value)| (key.as_str(), value)) + .collect(), + &defs + .as_ref() + .map(|defs| { + defs.iter() + .map(|(key, value)| Ok((key.clone(), value))) + .collect::, ProtocolError>>() + }) + .transpose()? + .unwrap_or_default(), + config.documents_keep_history_contract_default, + config.documents_mutable_contract_default, + )?; + + let binary_properties = documents + .iter() + .map(|(doc_type, schema)| Ok((String::from(doc_type), get_binary_properties(&schema.clone().try_into()?)))) + .collect::>, ProtocolError>>()?; + + let data_contract = DataContract { + protocol_version, + id, + schema, + version, + owner_id, + document_types, + metadata: None, + config, + documents: documents + .into_iter() + .map(|(key, value)| Ok((key, value.try_into()?))) + .collect::, ProtocolError>>()?, + defs: defs + .map(|defs| { + defs.into_iter() + .map(|(key, value)| Ok((key, value.try_into()?))) + .collect::, ProtocolError>>() + }) + .transpose()?, + entropy: Default::default(), + binary_properties, + }; + + Ok(data_contract) } } @@ -641,15 +700,32 @@ pub fn get_document_types_from_value( .as_map() .ok_or(ProtocolError::DataContractError( DataContractError::InvalidContractStructure("documents must be a map"), - ))?; - let mut contract_document_types: BTreeMap = BTreeMap::new(); - for (type_key_value, document_type_value) in contract_document_types_raw { - let Some(type_key_str) = type_key_value.as_text() else { - return Err(ProtocolError::DataContractError(DataContractError::InvalidContractStructure( - "document type name is not a string as expected", - ))); - }; + ))?.iter().map(|(key, value)| { + let Some(type_key_str) = key.as_text() else { + return Err(ProtocolError::DataContractError(DataContractError::InvalidContractStructure( + "document type name is not a string as expected", + ))); + }; + Ok((type_key_str, value)) + }).collect::, ProtocolError>>()?; + get_document_types_from_value_array( + data_contract_id, + &contract_document_types_raw, + definition_references, + documents_keep_history_contract_default, + documents_mutable_contract_default, + ) +} +pub fn get_document_types_from_value_array( + data_contract_id: Identifier, + contract_document_types_raw: &Vec<(&str, &Value)>, + definition_references: &BTreeMap, + documents_keep_history_contract_default: bool, + documents_mutable_contract_default: bool, +) -> Result, ProtocolError> { + let mut contract_document_types: BTreeMap = BTreeMap::new(); + for (type_key_str, document_type_value) in contract_document_types_raw { // Make sure the document_type_value is a map let Some(document_type_value_map) = document_type_value.as_map() else { return Err(ProtocolError::DataContractError(DataContractError::InvalidContractStructure( diff --git a/packages/rs-drive/src/drive/identity/key/insert.rs b/packages/rs-drive/src/drive/identity/key/insert.rs index 0bc17afb6b5..89e8cc8f1ec 100644 --- a/packages/rs-drive/src/drive/identity/key/insert.rs +++ b/packages/rs-drive/src/drive/identity/key/insert.rs @@ -23,6 +23,7 @@ use grovedb::reference_path::ReferencePathType; use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; use integer_encoding::VarInt; use std::collections::HashMap; +use dpp::serialization_traits::PlatformSerializable; /// The contract apply info pub enum ContractApplyInfo { diff --git a/packages/rs-drive/src/drive/verify/mod.rs b/packages/rs-drive/src/drive/verify/mod.rs index 38dcfa4f96c..e34e1dfae97 100644 --- a/packages/rs-drive/src/drive/verify/mod.rs +++ b/packages/rs-drive/src/drive/verify/mod.rs @@ -13,6 +13,7 @@ use dpp::prelude::{Identity, Revision}; use crate::fee::credits::Credits; use grovedb::GroveDb; use std::collections::BTreeMap; +use dpp::serialization_traits::PlatformDeserializable; /// Represents the root hash of the grovedb tree pub type RootHash = [u8; 32]; From 05e5e4a033b88a2bcf09d756927c50cb9b12b868 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 11:57:54 +0700 Subject: [PATCH 32/50] all dpp tests passing --- .../validate_state_transition_basic.rs | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) 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 ee8145a148e..eb2391d0862 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 @@ -99,14 +99,26 @@ where create_state_transition(self.state_repository.as_ref(), raw_state_transition.clone()) .await?; - if let Err(ProtocolError::MaxEncodedBytesReachedError { - max_size_kbytes, - size_hit, - }) = state_transition.serialize() - { - result.add_error(BasicError::StateTransitionMaxSizeExceededError( - StateTransitionMaxSizeExceededError::new(size_hit / 1024, max_size_kbytes), - )); + let serialization_result = state_transition.serialize(); + + match serialization_result { + Ok(serialized) => { + let len = serialized.len(); + if len > 16384 { + result.add_error(BasicError::StateTransitionMaxSizeExceededError( + StateTransitionMaxSizeExceededError::new(len / 1024, 16), + )); + } + } + Err(ProtocolError::MaxEncodedBytesReachedError { + max_size_kbytes, + size_hit, + }) => { + result.add_error(BasicError::StateTransitionMaxSizeExceededError( + StateTransitionMaxSizeExceededError::new(size_hit / 1024, max_size_kbytes), + )); + } + _ => {} } Ok(result) @@ -332,7 +344,7 @@ mod test { match basic_error { BasicError::StateTransitionMaxSizeExceededError(err) => { - assert_eq!(err.actual_size_kbytes(), 53); + assert_eq!(err.actual_size_kbytes(), 60); assert_eq!(err.max_size_kbytes(), 16); } _ => panic!( From 155774130812de70a8ff124690fb99fadb6cb440 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 12:24:43 +0700 Subject: [PATCH 33/50] changed a lot of errors --- packages/rs-drive/src/drive/contract/mod.rs | 1 + .../rs-drive/src/drive/document/insert.rs | 459 +++++++++++------- .../rs-drive/src/drive/identity/key/fetch.rs | 1 + .../rs-drive/src/drive/identity/key/insert.rs | 2 +- packages/rs-drive/src/drive/verify/mod.rs | 2 +- 5 files changed, 296 insertions(+), 169 deletions(-) diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index f036e28c7a6..4ac2009a11a 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -112,6 +112,7 @@ use crate::query::QueryResultEncoding; #[cfg(feature = "full")] use dpp::block::epoch::Epoch; use dpp::prelude::DataContract; +use dpp::serialization_traits::{PlatformDeserializable, PlatformSerializable}; #[cfg(feature = "full")] /// Adds operations to the op batch relevant to initializing the contract's structure. diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index a12d8125abc..7df0197e604 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -1260,7 +1260,7 @@ mod tests { use std::option::Option::None; use super::*; - use dpp::data_contract::extra::common::json_document_to_cbor; + use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_document}; use rand::Rng; use tempfile::TempDir; @@ -1278,54 +1278,78 @@ mod tests { #[test] fn test_add_dashpay_documents_no_transaction() { - let (drive, dashpay_cbor) = setup_dashpay("add", true); + let (drive, dashpay) = setup_dashpay("add", true); - let dashpay_cr_serialized_document = json_document_to_cbor( + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let document_type = dashpay + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + + let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); drive - .add_serialized_document_for_serialized_contract( - &dashpay_cr_serialized_document, - &dashpay_cbor, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), - None, + Some(&db_transaction), ) .expect("expected to insert a document successfully"); drive - .add_serialized_document_for_serialized_contract( - &dashpay_cr_serialized_document, - &dashpay_cbor, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), - None, + Some(&db_transaction), ) .expect_err("expected not to be able to insert same document twice"); drive - .add_serialized_document_for_serialized_contract( - &dashpay_cr_serialized_document, - &dashpay_cbor, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, true, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), - None, + Some(&db_transaction), ) .expect("expected to override a document successfully"); } @@ -1348,51 +1372,75 @@ mod tests { Some(&db_transaction), ); - let dashpay_cr_serialized_document = json_document_to_cbor( + let document_type = dashpay + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect("expected to insert a document successfully"); drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect_err("expected not to be able to insert same document twice"); drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, true, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect("expected to override a document successfully"); @@ -1416,24 +1464,35 @@ mod tests { Some(&db_transaction), ); - let dashpay_cr_serialized_document = json_document_to_cbor( + let document_type = dashpay + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let fee_result = drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect("expected to insert a document successfully"); @@ -1469,24 +1528,35 @@ mod tests { Some(&db_transaction), ); - let dashpay_cr_serialized_document = json_document_to_cbor( + let document_type = dashpay + .document_type_for_name("profile") + .expect("expected to get document type"); + + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let dashpay_profile_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let fee_result = drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "profile", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_profile_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect("expected to insert a document successfully"); @@ -1522,29 +1592,40 @@ mod tests { Some(&db_transaction), ); - let dashpay_cr_serialized_document = json_document_to_cbor( + let document_type = dashpay + .document_type_for_name("profile") + .expect("expected to get document type"); + + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let dashpay_profile_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let FeeResult { storage_fee, processing_fee, fee_refunds: _, removed_bytes_from_system: _, } = drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "profile", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_profile_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), false, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect("expected to insert a document successfully"); @@ -1575,37 +1656,55 @@ mod tests { Some(&db_transaction), ); - let dashpay_cr_serialized_document = json_document_to_cbor( + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let document_type = dashpay + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + + let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let fees = drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), false, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) - .expect("expected to get back fee for document insertion successfully"); + .expect("expected to insert a document successfully"); let actual_fees = drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect("expected to insert a document successfully"); @@ -1631,27 +1730,23 @@ mod tests { Some(&db_transaction), ); - let dashpay_cr_serialized_document = json_document_to_cbor( + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let document_type = dashpay + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + + let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let owner_id = rand::thread_rng().gen::<[u8; 32]>(); - 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))); - let document_info = DocumentRefAndSerialization(( - &document, - &dashpay_cr_serialized_document, - storage_flags, - )); + let document_info = DocumentRefWithoutSerialization((&dashpay_cr_document, storage_flags)); - let document_type = contract - .document_type_for_name("contactRequest") - .expect("expected to get document type successfully"); let mut fee_drive_operations: Vec = vec![]; let mut actual_drive_operations: Vec = vec![]; @@ -1728,22 +1823,18 @@ mod tests { Some(&db_transaction), ); - let dpns_domain_serialized_document = - json_document_to_cbor("tests/supporting_files/contract/dpns/domain0.json", Some(1)) - .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let document = Document::from_cbor( - &dpns_domain_serialized_document, - None, - Some(random_owner_id), - ) - .expect("expected to deserialize the document"); - - let document_type = contract + let document_type = dashpay .document_type_for_name("domain") - .expect("expected to get a document type"); + .expect("expected to get document type"); + + let dpns_domain_document = json_document_to_document( + "tests/supporting_files/contract/dpns/domain0.json", + Some(random_owner_id.into()), + document_type, + ) + .expect("expected to get document"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -1751,11 +1842,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &dpns_domain_serialized_document, - storage_flags, - )), + document_info: DocumentRefWithoutSerialization((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -1791,61 +1878,85 @@ mod tests { fn test_add_dashpay_many_non_conflicting_documents() { let (drive, dashpay_cbor) = setup_dashpay("add_no_conflict", true); - let dashpay_cr_serialized_document_0 = json_document_to_cbor( + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let dashpay_cr_document_0 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let dashpay_cr_serialized_document_1 = json_document_to_cbor( + let dashpay_cr_document_1 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request1.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let dashpay_cr_serialized_document_2 = json_document_to_cbor( + let dashpay_cr_document_2 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request2.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); drive - .add_serialized_document_for_serialized_contract( - &dashpay_cr_serialized_document_0, - &dashpay_cbor, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document_0, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), None, ) .expect("expected to insert a document successfully"); + drive - .add_serialized_document_for_serialized_contract( - &dashpay_cr_serialized_document_1, - &dashpay_cbor, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document_1, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), None, ) .expect("expected to insert a document successfully"); + drive - .add_serialized_document_for_serialized_contract( - &dashpay_cr_serialized_document_2, - &dashpay_cbor, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document_2, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), None, ) .expect("expected to insert a document successfully"); @@ -1855,42 +1966,56 @@ mod tests { fn test_add_dashpay_conflicting_unique_index_documents() { let (drive, dashpay_cbor) = setup_dashpay("add_conflict", true); - let dashpay_cr_serialized_document_0 = json_document_to_cbor( + let dashpay_cr_document_0 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let dashpay_cr_serialized_document_0_dup = json_document_to_cbor( + let dashpay_cr_document_0_dup = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0-dup-unique-index.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); drive - .add_serialized_document_for_serialized_contract( - &dashpay_cr_serialized_document_0, - &dashpay_cbor, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document_0, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), None, ) .expect("expected to insert a document successfully"); + drive - .add_serialized_document_for_serialized_contract( - &dashpay_cr_serialized_document_0_dup, - &dashpay_cbor, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document_0_dup, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), None, ) .expect_err( diff --git a/packages/rs-drive/src/drive/identity/key/fetch.rs b/packages/rs-drive/src/drive/identity/key/fetch.rs index 6474914e9e7..f16e52bf674 100644 --- a/packages/rs-drive/src/drive/identity/key/fetch.rs +++ b/packages/rs-drive/src/drive/identity/key/fetch.rs @@ -35,6 +35,7 @@ use dpp::identity::IDENTITY_MAX_KEYS; use dpp::identity::{Purpose, SecurityLevel}; #[cfg(feature = "full")] use dpp::prelude::IdentityPublicKey; +use dpp::serialization_traits::PlatformDeserializable; #[cfg(feature = "full")] use grovedb::query_result_type::QueryResultType::QueryPathKeyElementTrioResultType; #[cfg(feature = "full")] diff --git a/packages/rs-drive/src/drive/identity/key/insert.rs b/packages/rs-drive/src/drive/identity/key/insert.rs index 89e8cc8f1ec..bf3d37f93db 100644 --- a/packages/rs-drive/src/drive/identity/key/insert.rs +++ b/packages/rs-drive/src/drive/identity/key/insert.rs @@ -20,10 +20,10 @@ use dpp::identity::{IdentityPublicKey, Purpose, SecurityLevel}; use grovedb::batch::KeyInfoPath; use grovedb::reference_path::ReferencePathType; +use dpp::serialization_traits::PlatformSerializable; use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; use integer_encoding::VarInt; use std::collections::HashMap; -use dpp::serialization_traits::PlatformSerializable; /// The contract apply info pub enum ContractApplyInfo { diff --git a/packages/rs-drive/src/drive/verify/mod.rs b/packages/rs-drive/src/drive/verify/mod.rs index e34e1dfae97..17839255002 100644 --- a/packages/rs-drive/src/drive/verify/mod.rs +++ b/packages/rs-drive/src/drive/verify/mod.rs @@ -11,9 +11,9 @@ use dpp::identity::{IdentityPublicKey, KeyID}; use dpp::prelude::{Identity, Revision}; use crate::fee::credits::Credits; +use dpp::serialization_traits::PlatformDeserializable; use grovedb::GroveDb; use std::collections::BTreeMap; -use dpp::serialization_traits::PlatformDeserializable; /// Represents the root hash of the grovedb tree pub type RootHash = [u8; 32]; From b0bf077073f32e2962a9eeec5c30228025463e96 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 12:47:14 +0700 Subject: [PATCH 34/50] more fixes --- .../src/drive/batch/drive_op_batch/mod.rs | 256 +++++++----------- .../rs-drive/src/drive/document/delete.rs | 4 +- .../rs-drive/src/drive/document/insert.rs | 8 + 3 files changed, 114 insertions(+), 154 deletions(-) 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 064ae43e3a7..1a59f557449 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 @@ -215,6 +215,7 @@ mod tests { use dpp::data_contract::extra::common::{json_document_to_contract, json_document_to_document}; use dpp::document::Document; + use dpp::serialization_traits::PlatformSerializable; use dpp::util::cbor_serializer; use rand::Rng; use serde_json::json; @@ -259,7 +260,7 @@ mod tests { let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", ) - .expect("expected to get cbor contract"); + .expect("expected to get contract"); let document_type = contract .document_type_for_name("contactRequest") @@ -270,21 +271,32 @@ mod tests { storage_flags: None, })); - let dashpay_cr_serialized_document = json_document_to_cbor( + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let document_type = contract + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + + let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) - .expect("expected to get cbor contract"); + .expect("expected to get document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - - drive_operations.push(DocumentOperation(AddSerializedDocumentForContract { - serialized_document: dashpay_cr_serialized_document.as_slice(), - contract: &contract, - document_type_name: "contactRequest", - owner_id: Some(random_owner_id), + drive_operations.push(DocumentOperation(AddDocumentForContract { + document_and_contract_info: DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefWithoutSerialization(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: None, + }, + contract: &contract, + document_type, + }, override_document: false, - storage_flags: StorageFlags::optional_default_as_cow(), })); drive @@ -354,7 +366,7 @@ mod tests { let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", ) - .expect("expected to get cbor contract"); + .expect("expected to get contract"); let document_type = contract .document_type_for_name("contactRequest") @@ -371,7 +383,7 @@ mod tests { Some(random_owner_id.into()), document_type, ) - .expect("expected to get cbor contract"); + .expect("expected to get contract"); drive_operations.push(DocumentOperation(AddDocumentForContract { document_and_contract_info: DocumentAndContractInfo { @@ -392,7 +404,7 @@ mod tests { Some(random_owner_id.into()), document_type, ) - .expect("expected to get cbor contract"); + .expect("expected to get contract"); drive_operations.push(DocumentOperation(AddDocumentForContract { document_and_contract_info: DocumentAndContractInfo { @@ -440,7 +452,7 @@ mod tests { let contract = json_document_to_contract( "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", ) - .expect("expected to get cbor contract"); + .expect("expected to get contract"); let document_type = contract .document_type_for_name("contactRequest") @@ -583,34 +595,30 @@ mod tests { .document_type_for_name("person") .expect("expected to get document type"); - let person_serialized_document0 = json_document_to_cbor( + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( "tests/supporting_files/contract/family/person0.json", - Some(1), + Some(random_owner_id0.into()), + document_type, ) - .expect("expected to get cbor document"); + .expect("expected to get document"); - let person_serialized_document1 = json_document_to_cbor( + let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document1 = json_document_to_document( "tests/supporting_files/contract/family/person3.json", - Some(1), + Some(random_owner_id1.into()), + document_type, ) - .expect("expected to get cbor document"); - - let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + .expect("expected to get document"); let mut operations = vec![]; - let document0 = Document::from_cbor( - person_serialized_document0.as_slice(), - None, - Some(random_owner_id0), - ) - .expect("expected to deserialize contact request"); - operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document0, - person_serialized_document0.as_slice(), + document_info: DocumentRefWithoutSerialization(( + &person_document0, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id0), @@ -620,18 +628,10 @@ mod tests { let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); - let document1 = Document::from_cbor( - person_serialized_document1.as_slice(), - None, - Some(random_owner_id1), - ) - .expect("expected to deserialize contact request"); - operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document1, - person_serialized_document0.as_slice(), + document_info: DocumentRefWithoutSerialization(( + &person_document1, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id1), @@ -711,34 +711,30 @@ mod tests { .document_type_for_name("person") .expect("expected to get document type"); - let person_serialized_document0 = json_document_to_cbor( + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( "tests/supporting_files/contract/family/person0.json", - Some(1), + Some(random_owner_id0.into()), + document_type, ) - .expect("expected to get cbor document"); + .expect("expected to get document"); - let person_serialized_document1 = json_document_to_cbor( + let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document1 = json_document_to_document( "tests/supporting_files/contract/family/person3.json", - Some(1), + Some(random_owner_id1.into()), + document_type, ) - .expect("expected to get cbor document"); - - let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + .expect("expected to get document"); let mut operations = vec![]; - let document0 = Document::from_cbor( - person_serialized_document0.as_slice(), - None, - Some(random_owner_id0), - ) - .expect("expected to deserialize contact request"); - operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document0, - person_serialized_document0.as_slice(), + document_info: DocumentRefWithoutSerialization(( + &person_document0, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id0), @@ -746,20 +742,10 @@ mod tests { override_document: false, }); - let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); - - let document1 = Document::from_cbor( - person_serialized_document1.as_slice(), - None, - Some(random_owner_id1), - ) - .expect("expected to deserialize contact request"); - operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document1, - person_serialized_document1.as_slice(), + document_info: DocumentRefWithoutSerialization(( + &person_document1, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id1), @@ -790,44 +776,36 @@ mod tests { drive_operations = vec![]; - let person_serialized_document0 = json_document_to_cbor( + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( "tests/supporting_files/contract/family/person0-older.json", - Some(1), + Some(random_owner_id0.into()), + document_type, ) - .expect("expected to get cbor document"); + .expect("expected to get document"); + + let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); - let person_serialized_document1 = json_document_to_cbor( + let person_document1 = json_document_to_document( "tests/supporting_files/contract/family/person3-older.json", - Some(1), + Some(random_owner_id1.into()), + document_type, ) - .expect("expected to get cbor document"); + .expect("expected to get document"); let mut operations = vec![]; - let document0 = Document::from_cbor( - person_serialized_document0.as_slice(), - None, - Some(random_owner_id0), - ) - .expect("expected to deserialize contact request"); - operations.push(UpdateOperation(UpdateOperationInfo { - document: &document0, - serialized_document: Some(person_serialized_document0.as_slice()), + document: &person_document0, + serialized_document: None, owner_id: Some(random_owner_id0), storage_flags: None, })); - let document1 = Document::from_cbor( - person_serialized_document1.as_slice(), - None, - Some(random_owner_id1), - ) - .expect("expected to deserialize contact request"); - operations.push(UpdateOperation(UpdateOperationInfo { - document: &document1, - serialized_document: Some(person_serialized_document1.as_slice()), + document: &person_document1, + serialized_document: None, owner_id: Some(random_owner_id1), storage_flags: None, })); @@ -950,34 +928,30 @@ mod tests { .document_type_for_name("person") .expect("expected to get document type"); - let person_serialized_document0 = json_document_to_cbor( + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( "tests/supporting_files/contract/family/person0.json", - Some(1), + Some(random_owner_id0.into()), + document_type, ) - .expect("expected to get cbor document"); + .expect("expected to get document"); + + let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); - let person_serialized_document1 = json_document_to_cbor( + let person_document1 = json_document_to_document( "tests/supporting_files/contract/family/person3-older.json", - Some(1), + Some(random_owner_id1.into()), + document_type, ) - .expect("expected to get cbor document"); - - let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + .expect("expected to get document"); let mut operations = vec![]; - let document0 = Document::from_cbor( - person_serialized_document0.as_slice(), - None, - Some(random_owner_id0), - ) - .expect("expected to deserialize contact request"); - operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document0, - person_serialized_document0.as_slice(), + document_info: DocumentRefWithoutSerialization(( + &person_document0, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id0), @@ -985,20 +959,10 @@ mod tests { override_document: false, }); - let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); - - let document1 = Document::from_cbor( - person_serialized_document1.as_slice(), - None, - Some(random_owner_id1), - ) - .expect("expected to deserialize contact request"); - operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document1, - person_serialized_document1.as_slice(), + document_info: DocumentRefWithoutSerialization(( + &person_document1, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id1), @@ -1029,44 +993,32 @@ mod tests { drive_operations = vec![]; - let person_serialized_document0 = json_document_to_cbor( + let person_document0 = json_document_to_document( "tests/supporting_files/contract/family/person0-older.json", - Some(1), + Some(random_owner_id0.into()), + document_type, ) - .expect("expected to get cbor document"); + .expect("expected to get document"); - let person_serialized_document1 = json_document_to_cbor( + let person_document1 = json_document_to_document( "tests/supporting_files/contract/family/person3.json", - Some(1), + Some(random_owner_id1.into()), + document_type, ) - .expect("expected to get cbor document"); + .expect("expected to get document"); let mut operations = vec![]; - let document0 = Document::from_cbor( - person_serialized_document0.as_slice(), - None, - Some(random_owner_id0), - ) - .expect("expected to deserialize contact request"); - operations.push(UpdateOperation(UpdateOperationInfo { - document: &document0, - serialized_document: Some(person_serialized_document0.as_slice()), + document: &person_document0, + serialized_document: None, owner_id: Some(random_owner_id0), storage_flags: None, })); - let document1 = Document::from_cbor( - person_serialized_document1.as_slice(), - None, - Some(random_owner_id1), - ) - .expect("expected to deserialize contact request"); - operations.push(UpdateOperation(UpdateOperationInfo { - document: &document1, - serialized_document: Some(person_serialized_document1.as_slice()), + document: &person_document1, + serialized_document: None, owner_id: Some(random_owner_id1), storage_flags: None, })); diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 1c1bcdf900d..4ab3283943a 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -844,11 +844,11 @@ mod tests { None, ); - let person_serialized_document = json_document_to_cbor( + let person_document0 = json_document_to_cbor( "tests/supporting_files/contract/family/person0.json", Some(1), ) - .expect("expected to get cbor document"); + .expect("expected to get document"); let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 7df0197e604..e8a5b6d5d40 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -1880,6 +1880,10 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + let document_type = dashpay + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + let dashpay_cr_document_0 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", Some(random_owner_id.into()), @@ -1966,6 +1970,10 @@ mod tests { fn test_add_dashpay_conflicting_unique_index_documents() { let (drive, dashpay_cbor) = setup_dashpay("add_conflict", true); + let document_type = dashpay + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + let dashpay_cr_document_0 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", Some(random_owner_id.into()), From 7a27923312905cf57e937f7c798ac0b1d5788143 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 13:27:00 +0700 Subject: [PATCH 35/50] more work --- .../reward_share_data_triggers/mod.rs | 6 +- .../withdrawals_data_triggers/mod.rs | 4 +- packages/rs-drive-abci/src/state/genesis.rs | 2 +- .../src/test/helpers/fee_pools.rs | 7 +- .../drive/batch/drive_op_batch/document.rs | 8 +- .../src/drive/batch/drive_op_batch/mod.rs | 24 +-- .../document/document_create_transition.rs | 7 +- .../document/document_update_transition.rs | 7 +- .../identity_credit_withdrawal_transition.rs | 2 +- packages/rs-drive/src/drive/contract/mod.rs | 81 ++------ .../rs-drive/src/drive/document/delete.rs | 186 +++++++----------- .../rs-drive/src/drive/document/insert.rs | 112 +++++------ .../rs-drive/src/drive/document/update.rs | 56 +++--- .../rs-drive/src/drive/object_size_info.rs | 36 ++-- packages/rs-drive/src/tests/helpers/setup.rs | 4 +- .../rs-drive/tests/deterministic_root_hash.rs | 6 +- packages/rs-drive/tests/query_tests.rs | 87 ++------ .../rs-drive/tests/query_tests_history.rs | 12 +- 18 files changed, 242 insertions(+), 405 deletions(-) diff --git a/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs index b6b7caaf2d8..5334934a67c 100644 --- a/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs @@ -193,7 +193,7 @@ mod test { use dpp::DataTriggerActionError; use drive::drive::object_size_info::DocumentInfo::{ - DocumentRefWithoutSerialization, DocumentWithoutSerialization, + DocumentRefInfo, DocumentOwnedInfo, }; use drive::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use std::net::SocketAddr; @@ -350,7 +350,7 @@ mod test { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &document.document, None, )), @@ -593,7 +593,7 @@ mod test { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentWithoutSerialization((document, None)), + document_info: DocumentOwnedInfo((document, None)), owner_id: Some(top_level_identifier.to_buffer()), }, contract: &data_contract, diff --git a/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs index 647f7135c9d..2eccae4d1cc 100644 --- a/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs @@ -125,7 +125,7 @@ mod tests { use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use dpp::tests::fixtures::{get_data_contract_fixture, get_withdrawal_document_fixture}; - use drive::drive::object_size_info::DocumentInfo::DocumentRefWithoutSerialization; + use drive::drive::object_size_info::DocumentInfo::DocumentRefInfo; use drive::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; #[test] @@ -208,7 +208,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&document, None)), + document_info: DocumentRefInfo((&document, None)), owner_id: Some(owner_id.to_buffer()), }, contract: &data_contract, diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 858abaefbf4..a4c075045f6 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -229,7 +229,7 @@ impl Platform { DriveOperation::DocumentOperation(DocumentOperationType::AddDocumentForContract { document_and_contract_info: DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentInfo::DocumentWithoutSerialization((document, None)), + document_info: DocumentInfo::DocumentOwnedInfo((document, None)), owner_id: None, }, contract, 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 c67bdbe567a..6426c11d369 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -47,9 +47,9 @@ use drive::common::helpers::identities::create_test_identity_with_rng; use drive::contract::Contract; use drive::dpp::document::Document; use drive::drive::flags::StorageFlags; -use drive::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; use drive::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use drive::drive::Drive; +use drive::drive::object_size_info::DocumentInfo::DocumentRefInfo; use drive::grovedb::TransactionArg; use crate::contracts::reward_shares::MN_REWARD_SHARES_DOCUMENT_TYPE; @@ -88,15 +88,12 @@ fn create_test_mn_share_document( let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); - let document_cbor = document.to_cbor().expect("expected to encode to cbor"); - drive .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( + document_info: DocumentRefInfo(( &document, - &document_cbor, storage_flags, )), owner_id: None, 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 f3dc494e4ad..7e89c233812 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 @@ -1,8 +1,6 @@ use crate::drive::batch::drive_op_batch::DriveLowLevelOperationConverter; use crate::drive::flags::StorageFlags; -use crate::drive::object_size_info::DocumentInfo::{ - DocumentRefAndSerialization, DocumentRefWithoutSerialization, -}; +use crate::drive::object_size_info::DocumentInfo::{DocumentRefAndSerialization, DocumentRefInfo}; use crate::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use crate::drive::Drive; use crate::error::document::DocumentError; @@ -421,7 +419,7 @@ impl DriveLowLevelOperationConverter for DocumentOperationType<'_> { let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = - DocumentRefAndSerialization((&document, serialized_document, storage_flags)); + DocumentRefSerialization((&document, serialized_document, storage_flags)); let document_type = contract.document_type_for_name(document_type_name)?; @@ -547,7 +545,7 @@ impl DriveLowLevelOperationConverter for DocumentOperationType<'_> { storage_flags, )) } else { - DocumentRefWithoutSerialization((document, storage_flags)) + DocumentRefInfo((document, storage_flags)) }; let document_and_contract_info = DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { 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 1a59f557449..66af66a5c63 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 @@ -240,7 +240,7 @@ mod tests { use crate::drive::contract::paths::contract_root_path; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentInfo::{ - DocumentRefAndSerialization, DocumentRefWithoutSerialization, + DocumentRefAndSerialization, DocumentRefInfo, }; use crate::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use crate::drive::Drive; @@ -287,7 +287,7 @@ mod tests { drive_operations.push(DocumentOperation(AddDocumentForContract { document_and_contract_info: DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), @@ -388,7 +388,7 @@ mod tests { drive_operations.push(DocumentOperation(AddDocumentForContract { document_and_contract_info: DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&dashpay_cr_document, None)), + document_info: DocumentRefInfo((&dashpay_cr_document, None)), owner_id: Some(random_owner_id), }, contract: &contract, @@ -409,7 +409,7 @@ mod tests { drive_operations.push(DocumentOperation(AddDocumentForContract { document_and_contract_info: DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&dashpay_cr_1_document, None)), + document_info: DocumentRefInfo((&dashpay_cr_1_document, None)), owner_id: Some(random_owner_id), }, contract: &contract, @@ -483,7 +483,7 @@ mod tests { operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &document0, StorageFlags::optional_default_as_cow(), )), @@ -494,7 +494,7 @@ mod tests { operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &document1, StorageFlags::optional_default_as_cow(), )), @@ -617,7 +617,7 @@ mod tests { operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &person_document0, StorageFlags::optional_default_as_cow(), )), @@ -630,7 +630,7 @@ mod tests { operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &person_document1, StorageFlags::optional_default_as_cow(), )), @@ -733,7 +733,7 @@ mod tests { operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &person_document0, StorageFlags::optional_default_as_cow(), )), @@ -744,7 +744,7 @@ mod tests { operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &person_document1, StorageFlags::optional_default_as_cow(), )), @@ -950,7 +950,7 @@ mod tests { operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &person_document0, StorageFlags::optional_default_as_cow(), )), @@ -961,7 +961,7 @@ mod tests { operations.push(AddOperation { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &person_document1, StorageFlags::optional_default_as_cow(), )), diff --git a/packages/rs-drive/src/drive/batch/transitions/document/document_create_transition.rs b/packages/rs-drive/src/drive/batch/transitions/document/document_create_transition.rs index f193038275c..30f36b7d92b 100644 --- a/packages/rs-drive/src/drive/batch/transitions/document/document_create_transition.rs +++ b/packages/rs-drive/src/drive/batch/transitions/document/document_create_transition.rs @@ -2,7 +2,7 @@ use crate::drive::batch::transitions::document::DriveHighLevelDocumentOperationC use crate::drive::batch::DriveOperation::DocumentOperation; use crate::drive::batch::{DocumentOperationType, DriveOperation}; use crate::drive::flags::StorageFlags; -use crate::drive::object_size_info::DocumentInfo::DocumentWithoutSerialization; +use crate::drive::object_size_info::DocumentInfo::DocumentOwnedInfo; use crate::drive::object_size_info::OwnedDocumentInfo; use crate::error::Error; use dpp::block::epoch::Epoch; @@ -50,10 +50,7 @@ impl DriveHighLevelDocumentOperationConverter for DocumentCreateTransitionAction let mut drive_operations = vec![]; drive_operations.push(DocumentOperation(DocumentOperationType::AddDocument { owned_document_info: OwnedDocumentInfo { - document_info: DocumentWithoutSerialization(( - document, - Some(Cow::Owned(storage_flags)), - )), + document_info: DocumentOwnedInfo((document, Some(Cow::Owned(storage_flags)))), owner_id: Some(owner_id.into_buffer()), }, contract_id: data_contract_id, diff --git a/packages/rs-drive/src/drive/batch/transitions/document/document_update_transition.rs b/packages/rs-drive/src/drive/batch/transitions/document/document_update_transition.rs index 774ccd9c30b..1839fcdc7f9 100644 --- a/packages/rs-drive/src/drive/batch/transitions/document/document_update_transition.rs +++ b/packages/rs-drive/src/drive/batch/transitions/document/document_update_transition.rs @@ -2,7 +2,7 @@ use crate::drive::batch::transitions::document::DriveHighLevelDocumentOperationC use crate::drive::batch::DriveOperation::DocumentOperation; use crate::drive::batch::{DocumentOperationType, DriveOperation}; use crate::drive::flags::StorageFlags; -use crate::drive::object_size_info::DocumentInfo::DocumentWithoutSerialization; +use crate::drive::object_size_info::DocumentInfo::DocumentOwnedInfo; use crate::drive::object_size_info::OwnedDocumentInfo; use crate::error::Error; use dpp::block::epoch::Epoch; @@ -50,10 +50,7 @@ impl DriveHighLevelDocumentOperationConverter for DocumentReplaceTransitionActio let mut drive_operations = vec![]; drive_operations.push(DocumentOperation(DocumentOperationType::UpdateDocument { owned_document_info: OwnedDocumentInfo { - document_info: DocumentWithoutSerialization(( - document, - Some(Cow::Owned(storage_flags)), - )), + document_info: DocumentOwnedInfo((document, Some(Cow::Owned(storage_flags)))), owner_id: Some(owner_id.into_buffer()), }, contract_id: data_contract_id, diff --git a/packages/rs-drive/src/drive/batch/transitions/identity/identity_credit_withdrawal_transition.rs b/packages/rs-drive/src/drive/batch/transitions/identity/identity_credit_withdrawal_transition.rs index 030b5d8d102..d9287b27edc 100644 --- a/packages/rs-drive/src/drive/batch/transitions/identity/identity_credit_withdrawal_transition.rs +++ b/packages/rs-drive/src/drive/batch/transitions/identity/identity_credit_withdrawal_transition.rs @@ -26,7 +26,7 @@ impl DriveHighLevelOperationConverter for IdentityCreditWithdrawalTransitionActi }), DocumentOperation(DocumentOperationType::AddWithdrawalDocument { owned_document_info: OwnedDocumentInfo { - document_info: DocumentInfo::DocumentWithoutSerialization(( + document_info: DocumentInfo::DocumentOwnedInfo(( prepared_withdrawal_document, None, )), diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 4ac2009a11a..adcd4d79706 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -708,14 +708,7 @@ impl Drive { contract_id.map(|identifier| Identifier::from(identifier)), )?; - self.apply_contract_with_serialization( - &contract, - contract_cbor, - block_info, - apply, - storage_flags, - transaction, - ) + self.apply_contract(&contract, block_info, apply, storage_flags, transaction) } /// Returns the contract with fetch info and operations with the given ID. @@ -1131,7 +1124,7 @@ mod tests { use crate::tests::helpers::setup::setup_drive_with_initial_state_structure; - fn setup_deep_nested_50_contract() -> (Drive, Contract, Vec) { + fn setup_deep_nested_50_contract() -> (Drive, DataContract) { // Todo: make TempDir based on _prefix let tmp_dir = TempDir::new().unwrap(); let drive: Drive = Drive::open(tmp_dir, None).expect("expected to open Drive successfully"); @@ -1142,15 +1135,11 @@ mod tests { let contract_path = "tests/supporting_files/contract/deepNested/deep-nested50.json"; // let's construct the grovedb structure for the dashpay data contract - let contract_cbor = - json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + json_document_to_contract(contract_path).expect("expected to get a contract"); drive - .apply_contract_with_serialization( + .apply_contract( &contract, - contract_cbor.clone(), BlockInfo::default(), true, StorageFlags::optional_default_as_cow(), @@ -1158,10 +1147,10 @@ mod tests { ) .expect("expected to apply contract successfully"); - (drive, contract, contract_cbor) + (drive, contract) } - fn setup_deep_nested_10_contract() -> (Drive, Contract, Vec) { + fn setup_deep_nested_10_contract() -> (Drive, DataContract) { // Todo: make TempDir based on _prefix let tmp_dir = TempDir::new().unwrap(); let drive: Drive = Drive::open(tmp_dir, None).expect("expected to open Drive successfully"); @@ -1172,14 +1161,11 @@ mod tests { let contract_path = "tests/supporting_files/contract/deepNested/deep-nested10.json"; // let's construct the grovedb structure for the dashpay data contract - let contract_cbor = - json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); let contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + json_document_to_contract(contract_path).expect("expected to get a contract"); drive - .apply_contract_with_serialization( + .apply_contract( &contract, - contract_cbor.clone(), BlockInfo::default(), true, StorageFlags::optional_default_as_cow(), @@ -1187,10 +1173,10 @@ mod tests { ) .expect("expected to apply contract successfully"); - (drive, contract, contract_cbor) + (drive, contract) } - fn setup_reference_contract() -> (Drive, Contract, Vec) { + fn setup_reference_contract() -> (Drive, Contract) { let tmp_dir = TempDir::new().unwrap(); let drive: Drive = Drive::open(tmp_dir, None).expect("expected to open Drive successfully"); @@ -1201,10 +1187,8 @@ mod tests { let contract_path = "tests/supporting_files/contract/references/references.json"; // let's construct the grovedb structure for the dashpay data contract - let contract_cbor = - json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); let contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + json_document_to_contract(contract_path).expect("expected to get a contract"); drive .apply_contract( &contract, @@ -1215,7 +1199,7 @@ mod tests { ) .expect("expected to apply contract successfully"); - (drive, contract, contract_cbor) + (drive, contract) } #[test] @@ -1256,7 +1240,7 @@ mod tests { #[test] fn test_create_deep_nested_contract_50() { - let (drive, contract, _contract_cbor) = setup_deep_nested_50_contract(); + let (drive, contract) = setup_deep_nested_50_contract(); let document_type = contract .document_type_for_name("nest") @@ -1275,14 +1259,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentInfo::DocumentRefAndSerialization(( - &document, - document - .to_cbor() - .expect("expected to encode to cbor") - .as_slice(), - storage_flags, - )), + document_info: DocumentInfo::DocumentRefInfo((&document, storage_flags)), owner_id: Some(random_owner_id), }, contract: &contract, @@ -1317,14 +1294,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentInfo::DocumentRefAndSerialization(( - &document, - document - .to_cbor() - .expect("expected to encode to cbor") - .as_slice(), - storage_flags, - )), + document_info: DocumentInfo::DocumentRefInfo((&document, storage_flags)), owner_id: Some(random_owner_id), }, contract: &contract, @@ -1350,14 +1320,11 @@ mod tests { let contract_path = "tests/supporting_files/contract/references/references.json"; // let's construct the grovedb structure for the dashpay data contract - let contract_cbor = - json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); let contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + json_document_to_contract(contract_path).expect("expected to get cbor document"); drive - .apply_contract_with_serialization( + .apply_contract( &contract, - contract_cbor, BlockInfo::default(), false, StorageFlags::optional_default_as_cow(), @@ -1379,14 +1346,10 @@ mod tests { "tests/supporting_files/contract/references/references_with_contract_history.json"; // let's construct the grovedb structure for the dashpay data contract - let contract_cbor = - json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + let contract = json_document_to_contract(contract_path).expect("expected to get contract"); drive - .apply_contract_with_serialization( + .apply_contract( &contract, - contract_cbor, BlockInfo::default(), false, StorageFlags::optional_default_as_cow(), @@ -1440,8 +1403,6 @@ mod tests { contract.increment_version(); - let updated_contract_bytes = contract.serialize().expect("should serialize a contract"); - drive .update_contract(&contract, BlockInfo::default(), true, Some(&transaction)) .expect("should update contract"); @@ -1531,10 +1492,8 @@ mod tests { // Create a deep placed contract let contract_path = "tests/supporting_files/contract/deepNested/deep-nested10.json"; - let contract_cbor = json_document_to_cbor(contract_path, Some(1)) - .expect("expected to get cbor document"); let deep_contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + json_document_to_contract(contract_path).expect("expected to get cbor document"); drive .apply_contract( &deep_contract, diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 4ab3283943a..93da5b60ee6 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -55,7 +55,7 @@ use crate::drive::document::{ }; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentInfo::{ - DocumentEstimatedAverageSize, DocumentWithoutSerialization, + DocumentEstimatedAverageSize, DocumentOwnedInfo, }; use crate::drive::object_size_info::DriveKeyInfo::KeyRef; use dpp::block::block_info::BlockInfo; @@ -759,7 +759,7 @@ impl Drive { if let Element::Item(data, element_flags) = document_element { let document = Document::from_bytes(data.as_slice(), document_type)?; let storage_flags = StorageFlags::map_cow_some_element_flags_ref(element_flags)?; - DocumentWithoutSerialization((document, storage_flags)) + DocumentOwnedInfo((document, storage_flags)) } else { return Err(Error::Drive(DriveError::CorruptedDocumentNotItem( "document being deleted is not an item", @@ -817,7 +817,7 @@ mod tests { use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentAndContractInfo; use crate::drive::object_size_info::DocumentInfo::{ - DocumentRefAndSerialization, DocumentRefWithoutSerialization, + DocumentRefAndSerialization, DocumentRefInfo, }; use crate::drive::Drive; use crate::fee::credits::Creditable; @@ -844,33 +844,26 @@ mod tests { None, ); - let person_document0 = json_document_to_cbor( + let document_type = contract + .document_type_for_name("person") + .expect("expected to get document type"); + + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( "tests/supporting_files/contract/family/person0.json", - Some(1), + Some(random_owner_id0.into()), + document_type, ) .expect("expected to get document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - - let document = - Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) - .expect("expected to deserialize the document"); - - let document_type = contract - .document_type_for_name("person") - .expect("expected to get a document type"); - let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); drive .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_serialized_document, - storage_flags, - )), + document_info: DocumentRefInfo((&person_document0, storage_flags)), owner_id: None, }, contract: &contract, @@ -910,7 +903,7 @@ mod tests { document_id, &contract, "person", - Some(random_owner_id), + Some(random_owner_id0), BlockInfo::default(), true, None, @@ -942,33 +935,26 @@ mod tests { Some(&db_transaction), ); - let person_serialized_document = json_document_to_cbor( - "tests/supporting_files/contract/family/person0.json", - Some(1), - ) - .expect("expected to get cbor document"); - - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - - let document = - Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) - .expect("expected to deserialize the document"); - let document_type = contract .document_type_for_name("person") .expect("expected to get a document type"); + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( + "tests/supporting_files/contract/family/person0.json", + Some(random_owner_id0.into()), + document_type, + ) + .expect("expected to get document"); + let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); drive .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_serialized_document, - storage_flags, - )), + document_info: DocumentRefInfo((&person_document0, storage_flags)), owner_id: None, }, contract: &contract, @@ -1016,7 +1002,7 @@ mod tests { document_id, &contract, "person", - Some(random_owner_id), + Some(random_owner_id0), BlockInfo::default(), true, Some(&db_transaction), @@ -1056,29 +1042,26 @@ mod tests { Some(&db_transaction), ); - let person_serialized_document = json_document_to_cbor( - "tests/supporting_files/contract/family/person0.json", - Some(1), - ) - .expect("expected to get cbor document"); - - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - - let document = - Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) - .expect("expected to deserialize the document"); - let document_type = contract .document_type_for_name("person") .expect("expected to get a document type"); + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( + "tests/supporting_files/contract/family/person0.json", + Some(random_owner_id0.into()), + document_type, + ) + .expect("expected to get document"); + let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); drive .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&document, storage_flags)), + document_info: DocumentRefInfo((&person_document0, storage_flags)), owner_id: None, }, contract: &contract, @@ -1091,29 +1074,26 @@ mod tests { ) .expect("expected to insert a document successfully"); - let person_serialized_document = json_document_to_cbor( - "tests/supporting_files/contract/family/person1.json", - Some(1), - ) - .expect("expected to get cbor document"); - - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - - let document = - Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) - .expect("expected to deserialize the document"); - let document_type = contract .document_type_for_name("person") .expect("expected to get a document type"); + let random_owner_id1 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document1 = json_document_to_document( + "tests/supporting_files/contract/family/person1.json", + Some(random_owner_id0.into()), + document_type, + ) + .expect("expected to get document"); + let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); drive .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&document, storage_flags)), + document_info: DocumentRefInfo((&person_document1, storage_flags)), owner_id: None, }, contract: &contract, @@ -1156,7 +1136,7 @@ mod tests { document_id, &contract, "person", - Some(random_owner_id), + Some(random_owner_id0), BlockInfo::default(), true, Some(&db_transaction), @@ -1193,7 +1173,7 @@ mod tests { document_id, &contract, "person", - Some(random_owner_id), + Some(random_owner_id0), BlockInfo::default(), true, Some(&db_transaction), @@ -1235,21 +1215,18 @@ mod tests { Some(&db_transaction), ); - let person_serialized_document = json_document_to_cbor( - "tests/supporting_files/contract/family/person0.json", - Some(1), - ) - .expect("expected to get cbor document"); - - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - - let document = - Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) - .expect("expected to deserialize the document"); - let document_type = contract .document_type_for_name("person") - .expect("expected to get a document type"); + .expect("expected to get document type"); + + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( + "tests/supporting_files/contract/family/person0.json", + Some(random_owner_id0.into()), + document_type, + ) + .expect("expected to get document"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -1257,11 +1234,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_serialized_document, - storage_flags, - )), + document_info: DocumentRefInfo((&person_document0, storage_flags)), owner_id: None, }, contract: &contract, @@ -1274,21 +1247,14 @@ mod tests { ) .expect("expected to insert a document successfully"); - let person_serialized_document = json_document_to_cbor( + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document1 = json_document_to_document( "tests/supporting_files/contract/family/person2-no-middle-name.json", - Some(1), + Some(random_owner_id0.into()), + document_type, ) - .expect("expected to get cbor document"); - - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - - let document = - Document::from_cbor(&person_serialized_document, None, Some(random_owner_id)) - .expect("expected to deserialize the document"); - - let document_type = contract - .document_type_for_name("person") - .expect("expected to get a document type"); + .expect("expected to get document"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -1296,11 +1262,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_serialized_document, - storage_flags, - )), + document_info: DocumentRefInfo((&person_document1, storage_flags)), owner_id: None, }, contract: &contract, @@ -1343,7 +1305,7 @@ mod tests { document_id, &contract, "person", - Some(random_owner_id), + Some(random_owner_id0), BlockInfo::default(), true, Some(&db_transaction), @@ -1360,21 +1322,13 @@ mod tests { let db_transaction = drive.grove.start_transaction(); - let document = - 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))); drive .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_serialized_document, - storage_flags, - )), + document_info: DocumentRefInfo((&person_document1, storage_flags)), owner_id: None, }, contract: &contract, @@ -1402,7 +1356,7 @@ mod tests { document_id, &contract, "person", - Some(random_owner_id), + Some(random_owner_id0), BlockInfo::default(), true, Some(&db_transaction), @@ -1421,7 +1375,7 @@ mod tests { document_id, &contract, "person", - Some(random_owner_id), + Some(random_owner_id0), BlockInfo::default(), true, Some(&db_transaction), @@ -1462,7 +1416,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_profile_document, StorageFlags::optional_default_as_cow(), )), diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index e8a5b6d5d40..b168f0d127d 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -58,8 +58,8 @@ use crate::drive::document::{ }; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentInfo::{ - DocumentAndSerialization, DocumentEstimatedAverageSize, DocumentRefAndSerialization, - DocumentRefWithoutSerialization, DocumentWithoutSerialization, + DocumentAndSerialization, DocumentEstimatedAverageSize, DocumentOwnedInfo, + DocumentRefAndSerialization, DocumentRefInfo, }; use crate::drive::object_size_info::DriveKeyInfo::{Key, KeyRef}; use crate::drive::object_size_info::KeyElementInfo::{KeyElement, KeyUnknownElementSize}; @@ -215,7 +215,7 @@ impl Drive { element, )) } - DocumentWithoutSerialization((document, storage_flags)) => { + DocumentOwnedInfo((document, storage_flags)) => { let serialized_document = document.serialize(document_and_contract_info.document_type)?; let element = Element::Item( @@ -234,7 +234,7 @@ impl Drive { element, )) } - DocumentRefWithoutSerialization((document, storage_flags)) => { + DocumentRefInfo((document, storage_flags)) => { let serialized_document = document.serialize(document_and_contract_info.document_type)?; let element = Element::Item( @@ -332,7 +332,7 @@ impl Drive { ); PathFixedSizeKeyRefElement((primary_key_path, document.id.as_slice(), element)) } - DocumentRefWithoutSerialization((document, storage_flags)) => { + DocumentRefInfo((document, storage_flags)) => { let serialized_document = document.serialize(document_and_contract_info.document_type)?; let element = Element::Item( @@ -349,7 +349,7 @@ impl Drive { }, Element::required_item_space(*average_size, STORAGE_FLAGS_SIZE), )), - DocumentWithoutSerialization((document, storage_flags)) => { + DocumentOwnedInfo((document, storage_flags)) => { let serialized_document = document.serialize(document_and_contract_info.document_type)?; let element = Element::Item( @@ -379,7 +379,7 @@ impl Drive { ); PathFixedSizeKeyRefElement((primary_key_path, document.id.as_slice(), element)) } - DocumentWithoutSerialization((document, storage_flags)) => { + DocumentOwnedInfo((document, storage_flags)) => { let serialized_document = document.serialize(document_and_contract_info.document_type)?; let element = Element::Item( @@ -388,7 +388,7 @@ impl Drive { ); PathFixedSizeKeyRefElement((primary_key_path, document.id.as_slice(), element)) } - DocumentRefWithoutSerialization((document, storage_flags)) => { + DocumentRefInfo((document, storage_flags)) => { let serialized_document = document.serialize(document_and_contract_info.document_type)?; let element = Element::Item( @@ -743,7 +743,7 @@ impl Drive { let key_element_info = match &document_and_contract_info.owned_document_info.document_info { DocumentRefAndSerialization((document, _, storage_flags)) - | DocumentRefWithoutSerialization((document, storage_flags)) => { + | DocumentRefInfo((document, storage_flags)) => { let document_reference = make_document_reference( document, document_and_contract_info.document_type, @@ -751,7 +751,7 @@ impl Drive { ); KeyElement((document.id.as_slice(), document_reference)) } - DocumentWithoutSerialization((document, storage_flags)) + DocumentOwnedInfo((document, storage_flags)) | DocumentAndSerialization((document, _, storage_flags)) => { let document_reference = make_document_reference( document, @@ -783,7 +783,7 @@ impl Drive { let key_element_info = match &document_and_contract_info.owned_document_info.document_info { DocumentRefAndSerialization((document, _, storage_flags)) - | DocumentRefWithoutSerialization((document, storage_flags)) => { + | DocumentRefInfo((document, storage_flags)) => { let document_reference = make_document_reference( document, document_and_contract_info.document_type, @@ -791,7 +791,7 @@ impl Drive { ); KeyElement((&[0], document_reference)) } - DocumentWithoutSerialization((document, storage_flags)) + DocumentOwnedInfo((document, storage_flags)) | DocumentAndSerialization((document, _, storage_flags)) => { let document_reference = make_document_reference( document, @@ -1260,7 +1260,7 @@ mod tests { use std::option::Option::None; use super::*; - use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_document}; + use dpp::data_contract::extra::common::json_document_to_document; use rand::Rng; use tempfile::TempDir; @@ -1268,13 +1268,11 @@ mod tests { use crate::drive::document::tests::setup_dashpay; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentAndContractInfo; - use crate::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; use crate::drive::Drive; use crate::fee::default_costs::EpochCosts; use crate::fee::default_costs::KnownCostItem::StorageDiskUsageCreditPerByte; use crate::fee::op::LowLevelDriveOperation; use dpp::block::epoch::Epoch; - use dpp::document::Document; #[test] fn test_add_dashpay_documents_no_transaction() { @@ -1297,19 +1295,19 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id), }, - contract: &contract, + contract: &dashpay, document_type, }, false, BlockInfo::default(), true, - Some(&db_transaction), + None, ) .expect("expected to insert a document successfully"); @@ -1317,19 +1315,19 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id), }, - contract: &contract, + contract: &dashpay, document_type, }, false, BlockInfo::default(), true, - Some(&db_transaction), + None, ) .expect_err("expected not to be able to insert same document twice"); @@ -1337,19 +1335,19 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id), }, - contract: &contract, + contract: &dashpay, document_type, }, true, BlockInfo::default(), true, - Some(&db_transaction), + None, ) .expect("expected to override a document successfully"); } @@ -1372,7 +1370,7 @@ mod tests { Some(&db_transaction), ); - let document_type = dashpay + let document_type = contract .document_type_for_name("contactRequest") .expect("expected to get document type"); @@ -1389,7 +1387,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), @@ -1409,7 +1407,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), @@ -1429,7 +1427,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), @@ -1464,7 +1462,7 @@ mod tests { Some(&db_transaction), ); - let document_type = dashpay + let document_type = contract .document_type_for_name("contactRequest") .expect("expected to get document type"); @@ -1481,7 +1479,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), @@ -1528,7 +1526,7 @@ mod tests { Some(&db_transaction), ); - let document_type = dashpay + let document_type = contract .document_type_for_name("profile") .expect("expected to get document type"); @@ -1545,7 +1543,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_profile_document, StorageFlags::optional_default_as_cow(), )), @@ -1592,7 +1590,7 @@ mod tests { Some(&db_transaction), ); - let document_type = dashpay + let document_type = contract .document_type_for_name("profile") .expect("expected to get document type"); @@ -1614,7 +1612,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_profile_document, StorageFlags::optional_default_as_cow(), )), @@ -1658,7 +1656,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let document_type = dashpay + let document_type = contract .document_type_for_name("contactRequest") .expect("expected to get document type"); @@ -1673,7 +1671,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), @@ -1693,7 +1691,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document, StorageFlags::optional_default_as_cow(), )), @@ -1732,7 +1730,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let document_type = dashpay + let document_type = contract .document_type_for_name("contactRequest") .expect("expected to get document type"); @@ -1745,7 +1743,7 @@ mod tests { let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); - let document_info = DocumentRefWithoutSerialization((&dashpay_cr_document, storage_flags)); + let document_info = DocumentRefInfo((&dashpay_cr_document, storage_flags)); let mut fee_drive_operations: Vec = vec![]; let mut actual_drive_operations: Vec = vec![]; @@ -1788,7 +1786,7 @@ mod tests { DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { document_info, - owner_id: Some(owner_id), + owner_id: None, }, contract: &contract, document_type, @@ -1825,7 +1823,7 @@ mod tests { let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); - let document_type = dashpay + let document_type = contract .document_type_for_name("domain") .expect("expected to get document type"); @@ -1842,7 +1840,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&document, storage_flags)), + document_info: DocumentRefInfo((&dpns_domain_document, storage_flags)), owner_id: None, }, contract: &contract, @@ -1876,7 +1874,7 @@ mod tests { #[test] fn test_add_dashpay_many_non_conflicting_documents() { - let (drive, dashpay_cbor) = setup_dashpay("add_no_conflict", true); + let (drive, dashpay) = setup_dashpay("add_no_conflict", true); let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); @@ -1909,13 +1907,13 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document_0, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id), }, - contract: &contract, + contract: &dashpay, document_type, }, false, @@ -1929,13 +1927,13 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document_1, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id), }, - contract: &contract, + contract: &dashpay, document_type, }, false, @@ -1949,13 +1947,13 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document_2, StorageFlags::optional_default_as_cow(), )), owner_id: Some(random_owner_id), }, - contract: &contract, + contract: &dashpay, document_type, }, false, @@ -1968,12 +1966,14 @@ mod tests { #[test] fn test_add_dashpay_conflicting_unique_index_documents() { - let (drive, dashpay_cbor) = setup_dashpay("add_conflict", true); + let (drive, dashpay) = setup_dashpay("add_conflict", true); let document_type = dashpay .document_type_for_name("contactRequest") .expect("expected to get document type"); + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + let dashpay_cr_document_0 = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", Some(random_owner_id.into()), @@ -1992,13 +1992,13 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document_0, StorageFlags::optional_default_as_cow(), )), - owner_id: Some(random_owner_id), + owner_id: None, }, - contract: &contract, + contract: &dashpay, document_type, }, false, @@ -2012,13 +2012,13 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( + document_info: DocumentRefInfo(( &dashpay_cr_document_0_dup, StorageFlags::optional_default_as_cow(), )), - owner_id: Some(random_owner_id), + owner_id: None, }, - contract: &contract, + contract: &dashpay, document_type, }, false, diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index e3ffe04f549..00e221392da 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -55,7 +55,7 @@ use crate::drive::document::{ }; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentInfo::{ - DocumentRefAndSerialization, DocumentWithoutSerialization, + DocumentOwnedInfo, DocumentRefAndSerialization, }; use dpp::document::Document; @@ -372,10 +372,7 @@ impl Drive { let document = Document::from_bytes(old_serialized_document.as_slice(), document_type)?; let storage_flags = StorageFlags::map_some_element_flags_ref(&element_flags)?; - Ok(DocumentWithoutSerialization(( - document, - storage_flags.map(Cow::Owned), - ))) + Ok(DocumentOwnedInfo((document, storage_flags.map(Cow::Owned)))) } else { Err(Error::Drive(DriveError::CorruptedDocumentNotItem( "old document is not an item", @@ -678,7 +675,6 @@ mod tests { use std::option::Option::None; use std::sync::Arc; - use dpp::data_contract::extra::common::json_document_to_cbor; use dpp::data_contract::validation::data_contract_validator::DataContractValidator; use dpp::data_contract::DataContractFactory; use dpp::document::document_factory::DocumentFactory; @@ -697,7 +693,9 @@ mod tests { use crate::drive::config::{DriveConfig, DriveEncoding}; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentAndContractInfo; - use crate::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; + use crate::drive::object_size_info::DocumentInfo::{ + DocumentRefAndSerialization, DocumentRefInfo, + }; use crate::drive::{defaults, Drive}; use crate::fee::credits::Creditable; use crate::fee::default_costs::EpochCosts; @@ -705,6 +703,7 @@ mod tests { use crate::query::DriveQuery; use crate::{common::setup_contract, drive::test_utils::TestEntropyGenerator}; use dpp::block::epoch::Epoch; + use dpp::data_contract::extra::common::json_document_to_document; #[test] fn test_create_and_update_document_same_transaction() { @@ -807,9 +806,8 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( + document_info: DocumentRefWithoutSerialization(( &alice_profile, - alice_profile_cbor.as_slice(), storage_flags, )), owner_id: None, @@ -900,9 +898,8 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( + document_info: DocumentRefWithoutSerialization(( &alice_profile, - alice_profile_cbor.as_slice(), storage_flags, )), owner_id: None, @@ -1013,9 +1010,8 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( + document_info: DocumentRefWithoutSerialization(( &alice_profile, - alice_profile_cbor.as_slice(), storage_flags, )), owner_id: None, @@ -1268,29 +1264,41 @@ mod tests { Some(&db_transaction), ); - let dashpay_cr_serialized_document = json_document_to_cbor( + let document_type = contract + .document_type_for_name("contactRequest") + .expect("expected to get document type"); + + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let dashpay_cr_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) - .expect("expected to get cbor document"); + .expect("expected to get document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect("expected to insert a document successfully"); drive - .update_serialized_document_for_contract( + .update_document_for_contract( &dashpay_cr_serialized_document, &contract, "contactRequest", diff --git a/packages/rs-drive/src/drive/object_size_info.rs b/packages/rs-drive/src/drive/object_size_info.rs index 2e2c2ea7614..1bc2f22c8c8 100644 --- a/packages/rs-drive/src/drive/object_size_info.rs +++ b/packages/rs-drive/src/drive/object_size_info.rs @@ -528,14 +528,14 @@ pub struct DocumentAndContractInfo<'a> { /// Document info #[derive(Clone, Debug)] pub enum DocumentInfo<'a> { + /// The document without it's serialized form + DocumentOwnedInfo((Document, Option>)), + /// The borrowed document without it's serialized form + DocumentRefInfo((&'a Document, Option>)), /// The borrowed document and it's serialized form DocumentRefAndSerialization((&'a Document, &'a [u8], Option>)), - /// The borrowed document without it's serialized form - DocumentRefWithoutSerialization((&'a Document, Option>)), /// The document and it's serialized form DocumentAndSerialization((Document, Vec, Option>)), - /// The document without it's serialized form - DocumentWithoutSerialization((Document, Option>)), /// An element size DocumentEstimatedAverageSize(u32), } @@ -555,8 +555,8 @@ impl<'a> DocumentInfo<'a> { pub fn get_borrowed_document(&self) -> Option<&Document> { match self { DocumentInfo::DocumentRefAndSerialization((document, _, _)) - | DocumentInfo::DocumentRefWithoutSerialization((document, _)) => Some(document), - DocumentInfo::DocumentWithoutSerialization((document, _)) + | DocumentInfo::DocumentRefInfo((document, _)) => Some(document), + DocumentInfo::DocumentOwnedInfo((document, _)) | DocumentInfo::DocumentAndSerialization((document, _, _)) => Some(document), DocumentInfo::DocumentEstimatedAverageSize(_) => None, } @@ -566,10 +566,8 @@ impl<'a> DocumentInfo<'a> { pub fn id_key_value_info(&self) -> KeyValueInfo { match self { DocumentInfo::DocumentRefAndSerialization((document, _, _)) - | DocumentInfo::DocumentRefWithoutSerialization((document, _)) => { - KeyRefRequest(document.id.as_slice()) - } - DocumentInfo::DocumentWithoutSerialization((document, _)) + | DocumentInfo::DocumentRefInfo((document, _)) => KeyRefRequest(document.id.as_slice()), + DocumentInfo::DocumentOwnedInfo((document, _)) | DocumentInfo::DocumentAndSerialization((document, _, _)) => { KeyRefRequest(document.id.as_slice()) } @@ -617,7 +615,7 @@ impl<'a> DocumentInfo<'a> { ) -> Result, Error> { match self { DocumentInfo::DocumentRefAndSerialization((document, _, _)) - | DocumentInfo::DocumentRefWithoutSerialization((document, _)) => { + | DocumentInfo::DocumentRefInfo((document, _)) => { let raw_value = document.get_raw_for_document_type(key_path, document_type, owner_id)?; match raw_value { @@ -625,7 +623,7 @@ impl<'a> DocumentInfo<'a> { Some(value) => Ok(Some(Key(value))), } } - DocumentInfo::DocumentWithoutSerialization((document, _)) + DocumentInfo::DocumentOwnedInfo((document, _)) | DocumentInfo::DocumentAndSerialization((document, _, _)) => { let raw_value = document.get_raw_for_document_type(key_path, document_type, owner_id)?; @@ -685,10 +683,10 @@ impl<'a> DocumentInfo<'a> { ) -> Option<(&Document, Option<&StorageFlags>)> { match self { DocumentInfo::DocumentRefAndSerialization((document, _, storage_flags)) - | DocumentInfo::DocumentRefWithoutSerialization((document, storage_flags)) => { + | DocumentInfo::DocumentRefInfo((document, storage_flags)) => { Some((document, storage_flags.as_ref().map(|flags| flags.as_ref()))) } - DocumentInfo::DocumentWithoutSerialization((document, storage_flags)) + DocumentInfo::DocumentOwnedInfo((document, storage_flags)) | DocumentInfo::DocumentAndSerialization((document, _, storage_flags)) => { Some((document, storage_flags.as_ref().map(|flags| flags.as_ref()))) } @@ -700,8 +698,8 @@ impl<'a> DocumentInfo<'a> { pub fn get_storage_flags_ref(&self) -> Option<&StorageFlags> { match self { DocumentInfo::DocumentRefAndSerialization((_, _, storage_flags)) - | DocumentInfo::DocumentRefWithoutSerialization((_, storage_flags)) - | DocumentInfo::DocumentWithoutSerialization((_, storage_flags)) + | DocumentInfo::DocumentRefInfo((_, storage_flags)) + | DocumentInfo::DocumentOwnedInfo((_, storage_flags)) | DocumentInfo::DocumentAndSerialization((_, _, storage_flags)) => { storage_flags.as_ref().map(|flags| flags.as_ref()) } @@ -715,10 +713,8 @@ impl<'a> DocumentInfo<'a> { pub fn get_document_id_as_slice(&self) -> Option<&[u8]> { match self { DocumentInfo::DocumentRefAndSerialization((document, _, _)) - | DocumentInfo::DocumentRefWithoutSerialization((document, _)) => { - Some(document.id.as_slice()) - } - DocumentInfo::DocumentWithoutSerialization((document, _)) + | DocumentInfo::DocumentRefInfo((document, _)) => Some(document.id.as_slice()), + DocumentInfo::DocumentOwnedInfo((document, _)) | DocumentInfo::DocumentAndSerialization((document, _, _)) => { Some(document.id.as_slice()) } diff --git a/packages/rs-drive/src/tests/helpers/setup.rs b/packages/rs-drive/src/tests/helpers/setup.rs index 21baa212e91..10ab7ad2a66 100644 --- a/packages/rs-drive/src/tests/helpers/setup.rs +++ b/packages/rs-drive/src/tests/helpers/setup.rs @@ -36,7 +36,7 @@ use crate::drive::config::DriveConfig; use crate::drive::Drive; use dpp::block::block_info::BlockInfo; -use crate::drive::object_size_info::DocumentInfo::DocumentRefWithoutSerialization; +use crate::drive::object_size_info::DocumentInfo::DocumentRefInfo; use crate::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use dpp::data_contract::document_type::DocumentType; use dpp::data_contract::DataContract; @@ -103,7 +103,7 @@ pub fn setup_document( .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((document, None)), + document_info: DocumentRefInfo((document, None)), owner_id: None, }, contract: data_contract, diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index 4ac19b946c2..94567a79da0 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -157,11 +157,7 @@ pub fn add_domains_to_contract( .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &document_cbor, - storage_flags, - )), + document_info: DocumentRefWithoutSerialization((&document, storage_flags)), owner_id: None, }, contract, diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 0458135d29c..742a0fb4375 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -72,8 +72,6 @@ use drive::drive::contract::add_init_contracts_structure_operations; #[cfg(feature = "full")] use drive::drive::flags::StorageFlags; #[cfg(feature = "full")] -use drive::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; -#[cfg(feature = "full")] use drive::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; #[cfg(feature = "full")] use drive::drive::Drive; @@ -105,6 +103,7 @@ use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; #[cfg(feature = "full")] use drive::contract::Contract; use drive::drive::defaults; +use drive::drive::object_size_info::DocumentInfo::DocumentRefInfo; #[cfg(feature = "full")] use drive::drive::query::QuerySerializedDocumentsOutcome; @@ -253,11 +252,7 @@ pub fn setup_family_tests(count: u32, seed: u64) -> (Drive, Contract) { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &document_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -325,11 +320,7 @@ pub fn setup_family_tests_with_nulls(count: u32, seed: u64) -> (Drive, Contract) .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &document_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -398,11 +389,7 @@ pub fn setup_family_tests_only_first_name_index(count: u32, seed: u64) -> (Drive .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &document_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -511,11 +498,7 @@ pub fn add_domains_to_contract( .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &document_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract, @@ -612,11 +595,7 @@ pub fn setup_dpns_test_with_data(path: &str) -> (Drive, Contract) { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &domain, - &domain_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&domain, storage_flags)), owner_id: None, }, contract: &contract, @@ -665,11 +644,7 @@ fn test_query_many() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &document_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -1597,11 +1572,7 @@ fn test_family_basic_queries() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -1647,11 +1618,7 @@ fn test_family_basic_queries() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -3526,11 +3493,7 @@ fn test_dpns_query_start_at_with_null_id() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document0, - &document_cbor0, - storage_flags, - )), + document_info: DocumentRefInfo((&document0, storage_flags)), owner_id: None, }, contract: &contract, @@ -3572,11 +3535,7 @@ fn test_dpns_query_start_at_with_null_id() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document1, - &document_cbor1, - storage_flags, - )), + document_info: DocumentRefInfo((&document1, storage_flags)), owner_id: None, }, contract: &contract, @@ -3730,11 +3689,7 @@ fn test_dpns_query_start_after_with_null_id() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document0, - &document_cbor0, - storage_flags, - )), + document_info: DocumentRefInfo((&document0, storage_flags)), owner_id: None, }, contract: &contract, @@ -3777,11 +3732,7 @@ fn test_dpns_query_start_after_with_null_id() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document1, - &document_cbor1, - storage_flags, - )), + document_info: DocumentRefInfo((&document1, storage_flags)), owner_id: None, }, contract: &contract, @@ -3937,11 +3888,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document0, - &document_cbor0, - storage_flags, - )), + document_info: DocumentRefInfo((&document0, storage_flags)), owner_id: None, }, contract: &contract, @@ -3984,11 +3931,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document1, - &document_cbor1, - storage_flags, - )), + document_info: DocumentRefInfo((&document1, storage_flags)), owner_id: None, }, contract: &contract, diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 68929572a62..1e1c95253af 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -1076,11 +1076,7 @@ fn test_query_historical() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_cbor, - storage_flags, - )), + document_info: DocumentRefWithoutSerialization((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -1127,11 +1123,7 @@ fn test_query_historical() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &person_cbor, - storage_flags, - )), + document_info: DocumentRefWithoutSerialization((&document, storage_flags)), owner_id: None, }, contract: &contract, From a8c0e00926c8389e27639f45edd3d1879bf0ba1f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 13:50:15 +0700 Subject: [PATCH 36/50] tests compiling --- .../drive/batch/drive_op_batch/document.rs | 2 +- packages/rs-drive/src/drive/contract/mod.rs | 6 +- .../rs-drive/src/drive/document/delete.rs | 4 +- .../rs-drive/src/drive/document/update.rs | 129 ++++++++++++------ 4 files changed, 94 insertions(+), 47 deletions(-) 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 7e89c233812..a268da98ad0 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 @@ -419,7 +419,7 @@ impl DriveLowLevelOperationConverter for DocumentOperationType<'_> { let document = Document::from_cbor(serialized_document, None, owner_id)?; let document_info = - DocumentRefSerialization((&document, serialized_document, storage_flags)); + DocumentRefAndSerialization((&document, serialized_document, storage_flags)); let document_type = contract.document_type_for_name(document_type_name)?; diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index adcd4d79706..6fde0955bd8 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -1275,7 +1275,7 @@ mod tests { #[test] fn test_create_reference_contract() { - let (drive, contract, _contract_cbor) = setup_reference_contract(); + let (drive, contract) = setup_reference_contract(); let document_type = contract .document_type_for_name("note") @@ -1397,7 +1397,7 @@ mod tests { #[test] fn should_get_contract_from_global_and_block_cache() { - let (drive, mut contract, _) = setup_reference_contract(); + let (drive, mut contract) = setup_reference_contract(); let transaction = drive.grove.start_transaction(); @@ -1465,7 +1465,7 @@ mod tests { // Merk trees have own cache and depends on does contract node cached or not // we get could get different costs. To avoid of it we fetch contracts without tree caching - let (drive, mut ref_contract, _) = setup_reference_contract(); + let (drive, mut ref_contract) = setup_reference_contract(); /* * Firstly, we create multiple contracts during block processing (in transaction) diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 93da5b60ee6..6778ee0c8ae 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -1403,7 +1403,9 @@ mod tests { fn test_delete_dashpay_documents_no_transaction() { let (drive, dashpay) = setup_dashpay("delete", false); - let document_type = dashpay.document_type_for_name("profile")?; + let document_type = dashpay + .document_type_for_name("profile") + .expect("expected to get profile document type"); let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); let dashpay_profile_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0.json", diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 00e221392da..4d05c1ea487 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -55,7 +55,7 @@ use crate::drive::document::{ }; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentInfo::{ - DocumentOwnedInfo, DocumentRefAndSerialization, + DocumentOwnedInfo, DocumentRefAndSerialization, DocumentRefInfo, }; use dpp::document::Document; @@ -102,7 +102,7 @@ impl Drive { let reserialized_document = document.serialize(document_type)?; - self.update_document_for_contract( + self.update_document_with_serialization_for_contract( &document, reserialized_document.as_slice(), &contract, @@ -187,7 +187,7 @@ impl Drive { ) -> Result { let document = Document::from_cbor(serialized_document, None, owner_id)?; - self.update_document_for_contract( + self.update_document_with_serialization_for_contract( &document, serialized_document, contract, @@ -202,6 +202,45 @@ impl Drive { /// Updates a document and returns the associated fee. pub fn update_document_for_contract( + &self, + document: &Document, + contract: &Contract, + document_type: &DocumentType, + owner_id: Option<[u8; 32]>, + block_info: BlockInfo, + apply: bool, + storage_flags: Option>, + transaction: TransactionArg, + ) -> Result { + let mut drive_operations: Vec = vec![]; + let estimated_costs_only_with_layer_info = if apply { + None::> + } else { + Some(HashMap::new()) + }; + + let document_info = DocumentRefInfo((document, storage_flags)); + + self.update_document_for_contract_apply_and_add_to_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info, + owner_id, + }, + contract, + document_type, + }, + &block_info, + estimated_costs_only_with_layer_info, + transaction, + &mut drive_operations, + )?; + let fees = calculate_fee(None, Some(drive_operations), &block_info.epoch)?; + Ok(fees) + } + + /// Updates a document and returns the associated fee. + pub fn update_document_with_serialization_for_contract( &self, document: &Document, serialized_document: &[u8], @@ -806,10 +845,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( - &alice_profile, - storage_flags, - )), + document_info: DocumentRefInfo((&alice_profile, storage_flags)), owner_id: None, }, contract: &contract, @@ -898,10 +934,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( - &alice_profile, - storage_flags, - )), + document_info: DocumentRefInfo((&alice_profile, storage_flags)), owner_id: None, }, contract: &contract, @@ -1010,10 +1043,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization(( - &alice_profile, - storage_flags, - )), + document_info: DocumentRefInfo((&alice_profile, storage_flags)), owner_id: None, }, contract: &contract, @@ -1299,9 +1329,9 @@ mod tests { drive .update_document_for_contract( - &dashpay_cr_serialized_document, + &dashpay_cr_document, &contract, - "contactRequest", + document_type, Some(random_owner_id), BlockInfo::default(), true, @@ -1311,15 +1341,21 @@ mod tests { .expect_err("expected not to be able to update a non mutable document"); drive - .add_serialized_document_for_contract( - &dashpay_cr_serialized_document, - &contract, - "contactRequest", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo(( + &dashpay_cr_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: Some(random_owner_id), + }, + contract: &contract, + document_type, + }, true, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect_err("expected not to be able to override a non mutable document"); @@ -1343,38 +1379,51 @@ mod tests { Some(&db_transaction), ); - let dashpay_profile_serialized_document = json_document_to_cbor( + let document_type = contract + .document_type_for_name("profile") + .expect("expected to get document type"); + + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let dashpay_profile_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let dashpay_profile_updated_public_message_serialized_document = json_document_to_cbor( + let dashpay_profile_updated_public_message_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0-updated-public-message.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); - let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); drive - .add_serialized_document_for_contract( - &dashpay_profile_serialized_document, - &contract, - "profile", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo(( + &dashpay_profile_document, + StorageFlags::optional_default_as_cow(), + )), + owner_id: None, + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - StorageFlags::optional_default_as_cow(), Some(&db_transaction), ) .expect("expected to insert a document successfully"); drive - .update_serialized_document_for_contract( - &dashpay_profile_updated_public_message_serialized_document, + .update_document_for_contract( + &dashpay_profile_updated_public_message_document, &contract, - "profile", + document_type, Some(random_owner_id), BlockInfo::default(), true, @@ -2139,11 +2188,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - document_cbor.as_slice(), - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract, From baef2d547651ff59c33a6a8e6f0a1dd476e4d36d Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 24 Apr 2023 14:17:58 +0700 Subject: [PATCH 37/50] 41 failing --- .../document_type/document_type.rs | 6 +- .../rs-drive/src/drive/document/delete.rs | 66 +++++++++++-------- .../rs-drive/src/drive/document/insert.rs | 16 ++--- .../rs-drive/tests/deterministic_root_hash.rs | 3 +- .../rs-drive/tests/query_tests_history.rs | 14 ++-- 5 files changed, 58 insertions(+), 47 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 45994c9a934..f0ac228ee83 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 @@ -192,11 +192,11 @@ impl DocumentType { pub fn convert_value_to_document(&self, mut data: Value) -> Result { let mut document = Document { id: data.remove_identifier("$id")?, - owner_id: data.remove_identifier("$owner_id")?, + owner_id: data.remove_identifier("$ownerId")?, properties: Default::default(), revision: data.remove_optional_integer("$revision")?, - created_at: data.remove_optional_integer("$created_at")?, - updated_at: data.remove_optional_integer("$updated_at")?, + created_at: data.remove_optional_integer("$createdAt")?, + updated_at: data.remove_optional_integer("$updatedAt")?, }; data.replace_at_paths( diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 6778ee0c8ae..4c53a2ef5b1 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -816,9 +816,7 @@ mod tests { use crate::drive::document::tests::setup_dashpay; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentAndContractInfo; - use crate::drive::object_size_info::DocumentInfo::{ - DocumentRefAndSerialization, DocumentRefInfo, - }; + use crate::drive::object_size_info::DocumentInfo::DocumentRefInfo; use crate::drive::Drive; use crate::fee::credits::Creditable; use crate::fee::default_costs::EpochCosts; @@ -1472,9 +1470,16 @@ mod tests { Some(&db_transaction), ); - let dashpay_profile_serialized_document = json_document_to_cbor( + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let document_type = contract + .document_type_for_name("profile") + .expect("expected to get profile document type"); + + let dashpay_profile_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); @@ -1484,15 +1489,18 @@ mod tests { random_owner_id, ))); let fee_result = drive - .add_serialized_document_for_contract( - &dashpay_profile_serialized_document, - &contract, - "profile", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo((&dashpay_profile_document, storage_flags)), + owner_id: None, + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - storage_flags, Some(&db_transaction), ) .expect("expected to insert a document successfully"); @@ -1501,8 +1509,8 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - // We added 1679 bytes - assert_eq!(added_bytes, 1679); + // We added 1552 bytes + assert_eq!(added_bytes, 1552); let document_id = bs58::decode("AM47xnyLfTAC9f61ZQPGfMK5Datk2FeYZwgYvcAnzqFY") .into_vec() @@ -1559,9 +1567,16 @@ mod tests { Some(&db_transaction), ); - let dashpay_profile_serialized_document = json_document_to_cbor( + let document_type = contract + .document_type_for_name("profile") + .expect("expected to get profile document type"); + + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + + let dashpay_profile_document = json_document_to_document( "tests/supporting_files/contract/dashpay/profile0.json", - Some(1), + Some(random_owner_id.into()), + document_type, ) .expect("expected to get cbor document"); @@ -1571,15 +1586,18 @@ mod tests { random_owner_id, ))); let fee_result = drive - .add_serialized_document_for_contract( - &dashpay_profile_serialized_document, - &contract, - "profile", - Some(random_owner_id), + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo((&dashpay_profile_document, storage_flags)), + owner_id: None, + }, + contract: &contract, + document_type, + }, false, BlockInfo::default(), true, - storage_flags, Some(&db_transaction), ) .expect("expected to insert a document successfully"); @@ -1659,11 +1677,7 @@ mod tests { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &serialized_document, - storage_flags.clone(), - )), + document_info: DocumentRefInfo((&document, storage_flags.clone())), owner_id: None, }, contract: &contract, diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index b168f0d127d..73174c1b57d 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -1498,11 +1498,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 3244 + storage_fee: 3060 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 2392120, + processing_fee: 2318070, ..Default::default() } ); @@ -1562,11 +1562,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 1425 + storage_fee: 1298 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 1546190, + processing_fee: 1495210, ..Default::default() } ); @@ -1632,8 +1632,8 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - assert_eq!(1425, added_bytes); - assert_eq!(145173660, processing_fee); + assert_eq!(1298, added_bytes); + assert_eq!(145122800, processing_fee); } #[test] @@ -1856,11 +1856,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 1983 + storage_fee: 1716 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 2177870, + processing_fee: 2070470, ..Default::default() } ); diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index 94567a79da0..3ee40d3e5e9 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -68,6 +68,7 @@ use drive::drive::{Drive, RootTree}; #[cfg(feature = "full")] use dpp::block::block_info::BlockInfo; +use drive::drive::object_size_info::DocumentInfo::DocumentRefInfo; #[cfg(feature = "full")] /// Contains the unique ID for a Dash identity. @@ -157,7 +158,7 @@ pub fn add_domains_to_contract( .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&document, storage_flags)), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract, diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 1e1c95253af..41bb9ca7ce6 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -69,8 +69,6 @@ use drive::drive::contract::add_init_contracts_structure_operations; #[cfg(feature = "full")] use drive::drive::flags::StorageFlags; #[cfg(feature = "full")] -use drive::drive::object_size_info::DocumentInfo::DocumentRefAndSerialization; -#[cfg(feature = "full")] use drive::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; #[cfg(feature = "full")] use drive::drive::Drive; @@ -81,6 +79,8 @@ use drive::query::DriveQuery; #[cfg(feature = "full")] use dpp::block::block_info::BlockInfo; +#[cfg(feature = "full")] +use drive::drive::object_size_info::DocumentInfo::DocumentRefInfo; #[cfg(feature = "full")] #[derive(Serialize, Deserialize)] @@ -240,11 +240,7 @@ pub fn setup( .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefAndSerialization(( - &document, - &document_cbor, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -1076,7 +1072,7 @@ fn test_query_historical() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&document, storage_flags)), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, @@ -1123,7 +1119,7 @@ fn test_query_historical() { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefWithoutSerialization((&document, storage_flags)), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract: &contract, From 6b77c9ad4d6f94b262e1167d8214f7ec78571909 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 01:34:38 +0700 Subject: [PATCH 38/50] abci tests passing --- packages/rs-dpp/Cargo.toml | 2 +- .../document_type/document_field.rs | 2 +- packages/rs-drive-abci/src/abci/mimic.rs | 1 + .../src/contracts/reward_shares.rs | 57 ++++++++++++------- .../reward_share_data_triggers/mod.rs | 9 +-- .../rs-drive-abci/src/execution/engine.rs | 1 + .../execution/fee_pools/fee_distribution.rs | 6 +- .../src/identity_credit_withdrawal/mod.rs | 17 +----- packages/rs-drive-abci/src/platform/mod.rs | 1 + packages/rs-drive-abci/src/state/genesis.rs | 3 +- .../src/test/helpers/fee_pools.rs | 7 +-- .../tests/strategy_tests/main.rs | 4 +- packages/rs-drive/Cargo.toml | 2 +- packages/rs-drive/src/common/mod.rs | 5 +- .../src/drive/batch/drive_op_batch/mod.rs | 6 +- .../src/drive/contract/estimation_costs.rs | 3 +- packages/rs-drive/src/drive/contract/mod.rs | 5 +- .../rs-drive/src/drive/document/delete.rs | 19 ++++--- .../rs-drive/src/drive/document/update.rs | 32 +++++------ .../src/drive/system_contracts_cache.rs | 3 + 20 files changed, 94 insertions(+), 91 deletions(-) diff --git a/packages/rs-dpp/Cargo.toml b/packages/rs-dpp/Cargo.toml index a0399a2626d..8f69a04f78f 100644 --- a/packages/rs-dpp/Cargo.toml +++ b/packages/rs-dpp/Cargo.toml @@ -61,6 +61,6 @@ tokio = { version = "1.17", features = ["full"] } pretty_assertions = { version = "1.3.0" } [features] -default = ["fixtures-and-mocks", "cbor"] +default = ["fixtures-and-mocks"] cbor = ["ciborium"] fixtures-and-mocks = ["mockall"] 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 01e37a4906d..73494c110d3 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 @@ -275,7 +275,7 @@ impl DocumentFieldType { Ok(None) } else { let mut value: Vec = vec![0u8; bytes]; - buf.read_exact(&mut value).map_err(|_| { + buf.read_exact(&mut value).map_err(|e| { ProtocolError::DataContractError(DataContractError::CorruptedSerialization( "error reading varint from serialized document", )) diff --git a/packages/rs-drive-abci/src/abci/mimic.rs b/packages/rs-drive-abci/src/abci/mimic.rs index 60ca3f32a4e..90f1d440bff 100644 --- a/packages/rs-drive-abci/src/abci/mimic.rs +++ b/packages/rs-drive-abci/src/abci/mimic.rs @@ -12,6 +12,7 @@ use dashcore::blockdata::transaction::special_transaction::TransactionPayload::A use dashcore::bls_sig_utils::BLSSignature; use dashcore::consensus::Decodable; use dpp::block::block_info::BlockInfo; +use dpp::serialization_traits::PlatformSerializable; use dpp::state_transition::StateTransition; use dpp::util::deserializer::ProtocolVersion; use tenderdash_abci::proto::abci::response_verify_vote_extension::VerifyStatus; diff --git a/packages/rs-drive-abci/src/contracts/reward_shares.rs b/packages/rs-drive-abci/src/contracts/reward_shares.rs index 149cd23a877..ba6d7288113 100644 --- a/packages/rs-drive-abci/src/contracts/reward_shares.rs +++ b/packages/rs-drive-abci/src/contracts/reward_shares.rs @@ -40,14 +40,17 @@ use crate::error::Error; use crate::platform::Platform; use dpp::block::block_info::BlockInfo; +use dpp::platform_value::Value; use drive::contract::Contract; use drive::dpp::document::Document; use drive::dpp::util::cbor_serializer; use drive::drive::flags::StorageFlags; -use drive::drive::query::QuerySerializedDocumentsOutcome; +use drive::drive::query::{QueryDocumentsOutcome, QuerySerializedDocumentsOutcome}; use drive::grovedb::TransactionArg; +use drive::query::{DriveQuery, InternalClauses, WhereClause, WhereOperator}; use serde_json::json; use std::borrow::Cow; +use std::collections::BTreeMap; /// Masternode reward shares contract ID pub const MN_REWARD_SHARES_CONTRACT_ID: [u8; 32] = [ @@ -65,28 +68,42 @@ impl Platform { masternode_owner_id: &Vec, transaction: TransactionArg, ) -> Result, Error> { - let query_json = json!({ - "where": [ - ["$ownerId", "==", bs58::encode(masternode_owner_id).into_string()] - ], - }); + let document_type = self + .drive + .system_contracts + .masternode_rewards + .document_type_for_name(MN_REWARD_SHARES_DOCUMENT_TYPE)?; - let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_json, None) - .expect("expected to serialize to cbor"); + let drive_query = DriveQuery { + contract: &self.drive.system_contracts.masternode_rewards, + document_type, + internal_clauses: InternalClauses { + primary_key_in_clause: None, + primary_key_equal_clause: None, + in_clause: None, + range_clause: None, + equal_clauses: BTreeMap::from([( + "$ownerId".to_string(), + WhereClause { + field: "$ownerId".to_string(), + operator: WhereOperator::Equal, + value: Value::Bytes(masternode_owner_id.clone()), + }, + )]), + }, + offset: 0, + limit: 1, + order_by: Default::default(), + start_at: None, + start_at_included: false, + block_time: None, + }; - let QuerySerializedDocumentsOutcome { items, .. } = - self.drive.query_documents_cbor_with_document_type_lookup( - &query_cbor, - MN_REWARD_SHARES_CONTRACT_ID, - MN_REWARD_SHARES_DOCUMENT_TYPE, - None, - transaction, - )?; + let QueryDocumentsOutcome { documents, .. } = + self.drive + .query_documents(drive_query, None, false, transaction)?; - items - .iter() - .map(|cbor| Document::from_cbor(cbor, None, None).map_err(Error::Protocol)) - .collect::, Error>>() + Ok(documents) } /// A function to create and apply the masternode reward shares contract. diff --git a/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs index 5334934a67c..fd7626cdb17 100644 --- a/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/data_trigger/reward_share_data_triggers/mod.rs @@ -192,9 +192,7 @@ mod test { use dpp::tests::utils::generate_random_identifier_struct; use dpp::DataTriggerActionError; - use drive::drive::object_size_info::DocumentInfo::{ - DocumentRefInfo, DocumentOwnedInfo, - }; + use drive::drive::object_size_info::DocumentInfo::{DocumentOwnedInfo, DocumentRefInfo}; use drive::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use std::net::SocketAddr; use std::str::FromStr; @@ -350,10 +348,7 @@ mod test { .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefInfo(( - &document.document, - None, - )), + document_info: DocumentRefInfo((&document.document, None)), owner_id: None, }, contract: &document.data_contract, diff --git a/packages/rs-drive-abci/src/execution/engine.rs b/packages/rs-drive-abci/src/execution/engine.rs index bf7a2e7d7ae..138c8708deb 100644 --- a/packages/rs-drive-abci/src/execution/engine.rs +++ b/packages/rs-drive-abci/src/execution/engine.rs @@ -16,6 +16,7 @@ use drive::fee::result::FeeResult; use drive::grovedb::{Transaction, TransactionArg}; use std::collections::BTreeMap; +use dpp::serialization_traits::{PlatformDeserializable, PlatformSerializable}; use tenderdash_abci::proto::abci::{ExecTxResult, ValidatorSetUpdate}; use tenderdash_abci::proto::serializers::timestamp::ToMilis; 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 627a1aab7eb..64492201cab 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 @@ -114,11 +114,9 @@ impl Platform { Some(transaction), )?; - if unpaid_epoch.is_none() { + let Some(unpaid_epoch) = unpaid_epoch else { return Ok(None); - } - - let unpaid_epoch = unpaid_epoch.unwrap(); + }; // Process more proposers at once if we have many unpaid epochs in past let proposers_limit: u16 = (current_epoch_index - unpaid_epoch.epoch_index) * 50; 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 ac77178f80d..4fa4a2432bf 100644 --- a/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/identity_credit_withdrawal/mod.rs @@ -501,7 +501,7 @@ where let state_transition_size = 190; - let output_script: Script = Script::from(output_script_bytes); + let output_script: Script = Script(output_script_bytes.into()); let tx_out = TxOut { value: convert_credits_to_satoshi(amount), @@ -1070,20 +1070,7 @@ mod tests { Some(&transaction), ); - let documents = vec![ - Document::from_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_cbor().expect("to convert document to cbor"), - None, - None, - ) - .expect("to create document from cbor"), - ]; + let documents = vec![document_1, document_2]; let mut batch = vec![]; diff --git a/packages/rs-drive-abci/src/platform/mod.rs b/packages/rs-drive-abci/src/platform/mod.rs index 966b811bcf3..3c363194ba9 100644 --- a/packages/rs-drive-abci/src/platform/mod.rs +++ b/packages/rs-drive-abci/src/platform/mod.rs @@ -48,6 +48,7 @@ use dashcore::hashes::Hash; use dashcore::{BlockHash, QuorumHash}; use dpp::block::block_info::BlockInfo; +use dpp::serialization_traits::PlatformDeserializable; use drive::error::drive::DriveError; use drive::error::Error::GroveDB; use serde_json::json; diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index a4c075045f6..b7967b2e55a 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -40,6 +40,7 @@ use drive::dpp::identity::{ }; use dpp::block::block_info::BlockInfo; +use dpp::serialization_traits::PlatformSerializable; use drive::dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use drive::drive::batch::{ ContractOperationType, DocumentOperationType, DriveOperation, IdentityOperationType, @@ -169,7 +170,7 @@ impl Platform { data_contract: DataContract, operations: &mut Vec, ) { - let serialization = data_contract.to_cbor().unwrap(); + let serialization = data_contract.serialize().unwrap(); operations.push(DriveOperation::ContractOperation( //todo: remove cbor ContractOperationType::ApplyContractWithSerialization { 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 6426c11d369..9e856d8d826 100644 --- a/packages/rs-drive-abci/src/test/helpers/fee_pools.rs +++ b/packages/rs-drive-abci/src/test/helpers/fee_pools.rs @@ -47,9 +47,9 @@ use drive::common::helpers::identities::create_test_identity_with_rng; use drive::contract::Contract; use drive::dpp::document::Document; use drive::drive::flags::StorageFlags; +use drive::drive::object_size_info::DocumentInfo::DocumentRefInfo; use drive::drive::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use drive::drive::Drive; -use drive::drive::object_size_info::DocumentInfo::DocumentRefInfo; use drive::grovedb::TransactionArg; use crate::contracts::reward_shares::MN_REWARD_SHARES_DOCUMENT_TYPE; @@ -92,10 +92,7 @@ fn create_test_mn_share_document( .add_document_for_contract( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { - document_info: DocumentRefInfo(( - &document, - storage_flags, - )), + document_info: DocumentRefInfo((&document, storage_flags)), owner_id: None, }, contract, diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 72de61f0e69..1feecab4974 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -95,6 +95,7 @@ use drive_abci::abci::AbciApplication; use drive_abci::execution::fee_pools::epoch::{EpochInfo, EPOCH_CHANGE_TIME_MS}; use dashcore_rpc::json::{MasternodeListDiff, RemovedMasternodeItem}; +use dpp::serialization_traits::PlatformSerializable; use drive_abci::abci::mimic::MimicExecuteBlockOutcome; use drive_abci::execution::test_quorum::TestQuorumInfo; use drive_abci::platform::Platform; @@ -357,7 +358,7 @@ impl Strategy { for op in &self.operations { match &op.op_type { OperationType::Document(doc_op) => { - let serialize = doc_op.contract.to_cbor().expect("expected to serialize"); + let serialize = doc_op.contract.serialize().expect("expected to serialize"); drive .apply_contract_with_serialization( &doc_op.contract, @@ -1666,7 +1667,6 @@ mod tests { Bip9SoftforkInfo, Bip9SoftforkStatus, ExtendedQuorumDetails, }; use dpp::data_contract::extra::common::json_document_to_contract; - use drive::dpp::data_contract::extra::common::json_document_to_cbor; use drive_abci::config::PlatformTestConfig; use drive_abci::rpc::core::QuorumListExtendedInfo; use tenderdash_abci::proto::types::CoreChainLock; diff --git a/packages/rs-drive/Cargo.toml b/packages/rs-drive/Cargo.toml index 90dedaad1ca..40bc6df39ec 100644 --- a/packages/rs-drive/Cargo.toml +++ b/packages/rs-drive/Cargo.toml @@ -18,7 +18,7 @@ sqlparser = { version = "0.13.0" } thiserror = { version = "1.0.30" } moka = { version = "0.10.1", features = ["future", "futures-util"]} nohash-hasher = { version = "0.2.0" } -dpp = { path = "../rs-dpp", features = ["fixtures-and-mocks"] } +dpp = { path = "../rs-dpp", features = ["fixtures-and-mocks", "cbor"] } bincode = { version="2.0.0-rc.3", features=["serde"] } # optional dependencies diff --git a/packages/rs-drive/src/common/mod.rs b/packages/rs-drive/src/common/mod.rs index 927a3f2b1a7..fe67d066aef 100644 --- a/packages/rs-drive/src/common/mod.rs +++ b/packages/rs-drive/src/common/mod.rs @@ -60,9 +60,6 @@ use crate::contract::Contract; #[cfg(feature = "full")] use crate::drive::Drive; -#[cfg(feature = "full")] -use dpp::data_contract::extra::common::json_document_to_cbor; - #[cfg(feature = "full")] use dpp::block::block_info::BlockInfo; use dpp::data_contract::extra::common::json_document_to_contract_with_ids; @@ -88,7 +85,7 @@ pub fn setup_contract( #[cfg(feature = "full")] /// Serializes to CBOR and applies to Drive a contract from hex string format. -pub fn setup_contract_from_hex( +pub fn setup_contract_from_cbor_hex( drive: &Drive, hex_string: String, transaction: TransactionArg, 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 66af66a5c63..288e18a92e6 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 @@ -389,7 +389,7 @@ mod tests { document_and_contract_info: DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { document_info: DocumentRefInfo((&dashpay_cr_document, None)), - owner_id: Some(random_owner_id), + owner_id: None, }, contract: &contract, document_type: &contract @@ -399,6 +399,8 @@ mod tests { override_document: false, })); + let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); + let dashpay_cr_1_document = json_document_to_document( "tests/supporting_files/contract/dashpay/contact-request1.json", Some(random_owner_id.into()), @@ -410,7 +412,7 @@ mod tests { document_and_contract_info: DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { document_info: DocumentRefInfo((&dashpay_cr_1_document, None)), - owner_id: Some(random_owner_id), + owner_id: None, }, contract: &contract, document_type: &contract diff --git a/packages/rs-drive/src/drive/contract/estimation_costs.rs b/packages/rs-drive/src/drive/contract/estimation_costs.rs index d3156dc95ad..f3bdebad9f5 100644 --- a/packages/rs-drive/src/drive/contract/estimation_costs.rs +++ b/packages/rs-drive/src/drive/contract/estimation_costs.rs @@ -8,6 +8,7 @@ use crate::drive::flags::StorageFlags; use crate::drive::Drive; use dpp::data_contract::DataContract; +use dpp::serialization_traits::PlatformSerializable; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel}; use grovedb::EstimatedLayerInformation; @@ -69,7 +70,7 @@ impl Drive { subtrees_size: None, items_size: Some(( DEFAULT_FLOAT_SIZE_U8, - contract.to_cbor().unwrap().len() as u32, //todo: fix this + contract.serialize().unwrap().len() as u32, //todo: fix this storage_flags, AVERAGE_NUMBER_OF_UPDATES, )), diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index 6fde0955bd8..fb952376b25 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -1008,8 +1008,7 @@ impl Drive { storage_flags: Option>, transaction: TransactionArg, ) -> Result, Error> { - //todo: change this from cbor - let serialized_contract = contract.to_cbor().map_err(Error::Protocol)?; + let serialized_contract = contract.serialize().map_err(Error::Protocol)?; self.apply_contract_with_serialization_operations( contract, serialized_contract, @@ -1080,7 +1079,7 @@ impl Drive { if already_exists { if !original_contract_stored_data.is_empty() { - let original_contract = Contract::from_cbor(&original_contract_stored_data)?; + let original_contract = Contract::deserialize(&original_contract_stored_data)?; // if the contract is not mutable update_contract will return an error self.update_contract_add_operations( contract_element, diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 4c53a2ef5b1..28a1536693e 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -812,7 +812,7 @@ mod tests { use tempfile::TempDir; use super::*; - use crate::common::{cbor_from_hex, setup_contract, setup_contract_from_hex}; + use crate::common::{cbor_from_hex, setup_contract, setup_contract_from_cbor_hex}; use crate::drive::document::tests::setup_dashpay; use crate::drive::flags::StorageFlags; use crate::drive::object_size_info::DocumentAndContractInfo; @@ -1606,8 +1606,8 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - // We added 1682 bytes - assert_eq!(added_bytes, 1679); + // We added 1552 bytes + assert_eq!(added_bytes, 1552); let document_id = bs58::decode("AM47xnyLfTAC9f61ZQPGfMK5Datk2FeYZwgYvcAnzqFY") .into_vec() @@ -1645,7 +1645,7 @@ mod tests { .create_initial_state_structure(Some(&db_transaction)) .expect("expected to create root tree successfully"); - let contract = setup_contract_from_hex( + let contract = setup_contract_from_cbor_hex( &drive, "01a5632469645820e8f72680f2e3910c95e1497a2b0029d9f7374891ac1f39ab1cfe3ae63336b9a96724736368656d61783468747470733a2f2f736368656d612e646173682e6f72672f6470702d302d342d302f6d6574612f646174612d636f6e7472616374676f776e6572496458209e412570bf3b7ce068b9bce81c569ce701e43edaea80b62a2773be7d21038b266776657273696f6e0169646f63756d656e7473a76b756e697175654461746573a56474797065666f626a65637467696e646963657382a3646e616d6566696e6465783166756e69717565f56a70726f7065727469657382a16a2463726561746564417463617363a16a2475706461746564417463617363a2646e616d6566696e646578326a70726f7065727469657381a16a2475706461746564417463617363687265717569726564836966697273744e616d656a246372656174656441746a247570646174656441746a70726f70657274696573a2686c6173744e616d65a1647479706566737472696e676966697273744e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f46c6e696365446f63756d656e74a56474797065666f626a65637467696e646963657384a2646e616d6566696e646578316a70726f7065727469657381a1646e616d6563617363a2646e616d6566696e646578336a70726f7065727469657381a1656f7264657263617363a2646e616d6566696e646578346a70726f7065727469657381a1686c6173744e616d6563617363a2646e616d6567696e64657831306a70726f7065727469657381a168246f776e657249646464657363687265717569726564816a246372656174656441746a70726f70657274696573a3646e616d65a1647479706566737472696e67656f72646572a16474797065666e756d626572686c6173744e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f46e6e6f54696d65446f63756d656e74a36474797065666f626a6563746a70726f70657274696573a1646e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f46e707265747479446f63756d656e74a46474797065666f626a65637468726571756972656482686c6173744e616d656a247570646174656441746a70726f70657274696573a1686c6173744e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f46e7769746842797465417272617973a56474797065666f626a65637467696e646963657381a2646e616d6566696e646578316a70726f7065727469657381a16e6279746541727261794669656c6463617363687265717569726564816e6279746541727261794669656c646a70726f70657274696573a26e6279746541727261794669656c64a36474797065656172726179686d61784974656d731069627974654172726179f56f6964656e7469666965724669656c64a56474797065656172726179686d61784974656d731820686d696e4974656d73182069627974654172726179f570636f6e74656e744d656469615479706578216170706c69636174696f6e2f782e646173682e6470702e6964656e746966696572746164646974696f6e616c50726f70657274696573f46f696e6465786564446f63756d656e74a56474797065666f626a65637467696e646963657386a3646e616d6566696e6465783166756e69717565f56a70726f7065727469657382a168246f776e6572496463617363a16966697273744e616d656464657363a3646e616d6566696e6465783266756e69717565f56a70726f7065727469657382a168246f776e6572496463617363a1686c6173744e616d656464657363a2646e616d6566696e646578336a70726f7065727469657381a1686c6173744e616d6563617363a2646e616d6566696e646578346a70726f7065727469657382a16a2463726561746564417463617363a16a2475706461746564417463617363a2646e616d6566696e646578356a70726f7065727469657381a16a2475706461746564417463617363a2646e616d6566696e646578366a70726f7065727469657381a16a2463726561746564417463617363687265717569726564846966697273744e616d656a246372656174656441746a24757064617465644174686c6173744e616d656a70726f70657274696573a2686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f6966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f746164646974696f6e616c50726f70657274696573f4781d6f7074696f6e616c556e69717565496e6465786564446f63756d656e74a56474797065666f626a65637467696e646963657383a3646e616d6566696e6465783166756e69717565f56a70726f7065727469657381a16966697273744e616d656464657363a3646e616d6566696e6465783266756e69717565f56a70726f7065727469657383a168246f776e6572496463617363a16966697273744e616d6563617363a1686c6173744e616d6563617363a3646e616d6566696e6465783366756e69717565f56a70726f7065727469657382a167636f756e74727963617363a1646369747963617363687265717569726564826966697273744e616d65686c6173744e616d656a70726f70657274696573a46463697479a2647479706566737472696e67696d61784c656e677468183f67636f756e747279a2647479706566737472696e67696d61784c656e677468183f686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f6966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f746164646974696f6e616c50726f70657274696573f4".to_string(), Some(&db_transaction), @@ -1661,17 +1661,20 @@ mod tests { let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); + let document_type = contract + .document_type_for_name("niceDocument") + .expect("expected to get a document type"); + let documents: Vec = document_hexes .iter() .map(|document_hex| { let serialized_document = cbor_from_hex(document_hex.to_string()); - let document = Document::from_cbor(&serialized_document, None, None) + let mut document = Document::from_cbor(&serialized_document, None, None) .expect("expected to deserialize the document"); - let document_type = contract - .document_type_for_name("niceDocument") - .expect("expected to get a document type"); + // Not sure why original documents were missing created at + document.created_at = Some(5); drive .add_document_for_contract( diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 4d05c1ea487..d854eba11bb 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -1503,14 +1503,14 @@ mod tests { //Explanation for 1290 //todo - 1287 + 1233 } else { //Explanation for 1014 // Document Storage //// Item - // = 412 Bytes + // = 358 Bytes // Explanation for 412 storage_written_bytes @@ -1525,7 +1525,7 @@ mod tests { // 35 for flags 32 + 1 + 2 // 1 for the enum type // 1 for item - // 170 for item serialized bytes + // 116 for item serialized bytes // 1 for Basic Merk // 32 for node hash // 32 for value hash @@ -1636,7 +1636,7 @@ mod tests { // Total 65 + 145 + 68 = 275 - 1011 + 957 }; assert_eq!(original_bytes, expected_added_bytes); @@ -1771,7 +1771,7 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1287 } else { 1011 }; + let expected_added_bytes = if using_history { 1233 } else { 957 }; assert_eq!(original_bytes, expected_added_bytes); if !using_history { // let's delete it, just to make sure everything is working. @@ -1963,32 +1963,32 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); let expected_added_bytes = if using_history { - //Explanation for 1290 + //Explanation for 1233 //todo - 1287 + 1233 } else { - //Explanation for 1114 + //Explanation for 957 // Document Storage //// Item - // = 409 Bytes + // = 355 Bytes - // Explanation for 409 storage_written_bytes + // Explanation for 355 storage_written_bytes // Key -> 65 bytes // 32 bytes for the key prefix // 32 bytes for the unique id // 1 byte for key_size (required space for 64) - // Value -> 276 + // Value -> 222 // 1 for the flag option with flags // 1 for the flags size // 35 for flags 32 + 1 + 2 // 1 for the enum type // 1 for item - // 170 for item serialized bytes + // 116 for item serialized bytes // 1 for Basic Merk // 32 for node hash // 32 for value hash @@ -2001,7 +2001,7 @@ mod tests { // Child Heights 2 // Feature Type Basic 1 - // Total 65 + 279 + 68 = 412 + // Total 65 + 222 + 68 = 355 //// Tree 1 / / 1 / person / message // Key: My apples are safe @@ -2099,9 +2099,9 @@ mod tests { // Total 65 + 145 + 68 = 278 - // 409 + 179 + 145 + 278 = 1011 + // 355 + 179 + 145 + 278 = 957 - 1011 + 957 }; assert_eq!(original_bytes, expected_added_bytes); @@ -2121,7 +2121,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1288 } else { 1012 }; + let expected_added_bytes = if using_history { 1234 } else { 958 }; assert_eq!(added_bytes, expected_added_bytes); } diff --git a/packages/rs-drive/src/drive/system_contracts_cache.rs b/packages/rs-drive/src/drive/system_contracts_cache.rs index a47892a3ac5..a6da99f59ef 100644 --- a/packages/rs-drive/src/drive/system_contracts_cache.rs +++ b/packages/rs-drive/src/drive/system_contracts_cache.rs @@ -5,12 +5,15 @@ use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; pub struct SystemContracts { /// Withdrawal contract pub withdrawal_contract: DataContract, + /// Masternode reward shares contract + pub masternode_rewards: DataContract, } impl SystemContracts { pub fn load_system_contracts() -> Result { Ok(SystemContracts { withdrawal_contract: load_system_data_contract(SystemDataContract::Withdrawals)?, + masternode_rewards: load_system_data_contract(SystemDataContract::MasternodeRewards)?, }) } } From e5d4a6f45bf31a18fc0074f7cbd259aa00d55835 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 05:24:43 +0700 Subject: [PATCH 39/50] more fixes --- .../document_type/document_type.rs | 4 +++ packages/rs-dpp/src/document/serialize.rs | 18 ++++++++--- packages/rs-drive/src/drive/contract/mod.rs | 3 +- .../rs-drive/src/drive/document/delete.rs | 32 ++++++++++++++++++- .../rs-drive/src/drive/document/insert.rs | 12 +++---- .../rs-drive/src/drive/document/update.rs | 24 +++++++------- .../contract/family/person0.json | 1 + 7 files changed, 69 insertions(+), 25 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 f0ac228ee83..a94fb4da74e 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 @@ -395,6 +395,10 @@ impl DocumentType { } } + pub fn requires_revision(&self) -> bool { + self.documents_mutable + } + pub(crate) fn find_identifier_and_binary_paths( properties: &BTreeMap, ) -> (BTreeSet, BTreeSet) { diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index f9ec0cbe9c2..e344569b1f2 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -16,7 +16,7 @@ use crate::ProtocolError; use byteorder::{BigEndian, ReadBytesExt}; #[cfg(feature = "cbor")] use ciborium::Value as CborValue; -use integer_encoding::VarIntWriter; +use integer_encoding::{VarInt, VarIntReader, VarIntWriter}; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; @@ -83,7 +83,9 @@ impl Document { 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()) + buffer.extend(revision.encode_var_vec()) + } else if document_type.requires_revision() { + buffer.extend((1 as Revision).encode_var_vec()) } document_type .properties @@ -91,6 +93,7 @@ impl Document { .try_for_each(|(field_name, field)| { if field_name == CREATED_AT { if let Some(created_at) = self.created_at { + // dbg!("we pushed created at {}", hex::encode(created_at.to_be_bytes())); buffer.extend(created_at.to_be_bytes()); Ok(()) } else if field.required { @@ -100,21 +103,24 @@ impl Document { ), )) } else { + // dbg!("we pushed created at with 0"); // 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 { + // dbg!("we pushed updated at {}", hex::encode(updated_at.to_be_bytes())); buffer.extend(updated_at.to_be_bytes()); Ok(()) } else if field.required { Err(ProtocolError::DataContractError( DataContractError::MissingRequiredKey( - "created at field is not present", + "updated at field is not present", ), )) } else { + // dbg!("we pushed updated at with 0"); // We don't have the updated_at that wasn't required buffer.push(0); Ok(()) @@ -123,6 +129,7 @@ impl Document { let value = field .document_type .encode_value_ref_with_size(value, field.required)?; + // dbg!("we pushed {} with {}", field_name, hex::encode(&value)); buffer.extend(value.as_slice()); Ok(()) } else if field.required { @@ -130,6 +137,7 @@ impl Document { DataContractError::MissingRequiredKey("a required field is not present"), )) } else { + // dbg!("we pushed {} with 0", field_name); // We don't have something that wasn't required buffer.push(0); Ok(()) @@ -234,8 +242,8 @@ impl Document { })?; // if the document type is mutable then we should deserialize the revision - let revision: Option = if document_type.documents_mutable { - let revision = buf.read_u64::().map_err(|_| { + let revision: Option = if document_type.requires_revision() { + let revision = buf.read_varint().map_err(|_| { ProtocolError::DecodingError( "error reading revision from serialized document for revision".to_string(), ) diff --git a/packages/rs-drive/src/drive/contract/mod.rs b/packages/rs-drive/src/drive/contract/mod.rs index fb952376b25..8550da4ee18 100644 --- a/packages/rs-drive/src/drive/contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/mod.rs @@ -900,7 +900,8 @@ impl Drive { Ok(Element::Item(stored_contract_bytes, element_flag)) => { let contract = cost_return_on_error_no_add!( &cost, - DataContract::deserialize(&stored_contract_bytes).map_err(Error::Protocol) + DataContract::deserialize_no_limit(&stored_contract_bytes) + .map_err(Error::Protocol) ); let drive_operation = CalculatedCostOperation(cost.clone()); let fee = if let Some(epoch) = epoch { diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 28a1536693e..b796086c89a 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -804,7 +804,9 @@ impl Drive { #[cfg(feature = "full")] #[cfg(test)] mod tests { - use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_document}; + use dpp::data_contract::extra::common::{ + json_document_to_cbor, json_document_to_contract, json_document_to_document, + }; use rand::Rng; use serde_json::json; use std::borrow::Cow; @@ -1022,6 +1024,34 @@ mod tests { assert_eq!(results_on_transaction.len(), 0); } + #[test] + fn serialize_deserialize_document() { + let contract = json_document_to_contract( + "tests/supporting_files/contract/family/family-contract-reduced.json", + ) + .expect("expected to get cbor contract"); + + let document_type = contract + .document_type_for_name("person") + .expect("expected to get a document type"); + + let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); + + let person_document0 = json_document_to_document( + "tests/supporting_files/contract/family/person0.json", + Some(random_owner_id0.into()), + document_type, + ) + .expect("expected to get document"); + + let serialized = person_document0 + .serialize(&document_type) + .expect("expected to serialize"); + + let deserialized = + Document::from_bytes(&serialized, &document_type).expect("expected to deserialize"); + } + #[test] fn test_add_and_remove_family_documents() { let tmp_dir = TempDir::new().unwrap(); diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 73174c1b57d..3a10d7a1bdc 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -1562,11 +1562,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 1298 + storage_fee: 1299 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 1495210, + processing_fee: 1495610, ..Default::default() } ); @@ -1632,8 +1632,8 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - assert_eq!(1298, added_bytes); - assert_eq!(145122800, processing_fee); + assert_eq!(1299, added_bytes); + assert_eq!(145123200, processing_fee); } #[test] @@ -1856,11 +1856,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 1716 + storage_fee: 1717 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 2070470, + processing_fee: 2070870, ..Default::default() } ); diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index d854eba11bb..b1ac8ca67ce 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -1500,10 +1500,10 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); let expected_added_bytes = if using_history { - //Explanation for 1290 + //Explanation for 1234 //todo - 1233 + 1234 } else { //Explanation for 1014 @@ -1636,7 +1636,7 @@ mod tests { // Total 65 + 145 + 68 = 275 - 957 + 958 }; assert_eq!(original_bytes, expected_added_bytes); @@ -1658,14 +1658,14 @@ mod tests { .get(&0) .unwrap(); - assert_eq!(*removed_credits, 27228298); + assert_eq!(*removed_credits, 25800855); let refund_equivalent_bytes = removed_credits.to_unsigned() / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); assert!(expected_added_bytes > refund_equivalent_bytes); - assert_eq!(refund_equivalent_bytes, 1008); // we refunded 1008 instead of 1011 + assert_eq!(refund_equivalent_bytes, 955); // we refunded 1008 instead of 1011 // let's re-add it again let original_fees = apply_person( @@ -1701,7 +1701,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 362 } else { 1 }; + let expected_added_bytes = if using_history { 309 } else { 1 }; assert_eq!(added_bytes, expected_added_bytes); } @@ -1771,7 +1771,7 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1233 } else { 957 }; + let expected_added_bytes = if using_history { 1234 } else { 958 }; assert_eq!(original_bytes, expected_added_bytes); if !using_history { // let's delete it, just to make sure everything is working. @@ -1790,14 +1790,14 @@ mod tests { .get(&0) .unwrap(); - assert_eq!(*removed_credits, 27228298); + assert_eq!(*removed_credits, 25800855); let refund_equivalent_bytes = removed_credits.to_unsigned() / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); assert!(expected_added_bytes > refund_equivalent_bytes); - assert_eq!(refund_equivalent_bytes, 1008); // we refunded 1008 instead of 1011 + assert_eq!(refund_equivalent_bytes, 955); // we refunded 1008 instead of 1011 // let's re-add it again let original_fees = apply_person( @@ -1966,7 +1966,7 @@ mod tests { //Explanation for 1233 //todo - 1233 + 1234 } else { //Explanation for 957 @@ -2101,7 +2101,7 @@ mod tests { // 355 + 179 + 145 + 278 = 957 - 957 + 958 }; assert_eq!(original_bytes, expected_added_bytes); @@ -2121,7 +2121,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1234 } else { 958 }; + let expected_added_bytes = if using_history { 1235 } else { 959 }; assert_eq!(added_bytes, expected_added_bytes); } diff --git a/packages/rs-drive/tests/supporting_files/contract/family/person0.json b/packages/rs-drive/tests/supporting_files/contract/family/person0.json index 88739b52f24..c646b217906 100644 --- a/packages/rs-drive/tests/supporting_files/contract/family/person0.json +++ b/packages/rs-drive/tests/supporting_files/contract/family/person0.json @@ -3,6 +3,7 @@ "$dataContractId": "94zNLp7A1ZcYG3Egqf2YmQk4DQr9P8D543GwXyCJRz4", "$id": "AYjYxDqLy2hvGQADqE6FAkBnQEpJSzNd3CRw1tpS6vZ7", "$type": "person", + "$revision": 1, "firstName": "Samuel", "middleName": "Abraham", "lastName": "Westrich", From ff69e6e5d38fe3b2241a9959b445002bfbc9769b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 05:40:43 +0700 Subject: [PATCH 40/50] fixes for tests --- .../src/drive/batch/drive_op_batch/mod.rs | 35 +++++++++++++++++-- packages/rs-drive/src/drive/config.rs | 4 --- .../rs-drive/src/drive/document/delete.rs | 12 +++---- .../rs-drive/src/drive/document/insert.rs | 9 +++-- .../rs-drive/src/drive/document/update.rs | 8 ++--- packages/rs-drive/tests/query_tests.rs | 2 +- 6 files changed, 45 insertions(+), 25 deletions(-) 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 288e18a92e6..eee67b0ed75 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 @@ -352,9 +352,16 @@ mod tests { } #[test] - fn test_add_multiple_dashpay_documents_individually_should_fail() { + fn test_add_multiple_dashpay_documents_individually_should_succeed() { let tmp_dir = TempDir::new().unwrap(); - let drive: Drive = Drive::open(tmp_dir, None).expect("expected to open Drive successfully"); + let drive: Drive = Drive::open( + tmp_dir, + Some(DriveConfig { + batching_consistency_verification: true, + ..Default::default() + }), + ) + .expect("expected to open Drive successfully"); let mut drive_operations = vec![]; let db_transaction = drive.grove.start_transaction(); @@ -429,7 +436,29 @@ mod tests { &BlockInfo::default(), Some(&db_transaction), ) - .expect_err("expected to not be able to insert documents"); + .expect("expected to be able to insert documents"); + + let query_value = json!({ + "where": [ + ], + "limit": 100, + "orderBy": [ + ["$ownerId", "asc"], + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let (docs, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + document_type, + where_cbor.as_slice(), + None, + Some(&db_transaction), + ) + .expect("expected to query"); + assert_eq!(docs.len(), 2); } #[test] diff --git a/packages/rs-drive/src/drive/config.rs b/packages/rs-drive/src/drive/config.rs index df8585af390..1ce44c1f926 100644 --- a/packages/rs-drive/src/drive/config.rs +++ b/packages/rs-drive/src/drive/config.rs @@ -62,9 +62,6 @@ pub struct DriveConfig { /// Default genesis time pub default_genesis_time: Option, - /// Encoding - pub encoding: DriveEncoding, - /// Maximum number of contracts in global cache pub data_contracts_global_cache_size: u64, @@ -79,7 +76,6 @@ impl Default for DriveConfig { DEFAULT_GROVE_BATCHING_CONSISTENCY_VERIFICATION_ENABLED, has_raw_enabled: DEFAULT_GROVE_HAS_RAW_ENABLED, default_genesis_time: None, - encoding: DriveCbor, data_contracts_global_cache_size: DEFAULT_DATA_CONTRACTS_CACHE_SIZE, data_contracts_block_cache_size: DEFAULT_DATA_CONTRACTS_CACHE_SIZE, } diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index b796086c89a..72b049790db 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -1539,8 +1539,8 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - // We added 1552 bytes - assert_eq!(added_bytes, 1552); + // We added 1553 bytes + assert_eq!(added_bytes, 1553); let document_id = bs58::decode("AM47xnyLfTAC9f61ZQPGfMK5Datk2FeYZwgYvcAnzqFY") .into_vec() @@ -1569,14 +1569,14 @@ mod tests { .get(&0) .unwrap(); - assert_eq!(*removed_credits, 44879092); + assert_eq!(*removed_credits, 41511232); let refund_equivalent_bytes = removed_credits.to_unsigned() / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); assert!(added_bytes > refund_equivalent_bytes); - assert_eq!(refund_equivalent_bytes, 1662); // we refunded 1662 instead of 1679 + assert_eq!(refund_equivalent_bytes, 1537); // we refunded 1537 instead of 1553 } #[test] @@ -1636,8 +1636,8 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - // We added 1552 bytes - assert_eq!(added_bytes, 1552); + // We added 1553 bytes + assert_eq!(added_bytes, 1553); let document_id = bs58::decode("AM47xnyLfTAC9f61ZQPGfMK5Datk2FeYZwgYvcAnzqFY") .into_vec() diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 3a10d7a1bdc..0f7031ba283 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -476,7 +476,7 @@ impl Drive { } /// Deserializes a document and a contract and adds the document to the contract. - pub fn add_serialized_document_for_serialized_contract( + pub fn add_cbor_serialized_document_for_serialized_contract( &self, serialized_document: &[u8], serialized_contract: &[u8], @@ -492,8 +492,7 @@ impl Drive { let document = Document::from_cbor(serialized_document, None, owner_id)?; - let document_info = - DocumentRefAndSerialization((&document, serialized_document, storage_flags)); + let document_info = DocumentRefInfo((&document, storage_flags)); let document_type = contract.document_type_for_name(document_type_name)?; @@ -2060,7 +2059,7 @@ mod tests { let dash_tld_cbor = hex::decode("01ac632469645820d7f2c53f46a917ab6e5b39a2d7bc260b649289453744d1e0d4f26a8d8eff37cf65247479706566646f6d61696e656c6162656c6464617368677265636f726473a17364617368416c6961734964656e74697479496458203012c19b98ec0033addb36cd64b7f510670f2a351a4304b5f6994144286efdac68246f776e6572496458203012c19b98ec0033addb36cd64b7f510670f2a351a4304b5f6994144286efdac69247265766973696f6e016a246372656174656441741b0000017f07c861586c7072656f7264657253616c745820e0b508c5a36825a206693a1f414aa13edbecf43c41e3c799ea9e737b4f9aa2266e737562646f6d61696e52756c6573a16f616c6c6f77537562646f6d61696e73f56f2464617461436f6e747261637449645820e668c659af66aee1e72c186dde7b5b7e0a1d712a09c40d5721f622bf53c531556f6e6f726d616c697a65644c6162656c6464617368781a6e6f726d616c697a6564506172656e74446f6d61696e4e616d6560").unwrap(); drive - .add_serialized_document_for_serialized_contract( + .add_cbor_serialized_document_for_serialized_contract( dash_tld_cbor.as_slice(), contract_cbor.as_slice(), "domain", @@ -2086,7 +2085,7 @@ mod tests { let random_tld_cbor = hex::decode("01ab632469645820655c9b5606f4ad53daea90de9c540aad656ed5fbe5fb14b40700f6f56dc793ac65247479706566646f6d61696e656c6162656c746433653966343532373963343865306261363561677265636f726473a17364617368416c6961734964656e74697479496458203012c19b98ec0033addb36cd64b7f510670f2a351a4304b5f6994144286efdac68246f776e6572496458203012c19b98ec0033addb36cd64b7f510670f2a351a4304b5f6994144286efdac69247265766973696f6e016c7072656f7264657253616c745820219353a923a29cd02c521b141f326ac0d12c362a84f1979a5de89b8dba12891b6e737562646f6d61696e52756c6573a16f616c6c6f77537562646f6d61696e73f56f2464617461436f6e747261637449645820e668c659af66aee1e72c186dde7b5b7e0a1d712a09c40d5721f622bf53c531556f6e6f726d616c697a65644c6162656c746433653966343532373963343865306261363561781a6e6f726d616c697a6564506172656e74446f6d61696e4e616d6560").unwrap(); drive - .add_serialized_document_for_serialized_contract( + .add_cbor_serialized_document_for_serialized_contract( random_tld_cbor.as_slice(), contract_cbor.as_slice(), "domain", diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index b1ac8ca67ce..d649aef8910 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -773,7 +773,7 @@ mod tests { let alice_profile_cbor = hex::decode("01a763246964582035edfec54aea574df968990abb47b39c206abe5c43a6157885f62958a1f1230c6524747970656770726f66696c656561626f75746a4920616d20416c69636568246f776e65724964582041d52f93f6f7c5af79ce994381c90df73cce2863d3850b9c05ef586ff0fe795f69247265766973696f6e016961766174617255726c7819687474703a2f2f746573742e636f6d2f616c6963652e6a70676f2464617461436f6e747261637449645820b0248cd9a27f86d05badf475dd9ff574d63219cd60c52e2be1e540c2fdd71333").unwrap(); drive - .add_serialized_document_for_serialized_contract( + .add_cbor_serialized_document_for_serialized_contract( alice_profile_cbor.as_slice(), contract_cbor.as_slice(), "profile", @@ -1207,7 +1207,7 @@ mod tests { .expect("expected to serialize to cbor"); drive - .add_serialized_document_for_serialized_contract( + .add_cbor_serialized_document_for_serialized_contract( serialized_document.as_slice(), contract.as_slice(), "indexedDocument", @@ -1438,7 +1438,6 @@ mod tests { batching_consistency_verification: true, has_raw_enabled: true, default_genesis_time: Some(0), - encoding: DriveEncoding::DriveCbor, ..Default::default() }; let tmp_dir = TempDir::new().unwrap(); @@ -1710,7 +1709,6 @@ mod tests { batching_consistency_verification: true, has_raw_enabled: true, default_genesis_time: Some(0), - encoding: DriveEncoding::DriveCbor, ..Default::default() }; let tmp_dir = TempDir::new().unwrap(); @@ -1901,7 +1899,6 @@ mod tests { batching_consistency_verification: true, has_raw_enabled: true, default_genesis_time: Some(0), - encoding: DriveEncoding::DriveCbor, ..Default::default() }; let tmp_dir = TempDir::new().unwrap(); @@ -2231,7 +2228,6 @@ mod tests { batching_consistency_verification: true, has_raw_enabled: using_has_raw, default_genesis_time: Some(0), - encoding: DriveEncoding::DriveCbor, ..Default::default() }; let tmp_dir = TempDir::new().unwrap(); diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 742a0fb4375..855f3fed7b3 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -4343,7 +4343,7 @@ fn test_query_documents_by_created_at() { .expect("expected to serialize to cbor"); drive - .add_serialized_document_for_serialized_contract( + .add_cbor_serialized_document_for_serialized_contract( serialized_document.as_slice(), contract_cbor.as_slice(), "indexedDocument", From f646e0096d94e29914b214c49eb8f60e24784617 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 09:21:17 +0700 Subject: [PATCH 41/50] fixing of required and added non flattened properties to document type --- .../document_type/document_factory.rs | 4 +- .../document_type/document_field.rs | 1 + .../document_type/document_type.rs | 202 +++++++++++- .../document_type/random_document.rs | 4 +- .../document_type/random_document_type.rs | 1 + packages/rs-dpp/src/document/serialize.rs | 8 +- .../rs-drive/src/drive/object_size_info.rs | 13 +- packages/rs-drive/src/query/mod.rs | 32 +- .../rs-drive/tests/deterministic_root_hash.rs | 10 +- packages/rs-drive/tests/query_tests.rs | 293 ++++++++++-------- .../rs-drive/tests/query_tests_history.rs | 2 +- packages/rs-platform-value/src/inner_value.rs | 59 +++- 12 files changed, 434 insertions(+), 195 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 8cb5df87a82..023f59922cc 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 @@ -19,13 +19,13 @@ impl DocumentType { owner_id: Identifier, properties: BTreeMap, ) -> Result { - let created_at = if self.properties.contains_key(CREATED_AT) { + let created_at = if self.flattened_properties.contains_key(CREATED_AT) { Some(Utc::now().timestamp_millis() as TimestampMillis) } else { None }; - let updated_at = if self.properties.contains_key(UPDATED_AT) { + let updated_at = if self.flattened_properties.contains_key(UPDATED_AT) { Some(Utc::now().timestamp_millis() as TimestampMillis) } else { None 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 73494c110d3..d9bb69d7dfe 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 @@ -607,6 +607,7 @@ impl DocumentFieldType { 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)| { + dbg!(&key, &field); if let Some(value) = value_map.get(key) { let value = field .document_type 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 a94fb4da74e..829997f420b 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 @@ -37,6 +37,10 @@ pub struct DocumentType { pub indices: Vec, #[serde(skip)] pub index_structure: IndexLevel, + /// Flattened properties flatten all objects for quick lookups for indexes + /// Document field should not contain sub objects. + pub flattened_properties: BTreeMap, + /// Document field can contain sub objects. pub properties: BTreeMap, #[serde(skip)] pub identifier_paths: BTreeSet, @@ -103,6 +107,7 @@ impl DocumentType { name, indices, index_structure, + flattened_properties: properties.clone(), properties, identifier_paths, binary_paths, @@ -172,7 +177,7 @@ impl DocumentType { } } _ => { - let field_type = self.properties.get(key).ok_or({ + let field_type = self.flattened_properties.get(key).ok_or({ DataContractError::DocumentTypeFieldNotFound("expected contract to have field") })?; let bytes = field_type.document_type.encode_value_for_tree_keys(value)?; @@ -224,6 +229,7 @@ impl DocumentType { default_keeps_history: bool, default_mutability: bool, ) -> Result { + let mut flattened_document_properties: BTreeMap = BTreeMap::new(); let mut document_properties: BTreeMap = BTreeMap::new(); // Do documents of this type keep history? (Overrides contract value) @@ -267,26 +273,40 @@ impl DocumentType { Value::inner_optional_btree_map(document_type_value_map, property_names::PROPERTIES)? .unwrap_or_default(); - let mut required_fields = Value::inner_optional_array_of_strings( + let mut required_fields = Value::inner_recursive_optional_array_of_strings( document_type_value_map, + "".to_string(), + property_names::PROPERTIES, property_names::REQUIRED, - ) - .unwrap_or_default(); - + ); // Based on the property name, determine the type for (property_key, property_value) in property_values { insert_values( - &mut document_properties, - &mut required_fields, + &mut flattened_document_properties, + &required_fields, None, + property_key.clone(), + property_value, + definition_references, + )?; + + insert_values_nested( + &mut document_properties, + &required_fields, property_key, property_value, definition_references, )?; } - // Add system properties if required_fields.contains(property_names::CREATED_AT) { + flattened_document_properties.insert( + String::from(property_names::CREATED_AT), + DocumentField { + document_type: DocumentFieldType::Date, + required: true, + }, + ); document_properties.insert( String::from(property_names::CREATED_AT), DocumentField { @@ -297,6 +317,13 @@ impl DocumentType { } if required_fields.contains(property_names::UPDATED_AT) { + flattened_document_properties.insert( + String::from(property_names::UPDATED_AT), + DocumentField { + document_type: DocumentFieldType::Date, + required: true, + }, + ); document_properties.insert( String::from(property_names::UPDATED_AT), DocumentField { @@ -314,6 +341,7 @@ impl DocumentType { name: String::from(name), indices, index_structure, + flattened_properties: flattened_document_properties, properties: document_properties, identifier_paths, binary_paths, @@ -326,7 +354,7 @@ impl DocumentType { pub fn max_size(&self) -> u16 { let mut iter = self - .properties + .flattened_properties .iter() .filter_map(|(_, document_field_type)| { document_field_type.document_type.max_byte_size() @@ -340,7 +368,7 @@ impl DocumentType { /// The estimated size uses the middle ceil size of all attributes pub fn estimated_size(&self) -> u16 { let mut iter = self - .properties + .flattened_properties .iter() .filter_map(|(_, document_field_type)| { document_field_type.document_type.middle_byte_size_ceil() @@ -362,7 +390,7 @@ impl DocumentType { } pub fn document_field_for_property(&self, property: &str) -> Option { - self.properties.get(property).cloned() + self.flattened_properties.get(property).cloned() } pub fn document_field_type_for_property(&self, property: &str) -> Option { @@ -476,9 +504,157 @@ pub fn string_to_field_type(field_type_name: &str) -> Option } } +fn insert_values_nested( + document_properties: &mut BTreeMap, + known_required: &BTreeSet, + property_key: String, + property_value: &Value, + definition_references: &BTreeMap, +) -> Result<(), ProtocolError> { + 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)?; + let type_value = match type_value { + None => { + let ref_value = inner_properties + .get_str(property_names::REF) + .map_err(ProtocolError::ValueError)?; + let Some(ref_value) = ref_value.strip_prefix("#/$defs/") else { + return Err(ProtocolError::DataContractError( + DataContractError::InvalidContractStructure("malformed reference"), + )); + }; + inner_properties = definition_references + .get_inner_borrowed_str_value_map(ref_value) + .map_err(ProtocolError::ValueError)?; + + inner_properties.get_string(property_names::TYPE)? + } + Some(type_value) => type_value, + }; + let is_required = known_required.contains(&property_key); + let field_type: DocumentFieldType; + + match type_value.as_str() { + "integer" => { + field_type = DocumentFieldType::Integer; + } + "number" => { + field_type = DocumentFieldType::Number; + } + "string" => { + field_type = DocumentFieldType::String( + inner_properties.get_optional_integer(property_names::MIN_LENGTH)?, + inner_properties.get_optional_integer(property_names::MAX_LENGTH)?, + ); + } + "array" => { + // Only handling bytearrays for v1 + // Return an error if it is not a byte array + field_type = match inner_properties.get_optional_bool(property_names::BYTE_ARRAY)? { + Some(inner_bool) => { + if inner_bool { + DocumentFieldType::ByteArray( + inner_properties.get_optional_integer(property_names::MIN_ITEMS)?, + inner_properties.get_optional_integer(property_names::MAX_ITEMS)?, + ) + } else { + return Err(ProtocolError::DataContractError( + DataContractError::InvalidContractStructure( + "byteArray should always be true if defined", + ), + )); + } + } + // TODO: Contract indices and new encoding format don't support arrays + // but we still can use them as document fields with current cbor encoding + // This is a temporary workaround to bring back v0.22 behavior and should be + // replaced with a proper array support in future versions + None => DocumentFieldType::Array(ArrayFieldType::Boolean), + }; + } + "object" => { + let mut nested_properties = BTreeMap::new(); + 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"), + ))?; + + // Create a new set with the prefix removed from the keys + let stripped_required: BTreeSet = known_required + .iter() + .filter_map(|key| { + if key.starts_with(&property_key) && key.len() > property_key.len() { + Some(key[property_key.len() + 1..].to_string()) + } else { + None + } + }) + .collect(); + + // Create a new set with the prefix removed from the keys + let inner_definition_references: BTreeMap = definition_references + .iter() + .filter_map(|(key, value)| { + if key.starts_with(&property_key) && key.len() > property_key.len() { + Some((key[property_key.len() + 1..].to_string(), *value)) + } else { + None + } + }) + .collect(); + + 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(); + + insert_values_nested( + &mut nested_properties, + &stripped_required, + object_property_string, + object_property_value, + &inner_definition_references, + )?; + } + } + field_type = DocumentFieldType::Object(nested_properties); + document_properties.insert( + property_key, + DocumentField { + document_type: field_type, + required: is_required, + }, + ); + return Ok(()); + } + _ => { + field_type = string_to_field_type(type_value.as_str()) + .ok_or(DataContractError::ValueWrongType("invalid type"))?; + } + } + + document_properties.insert( + property_key, + DocumentField { + document_type: field_type, + required: is_required, + }, + ); + + Ok(()) +} + fn insert_values( document_properties: &mut BTreeMap, - known_required: &mut BTreeSet, + known_required: &BTreeSet, prefix: Option, property_key: String, property_value: &Value, @@ -514,7 +690,7 @@ fn insert_values( } Some(type_value) => type_value, }; - let is_required = known_required.contains(&type_value.to_string()); + let is_required = known_required.contains(&prefixed_property_key); let field_type: DocumentFieldType; match type_value.as_str() { 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 7e722db6ed5..10fd1f7d1e5 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 @@ -164,7 +164,7 @@ impl CreateRandomDocument for DocumentType { let mut created_at = None; let mut updated_at = None; let properties = self - .properties + .flattened_properties .iter() .filter_map(|(key, document_field)| { if key == CREATED_AT { @@ -225,7 +225,7 @@ impl CreateRandomDocument for DocumentType { let id = Identifier::random_with_rng(rng); let owner_id = Identifier::random_with_rng(rng); let properties = self - .properties + .flattened_properties .iter() .map(|(key, document_field)| { ( diff --git a/packages/rs-dpp/src/data_contract/document_type/random_document_type.rs b/packages/rs-dpp/src/data_contract/document_type/random_document_type.rs index a22ad294e7f..807c168215e 100644 --- a/packages/rs-dpp/src/data_contract/document_type/random_document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/random_document_type.rs @@ -229,6 +229,7 @@ impl DocumentType { name: format!("doc_type_{}", rng.gen::()), indices, index_structure, + flattened_properties: properties.clone(), properties, identifier_paths, binary_paths, diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index e344569b1f2..f5b452693ed 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -129,7 +129,7 @@ impl Document { let value = field .document_type .encode_value_ref_with_size(value, field.required)?; - // dbg!("we pushed {} with {}", field_name, hex::encode(&value)); + dbg!("we pushed {} with {}", field_name, hex::encode(&value)); buffer.extend(value.as_slice()); Ok(()) } else if field.required { @@ -137,7 +137,7 @@ impl Document { DataContractError::MissingRequiredKey("a required field is not present"), )) } else { - // dbg!("we pushed {} with 0", field_name); + dbg!("we pushed {} with 0", field_name); // We don't have something that wasn't required buffer.push(0); Ok(()) @@ -163,7 +163,7 @@ impl Document { buffer.extend(revision.to_be_bytes()) } document_type - .properties + .flattened_properties .iter() .try_for_each(|(field_name, field)| { if field_name == CREATED_AT { @@ -255,7 +255,7 @@ impl Document { let mut created_at = None; let mut updated_at = None; let properties = document_type - .properties + .flattened_properties .iter() .filter_map(|(key, field)| { if key == CREATED_AT { diff --git a/packages/rs-drive/src/drive/object_size_info.rs b/packages/rs-drive/src/drive/object_size_info.rs index 1bc2f22c8c8..72d1f8398f2 100644 --- a/packages/rs-drive/src/drive/object_size_info.rs +++ b/packages/rs-drive/src/drive/object_size_info.rs @@ -587,11 +587,12 @@ impl<'a> DocumentInfo<'a> { "$ownerId" | "$id" => Ok(DEFAULT_HASH_SIZE_U16), "$createdAt" | "$updatedAt" => Ok(DEFAULT_FLOAT_SIZE_U16), _ => { - let document_field_type = document_type.properties.get(key_path).ok_or({ - Error::Fee(FeeError::DocumentTypeFieldNotFoundForEstimation( - "incorrect key path for document type for estimated sizes", - )) - })?; + let document_field_type = + document_type.flattened_properties.get(key_path).ok_or({ + Error::Fee(FeeError::DocumentTypeFieldNotFoundForEstimation( + "incorrect key path for document type for estimated sizes", + )) + })?; let estimated_size = document_field_type .document_type .middle_byte_size_ceil() @@ -645,7 +646,7 @@ impl<'a> DocumentInfo<'a> { }))), _ => { let document_field_type = - document_type.properties.get(key_path).ok_or({ + document_type.flattened_properties.get(key_path).ok_or({ Error::Fee(FeeError::DocumentTypeFieldNotFoundForEstimation( "incorrect key path for document type", )) diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index f7fff6b9ec3..a724157d99b 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -674,7 +674,7 @@ impl<'a> DriveQuery<'a> { )))?; if let Element::Item(item, _) = start_at_document { - let document = Document::from_cbor(item.as_slice(), None, None)?; + let document = Document::from_bytes(item.as_slice(), self.document_type)?; Ok(Some((document, self.start_at_included))) } else { Err(Error::Drive(DriveError::CorruptedDocumentPath( @@ -1529,7 +1529,7 @@ mod tests { use crate::drive::Drive; use crate::query::DriveQuery; use dpp::data_contract::document_type::DocumentType; - use dpp::data_contract::extra::common::json_document_to_cbor; + use dpp::data_contract::extra::common::{json_document_to_cbor, json_document_to_contract}; use dpp::util::cbor_serializer; use serde_json::Value::Null; @@ -1547,21 +1547,11 @@ mod tests { let contract_path = "tests/supporting_files/contract/family/family-contract.json"; // let's construct the grovedb structure for the dashpay data contract - let contract_cbor = - json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + let contract = json_document_to_contract(contract_path).expect("expected to get document"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); drive - .apply_contract_with_serialization( - &contract, - contract_cbor, - BlockInfo::default(), - true, - storage_flags, - None, - ) + .apply_contract(&contract, BlockInfo::default(), true, storage_flags, None) .expect("expected to apply contract successfully"); (drive, contract) @@ -1579,20 +1569,10 @@ mod tests { "tests/supporting_files/contract/family/family-contract-with-birthday.json"; // let's construct the grovedb structure for the dashpay data contract - let contract_cbor = - json_document_to_cbor(contract_path, Some(1)).expect("expected to get cbor document"); - let contract = - Contract::from_cbor(&contract_cbor).expect("expected to deserialize the contract"); + let contract = json_document_to_contract(contract_path).expect("expected to get document"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); drive - .apply_contract_with_serialization( - &contract, - contract_cbor, - BlockInfo::default(), - true, - storage_flags, - None, - ) + .apply_contract(&contract, BlockInfo::default(), true, storage_flags, None) .expect("expected to apply contract successfully"); (drive, contract) diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index 3ee40d3e5e9..7598335c3ee 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -68,6 +68,8 @@ use drive::drive::{Drive, RootTree}; #[cfg(feature = "full")] use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::platform_value::Bytes32; use drive::drive::object_size_info::DocumentInfo::DocumentRefInfo; #[cfg(feature = "full")] @@ -113,14 +115,14 @@ impl Domain { let label = first_names.choose(&mut rng).unwrap(); let domain = Domain { id: Vec::from(rng.gen::<[u8; 32]>()), - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + owner_id: Identifier::random_with_rng(&mut rng), label: Some(label.clone()), normalized_label: Some(label.to_lowercase()), normalized_parent_domain_name: normalized_parent_domain_name.to_string(), records: Records { - dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, - preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), + preorder_salt: Bytes32::random_with_rng(&mut rng), subdomain_rules: false, }; vec.push(domain); @@ -443,7 +445,7 @@ fn test_root_hash_with_batches(drive: &Drive, db_transaction: &Transaction) { .unwrap() .expect("should return app hash"); - let expected_app_hash = "c0f7380e8608b068b149e29e238dbf0812d4c6a3c3f7e5b4af9ba620edd8f83e"; + let expected_app_hash = "4b6ef295b084f2a81b5e1863fff1454784e1f8262800c90a9120faeb83c2753a"; assert_eq!(hex::encode(app_hash), expected_app_hash); } diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 855f3fed7b3..8382bb29acc 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -87,12 +87,14 @@ 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; +use dpp::platform_value::{platform_value, BinaryData, Bytes32, Identifier}; #[cfg(feature = "full")] use dpp::block::block_info::BlockInfo; +use dpp::data_contract::extra::common::json_document_to_contract; +use dpp::platform_value; #[cfg(feature = "full")] use dpp::prelude::DataContract; use dpp::prelude::Revision; @@ -415,7 +417,7 @@ pub fn setup_family_tests_only_first_name_index(count: u32, seed: u64) -> (Drive #[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct Records { - dash_unique_identity_id: Vec, + dash_unique_identity_id: Identifier, } #[cfg(feature = "full")] @@ -425,17 +427,41 @@ struct Records { #[serde(rename_all = "camelCase")] struct Domain { #[serde(rename = "$id")] - id: Vec, + id: Identifier, #[serde(rename = "$ownerId")] - owner_id: Vec, + owner_id: Identifier, label: Option, normalized_label: Option, normalized_parent_domain_name: String, records: Records, - preorder_salt: Vec, + preorder_salt: Bytes32, subdomain_rules: bool, } +#[cfg(feature = "full")] +#[test] +fn test_serialization_and_deserialization() { + let domains = Domain::random_domains_in_parent(20, 100, "dash"); + let contract = + json_document_to_contract("tests/supporting_files/contract/dpns/dpns-contract.json") + .expect("expected to get cbor contract"); + + let document_type = contract + .document_type_for_name("domain") + .expect("expected to get document type"); + for domain in domains { + let value = platform_value::to_value(domain).expect("expected value"); + let mut document = Document::from_platform_value(value).expect("expected value"); + document.revision == Some(1); + let serialized = document + .serialize(document_type) + .expect("expected to serialize domain document"); + let deserialized = Document::from_bytes(&serialized, document_type) + .expect("expected to deserialize domain document"); + assert_eq!(document, deserialized); + } +} + #[cfg(feature = "full")] impl Domain { /// Creates `count` random names as domain names for the given parent domain @@ -452,15 +478,15 @@ impl Domain { for _i in 0..count { let label = first_names.choose(&mut rng).unwrap(); let domain = Domain { - id: Vec::from(rng.gen::<[u8; 32]>()), - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + id: Identifier::random_with_rng(&mut rng), + owner_id: Identifier::random_with_rng(&mut rng), label: Some(label.clone()), normalized_label: Some(label.to_lowercase()), normalized_parent_domain_name: normalized_parent_domain_name.to_string(), records: Records { - dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, - preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), + preorder_salt: Bytes32::random_with_rng(&mut rng), subdomain_rules: false, }; vec.push(domain); @@ -479,18 +505,13 @@ pub fn add_domains_to_contract( seed: u64, ) { let domains = Domain::random_domains_in_parent(count, seed, "dash"); + let document_type = contract + .document_type_for_name("domain") + .expect("expected to get document type"); for domain in domains { - let value = serde_json::to_value(domain).expect("serialized domain"); - let document_cbor = 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 - .document_type_for_name("domain") - .expect("expected to get document type"); + let value = platform_value::to_value(domain).expect("expected value"); + let document = Document::from_platform_value(value).expect("expected value"); + dbg!(&document); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -762,8 +783,8 @@ fn test_family_basic_queries() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 14, 30, 243, 35, 60, 65, 149, 207, 147, 239, 246, 80, 217, 1, 245, 128, 247, 215, 204, 191, - 128, 132, 225, 37, 149, 212, 118, 64, 95, 39, 229, 212, + 75, 45, 123, 128, 23, 145, 21, 146, 12, 116, 212, 159, 9, 201, 184, 77, 129, 155, 18, 61, + 234, 241, 154, 96, 195, 228, 217, 202, 66, 250, 152, 247, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -805,8 +826,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1120,8 +1141,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1172,8 +1193,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1219,8 +1240,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1269,8 +1290,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1323,8 +1344,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1367,8 +1388,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1423,8 +1444,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1478,8 +1499,8 @@ fn test_family_basic_queries() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -1510,8 +1531,8 @@ fn test_family_basic_queries() { let ages: HashMap = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let name_value = document .properties .get("firstName") @@ -2031,8 +2052,8 @@ fn test_family_starts_at_queries() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 14, 30, 243, 35, 60, 65, 149, 207, 147, 239, 246, 80, 217, 1, 245, 128, 247, 215, 204, 191, - 128, 132, 225, 37, 149, 212, 118, 64, 95, 39, 229, 212, + 75, 45, 123, 128, 23, 145, 21, 146, 12, 116, 212, 159, 9, 201, 184, 77, 129, 155, 18, 61, + 234, 241, 154, 96, 195, 228, 217, 202, 66, 250, 152, 247, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2078,8 +2099,8 @@ fn test_family_starts_at_queries() { let reduced_names_after: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -2133,8 +2154,8 @@ fn test_family_starts_at_queries() { let reduced_names_after: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -2182,8 +2203,8 @@ fn test_family_starts_at_queries() { let reduced_names_after: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -2238,8 +2259,8 @@ fn test_family_starts_at_queries() { let reduced_names_after: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -2420,8 +2441,8 @@ fn test_family_with_nulls_query() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 70, 226, 41, 129, 14, 200, 145, 72, 107, 225, 14, 120, 163, 201, 87, 167, 102, 97, 4, 252, - 24, 57, 124, 236, 104, 169, 84, 126, 88, 161, 73, 67, + 184, 131, 211, 63, 90, 189, 41, 251, 77, 197, 221, 165, 130, 197, 116, 21, 194, 199, 239, + 221, 163, 121, 7, 223, 21, 112, 55, 83, 137, 24, 154, 68, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2464,8 +2485,8 @@ fn test_family_with_nulls_query() { .clone() .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); let first_name_value = document .properties .get("firstName") @@ -2492,8 +2513,8 @@ fn test_family_with_nulls_query() { let ids: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), person_document_type) + .expect("we should be able to deserialize the document"); base64::encode(document.id.as_slice()) }) .collect(); @@ -2537,8 +2558,8 @@ fn test_query_with_cached_contract() { // Make sure the state is deterministic let expected_app_hash = vec![ - 14, 30, 243, 35, 60, 65, 149, 207, 147, 239, 246, 80, 217, 1, 245, 128, 247, 215, 204, 191, - 128, 132, 225, 37, 149, 212, 118, 64, 95, 39, 229, 212, + 75, 45, 123, 128, 23, 145, 21, 146, 12, 116, 212, 159, 9, 201, 184, 77, 129, 155, 18, 61, + 234, 241, 154, 96, 195, 228, 217, 202, 66, 250, 152, 247, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2596,8 +2617,8 @@ fn test_dpns_query() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 202, 105, 213, 191, 7, 171, 20, 95, 124, 109, 201, 45, 204, 152, 150, 16, 177, 159, 2, 148, - 238, 143, 171, 61, 233, 233, 248, 27, 219, 101, 204, 117, + 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, + 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2640,8 +2661,8 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -2687,8 +2708,8 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -2717,8 +2738,8 @@ fn test_dpns_query() { let ids: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); hex::encode(document.id.as_slice()) }) .collect(); @@ -2762,8 +2783,8 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -2816,8 +2837,8 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -2842,8 +2863,8 @@ fn test_dpns_query() { let record_id_base64: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let records_value = document .properties @@ -2887,8 +2908,8 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -2939,8 +2960,8 @@ fn test_dpns_query() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -3111,8 +3132,8 @@ fn test_dpns_query_start_at() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 202, 105, 213, 191, 7, 171, 20, 95, 124, 109, 201, 45, 204, 152, 150, 16, 177, 159, 2, 148, - 238, 143, 171, 61, 233, 233, 248, 27, 219, 101, 204, 117, + 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, + 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, ]; assert_eq!(root_hash.as_slice(), expected_app_hash,); @@ -3160,8 +3181,8 @@ fn test_dpns_query_start_at() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -3199,8 +3220,8 @@ fn test_dpns_query_start_after() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 202, 105, 213, 191, 7, 171, 20, 95, 124, 109, 201, 45, 204, 152, 150, 16, 177, 159, 2, 148, - 238, 143, 171, 61, 233, 233, 248, 27, 219, 101, 204, 117, + 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, + 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3248,8 +3269,8 @@ fn test_dpns_query_start_after() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -3287,8 +3308,8 @@ fn test_dpns_query_start_at_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 202, 105, 213, 191, 7, 171, 20, 95, 124, 109, 201, 45, 204, 152, 150, 16, 177, 159, 2, 148, - 238, 143, 171, 61, 233, 233, 248, 27, 219, 101, 204, 117, + 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, + 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3336,8 +3357,8 @@ fn test_dpns_query_start_at_desc() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -3375,8 +3396,8 @@ fn test_dpns_query_start_after_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 202, 105, 213, 191, 7, 171, 20, 95, 124, 109, 201, 45, 204, 152, 150, 16, 177, 159, 2, 148, - 238, 143, 171, 61, 233, 233, 248, 27, 219, 101, 204, 117, + 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, + 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3424,8 +3445,8 @@ fn test_dpns_query_start_after_desc() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -3464,17 +3485,17 @@ fn test_dpns_query_start_at_with_null_id() { let mut rng = rand::rngs::StdRng::seed_from_u64(11456); - let domain0_id = Vec::from(rng.gen::<[u8; 32]>()); + let domain0_id = Identifier::random_with_rng(&mut rng); let domain0 = Domain { id: domain0_id.clone(), - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + owner_id: Identifier::random_with_rng(&mut rng), label: None, normalized_label: None, normalized_parent_domain_name: "dash".to_string(), records: Records { - dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, - preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), + preorder_salt: Bytes32::random_with_rng(&mut rng), subdomain_rules: false, }; @@ -3506,18 +3527,18 @@ fn test_dpns_query_start_at_with_null_id() { ) .expect("document should be inserted"); - let domain1_id = Vec::from(rng.gen::<[u8; 32]>()); + let domain1_id = Identifier::random_with_rng(&mut rng); let domain1 = Domain { id: domain1_id, - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + owner_id: Identifier::random_with_rng(&mut rng), label: None, normalized_label: None, normalized_parent_domain_name: "dash".to_string(), records: Records { - dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, - preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), + preorder_salt: Bytes32::random_with_rng(&mut rng), subdomain_rules: false, }; @@ -3563,8 +3584,8 @@ fn test_dpns_query_start_at_with_null_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 250, 31, 183, 195, 12, 105, 79, 233, 229, 177, 204, 218, 232, 208, 182, 157, 100, 201, 214, - 202, 161, 199, 242, 36, 224, 115, 106, 126, 170, 55, 29, 25, + 188, 106, 61, 153, 242, 126, 73, 106, 36, 154, 183, 160, 46, 40, 123, 14, 21, 169, 14, 58, + 238, 236, 38, 38, 140, 28, 66, 158, 162, 148, 89, 208, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3612,8 +3633,8 @@ fn test_dpns_query_start_at_with_null_id() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -3660,17 +3681,17 @@ fn test_dpns_query_start_after_with_null_id() { let mut rng = rand::rngs::StdRng::seed_from_u64(11456); - let domain0_id = Vec::from(rng.gen::<[u8; 32]>()); + let domain0_id = Identifier::random_with_rng(&mut rng); let domain0 = Domain { id: domain0_id.clone(), - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + owner_id: Identifier::random_with_rng(&mut rng), label: None, normalized_label: None, normalized_parent_domain_name: "dash".to_string(), records: Records { - dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, - preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), + preorder_salt: Bytes32::random_with_rng(&mut rng), subdomain_rules: false, }; @@ -3702,18 +3723,18 @@ fn test_dpns_query_start_after_with_null_id() { ) .expect("document should be inserted"); - let domain1_id = Vec::from(rng.gen::<[u8; 32]>()); + let domain1_id = Identifier::random_with_rng(&mut rng); let domain1 = Domain { id: domain1_id, - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + owner_id: Identifier::random_with_rng(&mut rng), label: None, normalized_label: None, normalized_parent_domain_name: "dash".to_string(), records: Records { - dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, - preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), + preorder_salt: Bytes32::random_with_rng(&mut rng), subdomain_rules: false, }; @@ -3760,8 +3781,8 @@ fn test_dpns_query_start_after_with_null_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 250, 31, 183, 195, 12, 105, 79, 233, 229, 177, 204, 218, 232, 208, 182, 157, 100, 201, 214, - 202, 161, 199, 242, 36, 224, 115, 106, 126, 170, 55, 29, 25, + 188, 106, 61, 153, 242, 126, 73, 106, 36, 154, 183, 160, 46, 40, 123, 14, 21, 169, 14, 58, + 238, 236, 38, 38, 140, 28, 66, 158, 162, 148, 89, 208, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3815,8 +3836,8 @@ fn test_dpns_query_start_after_with_null_id() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") @@ -3859,17 +3880,17 @@ fn test_dpns_query_start_after_with_null_id_desc() { let mut rng = rand::rngs::StdRng::seed_from_u64(11456); - let domain0_id = Vec::from(rng.gen::<[u8; 32]>()); + let domain0_id = Identifier::random_with_rng(&mut rng); let domain0 = Domain { id: domain0_id.clone(), - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + owner_id: Identifier::random_with_rng(&mut rng), label: None, normalized_label: None, normalized_parent_domain_name: "dash".to_string(), records: Records { - dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, - preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), + preorder_salt: Bytes32::random_with_rng(&mut rng), subdomain_rules: false, }; @@ -3901,18 +3922,18 @@ fn test_dpns_query_start_after_with_null_id_desc() { ) .expect("document should be inserted"); - let domain1_id = Vec::from(rng.gen::<[u8; 32]>()); + let domain1_id = Identifier::random_with_rng(&mut rng); let domain1 = Domain { id: domain1_id.clone(), - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + owner_id: Identifier::random_with_rng(&mut rng), label: None, normalized_label: None, normalized_parent_domain_name: "dash".to_string(), records: Records { - dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, - preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), + preorder_salt: Bytes32::random_with_rng(&mut rng), subdomain_rules: false, }; @@ -3959,8 +3980,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 250, 31, 183, 195, 12, 105, 79, 233, 229, 177, 204, 218, 232, 208, 182, 157, 100, 201, 214, - 202, 161, 199, 242, 36, 224, 115, 106, 126, 170, 55, 29, 25, + 188, 106, 61, 153, 242, 126, 73, 106, 36, 154, 183, 160, 46, 40, 123, 14, 21, 169, 14, 58, + 238, 236, 38, 38, 140, 28, 66, 158, 162, 148, 89, 208, ]; assert_eq!(root_hash.as_slice(), expected_app_hash,); @@ -4018,8 +4039,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { .clone() .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); document.id.to_vec() }) .collect(); @@ -4034,7 +4055,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { // domain1 is smaller than domain0 // however on the lowest lever the order never matters, so we are always ascending on the id // hence we will get domain1 - let expected_docs = [domain0_id.clone()]; + let expected_docs = [domain0_id.to_vec()]; assert_eq!(docs, expected_docs); @@ -4066,8 +4087,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { let docs: Vec> = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); document.id.to_vec() }) .collect(); @@ -4076,7 +4097,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { // domain1 is smaller than domain0 // however on the lowest lever the order never matters, so we are always ascending on the id // hence we will get domain1 - let expected_docs = [domain1_id, domain0_id]; + let expected_docs = [domain1_id.to_vec(), domain0_id.to_vec()]; assert_eq!(docs, expected_docs); let (proof_root_hash, proof_results, _) = query @@ -4115,8 +4136,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(result.as_slice(), domain_document_type) + .expect("we should be able to deserialize the document"); let normalized_label_value = document .properties .get("normalizedLabel") diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 41bb9ca7ce6..9a2026a6277 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -132,7 +132,7 @@ impl Person { for _ in 0..count { let person = Person { id: Vec::from(rng.gen::<[u8; 32]>()), - owner_id: Vec::from(rng.gen::<[u8; 32]>()), + owner_id: Identifier::random_with_rng(&mut rng), first_name: first_names.choose(&mut rng).unwrap().clone(), middle_name: middle_names.choose(&mut rng).unwrap().clone(), last_name: last_names.choose(&mut rng).unwrap().clone(), diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index 52473a566d9..aa9dd0b19d3 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -2,7 +2,8 @@ use crate::value_map::{ValueMap, ValueMapHelper}; use crate::{BinaryData, Bytes32, Identifier}; use crate::{Error, Value}; use std::cmp::Ordering; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; +use std::fmt::format; impl Value { pub fn has(&self, key: &str) -> Result { @@ -469,6 +470,62 @@ impl Value { } } + /// Retrieves the value of a key from a map if it's an array of strings. + /// This is useful for constructing the required fields in a contract. + /// For the DPNS Contract we would get as a result + /// { + /// "label", + /// "normalizedLabel", + /// "normalizedParentDomainName", + /// "preorderSalt", + /// "records", + /// "subdomainRules", + /// "subdomainRules.allowSubdomains", + /// } + pub fn inner_recursive_optional_array_of_strings<'a>( + document_type: &'a [(Value, Value)], + prefix: String, + recursive_key: &'a str, + key: &'a str, + ) -> BTreeSet { + let mut result = if let Some(key_value) = Self::get_optional_from_map(document_type, key) { + if let Value::Array(key_value) = key_value { + key_value + .iter() + .filter_map(|v| { + if let Value::Text(text) = v { + Some(format!("{prefix}{text}")) + } else { + None + } + }) + .collect() + } else { + BTreeSet::new() + } + } else { + BTreeSet::new() + }; + if let Some(lower_levels) = Self::get_optional_from_map(document_type, recursive_key) { + if let Value::Map(lower_level) = lower_levels { + for (inner_key, value) in lower_level { + let level_prefix = if let Value::Text(text) = inner_key { + text.as_str() + } else { + continue; + }; + let Value::Map(level_map) = value else { + continue; + }; + + let prefix = format!("{prefix}{level_prefix}."); + result.extend(Self::inner_recursive_optional_array_of_strings(level_map, prefix, recursive_key, key)) + } + } + } + result + } + /// 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)], From d04c7289a857997ea36fef80eb4849ad2aa3b406 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 09:48:37 +0700 Subject: [PATCH 42/50] more fixes --- .../rs-dpp/src/data_contract/data_contract.rs | 1 - .../document_type/document_field.rs | 1 - packages/rs-dpp/src/document/serialize.rs | 6 +-- .../rs-drive/src/drive/document/insert.rs | 4 +- .../rs-drive/src/drive/document/update.rs | 24 ++++++------ .../rs-drive/tests/deterministic_root_hash.rs | 6 +-- packages/rs-drive/tests/query_tests.rs | 39 ++++++++++++++----- .../rs-drive/tests/query_tests_history.rs | 2 +- 8 files changed, 50 insertions(+), 33 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 9d692da9b8d..80656165350 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -937,7 +937,6 @@ mod test { let data_contract: DataContract = serde_json::from_str(&string_contract)?; let raw_data_contract = data_contract.to_json_object()?; - dbg!(&raw_data_contract); for path in IDENTIFIER_FIELDS { assert!(raw_data_contract .get(path) 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 d9bb69d7dfe..73494c110d3 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 @@ -607,7 +607,6 @@ impl DocumentFieldType { 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)| { - dbg!(&key, &field); if let Some(value) = value_map.get(key) { let value = field .document_type diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index f5b452693ed..2d564f1fdb3 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -129,7 +129,7 @@ impl Document { let value = field .document_type .encode_value_ref_with_size(value, field.required)?; - dbg!("we pushed {} with {}", field_name, hex::encode(&value)); + // dbg!("we pushed {} with {}", field_name, hex::encode(&value)); buffer.extend(value.as_slice()); Ok(()) } else if field.required { @@ -137,7 +137,7 @@ impl Document { DataContractError::MissingRequiredKey("a required field is not present"), )) } else { - dbg!("we pushed {} with 0", field_name); + // dbg!("we pushed {} with 0", field_name); // We don't have something that wasn't required buffer.push(0); Ok(()) @@ -255,7 +255,7 @@ impl Document { let mut created_at = None; let mut updated_at = None; let properties = document_type - .flattened_properties + .properties .iter() .filter_map(|(key, field)| { if key == CREATED_AT { diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 0f7031ba283..2d1d49691bc 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -1497,11 +1497,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 3060 + storage_fee: 3057 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 2318070, + processing_fee: 2316870, ..Default::default() } ); diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index d649aef8910..4a7cf67b390 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -1499,10 +1499,10 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); let expected_added_bytes = if using_history { - //Explanation for 1234 + //Explanation for 1233 //todo - 1234 + 1233 } else { //Explanation for 1014 @@ -1635,7 +1635,7 @@ mod tests { // Total 65 + 145 + 68 = 275 - 958 + 957 }; assert_eq!(original_bytes, expected_added_bytes); @@ -1657,14 +1657,14 @@ mod tests { .get(&0) .unwrap(); - assert_eq!(*removed_credits, 25800855); + assert_eq!(*removed_credits, 25773863); let refund_equivalent_bytes = removed_credits.to_unsigned() / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); assert!(expected_added_bytes > refund_equivalent_bytes); - assert_eq!(refund_equivalent_bytes, 955); // we refunded 1008 instead of 1011 + assert_eq!(refund_equivalent_bytes, 954); // we refunded 1008 instead of 1011 // let's re-add it again let original_fees = apply_person( @@ -1700,7 +1700,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 309 } else { 1 }; + let expected_added_bytes = if using_history { 308 } else { 1 }; assert_eq!(added_bytes, expected_added_bytes); } @@ -1769,7 +1769,7 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1234 } else { 958 }; + let expected_added_bytes = if using_history { 1233 } else { 957 }; assert_eq!(original_bytes, expected_added_bytes); if !using_history { // let's delete it, just to make sure everything is working. @@ -1788,14 +1788,14 @@ mod tests { .get(&0) .unwrap(); - assert_eq!(*removed_credits, 25800855); + assert_eq!(*removed_credits, 25773863); let refund_equivalent_bytes = removed_credits.to_unsigned() / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); assert!(expected_added_bytes > refund_equivalent_bytes); - assert_eq!(refund_equivalent_bytes, 955); // we refunded 1008 instead of 1011 + assert_eq!(refund_equivalent_bytes, 954); // we refunded 1008 instead of 1011 // let's re-add it again let original_fees = apply_person( @@ -1963,7 +1963,7 @@ mod tests { //Explanation for 1233 //todo - 1234 + 1233 } else { //Explanation for 957 @@ -2098,7 +2098,7 @@ mod tests { // 355 + 179 + 145 + 278 = 957 - 958 + 957 }; assert_eq!(original_bytes, expected_added_bytes); @@ -2118,7 +2118,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1235 } else { 959 }; + let expected_added_bytes = if using_history { 1233 } else { 957 }; assert_eq!(added_bytes, expected_added_bytes); } diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index 7598335c3ee..97b5c70b518 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -115,14 +115,14 @@ impl Domain { let label = first_names.choose(&mut rng).unwrap(); let domain = Domain { id: Vec::from(rng.gen::<[u8; 32]>()), - owner_id: Identifier::random_with_rng(&mut rng), + owner_id: Vec::from(rng.gen::<[u8; 32]>()), label: Some(label.clone()), normalized_label: Some(label.to_lowercase()), normalized_parent_domain_name: normalized_parent_domain_name.to_string(), records: Records { - dash_unique_identity_id: Identifier::random_with_rng(&mut rng), + dash_unique_identity_id: Vec::from(rng.gen::<[u8; 32]>()), }, - preorder_salt: Bytes32::random_with_rng(&mut rng), + preorder_salt: Vec::from(rng.gen::<[u8; 32]>()), subdomain_rules: false, }; vec.push(domain); diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 8382bb29acc..0115d49582c 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -420,6 +420,13 @@ struct Records { dash_unique_identity_id: Identifier, } +#[cfg(feature = "full")] +#[derive(Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct SubdomainRules { + allow_subdomains: bool, +} + #[cfg(feature = "full")] /// DPNS domain info // In the real dpns, label is required. We make it optional here for a test. @@ -435,7 +442,7 @@ struct Domain { normalized_parent_domain_name: String, records: Records, preorder_salt: Bytes32, - subdomain_rules: bool, + subdomain_rules: SubdomainRules, } #[cfg(feature = "full")] @@ -452,7 +459,6 @@ fn test_serialization_and_deserialization() { for domain in domains { let value = platform_value::to_value(domain).expect("expected value"); let mut document = Document::from_platform_value(value).expect("expected value"); - document.revision == Some(1); let serialized = document .serialize(document_type) .expect("expected to serialize domain document"); @@ -487,7 +493,9 @@ impl Domain { dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, preorder_salt: Bytes32::random_with_rng(&mut rng), - subdomain_rules: false, + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, }; vec.push(domain); } @@ -511,7 +519,6 @@ pub fn add_domains_to_contract( for domain in domains { let value = platform_value::to_value(domain).expect("expected value"); let document = Document::from_platform_value(value).expect("expected value"); - dbg!(&document); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -3496,7 +3503,9 @@ fn test_dpns_query_start_at_with_null_id() { dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, preorder_salt: Bytes32::random_with_rng(&mut rng), - subdomain_rules: false, + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); @@ -3539,7 +3548,9 @@ fn test_dpns_query_start_at_with_null_id() { dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, preorder_salt: Bytes32::random_with_rng(&mut rng), - subdomain_rules: false, + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); @@ -3692,7 +3703,9 @@ fn test_dpns_query_start_after_with_null_id() { dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, preorder_salt: Bytes32::random_with_rng(&mut rng), - subdomain_rules: false, + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); @@ -3735,7 +3748,9 @@ fn test_dpns_query_start_after_with_null_id() { dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, preorder_salt: Bytes32::random_with_rng(&mut rng), - subdomain_rules: false, + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); @@ -3891,7 +3906,9 @@ fn test_dpns_query_start_after_with_null_id_desc() { dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, preorder_salt: Bytes32::random_with_rng(&mut rng), - subdomain_rules: false, + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, }; let value0 = serde_json::to_value(&domain0).expect("serialized domain"); @@ -3934,7 +3951,9 @@ fn test_dpns_query_start_after_with_null_id_desc() { dash_unique_identity_id: Identifier::random_with_rng(&mut rng), }, preorder_salt: Bytes32::random_with_rng(&mut rng), - subdomain_rules: false, + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, }; let value1 = serde_json::to_value(&domain1).expect("serialized domain"); diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 9a2026a6277..41bb9ca7ce6 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -132,7 +132,7 @@ impl Person { for _ in 0..count { let person = Person { id: Vec::from(rng.gen::<[u8; 32]>()), - owner_id: Identifier::random_with_rng(&mut rng), + owner_id: Vec::from(rng.gen::<[u8; 32]>()), first_name: first_names.choose(&mut rng).unwrap().clone(), middle_name: middle_names.choose(&mut rng).unwrap().clone(), last_name: last_names.choose(&mut rng).unwrap().clone(), From cfa68cde46d0cdaded683065a3141328873a6fed Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 09:49:51 +0700 Subject: [PATCH 43/50] more fixes --- packages/rs-drive/src/drive/document/insert.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 2d1d49691bc..77ee2591621 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -1855,11 +1855,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 1717 + storage_fee: 1749 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 2070870, + processing_fee: 2083790, ..Default::default() } ); From 82ec9dafe95fff2a4c0eeae31cc0620bb9a77dfc Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 10:00:50 +0700 Subject: [PATCH 44/50] more work --- .../rs-drive/src/drive/document/update.rs | 61 +++++++++---------- 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 4a7cf67b390..67d18abb668 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -719,7 +719,7 @@ mod tests { use dpp::document::document_factory::DocumentFactory; use dpp::document::document_validator::DocumentValidator; - use dpp::platform_value::{platform_value, Value}; + use dpp::platform_value::{platform_value, Identifier, Value}; use dpp::prelude::DataContract; use dpp::util::cbor_serializer; use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; @@ -743,6 +743,7 @@ mod tests { use crate::{common::setup_contract, drive::test_utils::TestEntropyGenerator}; use dpp::block::epoch::Epoch; use dpp::data_contract::extra::common::json_document_to_document; + use dpp::platform_value; #[test] fn test_create_and_update_document_same_transaction() { @@ -1464,8 +1465,8 @@ mod tests { // setup code let contract = setup_contract(&drive, path, None, transaction.as_ref()); - let id = [1u8; 32]; - let owner_id = [2u8; 32]; + let id = Identifier::from([1u8; 32]); + let owner_id = Identifier::from([2u8; 32]); let person_0_original = Person { id, owner_id, @@ -1652,7 +1653,7 @@ mod tests { let removed_credits = deletion_fees .fee_refunds - .get(&owner_id) + .get(owner_id.as_bytes()) .unwrap() .get(&0) .unwrap(); @@ -1735,8 +1736,8 @@ mod tests { // setup code let contract = setup_contract(&drive, path, None, transaction.as_ref()); - let id = [1u8; 32]; - let owner_id = [2u8; 32]; + let id = Identifier::from([1u8; 32]); + let owner_id = Identifier::from([2u8; 32]); let person_0_original = Person { id, owner_id, @@ -1783,7 +1784,7 @@ mod tests { let removed_credits = deletion_fees .fee_refunds - .get(&owner_id) + .get(owner_id.as_bytes()) .unwrap() .get(&0) .unwrap(); @@ -1833,7 +1834,7 @@ mod tests { let removed_credits = update_fees .fee_refunds - .get(&owner_id) + .get(owner_id.as_bytes()) .unwrap() .get(&0) .unwrap(); @@ -1925,8 +1926,8 @@ mod tests { // setup code let contract = setup_contract(&drive, path, None, transaction.as_ref()); - let id = [1u8; 32]; - let owner_id = [2u8; 32]; + let id = Identifier::from([1u8; 32]); + let owner_id = Identifier::from([2u8; 32]); let person_0_original = Person { id, owner_id, @@ -2146,9 +2147,9 @@ mod tests { #[serde(rename_all = "camelCase")] struct Person { #[serde(rename = "$id")] - id: [u8; 32], + id: Identifier, #[serde(rename = "$ownerId")] - owner_id: [u8; 32], + owner_id: Identifier, first_name: String, middle_name: String, last_name: String, @@ -2164,21 +2165,17 @@ mod tests { apply: bool, transaction: TransactionArg, ) -> FeeResult { - let value = serde_json::to_value(person).expect("serialized person"); - let document_cbor = - 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 .document_type_for_name("person") .expect("expected to get document type"); + + let value = platform_value::to_value(person).expect("person into value"); + + let document = platform_value::from_value(value).expect("value to document"); + let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpochOwned( 0, - person - .owner_id - .try_into() - .expect("expected to get owner_id"), + person.owner_id.to_buffer(), ))); drive @@ -2208,10 +2205,10 @@ mod tests { ) -> FeeResult { drive .delete_document_for_contract( - person.id, + person.id.to_buffer(), contract, "person", - Some(person.owner_id), + Some(person.owner_id.to_buffer()), block_info, true, transaction, @@ -2255,8 +2252,8 @@ mod tests { let contract = setup_contract(&drive, path, None, transaction.as_ref()); let person_0_original = Person { - id: [0u8; 32], - owner_id: [0u8; 32], + id: Identifier::from([0u8; 32]), + owner_id: Identifier::from([0u8; 32]), first_name: "Samuel".to_string(), middle_name: "Abraham".to_string(), last_name: "Westrich".to_string(), @@ -2265,8 +2262,8 @@ mod tests { }; let person_0_updated = Person { - id: [0u8; 32], - owner_id: [0u8; 32], + id: Identifier::from([0u8; 32]), + owner_id: Identifier::from([0u8; 32]), first_name: "Samuel".to_string(), middle_name: "Abraham".to_string(), last_name: "Westrich".to_string(), @@ -2275,8 +2272,8 @@ mod tests { }; let person_1_original = Person { - id: [1u8; 32], - owner_id: [1u8; 32], + id: Identifier::from([1u8; 32]), + owner_id: Identifier::from([1u8; 32]), first_name: "Wisdom".to_string(), middle_name: "Madabuchukwu".to_string(), last_name: "Ogwu".to_string(), @@ -2285,8 +2282,8 @@ mod tests { }; let person_1_updated = Person { - id: [1u8; 32], - owner_id: [1u8; 32], + id: Identifier::from([1u8; 32]), + owner_id: Identifier::from([1u8; 32]), first_name: "Wisdom".to_string(), middle_name: "Madabuchukwu".to_string(), last_name: "Ogwu".to_string(), From 99e2ca05155b5a0d86e93a0d8c6e007dcf260c17 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 10:25:05 +0700 Subject: [PATCH 45/50] more work --- .../rs-drive/src/drive/document/update.rs | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 67d18abb668..0e3ca4ece60 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -1487,6 +1487,17 @@ mod tests { age: 35, }; + let document_type = contract + .document_type_for_name("person") + .expect("expected to get document type"); + + let value = platform_value::to_value(&person_0_original).expect("person into value"); + + let document : Document = platform_value::from_value(value).expect("value to document"); + + let document_serialized = document.serialize_consume(document_type).expect("expected to serialize document"); + + assert_eq!(document_serialized.len(), 115); let original_fees = apply_person( &drive, &contract, @@ -1505,27 +1516,27 @@ mod tests { //todo 1233 } else { - //Explanation for 1014 + //Explanation for 957 // Document Storage //// Item - // = 358 Bytes + // = 354 Bytes - // Explanation for 412 storage_written_bytes + // Explanation for 354 storage_written_bytes // Key -> 65 bytes // 32 bytes for the key prefix // 32 bytes for the unique id // 1 byte for key_size (required space for 64) - // Value -> 276 + // Value -> 221 // 1 for the flag option with flags // 1 for the flags size // 35 for flags 32 + 1 + 2 // 1 for the enum type // 1 for item - // 116 for item serialized bytes + // 115 for item serialized bytes (verified above) // 1 for Basic Merk // 32 for node hash // 32 for value hash @@ -1538,11 +1549,11 @@ mod tests { // Child Heights 2 // Basic Merk 1 - // Total 65 + 276 + 68 = 409 + // Total 65 + 221 + 68 = 354 //// Tree 1 / / 1 / person / message // Key: My apples are safe - // = 177 Bytes + // = 179 Bytes // Explanation for 179 storage_written_bytes @@ -1573,9 +1584,9 @@ mod tests { //// Tree 1 / / 1 / person / message / My apples are safe // Key: 0 - // = 143 Bytes + // = 145 Bytes - // Explanation for 143 storage_written_bytes + // Explanation for 145 storage_written_bytes // Key -> 34 bytes // 32 bytes for the key prefix @@ -1604,7 +1615,7 @@ mod tests { //// Ref 1 / / 1 / person / message / My apples are safe // Reference to Serialized Item - // = 319 Bytes + // = 276 Bytes // Explanation for 276 storage_written_bytes @@ -1634,7 +1645,9 @@ mod tests { // Child Heights 2 // Basic Merk 1 - // Total 65 + 145 + 68 = 275 + // Total 65 + 145 + 68 = 278 + + //// 354 + 179 + 145 + 278 957 }; @@ -1964,7 +1977,7 @@ mod tests { //Explanation for 1233 //todo - 1233 + 1234 } else { //Explanation for 957 @@ -2119,7 +2132,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1233 } else { 957 }; + let expected_added_bytes = if using_history { 1234 } else { 958 }; assert_eq!(added_bytes, expected_added_bytes); } From 9b1d8f6849156df587702560be04b20c0ca1688b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 11:04:02 +0700 Subject: [PATCH 46/50] more fixes --- .../document_type/document_field.rs | 9 ++- .../document_type/document_type.rs | 30 ++++++-- .../src/data_contract/document_type/mod.rs | 1 + .../rs-drive/src/drive/document/update.rs | 8 +- packages/rs-drive/tests/query_tests.rs | 74 ++++++++++--------- 5 files changed, 74 insertions(+), 48 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 73494c110d3..203175c0828 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 @@ -353,7 +353,14 @@ impl DocumentFieldType { } DocumentFieldType::ByteArray(_, _) => { let bytes = Self::read_varint_value(buf)?; - Ok(bytes.map(Value::Bytes)) + Ok(bytes.map(|bytes| { + match bytes.len() { + 32 => Value::Bytes32(bytes.try_into().unwrap()), + 20 => Value::Bytes20(bytes.try_into().unwrap()), + 36 => Value::Bytes36(bytes.try_into().unwrap()), + _ => Value::Bytes(bytes) + } + })) } DocumentFieldType::Identifier => { let bytes = Self::read_varint_value(buf)?; 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 829997f420b..6e76320be36 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 @@ -556,10 +556,17 @@ fn insert_values_nested( field_type = match inner_properties.get_optional_bool(property_names::BYTE_ARRAY)? { Some(inner_bool) => { if inner_bool { - DocumentFieldType::ByteArray( - inner_properties.get_optional_integer(property_names::MIN_ITEMS)?, - inner_properties.get_optional_integer(property_names::MAX_ITEMS)?, - ) + match inner_properties.get_optional_str(property_names::CONTENT_MEDIA_TYPE)? { + Some(content_media_type) if content_media_type == "application/x.dash.dpp.identifier" => { + DocumentFieldType::Identifier + } + Some(_) | None => { + DocumentFieldType::ByteArray( + inner_properties.get_optional_integer(property_names::MIN_ITEMS)?, + inner_properties.get_optional_integer(property_names::MAX_ITEMS)?, + ) + }, + } } else { return Err(ProtocolError::DataContractError( DataContractError::InvalidContractStructure( @@ -700,10 +707,17 @@ fn insert_values( field_type = match inner_properties.get_optional_bool(property_names::BYTE_ARRAY)? { Some(inner_bool) => { if inner_bool { - DocumentFieldType::ByteArray( - inner_properties.get_optional_integer(property_names::MIN_ITEMS)?, - inner_properties.get_optional_integer(property_names::MAX_ITEMS)?, - ) + match inner_properties.get_optional_str(property_names::CONTENT_MEDIA_TYPE)? { + Some(content_media_type) if content_media_type == "application/x.dash.dpp.identifier" => { + DocumentFieldType::Identifier + } + Some(_) | None => { + DocumentFieldType::ByteArray( + inner_properties.get_optional_integer(property_names::MIN_ITEMS)?, + inner_properties.get_optional_integer(property_names::MAX_ITEMS)?, + ) + }, + } } else { return Err(ProtocolError::DataContractError( DataContractError::InvalidContractStructure( 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 5718262f84a..80d61ca0452 100644 --- a/packages/rs-dpp/src/data_contract/document_type/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/mod.rs @@ -34,4 +34,5 @@ pub(self) mod property_names { pub const MIN_LENGTH: &str = "minLength"; pub const MAX_LENGTH: &str = "maxLength"; pub const BYTE_ARRAY: &str = "byteArray"; + pub const CONTENT_MEDIA_TYPE: &str = "contentMediaType"; } diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 0e3ca4ece60..2972aea3400 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -1493,9 +1493,11 @@ mod tests { let value = platform_value::to_value(&person_0_original).expect("person into value"); - let document : Document = platform_value::from_value(value).expect("value to document"); + let document: Document = platform_value::from_value(value).expect("value to document"); - let document_serialized = document.serialize_consume(document_type).expect("expected to serialize document"); + let document_serialized = document + .serialize_consume(document_type) + .expect("expected to serialize document"); assert_eq!(document_serialized.len(), 115); let original_fees = apply_person( @@ -1977,7 +1979,7 @@ mod tests { //Explanation for 1233 //todo - 1234 + 1233 } else { //Explanation for 957 diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 0115d49582c..b5e188b6e32 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -456,9 +456,11 @@ fn test_serialization_and_deserialization() { let document_type = contract .document_type_for_name("domain") .expect("expected to get document type"); + dbg!(document_type); for domain in domains { let value = platform_value::to_value(domain).expect("expected value"); let mut document = Document::from_platform_value(value).expect("expected value"); + document.revision = Some(1); let serialized = document .serialize(document_type) .expect("expected to serialize domain document"); @@ -790,8 +792,8 @@ fn test_family_basic_queries() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 75, 45, 123, 128, 23, 145, 21, 146, 12, 116, 212, 159, 9, 201, 184, 77, 129, 155, 18, 61, - 234, 241, 154, 96, 195, 228, 217, 202, 66, 250, 152, 247, + 178, 236, 137, 244, 12, 216, 5, 234, 232, 88, 124, 87, 0, 219, 236, 153, 67, 36, 226, 34, + 73, 82, 197, 167, 229, 202, 206, 121, 83, 206, 65, 232, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -933,8 +935,8 @@ fn test_family_basic_queries() { assert_eq!(root_hash, proof_root_hash); assert_eq!(results, proof_results); - let document = Document::from_cbor(results.first().unwrap().as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(results.first().unwrap().as_slice(), person_document_type) + .expect("we should be able to deserialize from bytes"); let last_name = document .properties .get("lastName") @@ -1032,8 +1034,8 @@ fn test_family_basic_queries() { assert_eq!(root_hash, proof_root_hash); assert_eq!(results, proof_results); - let document = Document::from_cbor(results.first().unwrap().as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let document = Document::from_bytes(results.first().unwrap().as_slice(), person_document_type) + .expect("we should be able to deserialize from bytes"); let last_name = document .properties .get("lastName") @@ -1728,8 +1730,8 @@ fn test_family_basic_queries() { assert_eq!(results.len(), 2); - let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let last_person = Document::from_bytes(results.first().unwrap().as_slice(), document_type) + .expect("we should be able to deserialize the document"); assert_eq!( last_person.id.to_vec(), @@ -1768,8 +1770,8 @@ fn test_family_basic_queries() { assert_eq!(results.len(), 2); - let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let last_person = Document::from_bytes(results.first().unwrap().as_slice(), document_type) + .expect("we should be able to deserialize the document"); assert_eq!( last_person.id.to_vec(), @@ -1831,8 +1833,8 @@ fn test_family_basic_queries() { assert_eq!(results.len(), 12); - let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let last_person = Document::from_bytes(results.first().unwrap().as_slice(), document_type) + .expect("we should be able to deserialize the document"); assert_eq!( last_person.id.to_vec(), @@ -2039,8 +2041,8 @@ fn test_family_basic_queries() { assert_eq!( root_hash.as_slice(), vec![ - 26, 81, 46, 125, 88, 54, 113, 4, 64, 5, 165, 84, 197, 93, 109, 3, 60, 108, 146, 204, - 10, 175, 168, 248, 199, 201, 24, 159, 213, 158, 58, 148, + 128, 53, 185, 186, 232, 226, 12, 157, 184, 63, 83, 178, 62, 1, 89, 27, 89, 135, 117, + 147, 87, 217, 100, 175, 152, 113, 89, 122, 105, 213, 224, 149, ], ); } @@ -2059,8 +2061,8 @@ fn test_family_starts_at_queries() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 75, 45, 123, 128, 23, 145, 21, 146, 12, 116, 212, 159, 9, 201, 184, 77, 129, 155, 18, 61, - 234, 241, 154, 96, 195, 228, 217, 202, 66, 250, 152, 247, + 178, 236, 137, 244, 12, 216, 5, 234, 232, 88, 124, 87, 0, 219, 236, 153, 67, 36, 226, 34, + 73, 82, 197, 167, 229, 202, 206, 121, 83, 206, 65, 232, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2448,8 +2450,8 @@ fn test_family_with_nulls_query() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 184, 131, 211, 63, 90, 189, 41, 251, 77, 197, 221, 165, 130, 197, 116, 21, 194, 199, 239, - 221, 163, 121, 7, 223, 21, 112, 55, 83, 137, 24, 154, 68, + 213, 209, 8, 112, 10, 188, 65, 168, 82, 180, 236, 252, 137, 4, 76, 109, 171, 144, 32, 189, + 65, 139, 45, 234, 210, 78, 245, 227, 15, 155, 19, 221, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2565,8 +2567,8 @@ fn test_query_with_cached_contract() { // Make sure the state is deterministic let expected_app_hash = vec![ - 75, 45, 123, 128, 23, 145, 21, 146, 12, 116, 212, 159, 9, 201, 184, 77, 129, 155, 18, 61, - 234, 241, 154, 96, 195, 228, 217, 202, 66, 250, 152, 247, + 178, 236, 137, 244, 12, 216, 5, 234, 232, 88, 124, 87, 0, 219, 236, 153, 67, 36, 226, 34, + 73, 82, 197, 167, 229, 202, 206, 121, 83, 206, 65, 232, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2624,8 +2626,8 @@ fn test_dpns_query() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, - 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, + 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, + 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3139,8 +3141,8 @@ fn test_dpns_query_start_at() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, - 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, + 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, + 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, ]; assert_eq!(root_hash.as_slice(), expected_app_hash,); @@ -3227,8 +3229,8 @@ fn test_dpns_query_start_after() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, - 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, + 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, + 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3315,8 +3317,8 @@ fn test_dpns_query_start_at_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, - 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, + 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, + 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3403,8 +3405,8 @@ fn test_dpns_query_start_after_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 16, 36, 107, 80, 207, 252, 236, 21, 95, 92, 63, 184, 0, 203, 103, 231, 250, 31, 40, 209, - 199, 180, 221, 111, 17, 9, 205, 35, 92, 53, 141, 179, + 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, + 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3595,8 +3597,8 @@ fn test_dpns_query_start_at_with_null_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 188, 106, 61, 153, 242, 126, 73, 106, 36, 154, 183, 160, 46, 40, 123, 14, 21, 169, 14, 58, - 238, 236, 38, 38, 140, 28, 66, 158, 162, 148, 89, 208, + 231, 220, 135, 142, 39, 139, 213, 116, 86, 129, 140, 236, 104, 198, 230, 80, 35, 86, 36, 1, + 127, 177, 116, 51, 44, 156, 29, 157, 72, 235, 182, 181, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3796,8 +3798,8 @@ fn test_dpns_query_start_after_with_null_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 188, 106, 61, 153, 242, 126, 73, 106, 36, 154, 183, 160, 46, 40, 123, 14, 21, 169, 14, 58, - 238, 236, 38, 38, 140, 28, 66, 158, 162, 148, 89, 208, + 231, 220, 135, 142, 39, 139, 213, 116, 86, 129, 140, 236, 104, 198, 230, 80, 35, 86, 36, 1, + 127, 177, 116, 51, 44, 156, 29, 157, 72, 235, 182, 181, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3999,8 +4001,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 188, 106, 61, 153, 242, 126, 73, 106, 36, 154, 183, 160, 46, 40, 123, 14, 21, 169, 14, 58, - 238, 236, 38, 38, 140, 28, 66, 158, 162, 148, 89, 208, + 231, 220, 135, 142, 39, 139, 213, 116, 86, 129, 140, 236, 104, 198, 230, 80, 35, 86, 36, 1, + 127, 177, 116, 51, 44, 156, 29, 157, 72, 235, 182, 181, ]; assert_eq!(root_hash.as_slice(), expected_app_hash,); From 26e254ae5ad9fb993e80cf92374311a79b5ce480 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 14:03:24 +0700 Subject: [PATCH 47/50] all rs-drive tests passing --- .../document_type/document_field.rs | 168 +++++++-------- packages/rs-dpp/src/document/serialize.rs | 39 +++- .../rs-drive/src/drive/document/delete.rs | 13 +- .../rs-drive/src/drive/document/insert.rs | 16 +- .../rs-drive/src/drive/document/update.rs | 38 ++-- packages/rs-drive/tests/query_tests.rs | 202 ++++++++++++++---- .../rs-drive/tests/query_tests_history.rs | 55 ++--- .../contract/dpns/domain0.json | 2 +- .../dpns-contract-label-not-required.json | 151 +++++++++++++ .../family-contract-fields-optional.json | 109 ++++++++++ 10 files changed, 592 insertions(+), 201 deletions(-) create mode 100644 packages/rs-drive/tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json create mode 100644 packages/rs-drive/tests/supporting_files/contract/family/family-contract-fields-optional.json 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 203175c0828..58168266d59 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 @@ -265,14 +265,14 @@ impl DocumentFieldType { } } - fn read_varint_value(buf: &mut BufReader<&[u8]>) -> Result>, ProtocolError> { + fn read_varint_value(buf: &mut BufReader<&[u8]>) -> Result, ProtocolError> { let bytes: usize = buf.read_varint().map_err(|_| { ProtocolError::DataContractError(DataContractError::CorruptedSerialization( "error reading varint length from serialized document", )) })?; if bytes == 0 { - Ok(None) + Ok(vec![]) } else { let mut value: Vec = vec![0u8; bytes]; buf.read_exact(&mut value).map_err(|e| { @@ -280,7 +280,7 @@ impl DocumentFieldType { "error reading varint from serialized document", )) })?; - Ok(Some(value)) + Ok(value) } } @@ -289,52 +289,38 @@ impl DocumentFieldType { buf: &mut BufReader<&[u8]>, required: bool, ) -> Result, ProtocolError> { + if !required { + let marker = buf.read_u8().map_err(|_| { + ProtocolError::DataContractError(DataContractError::CorruptedSerialization( + "error reading from serialized document", + )) + })?; + if marker == 0 { + return Ok(Some(Value::Null)); + } + } match self { DocumentFieldType::String(_, _) => { let bytes = Self::read_varint_value(buf)?; - if let Some(bytes) = bytes { - let string = String::from_utf8(bytes).map_err(|_| { - ProtocolError::DataContractError(DataContractError::CorruptedSerialization( - "error reading from serialized document", - )) - })?; - Ok(Some(Value::Text(string))) - } else { - Ok(None) - } + let string = String::from_utf8(bytes).map_err(|_| { + ProtocolError::DataContractError(DataContractError::CorruptedSerialization( + "error reading string from serialized document", + )) + })?; + Ok(Some(Value::Text(string))) } DocumentFieldType::Date | DocumentFieldType::Number => { - if !required { - let marker = buf.read_u8().map_err(|_| { - ProtocolError::DataContractError(DataContractError::CorruptedSerialization( - "error reading from serialized document", - )) - })?; - if marker == 0 { - return Ok(None); - } - } let date = buf.read_f64::().map_err(|_| { ProtocolError::DataContractError(DataContractError::CorruptedSerialization( - "error reading from serialized document", + "error reading date/number from serialized document", )) })?; Ok(Some(Value::Float(date))) } DocumentFieldType::Integer => { - if !required { - let marker = buf.read_u8().map_err(|_| { - ProtocolError::DataContractError(DataContractError::CorruptedSerialization( - "error reading from serialized document", - )) - })?; - if marker == 0 { - return Ok(None); - } - } let integer = buf.read_i64::().map_err(|_| { ProtocolError::DataContractError(DataContractError::CorruptedSerialization( - "error reading from serialized document", + "error reading integer from serialized document", )) })?; Ok(Some(Value::I64(integer))) @@ -342,37 +328,55 @@ impl DocumentFieldType { DocumentFieldType::Boolean => { let value = buf.read_u8().map_err(|_| { ProtocolError::DataContractError(DataContractError::CorruptedSerialization( - "error reading from serialized document", + "error reading bool from serialized document", )) })?; match value { - 0 => Ok(None), - 1 => Ok(Some(Value::Bool(true))), - _ => Ok(Some(Value::Bool(false))), + 0 => Ok(Some(Value::Bool(false))), + _ => Ok(Some(Value::Bool(true))), } } - DocumentFieldType::ByteArray(_, _) => { - let bytes = Self::read_varint_value(buf)?; - Ok(bytes.map(|bytes| { - match bytes.len() { - 32 => Value::Bytes32(bytes.try_into().unwrap()), - 20 => Value::Bytes20(bytes.try_into().unwrap()), - 36 => Value::Bytes36(bytes.try_into().unwrap()), - _ => Value::Bytes(bytes) + DocumentFieldType::ByteArray(min, max) => { + match (min, max) { + (Some(min), Some(max)) if min == max => { + // if min == max, then we don't need a varint for the length + let len = *min as usize; + let mut bytes = vec![0; len]; + buf.read_exact(&mut bytes).map_err(|_| { + ProtocolError::DecodingError( + "error reading 32 byte non main identifier".to_string(), + ) + })?; + //dbg!(hex::encode(&bytes)); + match bytes.len() { + 32 => Ok(Some(Value::Bytes32(bytes.try_into().unwrap()))), + 20 => Ok(Some(Value::Bytes20(bytes.try_into().unwrap()))), + 36 => Ok(Some(Value::Bytes36(bytes.try_into().unwrap()))), + _ => Ok(Some(Value::Bytes(bytes))) + } } - })) + _ => { + let bytes = Self::read_varint_value(buf)?; + Ok(Some(match bytes.len() { + 32 => Value::Bytes32(bytes.try_into().unwrap()), + 20 => Value::Bytes20(bytes.try_into().unwrap()), + 36 => Value::Bytes36(bytes.try_into().unwrap()), + _ => Value::Bytes(bytes) + }) + ) + } + } + } DocumentFieldType::Identifier => { - let bytes = Self::read_varint_value(buf)?; - - bytes - .map(|bytes| { - let fixed_bytes = bytes.try_into().map_err(|_| { - ProtocolError::DecodingError("identifier was not 32 bytes".to_string()) - })?; - Ok(Value::Identifier(fixed_bytes)) - }) - .transpose() + let mut id = [0; 32]; + buf.read_exact(&mut id).map_err(|_| { + ProtocolError::DecodingError( + "error reading 32 byte non main identifier".to_string(), + ) + })?; + //dbg!(hex::encode(&id)); + Ok(Some(Value::Identifier(id))) } DocumentFieldType::Object(inner_fields) => { @@ -562,41 +566,28 @@ impl DocumentFieldType { } DocumentFieldType::Integer => { let value_as_i64: i64 = value.to_integer().map_err(ProtocolError::ValueError)?; - let mut value_bytes = value_as_i64.to_be_bytes().to_vec(); - if required { - Ok(value_bytes) - } else { - // if the value wasn't required we need to add a byte to prove it existed - let mut r_vec = vec![255u8]; - r_vec.append(&mut value_bytes); - Ok(r_vec) - } + Ok(value_as_i64.to_be_bytes().to_vec()) } DocumentFieldType::Number => { let value_as_f64 = value.to_float().map_err(ProtocolError::ValueError)?; - let mut value_bytes = value_as_f64.to_be_bytes().to_vec(); - if required { - Ok(value_bytes) - } else { - // if the value wasn't required we need to add a byte to prove it existed - let mut r_vec = vec![255u8]; - r_vec.append(&mut value_bytes); - Ok(r_vec) - } + Ok(value_as_f64.to_be_bytes().to_vec()) } - DocumentFieldType::ByteArray(_, _) => { - let mut bytes = value.to_binary_bytes()?; + DocumentFieldType::ByteArray(min, max) => { + match (min, max) { + (Some(min), Some(max)) if min == max => { + Ok(value.to_binary_bytes()?) + } + _ => { + let mut bytes = value.to_binary_bytes()?; - let mut r_vec = bytes.len().encode_var_vec(); - r_vec.append(&mut bytes); - Ok(r_vec) + let mut r_vec = bytes.len().encode_var_vec(); + r_vec.append(&mut bytes); + Ok(r_vec) + } + } } DocumentFieldType::Identifier => { - let mut bytes = value.to_identifier_bytes()?; - - let mut r_vec = bytes.len().encode_var_vec(); - r_vec.append(&mut bytes); - Ok(r_vec) + Ok(value.to_identifier_bytes()?) } DocumentFieldType::Boolean => { let value_as_boolean = value.as_bool().ok_or_else(get_field_type_matching_error)?; @@ -604,7 +595,7 @@ impl DocumentFieldType { if value_as_boolean { Ok(vec![1]) // 1 is true } else { - Ok(vec![2]) // 2 is false + Ok(vec![0]) // 0 is false } } DocumentFieldType::Object(inner_fields) => { @@ -615,6 +606,9 @@ impl DocumentFieldType { let mut r_vec = vec![]; inner_fields.iter().try_for_each(|(key, field)| { if let Some(value) = value_map.get(key) { + if !field.required { + r_vec.push(1); + } let value = field .document_type .encode_value_ref_with_size(value, field.required)?; diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 2d564f1fdb3..c122fe4fab9 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -93,6 +93,9 @@ impl Document { .try_for_each(|(field_name, field)| { if field_name == CREATED_AT { if let Some(created_at) = self.created_at { + if !field.required { + buffer.push(1); + } // dbg!("we pushed created at {}", hex::encode(created_at.to_be_bytes())); buffer.extend(created_at.to_be_bytes()); Ok(()) @@ -110,6 +113,9 @@ impl Document { } } else if field_name == UPDATED_AT { if let Some(updated_at) = self.updated_at { + if !field.required { + buffer.push(1); + } // dbg!("we pushed updated at {}", hex::encode(updated_at.to_be_bytes())); buffer.extend(updated_at.to_be_bytes()); Ok(()) @@ -126,12 +132,29 @@ impl Document { Ok(()) } } else if let Some(value) = self.properties.get(field_name) { - let value = field - .document_type - .encode_value_ref_with_size(value, field.required)?; - // dbg!("we pushed {} with {}", field_name, hex::encode(&value)); - buffer.extend(value.as_slice()); - Ok(()) + if value.is_null() { + if field.required { + Err(ProtocolError::DataContractError( + DataContractError::MissingRequiredKey("a required field is not present"), + )) + } else { + // dbg!("we pushed {} with 0", field_name); + // We don't have something that wasn't required + buffer.push(0); + Ok(()) + } + } else { + if !field.required { + // dbg!("we added 1", field_name); + buffer.push(1); + } + let value = field + .document_type + .encode_value_ref_with_size(value, field.required)?; + // dbg!("we pushed {} with {}", field_name, hex::encode(&value)); + buffer.extend(value.as_slice()); + Ok(()) + } } else if field.required { Err(ProtocolError::DataContractError( DataContractError::MissingRequiredKey("a required field is not present"), @@ -268,7 +291,7 @@ impl Document { match marker_result { Ok(marker) => { if marker == 0 { - return None; + return Some(Ok((key.clone(), Value::Null))); } } Err(e) => return Some(Err(e)), @@ -296,7 +319,7 @@ impl Document { match marker_result { Ok(marker) => { if marker == 0 { - return None; + return Some(Ok((key.clone(), Value::Null))); } } Err(e) => return Some(Err(e)), diff --git a/packages/rs-drive/src/drive/document/delete.rs b/packages/rs-drive/src/drive/document/delete.rs index 72b049790db..5797ffa049e 100644 --- a/packages/rs-drive/src/drive/document/delete.rs +++ b/packages/rs-drive/src/drive/document/delete.rs @@ -1035,6 +1035,7 @@ mod tests { .document_type_for_name("person") .expect("expected to get a document type"); + dbg!(document_type); let random_owner_id0 = rand::thread_rng().gen::<[u8; 32]>(); let person_document0 = json_document_to_document( @@ -1047,7 +1048,7 @@ mod tests { let serialized = person_document0 .serialize(&document_type) .expect("expected to serialize"); - + dbg!(hex::encode(&serialized)); let deserialized = Document::from_bytes(&serialized, &document_type).expect("expected to deserialize"); } @@ -1539,8 +1540,8 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - // We added 1553 bytes - assert_eq!(added_bytes, 1553); + // We added 1556 bytes + assert_eq!(added_bytes, 1556); let document_id = bs58::decode("AM47xnyLfTAC9f61ZQPGfMK5Datk2FeYZwgYvcAnzqFY") .into_vec() @@ -1569,14 +1570,14 @@ mod tests { .get(&0) .unwrap(); - assert_eq!(*removed_credits, 41511232); + assert_eq!(*removed_credits, 41591420); let refund_equivalent_bytes = removed_credits.to_unsigned() / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); assert!(added_bytes > refund_equivalent_bytes); - assert_eq!(refund_equivalent_bytes, 1537); // we refunded 1537 instead of 1553 + assert_eq!(refund_equivalent_bytes, 1540); // we refunded 1540 instead of 1556 } #[test] @@ -1637,7 +1638,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); // We added 1553 bytes - assert_eq!(added_bytes, 1553); + assert_eq!(added_bytes, 1556); let document_id = bs58::decode("AM47xnyLfTAC9f61ZQPGfMK5Datk2FeYZwgYvcAnzqFY") .into_vec() diff --git a/packages/rs-drive/src/drive/document/insert.rs b/packages/rs-drive/src/drive/document/insert.rs index 77ee2591621..5fb9f227962 100644 --- a/packages/rs-drive/src/drive/document/insert.rs +++ b/packages/rs-drive/src/drive/document/insert.rs @@ -1497,11 +1497,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 3057 + storage_fee: 3055 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 2316870, + processing_fee: 2316070, ..Default::default() } ); @@ -1561,11 +1561,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 1299 + storage_fee: 1302 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 1495610, + processing_fee: 1496810, ..Default::default() } ); @@ -1631,8 +1631,8 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - assert_eq!(1299, added_bytes); - assert_eq!(145123200, processing_fee); + assert_eq!(1302, added_bytes); + assert_eq!(145124400, processing_fee); } #[test] @@ -1855,11 +1855,11 @@ mod tests { assert_eq!( fee_result, FeeResult { - storage_fee: 1749 + storage_fee: 1748 * Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte), - processing_fee: 2083790, + processing_fee: 2083390, ..Default::default() } ); diff --git a/packages/rs-drive/src/drive/document/update.rs b/packages/rs-drive/src/drive/document/update.rs index 2972aea3400..c46e4d95361 100644 --- a/packages/rs-drive/src/drive/document/update.rs +++ b/packages/rs-drive/src/drive/document/update.rs @@ -1513,17 +1513,17 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); let expected_added_bytes = if using_history { - //Explanation for 1233 + //Explanation for 1235 //todo - 1233 + 1235 } else { - //Explanation for 957 + //Explanation for 959 // Document Storage //// Item - // = 354 Bytes + // = 356 Bytes // Explanation for 354 storage_written_bytes @@ -1538,7 +1538,7 @@ mod tests { // 35 for flags 32 + 1 + 2 // 1 for the enum type // 1 for item - // 115 for item serialized bytes (verified above) + // 117 for item serialized bytes (verified above) // 1 for Basic Merk // 32 for node hash // 32 for value hash @@ -1649,9 +1649,9 @@ mod tests { // Total 65 + 145 + 68 = 278 - //// 354 + 179 + 145 + 278 + //// 356 + 179 + 145 + 278 - 957 + 959 }; assert_eq!(original_bytes, expected_added_bytes); @@ -1673,14 +1673,14 @@ mod tests { .get(&0) .unwrap(); - assert_eq!(*removed_credits, 25773863); + assert_eq!(*removed_credits, 25827688); let refund_equivalent_bytes = removed_credits.to_unsigned() / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); assert!(expected_added_bytes > refund_equivalent_bytes); - assert_eq!(refund_equivalent_bytes, 954); // we refunded 1008 instead of 1011 + assert_eq!(refund_equivalent_bytes, 956); // we refunded 956 instead of 959 // let's re-add it again let original_fees = apply_person( @@ -1716,7 +1716,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 308 } else { 1 }; + let expected_added_bytes = if using_history { 310 } else { 1 }; assert_eq!(added_bytes, expected_added_bytes); } @@ -1785,7 +1785,7 @@ mod tests { / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1233 } else { 957 }; + let expected_added_bytes = if using_history { 1235 } else { 959 }; assert_eq!(original_bytes, expected_added_bytes); if !using_history { // let's delete it, just to make sure everything is working. @@ -1804,14 +1804,14 @@ mod tests { .get(&0) .unwrap(); - assert_eq!(*removed_credits, 25773863); + assert_eq!(*removed_credits, 25827688); let refund_equivalent_bytes = removed_credits.to_unsigned() / Epoch::new(0) .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); assert!(expected_added_bytes > refund_equivalent_bytes); - assert_eq!(refund_equivalent_bytes, 954); // we refunded 1008 instead of 1011 + assert_eq!(refund_equivalent_bytes, 956); // we refunded 1008 instead of 1011 // let's re-add it again let original_fees = apply_person( @@ -1976,12 +1976,12 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); let expected_added_bytes = if using_history { - //Explanation for 1233 + //Explanation for 1235 //todo - 1233 + 1235 } else { - //Explanation for 957 + //Explanation for 959 // Document Storage @@ -2112,9 +2112,9 @@ mod tests { // Total 65 + 145 + 68 = 278 - // 355 + 179 + 145 + 278 = 957 + // 357 + 179 + 145 + 278 = 959 - 957 + 959 }; assert_eq!(original_bytes, expected_added_bytes); @@ -2134,7 +2134,7 @@ mod tests { .unwrap() .cost_for_known_cost_item(StorageDiskUsageCreditPerByte); - let expected_added_bytes = if using_history { 1234 } else { 958 }; + let expected_added_bytes = if using_history { 1236 } else { 960 }; assert_eq!(added_bytes, expected_added_bytes); } diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index b5e188b6e32..aa2fa86416e 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -95,6 +95,8 @@ use dpp::platform_value::{platform_value, BinaryData, Bytes32, Identifier}; use dpp::block::block_info::BlockInfo; use dpp::data_contract::extra::common::json_document_to_contract; use dpp::platform_value; +use dpp::platform_value::btreemap_extensions::BTreeValueMapInsertionPathHelper; +use dpp::platform_value::Value::Null; #[cfg(feature = "full")] use dpp::prelude::DataContract; use dpp::prelude::Revision; @@ -297,7 +299,7 @@ pub fn setup_family_tests_with_nulls(count: u32, seed: u64) -> (Drive, Contract) // setup code let contract = common::setup_contract( &drive, - "tests/supporting_files/contract/family/family-contract.json", + "tests/supporting_files/contract/family/family-contract-fields-optional.json", None, Some(&db_transaction), ); @@ -456,7 +458,6 @@ fn test_serialization_and_deserialization() { let document_type = contract .document_type_for_name("domain") .expect("expected to get document type"); - dbg!(document_type); for domain in domains { let value = platform_value::to_value(domain).expect("expected value"); let mut document = Document::from_platform_value(value).expect("expected value"); @@ -466,10 +467,90 @@ fn test_serialization_and_deserialization() { .expect("expected to serialize domain document"); let deserialized = Document::from_bytes(&serialized, document_type) .expect("expected to deserialize domain document"); - assert_eq!(document, deserialized); } } +#[cfg(feature = "full")] +#[test] +fn test_serialization_and_deserialization_with_null_values_should_fail_if_required() { + let contract = + json_document_to_contract("tests/supporting_files/contract/dpns/dpns-contract.json") + .expect("expected to get cbor contract"); + + let document_type = contract + .document_type_for_name("domain") + .expect("expected to get document type"); + + let mut rng = rand::rngs::StdRng::seed_from_u64(5); + + let domain = Domain { + id: Identifier::random_with_rng(&mut rng), + owner_id: Identifier::random_with_rng(&mut rng), + label: None, + normalized_label: None, + normalized_parent_domain_name: "dash".to_string(), + records: Records { + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), + }, + preorder_salt: Bytes32::random_with_rng(&mut rng), + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, + }; + + let value = platform_value::to_value(domain).expect("expected value"); + let mut document = Document::from_platform_value(value).expect("expected value"); + document.revision = Some(1); + document + .serialize(document_type) + .expect_err("expected to not be able to serialize domain document"); +} + +#[cfg(feature = "full")] +#[test] +fn test_serialization_and_deserialization_with_null_values() { + let contract = json_document_to_contract( + "tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json", + ) + .expect("expected to get cbor contract"); + + let document_type = contract + .document_type_for_name("domain") + .expect("expected to get document type"); + + let mut rng = rand::rngs::StdRng::seed_from_u64(5); + + let domain = Domain { + id: Identifier::random_with_rng(&mut rng), + owner_id: Identifier::random_with_rng(&mut rng), + label: None, + normalized_label: None, + normalized_parent_domain_name: "dash".to_string(), + records: Records { + dash_unique_identity_id: Identifier::random_with_rng(&mut rng), + }, + preorder_salt: Bytes32::random_with_rng(&mut rng), + subdomain_rules: SubdomainRules { + allow_subdomains: false, + }, + }; + + let mut value = platform_value::to_value(domain).expect("expected value"); + value + .remove_optional_value("label") + .expect("expected to remove null"); + value + .remove_optional_value("normalizedLabel") + .expect("expected to remove null"); + let mut document = Document::from_platform_value(value).expect("expected value"); + document.revision = Some(1); + let serialized = document + .serialize(document_type) + .expect("expected to be able to serialize domain document"); + Document::from_bytes(&serialized, document_type) + .expect("expected to deserialize domain document"); +} + #[cfg(feature = "full")] impl Domain { /// Creates `count` random names as domain names for the given parent domain @@ -577,6 +658,40 @@ pub fn setup_dpns_tests_with_batches(count: u32, seed: u64) -> (Drive, Contract) (drive, contract) } +#[cfg(feature = "full")] +/// Sets up and inserts random domain name data to the DPNS contract to test queries on. +pub fn setup_dpns_tests_label_not_required(count: u32, seed: u64) -> (Drive, Contract) { + let drive = setup_drive(Some(DriveConfig::default())); + + let db_transaction = drive.grove.start_transaction(); + + // Create contracts tree + let mut batch = GroveDbOpBatch::new(); + + add_init_contracts_structure_operations(&mut batch); + + drive + .grove_apply_batch(batch, false, Some(&db_transaction)) + .expect("expected to create contracts tree successfully"); + + // setup code + let contract = setup_contract( + &drive, + "tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json", + None, + Some(&db_transaction), + ); + + add_domains_to_contract(&drive, &contract, Some(&db_transaction), count, seed); + drive + .grove + .commit_transaction(db_transaction) + .unwrap() + .expect("transaction should be committed"); + + (drive, contract) +} + #[cfg(feature = "full")] /// Sets up the DPNS contract and inserts data from the given path to test queries on. pub fn setup_dpns_test_with_data(path: &str) -> (Drive, Contract) { @@ -792,8 +907,8 @@ fn test_family_basic_queries() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 178, 236, 137, 244, 12, 216, 5, 234, 232, 88, 124, 87, 0, 219, 236, 153, 67, 36, 226, 34, - 73, 82, 197, 167, 229, 202, 206, 121, 83, 206, 65, 232, + 181, 109, 8, 213, 170, 216, 114, 214, 14, 29, 33, 19, 214, 194, 147, 208, 69, 229, 255, 17, + 194, 142, 198, 188, 9, 141, 124, 102, 165, 16, 120, 237, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2041,8 +2156,8 @@ fn test_family_basic_queries() { assert_eq!( root_hash.as_slice(), vec![ - 128, 53, 185, 186, 232, 226, 12, 157, 184, 63, 83, 178, 62, 1, 89, 27, 89, 135, 117, - 147, 87, 217, 100, 175, 152, 113, 89, 122, 105, 213, 224, 149, + 122, 226, 108, 85, 10, 26, 53, 19, 226, 252, 13, 68, 155, 226, 231, 159, 52, 180, 74, + 65, 95, 241, 28, 9, 64, 194, 200, 104, 34, 44, 172, 217, ], ); } @@ -2061,8 +2176,8 @@ fn test_family_starts_at_queries() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 178, 236, 137, 244, 12, 216, 5, 234, 232, 88, 124, 87, 0, 219, 236, 153, 67, 36, 226, 34, - 73, 82, 197, 167, 229, 202, 206, 121, 83, 206, 65, 232, + 181, 109, 8, 213, 170, 216, 114, 214, 14, 29, 33, 19, 214, 194, 147, 208, 69, 229, 255, 17, + 194, 142, 198, 188, 9, 141, 124, 102, 165, 16, 120, 237, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2450,8 +2565,8 @@ fn test_family_with_nulls_query() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 213, 209, 8, 112, 10, 188, 65, 168, 82, 180, 236, 252, 137, 4, 76, 109, 171, 144, 32, 189, - 65, 139, 45, 234, 210, 78, 245, 227, 15, 155, 19, 221, + 35, 178, 180, 34, 225, 111, 160, 55, 202, 140, 247, 123, 80, 10, 164, 156, 176, 97, 11, + 225, 137, 192, 40, 254, 180, 159, 110, 122, 148, 85, 21, 195, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2567,8 +2682,8 @@ fn test_query_with_cached_contract() { // Make sure the state is deterministic let expected_app_hash = vec![ - 178, 236, 137, 244, 12, 216, 5, 234, 232, 88, 124, 87, 0, 219, 236, 153, 67, 36, 226, 34, - 73, 82, 197, 167, 229, 202, 206, 121, 83, 206, 65, 232, + 181, 109, 8, 213, 170, 216, 114, 214, 14, 29, 33, 19, 214, 194, 147, 208, 69, 229, 255, 17, + 194, 142, 198, 188, 9, 141, 124, 102, 165, 16, 120, 237, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2626,8 +2741,8 @@ fn test_dpns_query() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, - 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, + 54, 250, 97, 187, 157, 71, 4, 189, 235, 29, 185, 87, 218, 5, 29, 24, 104, 209, 223, 84, 79, + 98, 29, 243, 225, 220, 244, 162, 174, 131, 72, 224, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2869,7 +2984,7 @@ fn test_dpns_query() { assert_eq!(root_hash, proof_root_hash); assert_eq!(results, proof_results); - let record_id_base64: Vec = results + let record_id_base68: Vec = results .into_iter() .map(|result| { let document = Document::from_bytes(result.as_slice(), domain_document_type) @@ -2884,19 +2999,19 @@ fn test_dpns_query() { Value::inner_optional_bytes_value(map_records_value, "dashUniqueIdentityId") .unwrap() .expect("there should be a dashUniqueIdentityId"); - base64::encode(record_dash_unique_identity_id) + bs58::encode(record_dash_unique_identity_id).into_string() }) .collect(); - let a_record_id_base64 = ["RdBiF9ph2C6C4dRhT9C/xVSoOxb+uvduuLlT/0EEDZA=".to_string()]; + let a_record_id_base58 = ["5hXRj1xmmnNQ7RN1ATYym4x6bQugxcKn7FWiMnkQTQpF".to_string()]; - assert_eq!(record_id_base64, a_record_id_base64); + assert_eq!(record_id_base68, a_record_id_base58); // A query getting elements by the dashUniqueIdentityId desc let query_value = json!({ "where": [ - ["records.dashUniqueIdentityId", "<=", "RdBiF9ph2C6C4dRhT9C/xVSoOxb+uvduuLlT/0EEDZA="], + ["records.dashUniqueIdentityId", "<=", "5hXRj1xmmnNQ7RN1ATYym4x6bQugxcKn7FWiMnkQTQpF"], ], "limit": 10, "orderBy": [ @@ -2948,7 +3063,7 @@ fn test_dpns_query() { let query_value = json!({ "where": [ - ["records.dashUniqueIdentityId", "<=", "RdBiF9ph2C6C4dRhT9C/xVSoOxb+uvduuLlT/0EEDZA="], + ["records.dashUniqueIdentityId", "<=", "5hXRj1xmmnNQ7RN1ATYym4x6bQugxcKn7FWiMnkQTQpF"], ], "limit": 2, "orderBy": [ @@ -3141,8 +3256,8 @@ fn test_dpns_query_start_at() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, - 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, + 54, 250, 97, 187, 157, 71, 4, 189, 235, 29, 185, 87, 218, 5, 29, 24, 104, 209, 223, 84, 79, + 98, 29, 243, 225, 220, 244, 162, 174, 131, 72, 224, ]; assert_eq!(root_hash.as_slice(), expected_app_hash,); @@ -3229,8 +3344,8 @@ fn test_dpns_query_start_after() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, - 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, + 54, 250, 97, 187, 157, 71, 4, 189, 235, 29, 185, 87, 218, 5, 29, 24, 104, 209, 223, 84, 79, + 98, 29, 243, 225, 220, 244, 162, 174, 131, 72, 224, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3317,8 +3432,8 @@ fn test_dpns_query_start_at_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, - 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, + 54, 250, 97, 187, 157, 71, 4, 189, 235, 29, 185, 87, 218, 5, 29, 24, 104, 209, 223, 84, 79, + 98, 29, 243, 225, 220, 244, 162, 174, 131, 72, 224, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3405,8 +3520,8 @@ fn test_dpns_query_start_after_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 246, 202, 166, 148, 46, 62, 94, 55, 109, 113, 134, 119, 230, 189, 242, 30, 224, 66, 20, - 180, 169, 221, 231, 7, 113, 177, 49, 188, 79, 8, 97, 64, + 54, 250, 97, 187, 157, 71, 4, 189, 235, 29, 185, 87, 218, 5, 29, 24, 104, 209, 223, 84, 79, + 98, 29, 243, 225, 220, 244, 162, 174, 131, 72, 224, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3484,7 +3599,7 @@ fn test_dpns_query_start_at_with_null_id() { // The point of this test is to test the situation where we have a start at inside an index with a null value // While dpns doesn't really support this, other contracts might allow null values. // We are just using the DPNS contract because it is handy. - let (drive, contract) = setup_dpns_tests_with_batches(10, 11456); + let (drive, contract) = setup_dpns_tests_label_not_required(10, 11456); let document_type = contract .document_type_for_name("domain") @@ -3510,14 +3625,9 @@ fn test_dpns_query_start_at_with_null_id() { }, }; - let value0 = serde_json::to_value(&domain0).expect("serialized domain"); - let document_cbor0 = cbor_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"); + let value0 = platform_value::to_value(&domain0).expect("serialized domain"); + let document0 = + platform_value::from_value(value0).expect("document should be properly deserialized"); let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); @@ -3597,8 +3707,8 @@ fn test_dpns_query_start_at_with_null_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 231, 220, 135, 142, 39, 139, 213, 116, 86, 129, 140, 236, 104, 198, 230, 80, 35, 86, 36, 1, - 127, 177, 116, 51, 44, 156, 29, 157, 72, 235, 182, 181, + 190, 40, 187, 74, 248, 47, 25, 228, 232, 188, 239, 54, 120, 139, 47, 200, 120, 105, 80, 8, + 179, 214, 201, 248, 166, 6, 254, 182, 96, 41, 55, 127, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3684,7 +3794,7 @@ fn test_dpns_query_start_after_with_null_id() { // The point of this test is to test the situation where we have a start at inside an index with a null value // While dpns doesn't really support this, other contracts might allow null values. // We are just using the DPNS contract because it is handy. - let (drive, contract) = setup_dpns_tests_with_batches(10, 11456); + let (drive, contract) = setup_dpns_tests_label_not_required(10, 11456); let document_type = contract .document_type_for_name("domain") @@ -3798,8 +3908,8 @@ fn test_dpns_query_start_after_with_null_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 231, 220, 135, 142, 39, 139, 213, 116, 86, 129, 140, 236, 104, 198, 230, 80, 35, 86, 36, 1, - 127, 177, 116, 51, 44, 156, 29, 157, 72, 235, 182, 181, + 190, 40, 187, 74, 248, 47, 25, 228, 232, 188, 239, 54, 120, 139, 47, 200, 120, 105, 80, 8, + 179, 214, 201, 248, 166, 6, 254, 182, 96, 41, 55, 127, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3887,7 +3997,7 @@ fn test_dpns_query_start_after_with_null_id_desc() { // The point of this test is to test the situation where we have a start at inside an index with a null value // While dpns doesn't really support this, other contracts might allow null values. // We are just using the DPNS contract because it is handy. - let (drive, contract) = setup_dpns_tests_with_batches(10, 11456); + let (drive, contract) = setup_dpns_tests_label_not_required(10, 11456); let document_type = contract .document_type_for_name("domain") @@ -4001,8 +4111,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 231, 220, 135, 142, 39, 139, 213, 116, 86, 129, 140, 236, 104, 198, 230, 80, 35, 86, 36, 1, - 127, 177, 116, 51, 44, 156, 29, 157, 72, 235, 182, 181, + 190, 40, 187, 74, 248, 47, 25, 228, 232, 188, 239, 54, 120, 139, 47, 200, 120, 105, 80, 8, + 179, 214, 201, 248, 166, 6, 254, 182, 96, 41, 55, 127, ]; assert_eq!(root_hash.as_slice(), expected_app_hash,); diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 41bb9ca7ce6..133e56e1e60 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -285,8 +285,8 @@ fn test_query_historical() { assert_eq!( root_hash.as_slice(), vec![ - 140, 218, 169, 47, 164, 83, 109, 44, 50, 139, 214, 10, 233, 145, 82, 117, 131, 192, - 191, 239, 164, 63, 29, 154, 110, 116, 222, 137, 29, 71, 92, 184, + 222, 67, 79, 145, 168, 70, 218, 227, 10, 3, 153, 249, 35, 196, 119, 212, 66, 52, 94, + 22, 18, 133, 188, 20, 132, 161, 76, 88, 27, 29, 129, 117, ] ); @@ -327,7 +327,7 @@ fn test_query_historical() { let names: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -399,7 +399,7 @@ fn test_query_historical() { assert_eq!(results.len(), 1); - let document = Document::from_cbor(results.first().unwrap().as_slice(), None, None) + let document = Document::from_bytes(results.first().unwrap().as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let last_name = document .properties @@ -474,7 +474,7 @@ fn test_query_historical() { assert_eq!(results.len(), 1); - let document = Document::from_cbor(results.first().unwrap().as_slice(), None, None) + let document = Document::from_bytes(results.first().unwrap().as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let last_name = document .properties @@ -566,7 +566,7 @@ fn test_query_historical() { let names: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -612,7 +612,7 @@ fn test_query_historical() { let names: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -656,7 +656,7 @@ fn test_query_historical() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -686,7 +686,7 @@ fn test_query_historical() { let ids: HashMap> = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let name_value = document .properties @@ -732,7 +732,7 @@ fn test_query_historical() { let reduced_names_after: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -782,7 +782,7 @@ fn test_query_historical() { let reduced_names_after: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -824,7 +824,7 @@ fn test_query_historical() { let names: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -863,7 +863,7 @@ fn test_query_historical() { .clone() .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -879,7 +879,7 @@ fn test_query_historical() { let ages: Vec = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let age_value = document .properties @@ -933,7 +933,7 @@ fn test_query_historical() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -983,7 +983,7 @@ fn test_query_historical() { let names: Vec = results .iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let first_name_value = document .properties @@ -1009,7 +1009,7 @@ fn test_query_historical() { let ages: HashMap = results .into_iter() .map(|result| { - let document = Document::from_cbor(result.as_slice(), None, None) + let document = Document::from_bytes(result.as_slice(), person_document_type) .expect("we should be able to deserialize the cbor"); let name_value = document .properties @@ -1240,8 +1240,9 @@ fn test_query_historical() { assert_eq!(results.len(), 2); - let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let last_person = + Document::from_bytes(results.first().unwrap().as_slice(), person_document_type) + .expect("we should be able to deserialize the cbor"); assert_eq!( last_person.id.to_vec(), @@ -1281,8 +1282,9 @@ fn test_query_historical() { assert_eq!(results.len(), 2); - let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let last_person = + Document::from_bytes(results.first().unwrap().as_slice(), person_document_type) + .expect("we should be able to deserialize the cbor"); assert_eq!( last_person.id.to_vec(), @@ -1345,8 +1347,9 @@ fn test_query_historical() { assert_eq!(results.len(), 12); - let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) - .expect("we should be able to deserialize the cbor"); + let last_person = + Document::from_bytes(results.first().unwrap().as_slice(), person_document_type) + .expect("we should be able to deserialize the cbor"); assert_eq!( last_person.id.to_vec(), @@ -1397,7 +1400,7 @@ fn test_query_historical() { // assert_eq!(results.len(), 12); // - // let last_person = Document::from_cbor(results.first().unwrap().as_slice(), None, None) + // let last_person = Document::from_bytes(results.first().unwrap().as_slice(), person_document_type) // .expect("we should be able to deserialize the cbor"); // // assert_eq!( @@ -1588,8 +1591,8 @@ fn test_query_historical() { assert_eq!( root_hash.as_slice(), vec![ - 15, 83, 94, 236, 155, 187, 46, 209, 146, 1, 178, 253, 105, 27, 170, 160, 8, 102, 194, - 119, 30, 106, 12, 148, 59, 54, 179, 124, 99, 138, 97, 17, + 26, 7, 58, 46, 191, 247, 204, 52, 118, 248, 249, 101, 112, 98, 127, 148, 113, 216, 206, + 119, 165, 38, 13, 23, 219, 176, 105, 206, 188, 75, 176, 34, ] ); } diff --git a/packages/rs-drive/tests/supporting_files/contract/dpns/domain0.json b/packages/rs-drive/tests/supporting_files/contract/dpns/domain0.json index ffc3abbdbfa..e06db44a998 100644 --- a/packages/rs-drive/tests/supporting_files/contract/dpns/domain0.json +++ b/packages/rs-drive/tests/supporting_files/contract/dpns/domain0.json @@ -8,7 +8,7 @@ "normalizedParentDomainName": "dashpay", "preorderSalt": "SysX9ol1uoyAaEbFzImAcPP2JCO+ydh/Lb6ES0wU8Tc=", "records": { - "dashUniqueIdentityId": "SysX9ol1uoyAaEbFzImAcPP2JCO+ydh/Lb6ES0wU8Tc=" + "dashUniqueIdentityId": "AYjYxDqLy2hvGQADqE6FAkBnQEpJSzNd3CRw1tpS6vZ7" }, "subdomainRules": { "allowSubdomains": false diff --git a/packages/rs-drive/tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json b/packages/rs-drive/tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json new file mode 100644 index 00000000000..8414df2e446 --- /dev/null +++ b/packages/rs-drive/tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json @@ -0,0 +1,151 @@ +{ + "$id": "9Lo6Fq1idp7YG3Egqf2YmQk4DQr9P8D543GwXyCJRyG", + "ownerId": "AcYUCSvAmUwryNsQqkqqD1o3BnFuzepGtR3Mhh2swLk6", + "$schema": "https://schema.dash.org/dpp-0-4-0/meta/data-contract", + "version": 1, + "documents": { + "domain": { + "type": "object", + "indices": [ + { + "name": "parentNameAndLabel", + "properties": [ + { + "normalizedParentDomainName": "asc" + }, + { + "normalizedLabel": "asc" + } + ], + "unique": true + }, + { + "name": "dashIdentityId", + "properties": [ + { + "records.dashUniqueIdentityId": "asc" + } + ], + "unique": true + }, + { + "name": "dashAlias", + "properties": [ + { + "records.dashAliasIdentityId": "asc" + } + ] + } + ], + "properties": { + "label": { + "type": "string", + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9]$", + "minLength": 3, + "maxLength": 63, + "description": "Domain label. e.g. 'Bob'." + }, + "normalizedLabel": { + "type": "string", + "pattern": "^[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$", + "maxLength": 63, + "description": "Domain label in lowercase for case-insensitive uniqueness validation. e.g. 'bob'", + "$comment": "Must be equal to the label in lowercase. This property will be deprecated due to case insensitive indices" + }, + "normalizedParentDomainName": { + "type": "string", + "pattern": "^$|^[[a-z0-9][a-z0-9-\\.]{0,188}[a-z0-9]$", + "minLength": 0, + "maxLength": 190, + "description": "A full parent domain name in lowercase for case-insensitive uniqueness validation. e.g. 'dash'", + "$comment": "Must either be equal to an existing domain or empty to create a top level domain. Only the data contract owner can create top level domains." + }, + "preorderSalt": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "Salt used in the preorder document" + }, + "records": { + "type": "object", + "properties": { + "dashUniqueIdentityId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "contentMediaType": "application/x.dash.dpp.identifier", + "description": "Identity ID to be used to create the primary name the Identity", + "$comment": "Must be equal to the document owner" + }, + "dashAliasIdentityId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "contentMediaType": "application/x.dash.dpp.identifier", + "description": "Identity ID to be used to create alias names for the Identity", + "$comment": "Must be equal to the document owner" + } + }, + "$comment": "Constraint with max and min properties ensure that only one identity record is used - either a `dashUniqueIdentityId` or a `dashAliasIdentityId`", + "minProperties": 1, + "maxProperties": 1, + "additionalProperties": false + }, + "subdomainRules": { + "type": "object", + "properties": { + "allowSubdomains": { + "type": "boolean", + "description": "This option defines who can create subdomains: true - anyone; false - only the domain owner", + "$comment": "Only the domain owner is allowed to create subdomains for non top-level domains" + } + }, + "description": "Subdomain rules allow domain owners to define rules for subdomains", + "additionalProperties": false, + "required": [ + "allowSubdomains" + ] + } + }, + "required": [ + "normalizedParentDomainName", + "preorderSalt", + "records", + "subdomainRules" + ], + "additionalProperties": false, + "$comment": "In order to register a domain you need to create a preorder. The preorder step is needed to prevent man-in-the-middle attacks. normalizedLabel + '.' + normalizedParentDomain must not be longer than 253 chars length as defined by RFC 1035. Domain documents are immutable: modification and deletion are restricted" + }, + "preorder": { + "type": "object", + "indices": [ + { + "name": "saltedHash", + "properties": [ + { + "saltedDomainHash": "asc" + } + ], + "unique": true + } + ], + "properties": { + "saltedDomainHash": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "Double sha-256 of the concatenation of a 32 byte random salt and a normalized domain name" + } + }, + "required": [ + "saltedDomainHash" + ], + "additionalProperties": false, + "$comment": "Preorder documents are immutable: modification and deletion are restricted" + } + } +} \ No newline at end of file diff --git a/packages/rs-drive/tests/supporting_files/contract/family/family-contract-fields-optional.json b/packages/rs-drive/tests/supporting_files/contract/family/family-contract-fields-optional.json new file mode 100644 index 00000000000..c47b96ce67c --- /dev/null +++ b/packages/rs-drive/tests/supporting_files/contract/family/family-contract-fields-optional.json @@ -0,0 +1,109 @@ +{ + "$id": "94zNLp7A1ZcYG3Egqf2YmQk4DQr9P8D543GwXyCJRz4", + "ownerId": "AcYUCSvAmUwryNsQqkqqD1o3BnFuzepGtR3Mhh2swLk6", + "$schema": "https://schema.dash.org/dpp-0-4-0/meta/data-contract", + "version": 1, + "documents": { + "person": { + "indices": [ + { + "properties": [ + { + "$ownerId": "asc" + } + ] + }, + { + "properties": [ + { + "middleName": "asc" + } + ] + }, + { + "properties": [ + { + "firstName": "asc" + } + ] + }, + { + "properties": [ + { + "firstName": "asc" + }, + { + "age": "asc" + } + ] + }, + { + "properties": [ + { + "firstName": "asc" + }, + { + "lastName": "asc" + } + ] + }, + { + "properties": [ + { + "firstName": "asc" + }, + { + "middleName": "asc" + }, + { + "lastName": "asc" + } + ] + }, + { + "properties": [ + { + "age": "asc" + }, + { + "firstName": "asc" + }, + { + "middleName": "asc" + }, + { + "lastName": "asc" + } + ] + }, + { + "properties": [ + { + "age": "asc" + } + ] + } + ], + "properties": { + "age": { + "type": "integer" + }, + "firstName": { + "type": "string", + "maxLength": 50 + }, + "middleName": { + "type": "string", + "maxLength": 50 + }, + "lastName": { + "type": "string", + "maxLength": 50 + } + }, + "required": [ + ], + "additionalProperties": false + } + } +} \ No newline at end of file From 434585e2b278316e86b0f85bd501102422c29645 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 14:48:29 +0700 Subject: [PATCH 48/50] fixes --- .../document_type/document_field.rs | 15 ++++---- .../src/data_contract/errors/contract.rs | 2 +- packages/rs-dpp/src/document/serialize.rs | 15 ++++---- .../withdrawals_data_triggers/mod.rs | 35 +++++++++++++++++-- .../execution/fee_pools/fee_distribution.rs | 22 +++--------- packages/rs-drive-abci/src/state/genesis.rs | 3 +- .../schema/withdrawals-documents.json | 3 +- 7 files changed, 55 insertions(+), 40 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 58168266d59..2662c1d6d3c 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 @@ -357,13 +357,10 @@ impl DocumentFieldType { } _ => { let bytes = Self::read_varint_value(buf)?; - Ok(Some(match bytes.len() { - 32 => Value::Bytes32(bytes.try_into().unwrap()), - 20 => Value::Bytes20(bytes.try_into().unwrap()), - 36 => Value::Bytes36(bytes.try_into().unwrap()), - _ => Value::Bytes(bytes) - }) - ) + + + + Ok(Some(Value::Bytes(bytes))) } } @@ -499,7 +496,7 @@ impl DocumentFieldType { } else if field.required { Err(ProtocolError::DataContractError( DataContractError::MissingRequiredKey( - "a required field is not present", + "a required field is not present".to_string(), ), )) } else { @@ -617,7 +614,7 @@ impl DocumentFieldType { } else if field.required { Err(ProtocolError::DataContractError( DataContractError::MissingRequiredKey( - "a required field is not present", + "a required field is not present".to_string(), ), )) } else { diff --git a/packages/rs-dpp/src/data_contract/errors/contract.rs b/packages/rs-dpp/src/data_contract/errors/contract.rs index 670ae1f45b6..942f009be2e 100644 --- a/packages/rs-dpp/src/data_contract/errors/contract.rs +++ b/packages/rs-dpp/src/data_contract/errors/contract.rs @@ -19,7 +19,7 @@ pub enum DataContractError { InvalidDocumentTypeError(InvalidDocumentTypeError), #[error("missing required key: {0}")] - MissingRequiredKey(&'static str), + MissingRequiredKey(String), #[error("field requirement unmet: {0}")] FieldRequirementUnmet(&'static str), diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index c122fe4fab9..4a7f56ace53 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -102,7 +102,7 @@ impl Document { } else if field.required { Err(ProtocolError::DataContractError( DataContractError::MissingRequiredKey( - "created at field is not present", + "created at field is not present".to_string(), ), )) } else { @@ -114,6 +114,7 @@ impl Document { } else if field_name == UPDATED_AT { if let Some(updated_at) = self.updated_at { if !field.required { + // dbg!("we added 1", field_name); buffer.push(1); } // dbg!("we pushed updated at {}", hex::encode(updated_at.to_be_bytes())); @@ -122,7 +123,7 @@ impl Document { } else if field.required { Err(ProtocolError::DataContractError( DataContractError::MissingRequiredKey( - "updated at field is not present", + "updated at field is not present".to_string(), ), )) } else { @@ -135,7 +136,7 @@ impl Document { if value.is_null() { if field.required { Err(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey("a required field is not present"), + DataContractError::MissingRequiredKey("a required field is not present".to_string()), )) } else { // dbg!("we pushed {} with 0", field_name); @@ -157,7 +158,7 @@ impl Document { } } else if field.required { Err(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey("a required field is not present"), + DataContractError::MissingRequiredKey(format!("a required field {field_name} is not present")), )) } else { // dbg!("we pushed {} with 0", field_name); @@ -196,7 +197,7 @@ impl Document { } else if field.required { Err(ProtocolError::DataContractError( DataContractError::MissingRequiredKey( - "created at field is not present", + "created at field is not present".to_string(), ), )) } else { @@ -211,7 +212,7 @@ impl Document { } else if field.required { Err(ProtocolError::DataContractError( DataContractError::MissingRequiredKey( - "created at field is not present", + "created at field is not present".to_string(), ), )) } else { @@ -227,7 +228,7 @@ impl Document { Ok(()) } else if field.required { Err(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey("a required field is not present"), + DataContractError::MissingRequiredKey("a required field is not present".to_string()), )) } else { // We don't have something that wasn't required diff --git a/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs index 2eccae4d1cc..6c35e6033a1 100644 --- a/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs @@ -117,11 +117,12 @@ mod tests { use crate::platform::PlatformStateRef; use crate::test::helpers::setup::TestPlatformBuilder; use dpp::block::block_info::BlockInfo; + use dpp::document::Document; use dpp::document::document_transition::{ DocumentBaseTransitionAction, DocumentDeleteTransitionAction, }; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; - use dpp::platform_value::{platform_value, Bytes20}; + use dpp::platform_value::{platform_value, Bytes20, Bytes32}; use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use dpp::tests::fixtures::{get_data_contract_fixture, get_withdrawal_document_fixture}; @@ -163,6 +164,36 @@ mod tests { ); } + #[test] + fn can_serialize_and_deserialize_withdrawal() { + let data_contract = load_system_data_contract(SystemDataContract::Withdrawals) + .expect("to load system data contract"); + let owner_id = data_contract.owner_id; + + let document_type = data_contract + .document_type_for_name(withdrawals_contract::document_types::WITHDRAWAL) + .expect("expected to get withdrawal document type"); + let document = get_withdrawal_document_fixture( + &data_contract, + owner_id, + platform_value!({ + "amount": 1000u64, + "coreFeePerByte": 1u32, + "pooling": Pooling::Never as u8, + "outputScript": (0..23).collect::>(), + "status": withdrawals_contract::WithdrawalStatus::BROADCASTED as u8, + "transactionIndex": 1u64, + "transactionSignHeight": 93u64, + "transactionId": Bytes32::new([1;32]), + }), + None, + ) + .expect("expected withdrawal document"); + + let serialized = document.serialize(document_type).expect("expected to serialize document"); + Document::from_bytes(&serialized, document_type).expect("expected to deserialize document"); + } + #[test] fn should_throw_error_if_withdrawal_has_wrong_status() { let platform = TestPlatformBuilder::new() @@ -197,7 +228,7 @@ mod tests { "status": withdrawals_contract::WithdrawalStatus::BROADCASTED as u8, "transactionIndex": 1u64, "transactionSignHeight": 93u64, - "transactionId": Bytes20::new([1;20]), + "transactionId": Bytes32::new([1;32]), }), None, ) 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 64492201cab..f14f2e9f250 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 @@ -40,6 +40,8 @@ use crate::error::Error; use crate::platform::Platform; use dpp::block::block_info::BlockInfo; use dpp::block::epoch::Epoch; +use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; +use dpp::ProtocolError; use drive::drive::batch::drive_op_batch::IdentityOperationType::AddToIdentityBalance; use drive::drive::batch::DriveOperation::IdentityOperation; use drive::drive::batch::GroveDbOpBatch; @@ -273,23 +275,9 @@ impl Platform { self.get_reward_shares_list_for_masternode(&proposer_tx_hash, Some(transaction))?; for document in documents { - let pay_to_id: [u8; 32] = document + let pay_to_id = document .properties - .get("payToId") - .ok_or(Error::Execution(ExecutionError::DriveMissingData( - "payToId property is missing", - )))? - .as_bytes() - .ok_or(Error::Execution(ExecutionError::DriveIncoherence( - "payToId property type is not bytes", - )))? - .clone() - .try_into() - .map_err(|_| { - Error::Execution(ExecutionError::DriveIncoherence( - "payToId property type is not 32 bytes long", - )) - })?; + .get_identifier("payToId").map_err(|e| Error::Protocol(ProtocolError::ValueError(e)))?; // TODO this shouldn't be a percentage we need to update masternode share contract let share_percentage: u64 = document @@ -320,7 +308,7 @@ impl Platform { )))?; drive_operations.push(IdentityOperation(AddToIdentityBalance { - identity_id: pay_to_id, + identity_id: pay_to_id.to_buffer(), added_balance: share_reward, })); } diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index b7967b2e55a..96886bf5c0d 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -266,8 +266,7 @@ mod tests { assert_eq!( root_hash, [ - 223, 137, 33, 5, 253, 177, 248, 37, 0, 40, 198, 213, 196, 196, 66, 200, 71, 85, - 103, 138, 52, 63, 102, 105, 27, 86, 102, 242, 79, 247, 217, 108 + 95, 141, 114, 61, 67, 111, 218, 67, 16, 164, 121, 143, 222, 209, 67, 228, 39, 249, 53, 147, 145, 136, 8, 73, 43, 207, 147, 59, 226, 24, 30, 242 ] ) } diff --git a/packages/withdrawals-contract/schema/withdrawals-documents.json b/packages/withdrawals-contract/schema/withdrawals-documents.json index 3d1f5e06e1d..12ae9f10d30 100644 --- a/packages/withdrawals-contract/schema/withdrawals-documents.json +++ b/packages/withdrawals-contract/schema/withdrawals-documents.json @@ -66,7 +66,7 @@ ], "properties": { "transactionId": { - "description": "Hash of asset unlock transaction. Populated with untied transaction hash on “pooled” stage and with signed transaction on “broatcasted” stage", + "description": "Hash of asset unlock transaction. Populated with untied transaction hash on “pooled” stage and with signed transaction on “broadcasted” stage", "type": "array", "byteArray": true, "minItems": 32, @@ -127,7 +127,6 @@ "coreFeePerByte", "pooling", "outputScript", - "transactionIndex", "status" ] } From 8ec882cb2be63c9dcdffa77cbc9b5109c0112d72 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 14:52:15 +0700 Subject: [PATCH 49/50] fixes --- packages/rs-drive-abci/src/state/genesis.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 96886bf5c0d..8fca7e65e24 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -266,7 +266,7 @@ mod tests { assert_eq!( root_hash, [ - 95, 141, 114, 61, 67, 111, 218, 67, 16, 164, 121, 143, 222, 209, 67, 228, 39, 249, 53, 147, 145, 136, 8, 73, 43, 207, 147, 59, 226, 24, 30, 242 + 101, 108, 71, 168, 227, 6, 77, 33, 150, 83, 197, 157, 128, 17, 109, 126, 144, 69, 44, 137, 204, 33, 20, 166, 250, 181, 154, 106, 2, 170, 254, 238 ] ) } From 5c9ad4c9242ebf6c3095cc6f8c84d613d7fd07ad Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 25 Apr 2023 15:15:02 +0700 Subject: [PATCH 50/50] linting --- .../document_type/document_field.rs | 29 ++++------- .../document_type/document_type.rs | 50 +++++++++++-------- packages/rs-dpp/src/document/serialize.rs | 12 +++-- .../withdrawals_data_triggers/mod.rs | 8 +-- .../execution/fee_pools/fee_distribution.rs | 3 +- packages/rs-drive-abci/src/state/genesis.rs | 3 +- 6 files changed, 57 insertions(+), 48 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 2662c1d6d3c..1333eba988a 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 @@ -352,18 +352,15 @@ impl DocumentFieldType { 32 => Ok(Some(Value::Bytes32(bytes.try_into().unwrap()))), 20 => Ok(Some(Value::Bytes20(bytes.try_into().unwrap()))), 36 => Ok(Some(Value::Bytes36(bytes.try_into().unwrap()))), - _ => Ok(Some(Value::Bytes(bytes))) + _ => Ok(Some(Value::Bytes(bytes))), } } _ => { let bytes = Self::read_varint_value(buf)?; - - Ok(Some(Value::Bytes(bytes))) } } - } DocumentFieldType::Identifier => { let mut id = [0; 32]; @@ -569,23 +566,17 @@ impl DocumentFieldType { let value_as_f64 = value.to_float().map_err(ProtocolError::ValueError)?; Ok(value_as_f64.to_be_bytes().to_vec()) } - DocumentFieldType::ByteArray(min, max) => { - match (min, max) { - (Some(min), Some(max)) if min == max => { - Ok(value.to_binary_bytes()?) - } - _ => { - let mut bytes = value.to_binary_bytes()?; + DocumentFieldType::ByteArray(min, max) => match (min, max) { + (Some(min), Some(max)) if min == max => Ok(value.to_binary_bytes()?), + _ => { + let mut bytes = value.to_binary_bytes()?; - let mut r_vec = bytes.len().encode_var_vec(); - r_vec.append(&mut bytes); - Ok(r_vec) - } + let mut r_vec = bytes.len().encode_var_vec(); + r_vec.append(&mut bytes); + Ok(r_vec) } - } - DocumentFieldType::Identifier => { - Ok(value.to_identifier_bytes()?) - } + }, + DocumentFieldType::Identifier => Ok(value.to_identifier_bytes()?), DocumentFieldType::Boolean => { let value_as_boolean = value.as_bool().ok_or_else(get_field_type_matching_error)?; // 0 means does not exist 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 6e76320be36..782d0e64965 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 @@ -556,16 +556,18 @@ fn insert_values_nested( field_type = match inner_properties.get_optional_bool(property_names::BYTE_ARRAY)? { Some(inner_bool) => { if inner_bool { - match inner_properties.get_optional_str(property_names::CONTENT_MEDIA_TYPE)? { - Some(content_media_type) if content_media_type == "application/x.dash.dpp.identifier" => { + match inner_properties + .get_optional_str(property_names::CONTENT_MEDIA_TYPE)? + { + Some(content_media_type) + if content_media_type == "application/x.dash.dpp.identifier" => + { DocumentFieldType::Identifier } - Some(_) | None => { - DocumentFieldType::ByteArray( - inner_properties.get_optional_integer(property_names::MIN_ITEMS)?, - inner_properties.get_optional_integer(property_names::MAX_ITEMS)?, - ) - }, + Some(_) | None => DocumentFieldType::ByteArray( + inner_properties.get_optional_integer(property_names::MIN_ITEMS)?, + inner_properties.get_optional_integer(property_names::MAX_ITEMS)?, + ), } } else { return Err(ProtocolError::DataContractError( @@ -585,11 +587,12 @@ fn insert_values_nested( "object" => { let mut nested_properties = BTreeMap::new(); 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"), - ))?; + let properties = + properties_as_value + .as_map() + .ok_or(ProtocolError::StructureError( + StructureError::ValueWrongType("properties must be a map"), + ))?; // Create a new set with the prefix removed from the keys let stripped_required: BTreeSet = known_required @@ -707,16 +710,21 @@ fn insert_values( field_type = match inner_properties.get_optional_bool(property_names::BYTE_ARRAY)? { Some(inner_bool) => { if inner_bool { - match inner_properties.get_optional_str(property_names::CONTENT_MEDIA_TYPE)? { - Some(content_media_type) if content_media_type == "application/x.dash.dpp.identifier" => { + match inner_properties + .get_optional_str(property_names::CONTENT_MEDIA_TYPE)? + { + Some(content_media_type) + if content_media_type + == "application/x.dash.dpp.identifier" => + { DocumentFieldType::Identifier } - Some(_) | None => { - DocumentFieldType::ByteArray( - inner_properties.get_optional_integer(property_names::MIN_ITEMS)?, - inner_properties.get_optional_integer(property_names::MAX_ITEMS)?, - ) - }, + Some(_) | None => DocumentFieldType::ByteArray( + inner_properties + .get_optional_integer(property_names::MIN_ITEMS)?, + inner_properties + .get_optional_integer(property_names::MAX_ITEMS)?, + ), } } else { return Err(ProtocolError::DataContractError( diff --git a/packages/rs-dpp/src/document/serialize.rs b/packages/rs-dpp/src/document/serialize.rs index 4a7f56ace53..b6601be0236 100644 --- a/packages/rs-dpp/src/document/serialize.rs +++ b/packages/rs-dpp/src/document/serialize.rs @@ -136,7 +136,9 @@ impl Document { if value.is_null() { if field.required { Err(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey("a required field is not present".to_string()), + DataContractError::MissingRequiredKey( + "a required field is not present".to_string(), + ), )) } else { // dbg!("we pushed {} with 0", field_name); @@ -158,7 +160,9 @@ impl Document { } } else if field.required { Err(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey(format!("a required field {field_name} is not present")), + DataContractError::MissingRequiredKey(format!( + "a required field {field_name} is not present" + )), )) } else { // dbg!("we pushed {} with 0", field_name); @@ -228,7 +232,9 @@ impl Document { Ok(()) } else if field.required { Err(ProtocolError::DataContractError( - DataContractError::MissingRequiredKey("a required field is not present".to_string()), + DataContractError::MissingRequiredKey( + "a required field is not present".to_string(), + ), )) } else { // We don't have something that wasn't required diff --git a/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs index 6c35e6033a1..7a5f22972c3 100644 --- a/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/data_trigger/withdrawals_data_triggers/mod.rs @@ -117,10 +117,10 @@ mod tests { use crate::platform::PlatformStateRef; use crate::test::helpers::setup::TestPlatformBuilder; use dpp::block::block_info::BlockInfo; - use dpp::document::Document; use dpp::document::document_transition::{ DocumentBaseTransitionAction, DocumentDeleteTransitionAction, }; + use dpp::document::Document; use dpp::identity::state_transition::identity_credit_withdrawal_transition::Pooling; use dpp::platform_value::{platform_value, Bytes20, Bytes32}; use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; @@ -188,9 +188,11 @@ mod tests { }), None, ) - .expect("expected withdrawal document"); + .expect("expected withdrawal document"); - let serialized = document.serialize(document_type).expect("expected to serialize document"); + let serialized = document + .serialize(document_type) + .expect("expected to serialize document"); Document::from_bytes(&serialized, document_type).expect("expected to deserialize document"); } 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 f14f2e9f250..661a812dd1b 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 @@ -277,7 +277,8 @@ impl Platform { for document in documents { let pay_to_id = document .properties - .get_identifier("payToId").map_err(|e| Error::Protocol(ProtocolError::ValueError(e)))?; + .get_identifier("payToId") + .map_err(|e| Error::Protocol(ProtocolError::ValueError(e)))?; // TODO this shouldn't be a percentage we need to update masternode share contract let share_percentage: u64 = document diff --git a/packages/rs-drive-abci/src/state/genesis.rs b/packages/rs-drive-abci/src/state/genesis.rs index 8fca7e65e24..9a07bced43d 100644 --- a/packages/rs-drive-abci/src/state/genesis.rs +++ b/packages/rs-drive-abci/src/state/genesis.rs @@ -266,7 +266,8 @@ mod tests { assert_eq!( root_hash, [ - 101, 108, 71, 168, 227, 6, 77, 33, 150, 83, 197, 157, 128, 17, 109, 126, 144, 69, 44, 137, 204, 33, 20, 166, 250, 181, 154, 106, 2, 170, 254, 238 + 101, 108, 71, 168, 227, 6, 77, 33, 150, 83, 197, 157, 128, 17, 109, 126, 144, + 69, 44, 137, 204, 33, 20, 166, 250, 181, 154, 106, 2, 170, 254, 238 ] ) }