From 450205e0a6e98cbcc668c6e0853a1fa65c500f98 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 1 Feb 2023 16:14:30 +0500 Subject: [PATCH 01/35] wip --- .../state_transition_factory.rs | 126 +++++++++++++++++- .../validation/validator_transaction_basic.rs | 10 +- 2 files changed, 131 insertions(+), 5 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transition_factory.rs b/packages/rs-dpp/src/state_transition/state_transition_factory.rs index 302ae333285..c7b6a34096f 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -1,5 +1,8 @@ use anyhow::anyhow; -use std::convert::{TryFrom, TryInto}; +use std::{ + convert::{TryFrom, TryInto}, + sync::Arc, +}; use crate::{ consensus::{basic::BasicError, ConsensusError}, @@ -7,6 +10,7 @@ use crate::{ state_transition::{DataContractCreateTransition, DataContractUpdateTransition}, DataContract, }, + decode_protocol_entity_factory::DecodeProtocolEntity, document::DocumentsBatchTransition, identity::state_transition::{ identity_create_transition::IdentityCreateTransition, @@ -18,6 +22,7 @@ use crate::{ util::json_value::JsonValueExt, ProtocolError, }; +use serde_json::Number; use serde_json::Value as JsonValue; use super::{ @@ -25,6 +30,125 @@ use super::{ StateTransitionType, }; +pub struct StateTransitionFactoryOptions { + pub skip_validation: bool, +} + +impl Default for StateTransitionFactoryOptions { + fn default() -> Self { + StateTransitionFactoryOptions { + skip_validation: false, + } + } +} + +pub struct StateTransitionFactory { + state_repository: Arc, +} + +impl StateTransitionFactory +where + SR: StateRepositoryLike, +{ + pub fn new(state_repository: Arc) -> Self { + StateTransitionFactory { state_repository } + } + + pub async fn create_from_object( + &self, + raw_state_transition: JsonValue, + options: Option, + ) -> Result { + let options = options.unwrap_or_default(); + + if !options.skip_validation { + // TODO: validate basic + } + + self.create_state_transition(raw_state_transition).await + } + + pub async fn create_from_buffer( + &self, + state_transition_buffer: &[u8], + options: Option, + ) -> Result { + let (protocol_version, mut raw_state_transition) = + DecodeProtocolEntity::decode_protocol_entity(state_transition_buffer)?; + + match raw_state_transition { + JsonValue::Object(ref mut m) => m.insert( + String::from("protocolVersion"), + JsonValue::Number(Number::from(protocol_version)), + ), + _ => { + return Err(ConsensusError::SerializedObjectParsingError { + parsing_error: anyhow!("the '{:?}' is not a map", raw_state_transition), + } + .into()) + } + }; + + self.create_from_object(raw_state_transition, options).await + } + + pub async fn create_state_transition( + &self, + raw_state_transition: JsonValue, + ) -> Result { + let transition_type = try_get_transition_type(&raw_state_transition)?; + let execution_context = StateTransitionExecutionContext::default(); + + match transition_type { + StateTransitionType::DataContractCreate => { + let transition = + DataContractCreateTransition::from_raw_object(raw_state_transition)?; + Ok(StateTransition::DataContractCreate(transition)) + } + StateTransitionType::DataContractUpdate => { + let transition = + DataContractUpdateTransition::from_raw_object(raw_state_transition)?; + Ok(StateTransition::DataContractUpdate(transition)) + } + StateTransitionType::IdentityCreate => { + let transition = IdentityCreateTransition::new(raw_state_transition)?; + Ok(StateTransition::IdentityCreate(transition)) + } + StateTransitionType::IdentityTopUp => { + let transition = IdentityTopUpTransition::new(raw_state_transition)?; + Ok(StateTransition::IdentityTopUp(transition)) + } + StateTransitionType::IdentityCreditWithdrawal => { + let transition = + IdentityCreditWithdrawalTransition::from_raw_object(raw_state_transition)?; + Ok(StateTransition::IdentityCreditWithdrawal(transition)) + } + StateTransitionType::DocumentsBatch => { + let maybe_transitions = raw_state_transition + .get("transitions") + .ok_or_else(|| anyhow!("the transitions property doesn't exist"))?; + let raw_transitions = maybe_transitions + .as_array() + .ok_or_else(|| anyhow!("property transitions isn't an array"))?; + let data_contracts = fetch_data_contracts_for_document_transition( + self.state_repository, + raw_transitions, + &execution_context, + ) + .await?; + let documents_batch_transition = DocumentsBatchTransition::from_raw_object( + raw_state_transition, + data_contracts, + )?; + Ok(StateTransition::DocumentsBatch(documents_batch_transition)) + } + StateTransitionType::IdentityUpdate => { + Err(ProtocolError::InvalidStateTransitionTypeError) + } + } + } +} + pub async fn create_state_transition( state_repository: &impl StateRepositoryLike, raw_state_transition: JsonValue, diff --git a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs b/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs index a5864525737..26a4d8fae71 100644 --- a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs +++ b/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs @@ -1,4 +1,4 @@ -use std::convert::TryFrom; +use std::{convert::TryFrom, sync::Arc}; use async_trait::async_trait; #[cfg(test)] @@ -14,11 +14,11 @@ use crate::{ ProtocolError, }; -async fn validate_state_transition_basic( - state_repository: &impl StateRepositoryLike, +async fn validate_state_transition_basic( + state_repository: Arc, validate_functions_by_type: &impl ValidatorByStateTransitionType, raw_state_transition: JsonValue, -) -> Result { +) -> Result where SR: StateRepositoryLike { let mut result = SimpleValidationResult::default(); let raw_transition_type = match raw_state_transition.get_u64("type") { @@ -43,7 +43,9 @@ async fn validate_state_transition_basic( let validate_result = validate_functions_by_type .validate(&raw_state_transition, state_transition_type) .await?; + result.merge(validate_result); + if !result.is_valid() { return Ok(result); } From 520be108fd7e15168f55eebeca6ed84765cca23a Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 7 Feb 2023 17:50:29 +0500 Subject: [PATCH 02/35] chore: wip --- .../state_transition_factory.rs | 65 ++----------------- .../src/state_transition/validation/mod.rs | 2 +- ....rs => validate_state_transition_basic.rs} | 60 +++++++++++++++-- 3 files changed, 62 insertions(+), 65 deletions(-) rename packages/rs-dpp/src/state_transition/validation/{validator_transaction_basic.rs => validate_state_transition_basic.rs} (82%) 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 36b4d67201e..44095cb87cc 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -62,10 +62,15 @@ where let options = options.unwrap_or_default(); if !options.skip_validation { - // TODO: validate basic + // let validation_result = validate_state_transition_basic( + // self.state_repository.as_ref(), + // , + // raw_state_transition, + // ) + // .await?; } - self.create_state_transition(raw_state_transition).await + create_state_transition(self.state_repository.as_ref(), raw_state_transition).await } pub async fn create_from_buffer( @@ -91,62 +96,6 @@ where self.create_from_object(raw_state_transition, options).await } - - pub async fn create_state_transition( - &self, - raw_state_transition: JsonValue, - ) -> Result { - let transition_type = try_get_transition_type(&raw_state_transition)?; - let execution_context = StateTransitionExecutionContext::default(); - - match transition_type { - StateTransitionType::DataContractCreate => { - let transition = - DataContractCreateTransition::from_raw_object(raw_state_transition)?; - Ok(StateTransition::DataContractCreate(transition)) - } - StateTransitionType::DataContractUpdate => { - let transition = - DataContractUpdateTransition::from_raw_object(raw_state_transition)?; - Ok(StateTransition::DataContractUpdate(transition)) - } - StateTransitionType::IdentityCreate => { - let transition = IdentityCreateTransition::new(raw_state_transition)?; - Ok(StateTransition::IdentityCreate(transition)) - } - StateTransitionType::IdentityTopUp => { - let transition = IdentityTopUpTransition::new(raw_state_transition)?; - Ok(StateTransition::IdentityTopUp(transition)) - } - StateTransitionType::IdentityCreditWithdrawal => { - let transition = - IdentityCreditWithdrawalTransition::from_raw_object(raw_state_transition)?; - Ok(StateTransition::IdentityCreditWithdrawal(transition)) - } - StateTransitionType::DocumentsBatch => { - let maybe_transitions = raw_state_transition - .get("transitions") - .ok_or_else(|| anyhow!("the transitions property doesn't exist"))?; - let raw_transitions = maybe_transitions - .as_array() - .ok_or_else(|| anyhow!("property transitions isn't an array"))?; - let data_contracts = fetch_data_contracts_for_document_transition( - self.state_repository, - raw_transitions, - &execution_context, - ) - .await?; - let documents_batch_transition = DocumentsBatchTransition::from_raw_object( - raw_state_transition, - data_contracts, - )?; - Ok(StateTransition::DocumentsBatch(documents_batch_transition)) - } - StateTransitionType::IdentityUpdate => { - Err(ProtocolError::InvalidStateTransitionTypeError) - } - } - } } pub async fn create_state_transition( diff --git a/packages/rs-dpp/src/state_transition/validation/mod.rs b/packages/rs-dpp/src/state_transition/validation/mod.rs index be1d688e115..aa0d5029728 100644 --- a/packages/rs-dpp/src/state_transition/validation/mod.rs +++ b/packages/rs-dpp/src/state_transition/validation/mod.rs @@ -1,4 +1,4 @@ +pub mod validate_state_transition_basic; pub mod validate_state_transition_fee; pub mod validate_state_transition_identity_signature; pub mod validate_state_transition_key_signature; -pub mod validator_transaction_basic; diff --git a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs similarity index 82% rename from packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs rename to packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs index 26a4d8fae71..2dde926f269 100644 --- a/packages/rs-dpp/src/state_transition/validation/validator_transaction_basic.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_basic.rs @@ -1,4 +1,4 @@ -use std::{convert::TryFrom, sync::Arc}; +use std::convert::TryFrom; use async_trait::async_trait; #[cfg(test)] @@ -7,18 +7,25 @@ use serde_json::Value as JsonValue; use crate::{ consensus::basic::BasicError, + identity::{ + state_transition::{ + identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic, + validate_public_key_signatures::TPublicKeysSignaturesValidator, + }, + validation::TPublicKeysValidator, + }, state_repository::StateRepositoryLike, state_transition::{create_state_transition, StateTransitionConvert, StateTransitionType}, util::json_value::JsonValueExt, - validation::SimpleValidationResult, + validation::{SimpleValidationResult, ValidationResult}, ProtocolError, }; -async fn validate_state_transition_basic( - state_repository: Arc, +pub async fn validate_state_transition_basic( + state_repository: &impl StateRepositoryLike, validate_functions_by_type: &impl ValidatorByStateTransitionType, raw_state_transition: JsonValue, -) -> Result where SR: StateRepositoryLike { +) -> Result { let mut result = SimpleValidationResult::default(); let raw_transition_type = match raw_state_transition.get_u64("type") { @@ -67,7 +74,7 @@ async fn validate_state_transition_basic( #[cfg_attr(test, automock)] #[async_trait] -pub trait ValidatorByStateTransitionType { +pub trait ValidatorByStateTransitionType: Sync + Send { async fn validate( &self, raw_state_transition: &JsonValue, @@ -75,6 +82,47 @@ pub trait ValidatorByStateTransitionType { ) -> Result; } +pub struct StateTransitionBasicValidator { + data_contract_create_validator: ValidateIdentityUpdateTransitionBasic, +} + +impl StateTransitionBasicValidator { + pub fn new( + data_contract_create_validator: ValidateIdentityUpdateTransitionBasic, + ) -> Self { + StateTransitionBasicValidator { + data_contract_create_validator, + } + } +} + +#[async_trait] +impl ValidatorByStateTransitionType for StateTransitionBasicValidator +where + KV: TPublicKeysValidator + Sync + Send, + SV: TPublicKeysSignaturesValidator + Sync + Send, +{ + async fn validate( + &self, + raw_state_transition: &JsonValue, + state_transition_type: StateTransitionType, + ) -> Result { + let result = ValidationResult::default(); + + match state_transition_type { + StateTransitionType::DataContractCreate => (), + StateTransitionType::DocumentsBatch => (), + StateTransitionType::IdentityCreate => (), + StateTransitionType::IdentityTopUp => (), + StateTransitionType::DataContractUpdate => (), + StateTransitionType::IdentityUpdate => (), + StateTransitionType::IdentityCreditWithdrawal => (), + } + + Ok(result) + } +} + #[cfg(test)] mod test { use serde_json::{json, Value as JsonValue}; From bb4e21c85c13a6d9553093c61171e68b09dc40c4 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 8 Feb 2023 12:21:10 +0500 Subject: [PATCH 03/35] chore: wip --- .../validate_state_transition_basic.rs | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 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 2dde926f269..2cbe0bbbde1 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 @@ -18,7 +18,7 @@ use crate::{ state_transition::{create_state_transition, StateTransitionConvert, StateTransitionType}, util::json_value::JsonValueExt, validation::{SimpleValidationResult, ValidationResult}, - ProtocolError, + ProtocolError, data_contract::state_transition::data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, }; pub async fn validate_state_transition_basic( @@ -82,39 +82,51 @@ pub trait ValidatorByStateTransitionType: Sync + Send { ) -> Result; } -pub struct StateTransitionBasicValidator { +pub struct StateTransitionBasicValidator { data_contract_create_validator: ValidateIdentityUpdateTransitionBasic, + data_contract_update_validator: DataContractUpdateTransitionBasicValidator, } -impl StateTransitionBasicValidator { +impl StateTransitionBasicValidator where SR: StateRepositoryLike { pub fn new( data_contract_create_validator: ValidateIdentityUpdateTransitionBasic, + data_contract_update_validator: DataContractUpdateTransitionBasicValidator, ) -> Self { StateTransitionBasicValidator { data_contract_create_validator, + data_contract_update_validator, } } } #[async_trait] -impl ValidatorByStateTransitionType for StateTransitionBasicValidator +impl ValidatorByStateTransitionType for StateTransitionBasicValidator where KV: TPublicKeysValidator + Sync + Send, SV: TPublicKeysSignaturesValidator + Sync + Send, + SR: StateRepositoryLike, { async fn validate( &self, raw_state_transition: &JsonValue, state_transition_type: StateTransitionType, ) -> Result { - let result = ValidationResult::default(); + let mut result = ValidationResult::default(); match state_transition_type { - StateTransitionType::DataContractCreate => (), + StateTransitionType::DataContractCreate => { + let validation_result = self.data_contract_create_validator.validate(raw_state_transition)?; + + result.merge(validation_result); + }, + StateTransitionType::DataContractUpdate => { + let validation_result = self.data_contract_update_validator.validate(raw_state_transition).await?; + + result.merge(validation_result); + }, StateTransitionType::DocumentsBatch => (), StateTransitionType::IdentityCreate => (), StateTransitionType::IdentityTopUp => (), - StateTransitionType::DataContractUpdate => (), StateTransitionType::IdentityUpdate => (), StateTransitionType::IdentityCreditWithdrawal => (), } From d036203d746877b2bbdccf3e1b64e28dd18503b9 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 8 Feb 2023 20:54:57 +0500 Subject: [PATCH 04/35] chore: all except doc batch --- packages/rs-dpp/src/state_repository.rs | 4 +- .../state_transition_factory.rs | 9 +- .../validate_state_transition_basic.rs | 123 +++++++++++++++--- 3 files changed, 106 insertions(+), 30 deletions(-) diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index b5cb615bc18..0ba1765932a 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -36,7 +36,9 @@ pub trait StateRepositoryLike: Send + Sync { type ConversionError: Into; type FetchDataContract: TryInto; type FetchIdentity: TryInto; - type FetchTransaction: TryInto; + type FetchTransaction: TryInto + + Send + + Sync; /// Fetch the Data Contract by ID /// By default, the method should return data as bytes (`Vec`), but the deserialization to [`DataContract`] should be also possible 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 44095cb87cc..6233e057808 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -30,18 +30,11 @@ use super::{ StateTransitionType, }; +#[derive(Default)] pub struct StateTransitionFactoryOptions { pub skip_validation: bool, } -impl Default for StateTransitionFactoryOptions { - fn default() -> Self { - StateTransitionFactoryOptions { - skip_validation: false, - } - } -} - pub struct StateTransitionFactory { state_repository: Arc, } 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 2dde926f269..21267c77456 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 @@ -7,23 +7,31 @@ use serde_json::Value as JsonValue; use crate::{ consensus::basic::BasicError, + data_contract::state_transition::data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, identity::{ state_transition::{ + identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, + identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic, - validate_public_key_signatures::TPublicKeysSignaturesValidator, + validate_public_key_signatures::TPublicKeysSignaturesValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, }, validation::TPublicKeysValidator, }, state_repository::StateRepositoryLike, - state_transition::{create_state_transition, StateTransitionConvert, StateTransitionType}, + state_transition::{ + create_state_transition, + state_transition_execution_context::StateTransitionExecutionContext, + StateTransitionConvert, StateTransitionType, + }, util::json_value::JsonValueExt, validation::{SimpleValidationResult, ValidationResult}, - ProtocolError, + BlsModule, ProtocolError, }; pub async fn validate_state_transition_basic( state_repository: &impl StateRepositoryLike, validate_functions_by_type: &impl ValidatorByStateTransitionType, + execution_context: &StateTransitionExecutionContext, raw_state_transition: JsonValue, ) -> Result { let mut result = SimpleValidationResult::default(); @@ -48,7 +56,11 @@ pub async fn validate_state_transition_basic( }; let validate_result = validate_functions_by_type - .validate(&raw_state_transition, state_transition_type) + .validate( + &raw_state_transition, + state_transition_type, + execution_context, + ) .await?; result.merge(validate_result); @@ -79,45 +91,96 @@ pub trait ValidatorByStateTransitionType: Sync + Send { &self, raw_state_transition: &JsonValue, state_transition_type: StateTransitionType, + execution_context: &StateTransitionExecutionContext, ) -> Result; } -pub struct StateTransitionBasicValidator { +pub struct StateTransitionBasicValidator +where + SR: StateRepositoryLike, + BLS: BlsModule, +{ data_contract_create_validator: ValidateIdentityUpdateTransitionBasic, + data_contract_update_validator: DataContractUpdateTransitionBasicValidator, + identity_create_validator: IdentityCreateTransitionBasicValidator, + identity_update_validator: ValidateIdentityUpdateTransitionBasic, + identity_top_up_validator: IdentityTopUpTransitionBasicValidator, + identity_credit_withdrawal_validator: IdentityCreditWithdrawalTransitionBasicValidator, } -impl StateTransitionBasicValidator { +impl StateTransitionBasicValidator +where + SR: StateRepositoryLike, + BLS: BlsModule, +{ pub fn new( data_contract_create_validator: ValidateIdentityUpdateTransitionBasic, + data_contract_update_validator: DataContractUpdateTransitionBasicValidator, + identity_create_validator: IdentityCreateTransitionBasicValidator, + identity_update_validator: ValidateIdentityUpdateTransitionBasic, + identity_top_up_validator: IdentityTopUpTransitionBasicValidator, + identity_credit_withdrawal_validator: IdentityCreditWithdrawalTransitionBasicValidator, ) -> Self { StateTransitionBasicValidator { data_contract_create_validator, + data_contract_update_validator, + identity_create_validator, + identity_update_validator, + identity_top_up_validator, + identity_credit_withdrawal_validator, } } } #[async_trait] -impl ValidatorByStateTransitionType for StateTransitionBasicValidator +impl ValidatorByStateTransitionType + for StateTransitionBasicValidator where KV: TPublicKeysValidator + Sync + Send, + TXKV: TPublicKeysValidator + Sync + Send, SV: TPublicKeysSignaturesValidator + Sync + Send, + SR: StateRepositoryLike, + BLS: BlsModule + Sync + Send, { async fn validate( &self, raw_state_transition: &JsonValue, state_transition_type: StateTransitionType, + execution_context: &StateTransitionExecutionContext, ) -> Result { - let result = ValidationResult::default(); - - match state_transition_type { - StateTransitionType::DataContractCreate => (), - StateTransitionType::DocumentsBatch => (), - StateTransitionType::IdentityCreate => (), - StateTransitionType::IdentityTopUp => (), - StateTransitionType::DataContractUpdate => (), - StateTransitionType::IdentityUpdate => (), - StateTransitionType::IdentityCreditWithdrawal => (), - } + let mut result = ValidationResult::default(); + + let validation_result = match state_transition_type { + StateTransitionType::DataContractCreate => self + .data_contract_create_validator + .validate(raw_state_transition)?, + StateTransitionType::DataContractUpdate => { + self.data_contract_update_validator + .validate(raw_state_transition, execution_context) + .await? + } + StateTransitionType::IdentityCreate => { + self.identity_create_validator + .validate(raw_state_transition, execution_context) + .await? + } + StateTransitionType::IdentityUpdate => self + .identity_update_validator + .validate(raw_state_transition)?, + StateTransitionType::IdentityTopUp => { + self.identity_top_up_validator + .validate(raw_state_transition, execution_context) + .await? + } + StateTransitionType::IdentityCreditWithdrawal => { + self.identity_credit_withdrawal_validator + .validate(raw_state_transition) + .await? + } + StateTransitionType::DocumentsBatch => todo!(), + }; + + result.merge(validation_result); Ok(result) } @@ -136,7 +199,10 @@ mod test { DataContractFactory, }, state_repository::MockStateRepositoryLike, - state_transition::{StateTransitionConvert, StateTransitionLike}, + state_transition::{ + state_transition_execution_context::StateTransitionExecutionContext, + StateTransitionConvert, StateTransitionLike, + }, tests::{fixtures::get_data_contract_fixture, utils::get_basic_error_from_result}, util::json_value::JsonValueExt, validation::ValidationResult, @@ -205,9 +271,12 @@ mod test { .remove("type") .expect("type should exist and be remove"); + let execution_context = StateTransitionExecutionContext::default(); + let result = validate_state_transition_basic( &state_repository_mock, &validate_by_type_mock, + &execution_context, raw_state_transition, ) .await @@ -232,9 +301,12 @@ mod test { raw_state_transition["type"] = json!(123); + let execution_context = StateTransitionExecutionContext::default(); + let result = validate_state_transition_basic( &state_repository_mock, &validate_by_type_mock, + &execution_context, raw_state_transition, ) .await @@ -260,9 +332,12 @@ mod test { raw_state_transition["type"] = json!(123); + let execution_context = StateTransitionExecutionContext::default(); + let result = validate_state_transition_basic( &state_repository_mock, &validate_by_type_mock, + &execution_context, raw_state_transition, ) .await @@ -286,7 +361,7 @@ mod test { let mut validate_by_type_mock = MockValidatorByStateTransitionType::new(); validate_by_type_mock .expect_validate() - .returning(|_, _| Ok(ValidationResult::<()>::default())); + .returning(|_, _, _| Ok(ValidationResult::<()>::default())); for i in 0..500 { let document_type_name = format!("anotherDocument{}", i); @@ -294,9 +369,12 @@ mod test { raw_state_transition["dataContract"]["documents"]["niceDocument"].clone(); } + let execution_context = StateTransitionExecutionContext::default(); + let result = validate_state_transition_basic( &state_repository_mock, &validate_by_type_mock, + &execution_context, raw_state_transition, ) .await @@ -324,11 +402,14 @@ mod test { let mut validate_by_type_mock = MockValidatorByStateTransitionType::new(); validate_by_type_mock .expect_validate() - .returning(|_, _| Ok(ValidationResult::<()>::default())); + .returning(|_, _, _| Ok(ValidationResult::<()>::default())); + + let execution_context = StateTransitionExecutionContext::default(); let result = validate_state_transition_basic( &state_repository_mock, &validate_by_type_mock, + &execution_context, raw_state_transition, ) .await From 2392d0522093d8397eb3ea65ef07ea5d87b0c0b7 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Thu, 9 Feb 2023 23:42:15 +0500 Subject: [PATCH 05/35] chore: wip --- ...e_data_contract_update_transition_basic.rs | 12 +- .../state_transition_factory.rs | 31 +- .../src/state_transition/validation/mod.rs | 1 + .../validate_state_transition_basic.rs | 295 +++++++----------- .../validate_state_transition_by_type.rs | 215 +++++++++++++ ...a_contract_update_transition_basic_spec.rs | 1 + packages/rs-dpp/src/validation/mod.rs | 8 + 7 files changed, 364 insertions(+), 199 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 24b963bdcf7..705a4c376dc 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -2,12 +2,14 @@ use std::convert::TryInto; use anyhow::anyhow; use anyhow::Context; +use async_trait::async_trait; use json_patch::PatchOperation; use lazy_static::lazy_static; use serde_json::{json, Value as JsonValue}; use std::sync::Arc; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use crate::validation::AsyncDataValidatorWithContext; use crate::{ consensus::basic::BasicError, data_contract::{ @@ -60,8 +62,16 @@ where json_schema_validator, }) } +} + +#[async_trait] +impl AsyncDataValidatorWithContext for DataContractUpdateTransitionBasicValidator +where + SR: StateRepositoryLike, +{ + type Item = JsonValue; - pub async fn validate( + async fn validate( &self, raw_state_transition: &JsonValue, execution_context: &StateTransitionExecutionContext, 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 6233e057808..7b0dfb1f64e 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -20,6 +20,7 @@ use crate::{ prelude::Identifier, state_repository::StateRepositoryLike, util::json_value::JsonValueExt, + validation::AsyncDataValidatorWithContext, ProtocolError, }; use serde_json::Number; @@ -35,16 +36,24 @@ pub struct StateTransitionFactoryOptions { pub skip_validation: bool, } -pub struct StateTransitionFactory { +pub struct StateTransitionFactory +where + ADV: AsyncDataValidatorWithContext, +{ state_repository: Arc, + basic_validator: ADV, } -impl StateTransitionFactory +impl StateTransitionFactory where SR: StateRepositoryLike, + ADV: AsyncDataValidatorWithContext, { - pub fn new(state_repository: Arc) -> Self { - StateTransitionFactory { state_repository } + pub fn new(state_repository: Arc, basic_validator: ADV) -> Self { + StateTransitionFactory { + state_repository, + basic_validator, + } } pub async fn create_from_object( @@ -55,12 +64,14 @@ where let options = options.unwrap_or_default(); if !options.skip_validation { - // let validation_result = validate_state_transition_basic( - // self.state_repository.as_ref(), - // , - // raw_state_transition, - // ) - // .await?; + let execution_context = StateTransitionExecutionContext::default(); + + let validation_result = self + .basic_validator + .validate(&raw_state_transition, &execution_context) + .await?; + + // TODO: return InvalidStateTransitionError } create_state_transition(self.state_repository.as_ref(), raw_state_transition).await diff --git a/packages/rs-dpp/src/state_transition/validation/mod.rs b/packages/rs-dpp/src/state_transition/validation/mod.rs index aa0d5029728..5a938c7adea 100644 --- a/packages/rs-dpp/src/state_transition/validation/mod.rs +++ b/packages/rs-dpp/src/state_transition/validation/mod.rs @@ -1,4 +1,5 @@ pub mod validate_state_transition_basic; +pub mod validate_state_transition_by_type; pub mod validate_state_transition_fee; pub mod validate_state_transition_identity_signature; pub mod validate_state_transition_key_signature; 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 21267c77456..70b38e3fd6d 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 @@ -1,186 +1,92 @@ -use std::convert::TryFrom; +use std::sync::Arc; use async_trait::async_trait; -#[cfg(test)] -use mockall::{automock, predicate::*}; use serde_json::Value as JsonValue; use crate::{ consensus::basic::BasicError, - data_contract::state_transition::data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, - identity::{ - state_transition::{ - identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, - identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, - identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic, - validate_public_key_signatures::TPublicKeysSignaturesValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, - }, - validation::TPublicKeysValidator, - }, state_repository::StateRepositoryLike, state_transition::{ create_state_transition, state_transition_execution_context::StateTransitionExecutionContext, - StateTransitionConvert, StateTransitionType, + try_get_transition_type, StateTransitionConvert, }, - util::json_value::JsonValueExt, - validation::{SimpleValidationResult, ValidationResult}, - BlsModule, ProtocolError, + validation::{AsyncDataValidatorWithContext, SimpleValidationResult}, + ProtocolError, }; -pub async fn validate_state_transition_basic( - state_repository: &impl StateRepositoryLike, - validate_functions_by_type: &impl ValidatorByStateTransitionType, - execution_context: &StateTransitionExecutionContext, - raw_state_transition: JsonValue, -) -> Result { - let mut result = SimpleValidationResult::default(); - - let raw_transition_type = match raw_state_transition.get_u64("type") { - Err(_) => { - result.add_error(BasicError::MissingStateTransitionTypeError); - return Ok(result); - } - - Ok(transaction_type) => transaction_type, - } as u8; - - let state_transition_type = match StateTransitionType::try_from(raw_transition_type) { - Err(_) => { - result.add_error(BasicError::InvalidStateTransitionTypeError { - transition_type: raw_transition_type, - }); - return Ok(result); - } - Ok(transition_type) => transition_type, - }; - - let validate_result = validate_functions_by_type - .validate( - &raw_state_transition, - state_transition_type, - execution_context, - ) - .await?; - - result.merge(validate_result); - - if !result.is_valid() { - return Ok(result); - } - - let state_transition = create_state_transition(state_repository, raw_state_transition).await?; - if let Err(ProtocolError::MaxEncodedBytesReachedError { - max_size_kbytes, - payload, - }) = state_transition.to_buffer(false) - { - result.add_error(BasicError::StateTransitionMaxSizeExceededError { - actual_size_kbytes: payload.len() / 1024, - max_size_kbytes, - }); - } +use super::validate_state_transition_by_type::ValidatorByStateTransitionType; - Ok(result) -} - -#[cfg_attr(test, automock)] -#[async_trait] -pub trait ValidatorByStateTransitionType: Sync + Send { - async fn validate( - &self, - raw_state_transition: &JsonValue, - state_transition_type: StateTransitionType, - execution_context: &StateTransitionExecutionContext, - ) -> Result; -} - -pub struct StateTransitionBasicValidator +pub struct StateTransitionBasicValidator where SR: StateRepositoryLike, - BLS: BlsModule, + VBT: ValidatorByStateTransitionType, { - data_contract_create_validator: ValidateIdentityUpdateTransitionBasic, - data_contract_update_validator: DataContractUpdateTransitionBasicValidator, - identity_create_validator: IdentityCreateTransitionBasicValidator, - identity_update_validator: ValidateIdentityUpdateTransitionBasic, - identity_top_up_validator: IdentityTopUpTransitionBasicValidator, - identity_credit_withdrawal_validator: IdentityCreditWithdrawalTransitionBasicValidator, + state_repository: Arc, + validate_state_transition_by_type: VBT, } -impl StateTransitionBasicValidator +impl StateTransitionBasicValidator where SR: StateRepositoryLike, - BLS: BlsModule, + VBT: ValidatorByStateTransitionType, { - pub fn new( - data_contract_create_validator: ValidateIdentityUpdateTransitionBasic, - data_contract_update_validator: DataContractUpdateTransitionBasicValidator, - identity_create_validator: IdentityCreateTransitionBasicValidator, - identity_update_validator: ValidateIdentityUpdateTransitionBasic, - identity_top_up_validator: IdentityTopUpTransitionBasicValidator, - identity_credit_withdrawal_validator: IdentityCreditWithdrawalTransitionBasicValidator, - ) -> Self { + pub fn new(state_repository: Arc, validate_state_transition_by_type: VBT) -> Self { StateTransitionBasicValidator { - data_contract_create_validator, - data_contract_update_validator, - identity_create_validator, - identity_update_validator, - identity_top_up_validator, - identity_credit_withdrawal_validator, + state_repository, + validate_state_transition_by_type, } } } #[async_trait] -impl ValidatorByStateTransitionType - for StateTransitionBasicValidator +impl AsyncDataValidatorWithContext for StateTransitionBasicValidator where - KV: TPublicKeysValidator + Sync + Send, - TXKV: TPublicKeysValidator + Sync + Send, - SV: TPublicKeysSignaturesValidator + Sync + Send, SR: StateRepositoryLike, - BLS: BlsModule + Sync + Send, + VBT: ValidatorByStateTransitionType, { + type Item = JsonValue; + async fn validate( &self, raw_state_transition: &JsonValue, - state_transition_type: StateTransitionType, execution_context: &StateTransitionExecutionContext, ) -> Result { - let mut result = ValidationResult::default(); - - let validation_result = match state_transition_type { - StateTransitionType::DataContractCreate => self - .data_contract_create_validator - .validate(raw_state_transition)?, - StateTransitionType::DataContractUpdate => { - self.data_contract_update_validator - .validate(raw_state_transition, execution_context) - .await? - } - StateTransitionType::IdentityCreate => { - self.identity_create_validator - .validate(raw_state_transition, execution_context) - .await? - } - StateTransitionType::IdentityUpdate => self - .identity_update_validator - .validate(raw_state_transition)?, - StateTransitionType::IdentityTopUp => { - self.identity_top_up_validator - .validate(raw_state_transition, execution_context) - .await? - } - StateTransitionType::IdentityCreditWithdrawal => { - self.identity_credit_withdrawal_validator - .validate(raw_state_transition) - .await? - } - StateTransitionType::DocumentsBatch => todo!(), - }; + let mut result = SimpleValidationResult::default(); + + let state_transition_type_result = try_get_transition_type(raw_state_transition); - result.merge(validation_result); + let state_transition_type = state_transition_type_result?; + + let validate_result = self + .validate_state_transition_by_type + .validate( + raw_state_transition, + state_transition_type, + execution_context, + ) + .await?; + + result.merge(validate_result); + + if !result.is_valid() { + return Ok(result); + } + + let state_transition = + create_state_transition(self.state_repository.as_ref(), raw_state_transition.clone()) + .await?; + + if let Err(ProtocolError::MaxEncodedBytesReachedError { + max_size_kbytes, + payload, + }) = state_transition.to_buffer(false) + { + result.add_error(BasicError::StateTransitionMaxSizeExceededError { + actual_size_kbytes: payload.len() / 1024, + max_size_kbytes, + }); + } Ok(result) } @@ -191,6 +97,13 @@ mod test { use serde_json::{json, Value as JsonValue}; use std::sync::Arc; + use crate::{ + state_transition::validation::validate_state_transition_by_type::MockValidatorByStateTransitionType, + validation::AsyncDataValidatorWithContext, + }; + + use super::StateTransitionBasicValidator; + use crate::{ consensus::basic::BasicError, data_contract::{ @@ -210,8 +123,6 @@ mod test { NativeBlsModule, }; - use super::{validate_state_transition_basic, MockValidatorByStateTransitionType}; - struct TestData { data_contract: DataContract, state_transition: DataContractCreateTransition, @@ -271,16 +182,18 @@ mod test { .remove("type") .expect("type should exist and be remove"); + let validator = StateTransitionBasicValidator::new( + Arc::new(state_repository_mock), + validate_by_type_mock, + ); + let execution_context = StateTransitionExecutionContext::default(); - let result = validate_state_transition_basic( - &state_repository_mock, - &validate_by_type_mock, - &execution_context, - raw_state_transition, - ) - .await - .expect("the validation result should be returned"); + let result = validator + .validate(&raw_state_transition, &execution_context) + .await + .expect("the validation result should be returned"); + let basic_error = get_basic_error_from_result(&result, 0); assert!(matches!( @@ -301,16 +214,18 @@ mod test { raw_state_transition["type"] = json!(123); + let validator = StateTransitionBasicValidator::new( + Arc::new(state_repository_mock), + validate_by_type_mock, + ); + let execution_context = StateTransitionExecutionContext::default(); - let result = validate_state_transition_basic( - &state_repository_mock, - &validate_by_type_mock, - &execution_context, - raw_state_transition, - ) - .await - .expect("the validation result should be returned"); + let result = validator + .validate(&raw_state_transition, &execution_context) + .await + .expect("the validation result should be returned"); + let basic_error = get_basic_error_from_result(&result, 0); assert!(matches!( @@ -332,16 +247,18 @@ mod test { raw_state_transition["type"] = json!(123); + let validator = StateTransitionBasicValidator::new( + Arc::new(state_repository_mock), + validate_by_type_mock, + ); + let execution_context = StateTransitionExecutionContext::default(); - let result = validate_state_transition_basic( - &state_repository_mock, - &validate_by_type_mock, - &execution_context, - raw_state_transition, - ) - .await - .expect("the validation result should be returned"); + let result = validator + .validate(&raw_state_transition, &execution_context) + .await + .expect("the validation result should be returned"); + let basic_error = get_basic_error_from_result(&result, 0); assert!(matches!( @@ -369,16 +286,17 @@ mod test { raw_state_transition["dataContract"]["documents"]["niceDocument"].clone(); } + let validator = StateTransitionBasicValidator::new( + Arc::new(state_repository_mock), + validate_by_type_mock, + ); + let execution_context = StateTransitionExecutionContext::default(); - let result = validate_state_transition_basic( - &state_repository_mock, - &validate_by_type_mock, - &execution_context, - raw_state_transition, - ) - .await - .expect("the validation result should be returned"); + let result = validator + .validate(&raw_state_transition, &execution_context) + .await + .expect("the validation result should be returned"); let basic_error = get_basic_error_from_result(&result, 0); @@ -404,16 +322,17 @@ mod test { .expect_validate() .returning(|_, _, _| Ok(ValidationResult::<()>::default())); + let validator = StateTransitionBasicValidator::new( + Arc::new(state_repository_mock), + validate_by_type_mock, + ); + let execution_context = StateTransitionExecutionContext::default(); - let result = validate_state_transition_basic( - &state_repository_mock, - &validate_by_type_mock, - &execution_context, - raw_state_transition, - ) - .await - .expect("should return validation result"); + let result = validator + .validate(&raw_state_transition, &execution_context) + .await + .expect("should return validation result"); assert!(result.is_valid()); } diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs new file mode 100644 index 00000000000..b3a7c15b3f5 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs @@ -0,0 +1,215 @@ +use async_trait::async_trait; + +#[cfg(test)] +use mockall::{automock, predicate::*}; + +use serde_json::Value as JsonValue; + +use crate::{ + state_transition::{ + state_transition_execution_context::StateTransitionExecutionContext, StateTransitionType, + }, + validation::{AsyncDataValidatorWithContext, SimpleValidationResult, ValidationResult}, + ProtocolError, +}; + +#[cfg_attr(test, automock)] +#[async_trait] +pub trait ValidatorByStateTransitionType: Sync + Send { + async fn validate( + &self, + raw_state_transition: &JsonValue, + state_transition_type: StateTransitionType, + execution_context: &StateTransitionExecutionContext, + ) -> Result; +} + +pub struct StateTransitionByTypeValidator +where + ADV: AsyncDataValidatorWithContext, +{ + data_contract_create_validator: ADV, + data_contract_update_validator: ADV, + identity_create_validator: ADV, + identity_update_validator: ADV, + identity_top_up_validator: ADV, + identity_credit_withdrawal_validator: ADV, + document_batch_validator: ADV, +} + +impl StateTransitionByTypeValidator +where + ADV: AsyncDataValidatorWithContext, +{ + pub fn new( + data_contract_create_validator: ADV, + data_contract_update_validator: ADV, + identity_create_validator: ADV, + identity_update_validator: ADV, + identity_top_up_validator: ADV, + identity_credit_withdrawal_validator: ADV, + document_batch_validator: ADV, + ) -> Self { + StateTransitionByTypeValidator { + data_contract_create_validator, + data_contract_update_validator, + identity_create_validator, + identity_update_validator, + identity_top_up_validator, + identity_credit_withdrawal_validator, + document_batch_validator, + } + } +} + +#[async_trait] +impl ValidatorByStateTransitionType for StateTransitionByTypeValidator +where + ADV: AsyncDataValidatorWithContext + Send + Sync, +{ + async fn validate( + &self, + raw_state_transition: &JsonValue, + state_transition_type: StateTransitionType, + execution_context: &StateTransitionExecutionContext, + ) -> Result { + let mut result = ValidationResult::default(); + + let validator = match state_transition_type { + StateTransitionType::DataContractCreate => &self.data_contract_create_validator, + StateTransitionType::DataContractUpdate => &self.data_contract_update_validator, + StateTransitionType::IdentityCreate => &self.identity_create_validator, + StateTransitionType::IdentityUpdate => &self.identity_update_validator, + StateTransitionType::IdentityTopUp => &self.identity_top_up_validator, + StateTransitionType::IdentityCreditWithdrawal => { + &self.identity_credit_withdrawal_validator + } + StateTransitionType::DocumentsBatch => &self.document_batch_validator, + }; + + let validation_result = validator + .validate(raw_state_transition, execution_context) + .await?; + + result.merge(validation_result); + + Ok(result) + } +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use serde_json::Value as JsonValue; + + use crate::{ + data_contract::{ + state_transition::DataContractCreateTransition, + validation::data_contract_validator::DataContractValidator, DataContract, + DataContractFactory, + }, + state_transition::{ + state_transition_execution_context::StateTransitionExecutionContext, + try_get_transition_type, StateTransitionConvert, StateTransitionLike, + }, + tests::fixtures::get_data_contract_fixture, + validation::{MockAsyncDataValidatorWithContext, ValidationResult}, + version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}, + NativeBlsModule, + }; + + use crate::state_transition::validation::validate_state_transition_by_type::ValidatorByStateTransitionType; + + use super::StateTransitionByTypeValidator; + + struct TestData { + data_contract: DataContract, + state_transition: DataContractCreateTransition, + raw_state_transition: JsonValue, + bls: NativeBlsModule, + } + + fn setup_test() -> TestData { + let bls = NativeBlsModule::default(); + let data_contract = get_data_contract_fixture(None); + let private_key_bytes = + hex::decode("9b67f852093bc61cea0eeca38599dbfba0de28574d2ed9b99d10d33dc1bde7b2") + .unwrap(); + + let protocol_version_validator = ProtocolVersionValidator::new( + LATEST_VERSION, + LATEST_VERSION, + COMPATIBILITY_MAP.clone(), + ); + let data_contract_validator = + DataContractValidator::new(Arc::new(protocol_version_validator)); + let data_contract_factory = DataContractFactory::new(1, data_contract_validator); + + let mut state_transition = data_contract_factory + .create_data_contract_create_transition(data_contract.clone()) + .unwrap(); + + state_transition + .sign_by_private_key( + &private_key_bytes, + crate::identity::KeyType::ECDSA_SECP256K1, + &bls, + ) + .expect("the state transition should be signed"); + + let raw_state_transition = state_transition.to_object(false).unwrap(); + + TestData { + data_contract, + state_transition, + raw_state_transition, + bls, + } + } + + #[tokio::test] + async fn test_correct_validator_is_selected() { + let TestData { + raw_state_transition, + .. + } = setup_test(); + + let mut data_contract_create_validator_mock = MockAsyncDataValidatorWithContext::new(); + let data_contract_update_validator_mock = MockAsyncDataValidatorWithContext::new(); + let identity_create_validator_mock = MockAsyncDataValidatorWithContext::new(); + let identity_update_validator_mock = MockAsyncDataValidatorWithContext::new(); + let identity_top_up_validator_mock = MockAsyncDataValidatorWithContext::new(); + let identity_credit_withdrawal_validator_mock = MockAsyncDataValidatorWithContext::new(); + let document_batch_validator_mock = MockAsyncDataValidatorWithContext::new(); + + data_contract_create_validator_mock + .expect_validate() + .times(1) + .returning(|_, _| Ok(ValidationResult::default())); + + let validator = StateTransitionByTypeValidator::new( + data_contract_create_validator_mock, + data_contract_update_validator_mock, + identity_create_validator_mock, + identity_update_validator_mock, + identity_top_up_validator_mock, + identity_credit_withdrawal_validator_mock, + document_batch_validator_mock, + ); + + let execution_context = StateTransitionExecutionContext::default(); + + let state_transition_type = + try_get_transition_type(&raw_state_transition).expect("to get state transition type"); + + validator + .validate( + &raw_state_transition, + state_transition_type, + &execution_context, + ) + .await + .expect("expected to call basic validator `validate` function"); + } +} diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 0fe3170d973..090cab8341a 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -18,6 +18,7 @@ use crate::{ utils::{get_basic_error_from_result, get_schema_error}, }, util::json_value::JsonValueExt, + validation::AsyncDataValidatorWithContext, version::{ProtocolVersionValidator, LATEST_VERSION}, }; diff --git a/packages/rs-dpp/src/validation/mod.rs b/packages/rs-dpp/src/validation/mod.rs index d1a58914387..1b1956b3a18 100644 --- a/packages/rs-dpp/src/validation/mod.rs +++ b/packages/rs-dpp/src/validation/mod.rs @@ -1,4 +1,11 @@ use async_trait::async_trait; + +#[cfg(test)] +use mockall::automock; + +#[cfg(test)] +use serde_json::Value as JsonValue; + pub use json_schema_validator::JsonSchemaValidator; pub use validation_result::{SimpleValidationResult, ValidationResult}; @@ -39,6 +46,7 @@ pub trait DataValidatorWithContext { } /// Async validator takes additionally an execution context and generates fee +#[cfg_attr(test, automock(type Item = JsonValue;))] #[async_trait] pub trait AsyncDataValidatorWithContext { // TODO, when GAT is available remove the reference in method and use: `type Item<'a>` From a08ae7568fa73b12cced2477025559e08300465a Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Fri, 17 Feb 2023 14:21:15 +0500 Subject: [PATCH 06/35] chore: wip --- .../basic/validate_data_contract_update_transition_basic.rs | 4 ++-- packages/rs-dpp/src/state_repository.rs | 2 +- .../validation/validate_state_transition_basic.rs | 2 +- packages/rs-dpp/src/validation/mod.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 705a4c376dc..7d47341967e 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -64,10 +64,10 @@ where } } -#[async_trait] +#[async_trait(?Send)] impl AsyncDataValidatorWithContext for DataContractUpdateTransitionBasicValidator where - SR: StateRepositoryLike, + SR: StateRepositoryLike + Send, { type Item = JsonValue; diff --git a/packages/rs-dpp/src/state_repository.rs b/packages/rs-dpp/src/state_repository.rs index bfcf701dc42..79b65b3d152 100644 --- a/packages/rs-dpp/src/state_repository.rs +++ b/packages/rs-dpp/src/state_repository.rs @@ -34,7 +34,7 @@ pub struct FetchTransactionResponse { #[async_trait(?Send)] pub trait StateRepositoryLike: Sync { type ConversionError: Into; - type FetchDataContract: TryInto; + type FetchDataContract: TryInto + Send; type FetchIdentity: TryInto; type FetchTransaction: TryInto + Send 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 287d03b867c..caaf46208ed 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 @@ -42,7 +42,7 @@ where #[async_trait] impl AsyncDataValidatorWithContext for StateTransitionBasicValidator where - SR: StateRepositoryLike, + SR: StateRepositoryLike + Send, VBT: ValidatorByStateTransitionType, { type Item = JsonValue; diff --git a/packages/rs-dpp/src/validation/mod.rs b/packages/rs-dpp/src/validation/mod.rs index 1100b66737b..bcf8265dde2 100644 --- a/packages/rs-dpp/src/validation/mod.rs +++ b/packages/rs-dpp/src/validation/mod.rs @@ -48,7 +48,7 @@ pub trait DataValidatorWithContext { /// Async validator takes additionally an execution context and generates fee #[cfg_attr(test, automock(type Item = JsonValue;))] #[async_trait] -pub trait AsyncDataValidatorWithContext { +pub trait AsyncDataValidatorWithContext: Send + Sync { // TODO, when GAT is available remove the reference in method and use: `type Item<'a>` type Item; async fn validate( From 66033f766221f4768638ed7331591ed5505ad66d Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 22 Feb 2023 15:29:56 +0500 Subject: [PATCH 07/35] chore: make ?Send work --- .../validation/validate_state_transition_basic.rs | 2 +- .../validation/validate_state_transition_by_type.rs | 8 ++++---- packages/rs-dpp/src/validation/mod.rs | 4 ++-- 3 files changed, 7 insertions(+), 7 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 caaf46208ed..87d339e7031 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 @@ -39,7 +39,7 @@ where } } -#[async_trait] +#[async_trait(?Send)] impl AsyncDataValidatorWithContext for StateTransitionBasicValidator where SR: StateRepositoryLike + Send, diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs index b3a7c15b3f5..1f5276f02a8 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs @@ -14,8 +14,8 @@ use crate::{ }; #[cfg_attr(test, automock)] -#[async_trait] -pub trait ValidatorByStateTransitionType: Sync + Send { +#[async_trait(?Send)] +pub trait ValidatorByStateTransitionType { async fn validate( &self, raw_state_transition: &JsonValue, @@ -62,7 +62,7 @@ where } } -#[async_trait] +#[async_trait(?Send)] impl ValidatorByStateTransitionType for StateTransitionByTypeValidator where ADV: AsyncDataValidatorWithContext + Send + Sync, @@ -144,7 +144,7 @@ mod tests { ); let data_contract_validator = DataContractValidator::new(Arc::new(protocol_version_validator)); - let data_contract_factory = DataContractFactory::new(1, data_contract_validator); + let data_contract_factory = DataContractFactory::new(1, Arc::new(data_contract_validator)); let mut state_transition = data_contract_factory .create_data_contract_create_transition(data_contract.clone()) diff --git a/packages/rs-dpp/src/validation/mod.rs b/packages/rs-dpp/src/validation/mod.rs index bcf8265dde2..e6c3113e218 100644 --- a/packages/rs-dpp/src/validation/mod.rs +++ b/packages/rs-dpp/src/validation/mod.rs @@ -47,8 +47,8 @@ pub trait DataValidatorWithContext { /// Async validator takes additionally an execution context and generates fee #[cfg_attr(test, automock(type Item = JsonValue;))] -#[async_trait] -pub trait AsyncDataValidatorWithContext: Send + Sync { +#[async_trait(?Send)] +pub trait AsyncDataValidatorWithContext { // TODO, when GAT is available remove the reference in method and use: `type Item<'a>` type Item; async fn validate( From ff439f145fa9ea237dc700cec7d2d19df0358856 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 22 Feb 2023 23:12:45 +0500 Subject: [PATCH 08/35] chore: InvalidStateTransitionError --- packages/rs-dpp/src/errors/errors.rs | 4 ++++ packages/rs-dpp/src/state_transition/errors/mod.rs | 2 ++ .../src/state_transition/errors/state_transition.rs | 13 +++++++++++++ packages/rs-dpp/src/state_transition/mod.rs | 1 + .../state_transition/state_transition_factory.rs | 11 ++++++++++- 5 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 packages/rs-dpp/src/state_transition/errors/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/errors/state_transition.rs diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index 6ef8f5fc841..85428d28eaa 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -6,6 +6,7 @@ use crate::data_contract::errors::*; use crate::document::errors::*; use crate::identity::{IdentityPublicKey, KeyType, Purpose, SecurityLevel}; use crate::prelude::Identifier; +use crate::state_transition::errors::StateTransitionError; use crate::state_transition::StateTransition; use crate::{CompatibleProtocolVersionIsNotDefinedError, NonConsensusError, SerdeParsingError}; @@ -42,6 +43,9 @@ pub enum ProtocolError { #[error(transparent)] DataContractError(#[from] DataContractError), + #[error(transparent)] + StateTransitionError(#[from] StateTransitionError), + #[error(transparent)] StructureError(#[from] StructureError), diff --git a/packages/rs-dpp/src/state_transition/errors/mod.rs b/packages/rs-dpp/src/state_transition/errors/mod.rs new file mode 100644 index 00000000000..96039eb8eae --- /dev/null +++ b/packages/rs-dpp/src/state_transition/errors/mod.rs @@ -0,0 +1,2 @@ +mod state_transition; +pub use state_transition::*; diff --git a/packages/rs-dpp/src/state_transition/errors/state_transition.rs b/packages/rs-dpp/src/state_transition/errors/state_transition.rs new file mode 100644 index 00000000000..b8c3dfe3804 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/errors/state_transition.rs @@ -0,0 +1,13 @@ +use serde_json::Value as JsonValue; +use thiserror::Error; + +use crate::consensus::ConsensusError; + +#[derive(Error, Debug)] +pub enum StateTransitionError { + #[error("Invalid State Transition: {errors:?}")] + InvalidStateTransitionError { + errors: Vec, + raw_state_transition: JsonValue, + }, +} diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 0954f625643..269c9d0b4a4 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -28,6 +28,7 @@ pub mod validation; pub mod fee; pub mod state_transition_execution_context; +pub mod errors; mod example; macro_rules! call_method { 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 7b0dfb1f64e..b53d56107ad 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -71,7 +71,16 @@ where .validate(&raw_state_transition, &execution_context) .await?; - // TODO: return InvalidStateTransitionError + if !validation_result.is_valid() { + return Err( + ProtocolError::StateTransitionError( + super::errors::StateTransitionError::InvalidStateTransitionError { + errors: validation_result.errors, + raw_state_transition + } + ) + ); + } } create_state_transition(self.state_repository.as_ref(), raw_state_transition).await From 72f46b2616a379ce181d088431affdc485493790 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Thu, 23 Feb 2023 15:14:04 +0500 Subject: [PATCH 09/35] chore: fix validation function behaviour --- packages/rs-dpp/src/state_transition/mod.rs | 2 +- .../state_transition_factory.rs | 14 ++++----- .../validate_state_transition_basic.rs | 31 ++++++++++++++++--- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 269c9d0b4a4..39731bbc186 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -26,9 +26,9 @@ use self::state_transition_execution_context::StateTransitionExecutionContext; mod state_transition_types; pub mod validation; +pub mod errors; pub mod fee; pub mod state_transition_execution_context; -pub mod errors; mod example; macro_rules! call_method { 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 b53d56107ad..ea0f0abfe6c 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -72,14 +72,12 @@ where .await?; if !validation_result.is_valid() { - return Err( - ProtocolError::StateTransitionError( - super::errors::StateTransitionError::InvalidStateTransitionError { - errors: validation_result.errors, - raw_state_transition - } - ) - ); + return Err(ProtocolError::StateTransitionError( + super::errors::StateTransitionError::InvalidStateTransitionError { + errors: validation_result.errors, + raw_state_transition, + }, + )); } } 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 87d339e7031..543ab7fdf43 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 @@ -1,16 +1,17 @@ -use std::sync::Arc; +use std::{convert::TryFrom, sync::Arc}; use async_trait::async_trait; use serde_json::Value as JsonValue; use crate::{ - consensus::basic::BasicError, + consensus::{basic::BasicError, ConsensusError}, state_repository::StateRepositoryLike, state_transition::{ create_state_transition, state_transition_execution_context::StateTransitionExecutionContext, - try_get_transition_type, StateTransitionConvert, + StateTransitionConvert, StateTransitionType, }, + util::json_value::JsonValueExt, validation::{AsyncDataValidatorWithContext, SimpleValidationResult}, ProtocolError, }; @@ -54,9 +55,29 @@ where ) -> Result { let mut result = SimpleValidationResult::default(); - let state_transition_type_result = try_get_transition_type(raw_state_transition); + let Ok(state_transition_type) = raw_state_transition.get_u8("type") else { + result.add_error( + ConsensusError::BasicError( + Box::new(BasicError::MissingStateTransitionTypeError) + ) + ); - let state_transition_type = state_transition_type_result?; + return Ok(result); + }; + + let Ok(state_transition_type) = StateTransitionType::try_from(state_transition_type) else { + result.add_error( + ConsensusError::BasicError( + Box::new( + BasicError::InvalidStateTransitionTypeError { + transition_type: state_transition_type + } + ) + ) + ); + + return Ok(result); + }; let validate_result = self .validate_state_transition_by_type From 0cc2300589926a7386446e06641b899339671326 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Thu, 23 Feb 2023 19:51:14 +0500 Subject: [PATCH 10/35] chore: wip --- .../src/data_contract/data_contract_facade.rs | 3 - .../data_contract/data_contract_factory.rs | 8 +- ...e_data_contract_update_transition_state.rs | 2 +- .../src/data_contract/state_transition/mod.rs | 3 - ...lidate_documents_batch_transition_basic.rs | 178 ++++++++++-------- packages/rs-dpp/src/state_transition/mod.rs | 5 +- .../state_transition_factory.rs | 31 +-- .../validate_state_transition_basic.rs | 2 +- .../validate_state_transition_by_type.rs | 65 ++++--- .../validate_state_transition_fee.rs | 1 - ...a_contract_update_transition_basic_spec.rs | 2 +- packages/wasm-dpp/src/state_transition/mod.rs | 2 + .../state_transition_factory.rs | 7 + 13 files changed, 173 insertions(+), 136 deletions(-) create mode 100644 packages/wasm-dpp/src/state_transition/state_transition_factory.rs diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index 6abea896230..36d075ccb44 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -1,6 +1,3 @@ -use crate::data_contract::state_transition::{ - DataContractCreateTransition, DataContractUpdateTransition, -}; use crate::data_contract::validation::data_contract_validator::DataContractValidator; use crate::data_contract::{DataContract, DataContractFactory}; use crate::document::document_transition::document_base_transition::JsonValue; diff --git a/packages/rs-dpp/src/data_contract/data_contract_factory.rs b/packages/rs-dpp/src/data_contract/data_contract_factory.rs index e15c8168696..0ac1ef847e5 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -14,11 +14,9 @@ use crate::{ util::entropy_generator, }; -use super::{ - state_transition::{DataContractCreateTransition, DataContractUpdateTransition}, - validation::data_contract_validator::DataContractValidator, - DataContract, -}; +use super::state_transition::data_contract_create_transition::DataContractCreateTransition; +use super::state_transition::data_contract_update_transition::DataContractUpdateTransition; +use super::{validation::data_contract_validator::DataContractValidator, DataContract}; /// A way to provide external entropy generator. pub trait EntropyGenerator { diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/state/validate_data_contract_update_transition_state.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/state/validate_data_contract_update_transition_state.rs index ceb956cbc9f..7a9cfc4a555 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/state/validate_data_contract_update_transition_state.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/state/validate_data_contract_update_transition_state.rs @@ -4,7 +4,7 @@ use anyhow::Result; use async_trait::async_trait; use crate::{ - data_contract::{state_transition::DataContractUpdateTransition, DataContract}, + data_contract::{ DataContract}, errors::consensus::basic::BasicError, state_repository::StateRepositoryLike, state_transition::StateTransitionLike, diff --git a/packages/rs-dpp/src/data_contract/state_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/mod.rs index 6b75a4d569b..b58a5e14308 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/mod.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/mod.rs @@ -1,6 +1,3 @@ -pub use data_contract_create_transition::*; -pub use data_contract_update_transition::*; - pub mod data_contract_create_transition; pub mod data_contract_update_transition; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 6d4204bd348..2ca3a8f19ba 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -1,6 +1,7 @@ use std::{ collections::{hash_map::Entry, HashMap}, convert::{TryFrom, TryInto}, + sync::Arc, }; use crate::document::validation::basic::find_duplicates_by_id::find_duplicates_by_id; @@ -53,100 +54,111 @@ pub trait Validator { fn validate(&self, data: JsonValue) -> Result, ProtocolError>; } -pub async fn validate_documents_batch_transition_basic( - protocol_version_validator: &ProtocolVersionValidator, - raw_state_transition: &JsonValue, - state_repository: &impl StateRepositoryLike, - execution_context: &StateTransitionExecutionContext, -) -> Result, ProtocolError> { - let mut result = ValidationResult::default(); - let validator = - JsonSchemaValidator::new(DOCUMENTS_BATCH_TRANSITIONS_SCHEMA.clone()).map_err(|e| { - anyhow!( - "unable to compile the batch transitions schema: {}", - e.to_string() - ) - })?; - - let validation_result = validator.validate(raw_state_transition)?; - result.merge(validation_result); - if !result.is_valid() { - return Ok(result); - } +pub struct DocumentBatchTransitionBasicValidator { + state_repository: Arc, + protocol_version_validator: Arc, +} - let protocol_version = raw_state_transition.get_u64("protocolVersion")? as u32; - let validation_result = protocol_version_validator.validate(protocol_version)?; - result.merge(validation_result); - if !result.is_valid() { - return Ok(result); - } +impl DocumentBatchTransitionBasicValidator +where + SR: StateRepositoryLike, +{ + pub async fn validate( + &self, + raw_state_transition: &JsonValue, + execution_context: &StateTransitionExecutionContext, + ) -> Result, ProtocolError> { + let mut result = ValidationResult::default(); + let validator = JsonSchemaValidator::new(DOCUMENTS_BATCH_TRANSITIONS_SCHEMA.clone()) + .map_err(|e| { + anyhow!( + "unable to compile the batch transitions schema: {}", + e.to_string() + ) + })?; + + let validation_result = validator.validate(raw_state_transition)?; + result.merge(validation_result); + if !result.is_valid() { + return Ok(result); + } - let raw_document_transitions = raw_state_transition - .get("transitions") - .ok_or_else(|| anyhow!("transitions property doesn't exist"))? - .as_array() - .ok_or_else(|| anyhow!("transitions property isn't an array"))?; - let mut document_transitions_by_contracts: HashMap> = - HashMap::new(); + let protocol_version = raw_state_transition.get_u64("protocolVersion")? as u32; + let validation_result = self.protocol_version_validator.validate(protocol_version)?; + result.merge(validation_result); + if !result.is_valid() { + return Ok(result); + } - for raw_document_transition in raw_document_transitions { - let data_contract_id_bytes = match raw_document_transition.get_bytes("$dataContractId") { - Err(_) => { - result.add_error(BasicError::MissingDataContractIdError); - continue; - } - Ok(id) => id, - }; + let raw_document_transitions = raw_state_transition + .get("transitions") + .ok_or_else(|| anyhow!("transitions property doesn't exist"))? + .as_array() + .ok_or_else(|| anyhow!("transitions property isn't an array"))?; + let mut document_transitions_by_contracts: HashMap> = + HashMap::new(); + + for raw_document_transition in raw_document_transitions { + let data_contract_id_bytes = match raw_document_transition.get_bytes("$dataContractId") + { + Err(_) => { + result.add_error(BasicError::MissingDataContractIdError); + continue; + } + Ok(id) => id, + }; + + let identifier = match Identifier::from_bytes(&data_contract_id_bytes) { + Ok(identifier) => identifier, + Err(e) => { + result.add_error(BasicError::InvalidIdentifierError { + identifier_name: String::from("$dataContractId"), + error: e.to_string(), + }); + continue; + } + }; - let identifier = match Identifier::from_bytes(&data_contract_id_bytes) { - Ok(identifier) => identifier, - Err(e) => { - result.add_error(BasicError::InvalidIdentifierError { - identifier_name: String::from("$dataContractId"), - error: e.to_string(), - }); - continue; - } - }; + match document_transitions_by_contracts.entry(identifier) { + Entry::Vacant(vacant) => { + vacant.insert(vec![raw_document_transition]); + } + Entry::Occupied(mut identifiers) => { + identifiers.get_mut().push(raw_document_transition); + } + }; + } - match document_transitions_by_contracts.entry(identifier) { - Entry::Vacant(vacant) => { - vacant.insert(vec![raw_document_transition]); - } - Entry::Occupied(mut identifiers) => { - identifiers.get_mut().push(raw_document_transition); - } - }; - } + for (data_contract_id, transitions) in document_transitions_by_contracts { + let maybe_data_contract = self + .state_repository + .fetch_data_contract(&data_contract_id, execution_context) + .await? + .map(TryInto::try_into) + .transpose() + .map_err(Into::into)?; - for (data_contract_id, transitions) in document_transitions_by_contracts { - let maybe_data_contract = state_repository - .fetch_data_contract(&data_contract_id, execution_context) - .await? - .map(TryInto::try_into) - .transpose() - .map_err(Into::into)?; + if execution_context.is_dry_run() { + return Ok(result); + } - if execution_context.is_dry_run() { - return Ok(result); - } + let data_contract = match maybe_data_contract { + None => { + result.add_error(BasicError::DataContractNotPresent { data_contract_id }); + continue; + } + Some(data_contract) => data_contract, + }; - let data_contract = match maybe_data_contract { - None => { - result.add_error(BasicError::DataContractNotPresent { data_contract_id }); - continue; - } - Some(data_contract) => data_contract, - }; + let owner_id = Identifier::from_bytes(&raw_state_transition.get_bytes("ownerId")?)?; - let owner_id = Identifier::from_bytes(&raw_state_transition.get_bytes("ownerId")?)?; + let validation_result = + validate_document_transitions(&data_contract, &owner_id, transitions)?; + result.merge(validation_result); + } - let validation_result = - validate_document_transitions(&data_contract, &owner_id, transitions)?; - result.merge(validation_result); + Ok(result) } - - Ok(result) } fn validate_document_transitions<'a>( diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 39731bbc186..29f3474554f 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -6,9 +6,8 @@ pub use abstract_state_transition::{ pub use abstract_state_transition_identity_signed::StateTransitionIdentitySigned; pub use state_transition_types::*; -use crate::data_contract::state_transition::{ - DataContractCreateTransition, DataContractUpdateTransition, -}; +use crate::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; +use crate::data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition; // TODO unify the import paths ::object::state_transition::* use crate::document::DocumentsBatchTransition; use crate::identity::state_transition::identity_create_transition::IdentityCreateTransition; 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 ea0f0abfe6c..fb652b3746e 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -6,10 +6,7 @@ use std::{ use crate::{ consensus::{basic::BasicError, ConsensusError}, - data_contract::{ - state_transition::{DataContractCreateTransition, DataContractUpdateTransition}, - DataContract, - }, + data_contract::DataContract, decode_protocol_entity_factory::DecodeProtocolEntity, document::DocumentsBatchTransition, identity::state_transition::{ @@ -21,14 +18,18 @@ use crate::{ state_repository::StateRepositoryLike, util::json_value::JsonValueExt, validation::AsyncDataValidatorWithContext, - ProtocolError, + BlsModule, ProtocolError, }; use serde_json::Number; use serde_json::Value as JsonValue; use super::{ - state_transition_execution_context::StateTransitionExecutionContext, StateTransition, - StateTransitionType, + state_transition_execution_context::StateTransitionExecutionContext, + validation::{ + validate_state_transition_basic::StateTransitionBasicValidator, + validate_state_transition_by_type::StateTransitionByTypeValidator, + }, + StateTransition, StateTransitionType, }; #[derive(Default)] @@ -36,20 +37,24 @@ pub struct StateTransitionFactoryOptions { pub skip_validation: bool, } -pub struct StateTransitionFactory +pub struct StateTransitionFactory where - ADV: AsyncDataValidatorWithContext, + SR: StateRepositoryLike, + BLS: BlsModule, { state_repository: Arc, - basic_validator: ADV, + basic_validator: StateTransitionBasicValidator>, } -impl StateTransitionFactory +impl StateTransitionFactory where SR: StateRepositoryLike, - ADV: AsyncDataValidatorWithContext, + BLS: BlsModule, { - pub fn new(state_repository: Arc, basic_validator: ADV) -> Self { + pub fn new( + state_repository: Arc, + basic_validator: StateTransitionBasicValidator>, + ) -> Self { StateTransitionFactory { state_repository, basic_validator, 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 543ab7fdf43..c70e165c740 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 @@ -119,6 +119,7 @@ mod test { use std::sync::Arc; use crate::{ + data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition, state_transition::validation::validate_state_transition_by_type::MockValidatorByStateTransitionType, validation::AsyncDataValidatorWithContext, }; @@ -128,7 +129,6 @@ mod test { use crate::{ consensus::basic::BasicError, data_contract::{ - state_transition::DataContractCreateTransition, validation::data_contract_validator::DataContractValidator, DataContract, DataContractFactory, }, diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs index 1f5276f02a8..72293755c1e 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs @@ -10,7 +10,7 @@ use crate::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransitionType, }, validation::{AsyncDataValidatorWithContext, SimpleValidationResult, ValidationResult}, - ProtocolError, + ProtocolError, BlsModule, state_repository::StateRepositoryLike, data_contract::state_transition::{data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator}, identity::{state_transition::{identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, validate_public_key_signatures::PublicKeysSignaturesValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic, identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator}, validation::PublicKeysValidator}, document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, }; #[cfg_attr(test, automock)] @@ -24,31 +24,51 @@ pub trait ValidatorByStateTransitionType { ) -> Result; } -pub struct StateTransitionByTypeValidator +pub struct StateTransitionByTypeValidator where - ADV: AsyncDataValidatorWithContext, + SR: StateRepositoryLike, + BLS: BlsModule, { - data_contract_create_validator: ADV, - data_contract_update_validator: ADV, - identity_create_validator: ADV, - identity_update_validator: ADV, - identity_top_up_validator: ADV, - identity_credit_withdrawal_validator: ADV, - document_batch_validator: ADV, + data_contract_create_validator: DataContractCreateTransitionBasicValidator, + data_contract_update_validator: DataContractUpdateTransitionBasicValidator, + identity_create_validator: IdentityCreateTransitionBasicValidator< + PublicKeysValidator, + PublicKeysValidator, + SR, + PublicKeysSignaturesValidator, + BLS, + >, + identity_update_validator: ValidateIdentityUpdateTransitionBasic< + PublicKeysValidator, + PublicKeysSignaturesValidator, + >, + identity_top_up_validator: IdentityTopUpTransitionBasicValidator, + identity_credit_withdrawal_validator: IdentityCreditWithdrawalTransitionBasicValidator, + document_batch_validator: DocumentBatchTransitionBasicValidator, } -impl StateTransitionByTypeValidator +impl StateTransitionByTypeValidator where - ADV: AsyncDataValidatorWithContext, + SR: StateRepositoryLike, + BLS: BlsModule, { pub fn new( - data_contract_create_validator: ADV, - data_contract_update_validator: ADV, - identity_create_validator: ADV, - identity_update_validator: ADV, - identity_top_up_validator: ADV, - identity_credit_withdrawal_validator: ADV, - document_batch_validator: ADV, + data_contract_create_validator: DataContractCreateTransitionBasicValidator, + data_contract_update_validator: DataContractUpdateTransitionBasicValidator, + identity_create_validator: IdentityCreateTransitionBasicValidator< + PublicKeysValidator, + PublicKeysValidator, + SR, + PublicKeysSignaturesValidator, + BLS, + >, + identity_update_validator: ValidateIdentityUpdateTransitionBasic< + PublicKeysValidator, + PublicKeysSignaturesValidator, + >, + identity_top_up_validator: IdentityTopUpTransitionBasicValidator, + identity_credit_withdrawal_validator: IdentityCreditWithdrawalTransitionBasicValidator, + document_batch_validator: DocumentBatchTransitionBasicValidator, ) -> Self { StateTransitionByTypeValidator { data_contract_create_validator, @@ -63,9 +83,10 @@ where } #[async_trait(?Send)] -impl ValidatorByStateTransitionType for StateTransitionByTypeValidator +impl ValidatorByStateTransitionType for StateTransitionByTypeValidator where - ADV: AsyncDataValidatorWithContext + Send + Sync, + SR: StateRepositoryLike, + BLS: BlsModule, { async fn validate( &self, @@ -105,7 +126,7 @@ mod tests { use crate::{ data_contract::{ - state_transition::DataContractCreateTransition, + state_transition::data_contract_create_transition::DataContractCreateTransition, validation::data_contract_validator::DataContractValidator, DataContract, DataContractFactory, }, diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs index b32653ca600..e33d6300115 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs @@ -155,7 +155,6 @@ mod test { use crate::ProtocolError; use crate::{ consensus::fee::FeeError, - data_contract::state_transition::DataContractCreateTransition, document::{document_transition::Action, DocumentsBatchTransition}, identity::state_transition::identity_credit_withdrawal_transition::IdentityCreditWithdrawalTransition, state_repository::MockStateRepositoryLike, diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 090cab8341a..7362a246e62 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -6,7 +6,7 @@ use crate::{ consensus::basic::BasicError, data_contract::state_transition::{ data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, - property_names, DataContractUpdateTransition, + property_names, }, state_repository::MockStateRepositoryLike, state_transition::{ diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 6a9c5d6cf7b..24fbe6bf650 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -1,6 +1,8 @@ use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use wasm_bindgen::prelude::*; +pub mod state_transition_factory; + #[wasm_bindgen(js_name=StateTransitionExecutionContext)] pub struct StateTransitionExecutionContextWasm(StateTransitionExecutionContext); diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs new file mode 100644 index 00000000000..83c5651e970 --- /dev/null +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -0,0 +1,7 @@ +use dpp::state_transition::StateTransitionFactory; +use wasm_bindgen::prelude::wasm_bindgen; + +use crate::state_repository::ExternalStateRepositoryLikeWrapper; + +#[wasm_bindgen(js_name = StateTransitionFactory)] +pub struct StateTransitionFactoryWasm(StateTransitionFactory); From e476983fb8ae6318c57497e5e5beb15bfc05d0d9 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Thu, 23 Feb 2023 22:22:00 +0500 Subject: [PATCH 11/35] chore: wip --- .../src/data_contract/data_contract_facade.rs | 3 + ...e_data_contract_create_transition_state.rs | 5 +- ...e_data_contract_update_transition_basic.rs | 2 +- ...e_data_contract_update_transition_state.rs | 7 +- ...lidate_documents_batch_transition_basic.rs | 10 + .../state_transition_factory.rs | 10 +- .../validate_state_transition_basic.rs | 2 +- .../validate_state_transition_by_type.rs | 44 +- .../validate_state_transition_fee.rs | 1 + ...a_contract_update_transition_basic_spec.rs | 5 +- ..._documents_batch_transitions_basic_spec.rs | 553 ++++++++++-------- .../data_contract_create_transition/apply.rs | 2 +- .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_update_transition/apply.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- .../state_transition_factory.rs | 6 +- 16 files changed, 373 insertions(+), 283 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/data_contract_facade.rs b/packages/rs-dpp/src/data_contract/data_contract_facade.rs index 36d075ccb44..b42fd7474dd 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_facade.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_facade.rs @@ -6,6 +6,9 @@ use crate::version::ProtocolVersionValidator; use crate::ProtocolError; use std::sync::Arc; +use super::state_transition::data_contract_create_transition::DataContractCreateTransition; +use super::state_transition::data_contract_update_transition::DataContractUpdateTransition; + pub struct DataContractFacade { factory: DataContractFactory, data_contract_validator: Arc, diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs index f0bda530197..162e3686a18 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_create_transition/validation/state/validate_data_contract_create_transition_state.rs @@ -4,7 +4,10 @@ use anyhow::Result; use async_trait::async_trait; use crate::{ - data_contract::{state_transition::DataContractCreateTransition, DataContract}, + data_contract::{ + state_transition::data_contract_create_transition::DataContractCreateTransition, + DataContract, + }, errors::StateError, state_repository::StateRepositoryLike, state_transition::StateTransitionLike, diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 7d47341967e..10b75852ccc 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -67,7 +67,7 @@ where #[async_trait(?Send)] impl AsyncDataValidatorWithContext for DataContractUpdateTransitionBasicValidator where - SR: StateRepositoryLike + Send, + SR: StateRepositoryLike, { type Item = JsonValue; diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/state/validate_data_contract_update_transition_state.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/state/validate_data_contract_update_transition_state.rs index 7a9cfc4a555..241fe3d5d9e 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/state/validate_data_contract_update_transition_state.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/state/validate_data_contract_update_transition_state.rs @@ -4,7 +4,10 @@ use anyhow::Result; use async_trait::async_trait; use crate::{ - data_contract::{ DataContract}, + data_contract::{ + state_transition::data_contract_update_transition::DataContractUpdateTransition, + DataContract, + }, errors::consensus::basic::BasicError, state_repository::StateRepositoryLike, state_transition::StateTransitionLike, @@ -94,7 +97,7 @@ pub async fn validate_data_contract_update_transition_state( mod test { use super::*; use crate::{ - data_contract::state_transition::DataContractUpdateTransition, + data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition, state_repository::MockStateRepositoryLike, state_transition::StateTransitionLike, tests::fixtures::get_data_contract_fixture, }; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 2ca3a8f19ba..d46dc516c71 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -63,6 +63,16 @@ impl DocumentBatchTransitionBasicValidator where SR: StateRepositoryLike, { + pub fn new( + state_repository: Arc, + protocol_version_validator: Arc, + ) -> Self { + Self { + state_repository, + protocol_version_validator, + } + } + pub async fn validate( &self, raw_state_transition: &JsonValue, 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 fb652b3746e..e2852260153 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_factory.rs @@ -6,7 +6,13 @@ use std::{ use crate::{ consensus::{basic::BasicError, ConsensusError}, - data_contract::DataContract, + data_contract::{ + state_transition::{ + data_contract_create_transition::DataContractCreateTransition, + data_contract_update_transition::DataContractUpdateTransition, + }, + DataContract, + }, decode_protocol_entity_factory::DecodeProtocolEntity, document::DocumentsBatchTransition, identity::state_transition::{ @@ -215,7 +221,7 @@ mod test { use serde_json::{json, Value as JsonValue}; use crate::{ - data_contract::state_transition::DataContractCreateTransition, + data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition, document::{ document_transition::{Action, DocumentTransitionObjectLike}, DocumentsBatchTransition, 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 c70e165c740..7f447966ad1 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 @@ -43,7 +43,7 @@ where #[async_trait(?Send)] impl AsyncDataValidatorWithContext for StateTransitionBasicValidator where - SR: StateRepositoryLike + Send, + SR: StateRepositoryLike, VBT: ValidatorByStateTransitionType, { type Item = JsonValue; diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs index 72293755c1e..ad20a977097 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs @@ -9,7 +9,7 @@ use crate::{ state_transition::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransitionType, }, - validation::{AsyncDataValidatorWithContext, SimpleValidationResult, ValidationResult}, + validation::{AsyncDataValidatorWithContext, DataValidatorWithContext, SimpleValidationResult, ValidationResult}, ProtocolError, BlsModule, state_repository::StateRepositoryLike, data_contract::state_transition::{data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator}, identity::{state_transition::{identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, validate_public_key_signatures::PublicKeysSignaturesValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic, identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator}, validation::PublicKeysValidator}, document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, }; @@ -96,22 +96,40 @@ where ) -> Result { let mut result = ValidationResult::default(); - let validator = match state_transition_type { - StateTransitionType::DataContractCreate => &self.data_contract_create_validator, - StateTransitionType::DataContractUpdate => &self.data_contract_update_validator, - StateTransitionType::IdentityCreate => &self.identity_create_validator, - StateTransitionType::IdentityUpdate => &self.identity_update_validator, - StateTransitionType::IdentityTopUp => &self.identity_top_up_validator, + let validation_result = match state_transition_type { + StateTransitionType::DataContractCreate => self + .data_contract_create_validator + .validate(raw_state_transition, execution_context)?, + StateTransitionType::DataContractUpdate => { + self.data_contract_update_validator + .validate(raw_state_transition, execution_context) + .await? + } + StateTransitionType::IdentityCreate => { + self.identity_create_validator + .validate(raw_state_transition, execution_context) + .await? + } + StateTransitionType::IdentityUpdate => self + .identity_update_validator + .validate(raw_state_transition)?, + StateTransitionType::IdentityTopUp => { + self.identity_top_up_validator + .validate(raw_state_transition, execution_context) + .await? + } StateTransitionType::IdentityCreditWithdrawal => { - &self.identity_credit_withdrawal_validator + self.identity_credit_withdrawal_validator + .validate(raw_state_transition) + .await? + } + StateTransitionType::DocumentsBatch => { + self.document_batch_validator + .validate(raw_state_transition, execution_context) + .await? } - StateTransitionType::DocumentsBatch => &self.document_batch_validator, }; - let validation_result = validator - .validate(raw_state_transition, execution_context) - .await?; - result.merge(validation_result); Ok(result) diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs index e33d6300115..252d702b28d 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_fee.rs @@ -149,6 +149,7 @@ where mod test { use std::sync::Arc; + use crate::data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition; use crate::identity::state_transition::identity_topup_transition::IdentityTopUpTransition; use crate::state_transition::StateTransitionLike; use crate::tests::fixtures::identity_topup_transition_fixture_json; diff --git a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs index 7362a246e62..02411d8919d 100644 --- a/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic_spec.rs @@ -5,7 +5,10 @@ use test_case::test_case; use crate::{ consensus::basic::BasicError, data_contract::state_transition::{ - data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, + data_contract_update_transition::{ + validation::basic::DataContractUpdateTransitionBasicValidator, + DataContractUpdateTransition, + }, property_names, }, state_repository::MockStateRepositoryLike, diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index f621726b900..9587166d1d4 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -1,22 +1,23 @@ +use std::sync::Arc; + use crate::{ - data_contract::{DataContract}, + data_contract::DataContract, document::{ document_transition::{Action, DocumentTransitionObjectLike}, - state_transition::documents_batch_transition::validation::basic::validate_documents_batch_transition_basic::validate_documents_batch_transition_basic, + validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, DocumentsBatchTransition, }, - state_repository::{MockStateRepositoryLike}, - state_transition::{StateTransitionConvert, state_transition_execution_context::StateTransitionExecutionContext}, + state_repository::MockStateRepositoryLike, + state_transition::{ + state_transition_execution_context::StateTransitionExecutionContext, StateTransitionConvert, + }, tests::{ fixtures::{ get_data_contract_fixture, get_document_transitions_fixture, get_documents_fixture_with_owner_id_from_contract, get_protocol_version_validator_fixture, }, - utils::{ - generate_random_identifier, - get_schema_error, - }, + utils::{generate_random_identifier, get_schema_error}, }, util::json_value::JsonValueExt, version::{ProtocolVersionValidator, LATEST_VERSION}, @@ -105,14 +106,15 @@ async fn property_should_be_present(property: &str) { raw_state_transition.remove(property).unwrap(); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); assert!(matches!( @@ -134,16 +136,17 @@ async fn protocol_version_should_be_integer() { raw_state_transition["protocolVersion"] = json!("1"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/protocolVersion", schema_error.instance_path().to_string()); assert_eq!(Some("type"), schema_error.keyword(),); } @@ -159,16 +162,17 @@ async fn protocol_version_should_be_valid() { raw_state_transition["protocolVersion"] = json!("-1"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("protocol error should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/protocolVersion", schema_error.instance_path().to_string()); assert_eq!(Some("type"), schema_error.keyword(),); } @@ -184,14 +188,15 @@ async fn type_should_be_equal_1() { raw_state_transition["type"] = json!(666); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); assert_eq!("/type", schema_error.instance_path().to_string()); @@ -212,16 +217,17 @@ async fn property_in_state_transition_should_be_byte_array(property_name: &str) let array = ["string"; 32]; raw_state_transition[property_name] = json!(array); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + let byte_array_schema_error = get_schema_error(&result, 1); assert_eq!( format!("/{}/0", property_name), @@ -246,16 +252,17 @@ async fn owner_id_should_be_no_less_than_32_bytes() { let array = [0u8; 31]; raw_state_transition["ownerId"] = json!(array); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/ownerId", schema_error.instance_path().to_string()); assert_eq!(Some("minItems"), schema_error.keyword(),); } @@ -273,16 +280,17 @@ async fn owner_id_should_be_no_longer_than_32_bytes() { array.resize(33, 0u8); raw_state_transition["ownerId"] = json!(array); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/ownerId", schema_error.instance_path().to_string()); assert_eq!(Some("maxItems"), schema_error.keyword(),); } @@ -298,16 +306,17 @@ async fn transitions_should_be_an_array() { raw_state_transition["transitions"] = json!("not an array"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/transitions", schema_error.instance_path().to_string()); assert_eq!(Some("type"), schema_error.keyword(),); } @@ -323,16 +332,17 @@ async fn transitions_should_have_at_least_one_element() { raw_state_transition["transitions"] = json!([]); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/transitions", schema_error.instance_path().to_string()); assert_eq!(Some("minItems"), schema_error.keyword(),); } @@ -352,16 +362,17 @@ async fn transitions_should_have_no_more_than_10_elements() { } raw_state_transition["transitions"] = JsonValue::Array(elements); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/transitions", schema_error.instance_path().to_string()); assert_eq!(Some("maxItems"), schema_error.keyword(),); } @@ -378,16 +389,17 @@ async fn transitions_should_have_an_object_as_elements() { let elements = vec![json!(1)]; raw_state_transition["transitions"] = JsonValue::Array(elements); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/transitions/0", schema_error.instance_path().to_string()); assert_eq!(Some("type"), schema_error.keyword(),); } @@ -409,16 +421,17 @@ async fn property_in_document_transition_should_be_present(property: &str) { .remove(property) .expect("the property should exist and be removed"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { @@ -443,14 +456,16 @@ async fn property_should_should_exist_with_code(property_name: &str, error_code: .remove(property_name) .expect("the property should exist and be removed"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); + let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(error_code, error.code()); @@ -470,16 +485,17 @@ async fn property_should_be_byte_array(property_name: &str) { let array = ["string"; 32]; raw_state_transition["transitions"][0][property_name] = json!(array); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + let byte_array_schema_error = get_schema_error(&result, 1); assert_eq!( format!("/{}/0", property_name), @@ -503,14 +519,16 @@ async fn data_contract_id_should_be_byte_array() { raw_state_transition["transitions"][0]["$dataContractId"] = json!("something"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); + let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1025, error.code()); @@ -530,16 +548,17 @@ async fn property_should_be_no_less_than_32_bytes(property_name: &str) { let array = [0u8; 31]; raw_state_transition["transitions"][0][property_name] = json!(array); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!( format!("/{}", property_name), schema_error.instance_path().to_string() @@ -562,16 +581,17 @@ async fn id_should_be_no_longer_than_32_bytes(property_name: &str) { array.resize(33, 0u8); raw_state_transition["transitions"][0][property_name] = json!(array); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!( format!("/{}", property_name), schema_error.instance_path().to_string() @@ -595,14 +615,16 @@ async fn data_contract_should_exist_in_the_state() { .expect_fetch_data_contract() .returning(|_, _| Ok(None)); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); + let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1018, error.code()); @@ -619,14 +641,16 @@ async fn type_should_be_defined_in_data_contract() { raw_state_transition["transitions"][0]["$type"] = json!("wrong"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); + let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1024, error.code()); @@ -643,14 +667,16 @@ async fn should_throw_invalid_document_transaction_action_error_if_action_is_not raw_state_transition["transitions"][0]["$action"] = json!(4); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); + let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1022, error.code()); @@ -667,14 +693,16 @@ async fn id_should_be_valid_generated_id() { raw_state_transition["transitions"][0]["$id"] = json!(generate_random_identifier()); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); + let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1023, error.code()); @@ -694,16 +722,17 @@ async fn property_in_replace_transition_should_be_present(property: &str) { .remove(property) .expect("the property should exist and be removed"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { @@ -723,16 +752,17 @@ async fn revision_should_be_number() { raw_state_transition["transitions"][0]["$revision"] = json!("1"); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/$revision", schema_error.instance_path().to_string()); assert_eq!(Some("type"), schema_error.keyword(),); } @@ -748,16 +778,17 @@ async fn revision_should_not_be_fractional() { raw_state_transition["transitions"][0]["$revision"] = json!(1.2); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/$revision", schema_error.instance_path().to_string()); assert_eq!(Some("type"), schema_error.keyword(),); } @@ -773,16 +804,17 @@ async fn revision_should_be_at_least_1() { raw_state_transition["transitions"][0]["$revision"] = json!(0); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/$revision", schema_error.instance_path().to_string()); assert_eq!(Some("minimum"), schema_error.keyword(),); } @@ -800,16 +832,17 @@ async fn id_should_be_present_in_delete_transition() { .remove("$id") .unwrap(); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert!(matches!( schema_error.kind(), ValidationErrorKind::Required { @@ -842,16 +875,17 @@ async fn signature_should_be_not_less_than_65_bytes() { let array = [0u8; 64].to_vec(); raw_state_transition["signature"] = json!(array); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/signature", schema_error.instance_path().to_string()); assert_eq!(Some("minItems"), schema_error.keyword(),); } @@ -868,16 +902,17 @@ async fn signature_should_be_not_longer_than_96_bytes() { let array = [0u8; 97].to_vec(); raw_state_transition["signature"] = json!(array); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!("/signature", schema_error.instance_path().to_string()); assert_eq!(Some("maxItems"), schema_error.keyword(),); } @@ -893,16 +928,17 @@ async fn signature_public_key_should_be_an_integer() { raw_state_transition["signaturePublicKeyId"] = json!(1.4); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); let schema_error = get_schema_error(&result, 0); + assert_eq!( "/signaturePublicKeyId", schema_error.instance_path().to_string() @@ -919,14 +955,16 @@ async fn validation_should_be_successful() { .. } = setup_test(Action::Create); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &Default::default(), - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); + let schema_error = get_schema_error(&result, 0); assert!(result.is_valid()); } @@ -947,14 +985,17 @@ async fn should_not_validate_document_transitions_on_dry_run() { .expect_fetch_data_contract() .return_once(|_, _| Ok(None)); - let result = validate_documents_batch_transition_basic( - &protocol_version_validator, - &raw_state_transition, - &state_repository_mock, - &execution_context, - ) - .await - .expect("validation result should be returned"); + let validator = DocumentBatchTransitionBasicValidator::new( + Arc::new(state_repository_mock), + Arc::new(protocol_version_validator), + ); + + let result = validator + .validate(&raw_state_transition, &Default::default()) + .await + .expect("validation result should be returned"); + let schema_error = get_schema_error(&result, 0); + dbg!(&result); assert!(result.is_valid()); } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/apply.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/apply.rs index 1cd2a9d3fdc..3f2056cfc7c 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/apply.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/apply.rs @@ -1,6 +1,6 @@ use std::ops::Deref; -use dpp::data_contract::state_transition::apply_data_contract_create_transition_factory::ApplyDataContractCreateTransition; +use dpp::data_contract::state_transition::data_contract_create_transition::apply_data_contract_create_transition_factory::ApplyDataContractCreateTransition; use wasm_bindgen::prelude::*; use crate::{ diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index fb85588dadd..47c37767e1b 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -6,7 +6,7 @@ pub use validation::*; use dpp::identity::KeyID; use dpp::{ - data_contract::state_transition::DataContractCreateTransition, + data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, }, diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/apply.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/apply.rs index f1408360585..4a0d7df4f62 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/apply.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/apply.rs @@ -1,6 +1,6 @@ use std::ops::Deref; -use dpp::data_contract::state_transition::apply_data_contract_update_transition_factory::ApplyDataContractUpdateTransition; +use dpp::data_contract::state_transition::data_contract_update_transition::apply_data_contract_update_transition_factory::ApplyDataContractUpdateTransition; use wasm_bindgen::prelude::*; use crate::{ diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 6db939dbf2c..e4a8b6868a6 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -6,7 +6,7 @@ pub use validation::*; use dpp::identity::KeyID; use dpp::{ - data_contract::state_transition::DataContractUpdateTransition, + data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition, state_transition::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, }, diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index 83c5651e970..551b42f9a5c 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -1,7 +1,9 @@ use dpp::state_transition::StateTransitionFactory; use wasm_bindgen::prelude::wasm_bindgen; -use crate::state_repository::ExternalStateRepositoryLikeWrapper; +use crate::{bls_adapter::BlsAdapter, state_repository::ExternalStateRepositoryLikeWrapper}; #[wasm_bindgen(js_name = StateTransitionFactory)] -pub struct StateTransitionFactoryWasm(StateTransitionFactory); +pub struct StateTransitionFactoryWasm( + StateTransitionFactory, +); From c58c0059896e7be4c70ce6fdf049919bbff6139b Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Thu, 23 Feb 2023 22:38:13 +0500 Subject: [PATCH 12/35] chore: fixes --- .../validate_state_transition_by_type.rs | 117 ------------------ ..._documents_batch_transitions_basic_spec.rs | 11 +- 2 files changed, 1 insertion(+), 127 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs index ad20a977097..10c64288325 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_by_type.rs @@ -135,120 +135,3 @@ where Ok(result) } } - -#[cfg(test)] -mod tests { - use std::sync::Arc; - - use serde_json::Value as JsonValue; - - use crate::{ - data_contract::{ - state_transition::data_contract_create_transition::DataContractCreateTransition, - validation::data_contract_validator::DataContractValidator, DataContract, - DataContractFactory, - }, - state_transition::{ - state_transition_execution_context::StateTransitionExecutionContext, - try_get_transition_type, StateTransitionConvert, StateTransitionLike, - }, - tests::fixtures::get_data_contract_fixture, - validation::{MockAsyncDataValidatorWithContext, ValidationResult}, - version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}, - NativeBlsModule, - }; - - use crate::state_transition::validation::validate_state_transition_by_type::ValidatorByStateTransitionType; - - use super::StateTransitionByTypeValidator; - - struct TestData { - data_contract: DataContract, - state_transition: DataContractCreateTransition, - raw_state_transition: JsonValue, - bls: NativeBlsModule, - } - - fn setup_test() -> TestData { - let bls = NativeBlsModule::default(); - let data_contract = get_data_contract_fixture(None); - let private_key_bytes = - hex::decode("9b67f852093bc61cea0eeca38599dbfba0de28574d2ed9b99d10d33dc1bde7b2") - .unwrap(); - - let protocol_version_validator = ProtocolVersionValidator::new( - LATEST_VERSION, - LATEST_VERSION, - COMPATIBILITY_MAP.clone(), - ); - let data_contract_validator = - DataContractValidator::new(Arc::new(protocol_version_validator)); - let data_contract_factory = DataContractFactory::new(1, Arc::new(data_contract_validator)); - - let mut state_transition = data_contract_factory - .create_data_contract_create_transition(data_contract.clone()) - .unwrap(); - - state_transition - .sign_by_private_key( - &private_key_bytes, - crate::identity::KeyType::ECDSA_SECP256K1, - &bls, - ) - .expect("the state transition should be signed"); - - let raw_state_transition = state_transition.to_object(false).unwrap(); - - TestData { - data_contract, - state_transition, - raw_state_transition, - bls, - } - } - - #[tokio::test] - async fn test_correct_validator_is_selected() { - let TestData { - raw_state_transition, - .. - } = setup_test(); - - let mut data_contract_create_validator_mock = MockAsyncDataValidatorWithContext::new(); - let data_contract_update_validator_mock = MockAsyncDataValidatorWithContext::new(); - let identity_create_validator_mock = MockAsyncDataValidatorWithContext::new(); - let identity_update_validator_mock = MockAsyncDataValidatorWithContext::new(); - let identity_top_up_validator_mock = MockAsyncDataValidatorWithContext::new(); - let identity_credit_withdrawal_validator_mock = MockAsyncDataValidatorWithContext::new(); - let document_batch_validator_mock = MockAsyncDataValidatorWithContext::new(); - - data_contract_create_validator_mock - .expect_validate() - .times(1) - .returning(|_, _| Ok(ValidationResult::default())); - - let validator = StateTransitionByTypeValidator::new( - data_contract_create_validator_mock, - data_contract_update_validator_mock, - identity_create_validator_mock, - identity_update_validator_mock, - identity_top_up_validator_mock, - identity_credit_withdrawal_validator_mock, - document_batch_validator_mock, - ); - - let execution_context = StateTransitionExecutionContext::default(); - - let state_transition_type = - try_get_transition_type(&raw_state_transition).expect("to get state transition type"); - - validator - .validate( - &raw_state_transition, - state_transition_type, - &execution_context, - ) - .await - .expect("expected to call basic validator `validate` function"); - } -} diff --git a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs index 9587166d1d4..43654c93f86 100644 --- a/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs +++ b/packages/rs-dpp/src/tests/document/state_transitions/validation/validate_documents_batch_transitions_basic_spec.rs @@ -465,7 +465,6 @@ async fn property_should_should_exist_with_code(property_name: &str, error_code: .validate(&raw_state_transition, &Default::default()) .await .expect("validation result should be returned"); - let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(error_code, error.code()); @@ -528,7 +527,6 @@ async fn data_contract_id_should_be_byte_array() { .validate(&raw_state_transition, &Default::default()) .await .expect("validation result should be returned"); - let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1025, error.code()); @@ -624,7 +622,6 @@ async fn data_contract_should_exist_in_the_state() { .validate(&raw_state_transition, &Default::default()) .await .expect("validation result should be returned"); - let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1018, error.code()); @@ -650,7 +647,6 @@ async fn type_should_be_defined_in_data_contract() { .validate(&raw_state_transition, &Default::default()) .await .expect("validation result should be returned"); - let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1024, error.code()); @@ -676,7 +672,6 @@ async fn should_throw_invalid_document_transaction_action_error_if_action_is_not .validate(&raw_state_transition, &Default::default()) .await .expect("validation result should be returned"); - let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1022, error.code()); @@ -702,7 +697,6 @@ async fn id_should_be_valid_generated_id() { .validate(&raw_state_transition, &Default::default()) .await .expect("validation result should be returned"); - let schema_error = get_schema_error(&result, 0); let error = &result.errors()[0]; assert_eq!(1023, error.code()); @@ -964,7 +958,6 @@ async fn validation_should_be_successful() { .validate(&raw_state_transition, &Default::default()) .await .expect("validation result should be returned"); - let schema_error = get_schema_error(&result, 0); assert!(result.is_valid()); } @@ -991,11 +984,9 @@ async fn should_not_validate_document_transitions_on_dry_run() { ); let result = validator - .validate(&raw_state_transition, &Default::default()) + .validate(&raw_state_transition, &execution_context) .await .expect("validation result should be returned"); - let schema_error = get_schema_error(&result, 0); - dbg!(&result); assert!(result.is_valid()); } From 595fb9fa1629212d09cca5cc1654edfe8d679c2a Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Mon, 27 Feb 2023 23:00:36 +0500 Subject: [PATCH 13/35] chore: AbstractStateTransition --- ...ntity_create_transition_basic_validator.rs | 4 +- packages/wasm-dpp/src/errors/from.rs | 9 + .../wasm-dpp/src/identity/identity_factory.rs | 2 +- packages/wasm-dpp/src/state_transition/mod.rs | 319 +++++++++++++++++- .../state_transition_factory.rs | 186 +++++++++- 5 files changed, 513 insertions(+), 7 deletions(-) diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs index e505dfe1f2a..1e4ce9ee2d9 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator.rs @@ -29,7 +29,7 @@ pub struct IdentityCreateTransitionBasicValidator, public_keys_in_identity_transition_validator: Arc, asset_lock_proof_validator: Arc>, - public_keys_signatures_validator: SV, + public_keys_signatures_validator: Arc, bls_adapter: BLS, } @@ -47,7 +47,7 @@ impl< public_keys_in_identity_transition_validator: Arc, asset_lock_proof_validator: Arc>, bls_adapter: BLS, - public_keys_signatures_validator: SV, + public_keys_signatures_validator: Arc, ) -> Result { let json_schema_validator = JsonSchemaValidator::new(INDENTITY_CREATE_TRANSITION_SCHEMA.clone())?; diff --git a/packages/wasm-dpp/src/errors/from.rs b/packages/wasm-dpp/src/errors/from.rs index 67265b4bdfc..2ca19280d90 100644 --- a/packages/wasm-dpp/src/errors/from.rs +++ b/packages/wasm-dpp/src/errors/from.rs @@ -1,3 +1,4 @@ +use dpp::DashPlatformProtocolInitError; use wasm_bindgen::JsValue; use dpp::errors::ProtocolError; @@ -27,3 +28,11 @@ pub fn from_dpp_err(pe: ProtocolError) -> JsValue { _ => JsValue::from_str(&format!("Error conversion not implemented: {pe:#}",)), } } + +pub fn from_dpp_init_error(e: DashPlatformProtocolInitError) -> JsValue { + match e { + DashPlatformProtocolInitError::SchemaDeserializationError(e) => e.to_string().into(), + DashPlatformProtocolInitError::ValidationError(e) => e.to_string().into(), + DashPlatformProtocolInitError::InvalidSchemaError(e) => e.to_string().into(), + } +} diff --git a/packages/wasm-dpp/src/identity/identity_factory.rs b/packages/wasm-dpp/src/identity/identity_factory.rs index 7b467552f05..6c77e17b630 100644 --- a/packages/wasm-dpp/src/identity/identity_factory.rs +++ b/packages/wasm-dpp/src/identity/identity_factory.rs @@ -72,7 +72,7 @@ impl IdentityFactoryWasm { }; let identity_json = utils::stringify(&identity_object)?; - let raw_identity: Value = + let raw_identity: value = serde_json::from_str(&identity_json).map_err(|e| e.to_string())?; let result = self diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 24fbe6bf650..c1ea35e68e6 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -1,6 +1,16 @@ -use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use std::{convert::TryFrom, ops::Deref}; + +use dpp::{ + identity::KeyType, + state_transition::{ + state_transition_execution_context::StateTransitionExecutionContext, StateTransition, + StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, + }, +}; use wasm_bindgen::prelude::*; +use crate::{buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper}; + pub mod state_transition_factory; #[wasm_bindgen(js_name=StateTransitionExecutionContext)] @@ -59,3 +69,310 @@ impl StateTransitionExecutionContextWasm { self.0.disable_dry_run(); } } + +#[wasm_bindgen(js_name = AbstractStateTransition)] +pub struct StateTransitionWasm(StateTransition); + +#[wasm_bindgen(js_class = AbstractStateTransition)] +impl StateTransitionWasm { + #[wasm_bindgen(js_name = getProtocolVersion)] + pub fn get_protocol_version(&self) -> u32 { + match &self.0 { + StateTransition::DataContractCreate(st) => st.get_protocol_version(), + StateTransition::DataContractUpdate(st) => st.get_protocol_version(), + StateTransition::DocumentsBatch(st) => st.get_protocol_version(), + StateTransition::IdentityCreate(st) => st.get_protocol_version(), + StateTransition::IdentityTopUp(st) => st.get_protocol_version(), + StateTransition::IdentityCreditWithdrawal(st) => st.get_protocol_version(), + StateTransition::IdentityUpdate(st) => st.get_protocol_version(), + } + } + + #[wasm_bindgen(js_name = getType)] + pub fn get_type(&self) -> u8 { + match &self.0 { + StateTransition::DataContractCreate(st) => st.get_type().into(), + StateTransition::DataContractUpdate(st) => st.get_type().into(), + StateTransition::DocumentsBatch(st) => st.get_type().into(), + StateTransition::IdentityCreate(st) => st.get_type().into(), + StateTransition::IdentityTopUp(st) => st.get_type().into(), + StateTransition::IdentityCreditWithdrawal(st) => st.get_type().into(), + StateTransition::IdentityUpdate(st) => st.get_type().into(), + } + } + + #[wasm_bindgen(js_name = getSignature)] + pub fn get_signature(&self) -> Buffer { + match &self.0 { + StateTransition::DataContractCreate(st) => Buffer::from_bytes(st.get_signature()), + StateTransition::DataContractUpdate(st) => Buffer::from_bytes(st.get_signature()), + StateTransition::DocumentsBatch(st) => Buffer::from_bytes(st.get_signature()), + StateTransition::IdentityCreate(st) => Buffer::from_bytes(st.get_signature()), + StateTransition::IdentityTopUp(st) => Buffer::from_bytes(st.get_signature()), + StateTransition::IdentityCreditWithdrawal(st) => Buffer::from_bytes(st.get_signature()), + StateTransition::IdentityUpdate(st) => Buffer::from_bytes(st.get_signature()), + } + } + + #[wasm_bindgen(js_name = setSignature)] + pub fn set_signature(&self, signature: Vec) { + match &self.0 { + StateTransition::DataContractCreate(st) => st.set_signature(signature), + StateTransition::DataContractUpdate(st) => st.set_signature(signature), + StateTransition::DocumentsBatch(st) => st.set_signature(signature), + StateTransition::IdentityCreate(st) => st.set_signature(signature), + StateTransition::IdentityTopUp(st) => st.set_signature(signature), + StateTransition::IdentityCreditWithdrawal(st) => st.set_signature(signature), + StateTransition::IdentityUpdate(st) => st.set_signature(signature), + } + } + + #[wasm_bindgen(js_name = toObject)] + pub fn to_object(&self, options: JsValue) -> Result { + // TODO: construct options + match &self.0 { + StateTransition::DataContractCreate(st) => st.to_object(false).map_err(from_dpp_err), + StateTransition::DataContractUpdate(st) => st.to_object(false).map_err(from_dpp_err), + StateTransition::DocumentsBatch(st) => st.to_object(false).map_err(from_dpp_err), + StateTransition::IdentityCreate(st) => st.to_object(false).map_err(from_dpp_err), + StateTransition::IdentityTopUp(st) => st.to_object(false).map_err(from_dpp_err), + StateTransition::IdentityCreditWithdrawal(st) => { + st.to_object(false).map_err(from_dpp_err) + } + StateTransition::IdentityUpdate(st) => st.to_object(false).map_err(from_dpp_err), + } + } + + #[wasm_bindgen(js_name = getOwnerId)] + pub fn get_owner_id(&self) -> IdentifierWrapper { + match &self.0 { + StateTransition::DataContractCreate(st) => (*st.get_owner_id()).into(), + StateTransition::DataContractUpdate(st) => (*st.get_owner_id()).into(), + StateTransition::DocumentsBatch(st) => (*st.get_owner_id()).into(), + StateTransition::IdentityCreate(st) => (*st.get_owner_id()).into(), + StateTransition::IdentityTopUp(st) => (*st.get_owner_id()).into(), + StateTransition::IdentityCreditWithdrawal(st) => (*st.get_owner_id()).into(), + StateTransition::IdentityUpdate(st) => (*st.get_owner_id()).into(), + } + } + + #[wasm_bindgen(js_name = toJSON)] + pub fn to_json(&self, options: JsValue) -> Result { + // TODO: construct options + match &self.0 { + StateTransition::DataContractCreate(st) => st.to_json(false).map_err(from_dpp_err), + StateTransition::DataContractUpdate(st) => st.to_json(false).map_err(from_dpp_err), + StateTransition::DocumentsBatch(st) => st.to_json(false).map_err(from_dpp_err), + StateTransition::IdentityCreate(st) => st.to_json(false).map_err(from_dpp_err), + StateTransition::IdentityTopUp(st) => st.to_json(false).map_err(from_dpp_err), + StateTransition::IdentityCreditWithdrawal(st) => { + st.to_json(false).map_err(from_dpp_err) + } + StateTransition::IdentityUpdate(st) => st.to_json(false).map_err(from_dpp_err), + } + } + + #[wasm_bindgen(js_name = toBuffer)] + pub fn to_buffer(&self, options: JsValue) -> Result { + // TODO: construct options + match &self.0 { + StateTransition::DataContractCreate(st) => st.to_buffer(false).map_err(from_dpp_err), + StateTransition::DataContractUpdate(st) => st.to_buffer(false).map_err(from_dpp_err), + StateTransition::DocumentsBatch(st) => st.to_buffer(false).map_err(from_dpp_err), + StateTransition::IdentityCreate(st) => st.to_buffer(false).map_err(from_dpp_err), + StateTransition::IdentityTopUp(st) => st.to_buffer(false).map_err(from_dpp_err), + StateTransition::IdentityCreditWithdrawal(st) => { + st.to_buffer(false).map_err(from_dpp_err) + } + StateTransition::IdentityUpdate(st) => st.to_buffer(false).map_err(from_dpp_err), + } + } + + #[wasm_bindgen(js_name = hash)] + pub fn hash(&self, options: JsValue) -> Result { + // TODO: construct options + match &self.0 { + StateTransition::DataContractCreate(st) => st.hash(false).map_err(from_dpp_err), + StateTransition::DataContractUpdate(st) => st.hash(false).map_err(from_dpp_err), + StateTransition::DocumentsBatch(st) => st.hash(false).map_err(from_dpp_err), + StateTransition::IdentityCreate(st) => st.hash(false).map_err(from_dpp_err), + StateTransition::IdentityTopUp(st) => st.hash(false).map_err(from_dpp_err), + StateTransition::IdentityCreditWithdrawal(st) => st.hash(false).map_err(from_dpp_err), + StateTransition::IdentityUpdate(st) => st.hash(false).map_err(from_dpp_err), + } + } + + #[wasm_bindgen(js_name = signByPrivateKey)] + pub fn sign_by_private_key(&self, private_key: Vec, key_type: u8) -> Result<(), JsValue> { + match &self.0 { + StateTransition::DataContractCreate(st) => st + .sign_by_private_key( + &private_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("pass correct BLS"), + ) + .map_err(from_dpp_err), + StateTransition::DataContractUpdate(st) => st + .sign_by_private_key( + &private_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("pass correct BLS"), + ) + .map_err(from_dpp_err), + StateTransition::DocumentsBatch(st) => st + .sign_by_private_key( + &private_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("pass correct BLS"), + ) + .map_err(from_dpp_err), + StateTransition::IdentityCreate(st) => st + .sign_by_private_key( + &private_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("pass correct BLS"), + ) + .map_err(from_dpp_err), + StateTransition::IdentityTopUp(st) => st + .sign_by_private_key( + &private_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("pass correct BLS"), + ) + .map_err(from_dpp_err), + StateTransition::IdentityCreditWithdrawal(st) => st + .sign_by_private_key( + &private_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("pass correct BLS"), + ) + .map_err(from_dpp_err), + StateTransition::IdentityUpdate(st) => st + .sign_by_private_key( + &private_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("pass correct BLS"), + ) + .map_err(from_dpp_err), + } + } + + #[wasm_bindgen(js_name = verifyByPublicKey)] + pub fn verify_by_public_key(&self, public_key: Vec, key_type: u8) -> Result { + match &self.0 { + StateTransition::DataContractCreate(st) => st.verify_by_public_key( + &public_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("set up BLS"), + ), + StateTransition::DataContractUpdate(st) => st.verify_by_public_key( + &public_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("set up BLS"), + ), + StateTransition::DocumentsBatch(st) => st.verify_by_public_key( + &public_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("set up BLS"), + ), + StateTransition::IdentityCreate(st) => st.verify_by_public_key( + &public_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("set up BLS"), + ), + StateTransition::IdentityTopUp(st) => st.verify_by_public_key( + &public_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("set up BLS"), + ), + StateTransition::IdentityCreditWithdrawal(st) => st.verify_by_public_key( + &public_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("set up BLS"), + ), + StateTransition::IdentityUpdate(st) => st.verify_by_public_key( + &public_key, + KeyType::try_from(key_type).map_err(from_dpp_err)?, + todo!("set up BLS"), + ), + } + } + + #[wasm_bindgen(js_name = getModifiedDataIds)] + pub fn get_modified_data_ids(&self) -> Vec { + // TODO: implement! + vec![]; + } + + #[wasm_bindgen(js_name = isDocumentStateTransition)] + pub fn is_document_state_transition(&self) -> bool { + match &self.0 { + StateTransition::DataContractCreate(st) => st.is_document_state_transition(), + StateTransition::DataContractUpdate(st) => st.is_document_state_transition(), + StateTransition::DocumentsBatch(st) => st.is_document_state_transition(), + StateTransition::IdentityCreate(st) => st.is_document_state_transition(), + StateTransition::IdentityTopUp(st) => st.is_document_state_transition(), + StateTransition::IdentityCreditWithdrawal(st) => st.is_document_state_transition(), + StateTransition::IdentityUpdate(st) => st.is_document_state_transition(), + } + } + + #[wasm_bindgen(js_name = isDataContractStateTransition)] + pub fn is_data_contract_state_transition(&self) -> bool { + match &self.0 { + StateTransition::DataContractCreate(st) => st.is_data_contract_state_transition(), + StateTransition::DataContractUpdate(st) => st.is_data_contract_state_transition(), + StateTransition::DocumentsBatch(st) => st.is_data_contract_state_transition(), + StateTransition::IdentityCreate(st) => st.is_data_contract_state_transition(), + StateTransition::IdentityTopUp(st) => st.is_data_contract_state_transition(), + StateTransition::IdentityCreditWithdrawal(st) => st.is_data_contract_state_transition(), + StateTransition::IdentityUpdate(st) => st.is_data_contract_state_transition(), + } + } + + #[wasm_bindgen(js_name = isIdentityStateTransition)] + pub fn is_identity_state_transition(&self) -> bool { + match &self.0 { + StateTransition::DataContractCreate(st) => st.is_identity_state_transition(), + StateTransition::DataContractUpdate(st) => st.is_identity_state_transition(), + StateTransition::DocumentsBatch(st) => st.is_identity_state_transition(), + StateTransition::IdentityCreate(st) => st.is_identity_state_transition(), + StateTransition::IdentityTopUp(st) => st.is_identity_state_transition(), + StateTransition::IdentityCreditWithdrawal(st) => st.is_identity_state_transition(), + StateTransition::IdentityUpdate(st) => st.is_identity_state_transition(), + } + } + + #[wasm_bindgen(js_name = setExecutionContext)] + pub fn set_execution_context(&self, execution_context: StateTransitionExecutionContextWasm) { + match &self.0 { + StateTransition::DataContractCreate(st) => st.set_execution_context(execution_context.into()), + StateTransition::DataContractUpdate(st) => st.set_execution_context(execution_context.into()), + StateTransition::DocumentsBatch(st) => st.set_execution_context(execution_context.into()), + StateTransition::IdentityCreate(st) => st.set_execution_context(execution_context.into()), + StateTransition::IdentityTopUp(st) => st.set_execution_context(execution_context.into()), + StateTransition::IdentityCreditWithdrawal(st) => st.set_execution_context(execution_context.into()), + StateTransition::IdentityUpdate(st) => st.set_execution_context(execution_context.into()), + } + } + + #[wasm_bindgen(js_name = getExecutionContext)] + pub fn get_execution_context(&self) -> StateTransitionExecutionContextWasm { + match &self.0 { + StateTransition::DataContractCreate(st) => st.get_execution_context().into(), + StateTransition::DataContractUpdate(st) => st.get_execution_context().into(), + StateTransition::DocumentsBatch(st) => st.get_execution_context().into(), + StateTransition::IdentityCreate(st) => st.get_execution_context().into(), + StateTransition::IdentityTopUp(st) => st.get_execution_context().into(), + StateTransition::IdentityCreditWithdrawal(st) => st.get_execution_context().into(), + StateTransition::IdentityUpdate(st) => st.get_execution_context().into(), + } + } + +} + +impl From for StateTransitionWasm { + fn from(value: StateTransition) -> Self { + value.into() + } +} diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index 551b42f9a5c..ec85a110b0b 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -1,9 +1,189 @@ -use dpp::state_transition::StateTransitionFactory; -use wasm_bindgen::prelude::wasm_bindgen; +use std::{ops::Deref, sync::Arc}; -use crate::{bls_adapter::BlsAdapter, state_repository::ExternalStateRepositoryLikeWrapper}; +use serde_json::Value as JsonValue; + +use dpp::{ + state_transition::{ + validation::{ + validate_state_transition_basic::StateTransitionBasicValidator, + validate_state_transition_by_type::StateTransitionByTypeValidator, + }, + StateTransitionFactory, StateTransitionFactoryOptions, StateTransition, errors::StateTransitionError, + }, + version::ProtocolVersionValidator, data_contract::state_transition::{data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, self}, identity::{state_transition::{identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, validate_public_key_signatures::{PublicKeysSignaturesValidator, TPublicKeysSignaturesValidator}, asset_lock_proof::{AssetLockProofValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator, AssetLockTransactionValidator}, identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic}, validation::PublicKeysValidator}, document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, +}; +use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; + +use crate::{ + bls_adapter::{BlsAdapter, JsBlsAdapter}, + errors::{from_dpp_err, from_dpp_init_error}, + identity_facade::FromObjectOptions, + state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, + utils, with_js_error, StateTransitionWasm, +}; #[wasm_bindgen(js_name = StateTransitionFactory)] pub struct StateTransitionFactoryWasm( StateTransitionFactory, ); + +impl From> + for StateTransitionFactoryWasm +{ + fn from( + factory: StateTransitionFactory, + ) -> Self { + Self(factory) + } +} + +#[wasm_bindgen(js_class = StateTransitionFactory)] +impl StateTransitionFactoryWasm { + #[wasm_bindgen(constructor)] + pub fn new( + state_repository: ExternalStateRepositoryLike, + bls_adapter: JsBlsAdapter, + ) -> Result { + let state_repository_wrapper = ExternalStateRepositoryLikeWrapper::new(state_repository); + let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); + + let pk_validator = + Arc::new(PublicKeysValidator::new(bls_adapter.into()).map_err(from_dpp_init_error)?); + let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(bls_adapter.into())); + + let asset_lock_tx_validator = Arc::new(AssetLockTransactionValidator::new( + state_repository_wrapper.into(), + )); + + let asset_lock_validator = Arc::new(AssetLockProofValidator::new( + InstantAssetLockProofStructureValidator::new( + state_repository_wrapper.into(), + asset_lock_tx_validator, + ) + .map_err(from_dpp_init_error)?, + ChainAssetLockProofStructureValidator::new( + state_repository_wrapper.into(), + asset_lock_tx_validator, + ) + .map_err(from_dpp_init_error)?, + )); + + let factory = StateTransitionFactory::new( + state_repository_wrapper.into(), + StateTransitionBasicValidator::new( + state_repository_wrapper.into(), + StateTransitionByTypeValidator::new( + DataContractCreateTransitionBasicValidator::new(protocol_version_validator) + .map_err(from_dpp_err)?, + DataContractUpdateTransitionBasicValidator::new( + state_repository_wrapper.into(), + protocol_version_validator, + ) + .map_err(from_dpp_init_error)?, + IdentityCreateTransitionBasicValidator::new( + protocol_version_validator.deref().clone(), + pk_validator, + pk_validator, + asset_lock_validator, + bls_adapter.into(), + pk_sig_validator, + ) + .map_err(from_dpp_init_error)?, + ValidateIdentityUpdateTransitionBasic::new( + protocol_version_validator, + pk_validator, + pk_sig_validator, + ) + .map_err(from_dpp_err)?, + IdentityTopUpTransitionBasicValidator::new( + protocol_version_validator, + asset_lock_validator, + ) + .map_err(from_dpp_init_error)?, + IdentityCreditWithdrawalTransitionBasicValidator::new( + protocol_version_validator, + ) + .map_err(from_dpp_init_error)?, + DocumentBatchTransitionBasicValidator::new( + state_repository_wrapper.into(), + protocol_version_validator, + ), + ), + ), + ); + + Ok(factory.into()) + } + + #[wasm_bindgen(js_name=createFromObject)] + pub async fn create_from_object( + &self, + state_transition_object: JsValue, + options: JsValue, + ) -> Result { + let options: FromObjectOptions = if options.is_object() { + with_js_error!(serde_wasm_bindgen::from_value(options))? + } else { + Default::default() + }; + + let state_transition_json_string = utils::stringify(&state_transition_object)?; + let raw_state_transition: JsonValue = + serde_json::from_str(&state_transition_json_string).map_err(|e| e.to_string())?; + + let result = self + .0 + .create_from_object( + raw_state_transition, + Some(StateTransitionFactoryOptions { + skip_validation: options.skip_validation.unwrap_or(false), + }), + ) + .await; + + match result { + Ok(state_transition) => Ok(StateTransitionWasm::from(state_transition)), + Err(dpp::ProtocolError::StateTransitionError(e)) => match e { + StateTransitionError::InvalidStateTransitionError { + errors, + raw_state_transition, + } => Err(InvalidStateTransitionError::new(errors, state_transition_object).into()), + }, + Err(other) => Err(from_dpp_err(other)), + } + } + + #[wasm_bindgen(js_name=createFromBuffer)] + pub async fn create_from_buffer( + &self, + buffer: Vec, + options: JsValue, + ) -> Result { + let options: FromObjectOptions = if options.is_object() { + with_js_error!(serde_wasm_bindgen::from_value(options))? + } else { + Default::default() + }; + + let result = self + .0 + .create_from_buffer( + &buffer, + Some(StateTransitionFactoryOptions { + skip_validation: options.skip_validation.unwrap_or(false), + }), + ) + .await; + + match result { + Ok(state_transition) => Ok(StateTransitionWasm::from(state_transition)), + Err(dpp::ProtocolError::StateTransitionError(e)) => match e { + StateTransitionError::InvalidStateTransitionError { + errors, + raw_state_transition, + } => Err(InvalidStateTransitionError::new(errors, state_transition_object).into()), + }, + Err(other) => Err(from_dpp_err(other)), + } + } +} From dcc1b97a2a56c3b8aff69fa88a38a8c6a27e6e8d Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Mon, 27 Feb 2023 23:35:32 +0500 Subject: [PATCH 14/35] chore: use macro --- packages/wasm-dpp/src/state_transition/mod.rs | 246 +++--------------- 1 file changed, 32 insertions(+), 214 deletions(-) diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index c1ea35e68e6..322c53e6da7 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -70,6 +70,20 @@ impl StateTransitionExecutionContextWasm { } } +macro_rules! either_st { + ($value:expr, $pattern:pat => $result:expr) => { + match $value { + StateTransition::DataContractCreate($pattern) => $result, + StateTransition::DataContractUpdate($pattern) => $result, + StateTransition::DocumentsBatch($pattern) => $result, + StateTransition::IdentityCreate($pattern) => $result, + StateTransition::IdentityTopUp($pattern) => $result, + StateTransition::IdentityCreditWithdrawal($pattern) => $result, + StateTransition::IdentityUpdate($pattern) => $result, + } + }; +} + #[wasm_bindgen(js_name = AbstractStateTransition)] pub struct StateTransitionWasm(StateTransition); @@ -77,225 +91,70 @@ pub struct StateTransitionWasm(StateTransition); impl StateTransitionWasm { #[wasm_bindgen(js_name = getProtocolVersion)] pub fn get_protocol_version(&self) -> u32 { - match &self.0 { - StateTransition::DataContractCreate(st) => st.get_protocol_version(), - StateTransition::DataContractUpdate(st) => st.get_protocol_version(), - StateTransition::DocumentsBatch(st) => st.get_protocol_version(), - StateTransition::IdentityCreate(st) => st.get_protocol_version(), - StateTransition::IdentityTopUp(st) => st.get_protocol_version(), - StateTransition::IdentityCreditWithdrawal(st) => st.get_protocol_version(), - StateTransition::IdentityUpdate(st) => st.get_protocol_version(), - } + either_st!(&self.0, st => st.get_protocol_version()) } #[wasm_bindgen(js_name = getType)] pub fn get_type(&self) -> u8 { - match &self.0 { - StateTransition::DataContractCreate(st) => st.get_type().into(), - StateTransition::DataContractUpdate(st) => st.get_type().into(), - StateTransition::DocumentsBatch(st) => st.get_type().into(), - StateTransition::IdentityCreate(st) => st.get_type().into(), - StateTransition::IdentityTopUp(st) => st.get_type().into(), - StateTransition::IdentityCreditWithdrawal(st) => st.get_type().into(), - StateTransition::IdentityUpdate(st) => st.get_type().into(), - } + either_st!(&self.0, st => st.get_type().into()) } #[wasm_bindgen(js_name = getSignature)] pub fn get_signature(&self) -> Buffer { - match &self.0 { - StateTransition::DataContractCreate(st) => Buffer::from_bytes(st.get_signature()), - StateTransition::DataContractUpdate(st) => Buffer::from_bytes(st.get_signature()), - StateTransition::DocumentsBatch(st) => Buffer::from_bytes(st.get_signature()), - StateTransition::IdentityCreate(st) => Buffer::from_bytes(st.get_signature()), - StateTransition::IdentityTopUp(st) => Buffer::from_bytes(st.get_signature()), - StateTransition::IdentityCreditWithdrawal(st) => Buffer::from_bytes(st.get_signature()), - StateTransition::IdentityUpdate(st) => Buffer::from_bytes(st.get_signature()), - } + either_st!(&self.0, st => Buffer::from_bytes(st.get_signature())) } #[wasm_bindgen(js_name = setSignature)] pub fn set_signature(&self, signature: Vec) { - match &self.0 { - StateTransition::DataContractCreate(st) => st.set_signature(signature), - StateTransition::DataContractUpdate(st) => st.set_signature(signature), - StateTransition::DocumentsBatch(st) => st.set_signature(signature), - StateTransition::IdentityCreate(st) => st.set_signature(signature), - StateTransition::IdentityTopUp(st) => st.set_signature(signature), - StateTransition::IdentityCreditWithdrawal(st) => st.set_signature(signature), - StateTransition::IdentityUpdate(st) => st.set_signature(signature), - } + either_st!(&self.0, st => st.set_signature(signature)) } #[wasm_bindgen(js_name = toObject)] pub fn to_object(&self, options: JsValue) -> Result { // TODO: construct options - match &self.0 { - StateTransition::DataContractCreate(st) => st.to_object(false).map_err(from_dpp_err), - StateTransition::DataContractUpdate(st) => st.to_object(false).map_err(from_dpp_err), - StateTransition::DocumentsBatch(st) => st.to_object(false).map_err(from_dpp_err), - StateTransition::IdentityCreate(st) => st.to_object(false).map_err(from_dpp_err), - StateTransition::IdentityTopUp(st) => st.to_object(false).map_err(from_dpp_err), - StateTransition::IdentityCreditWithdrawal(st) => { - st.to_object(false).map_err(from_dpp_err) - } - StateTransition::IdentityUpdate(st) => st.to_object(false).map_err(from_dpp_err), - } + either_st!(&self.0, st => st.to_object(false).map_err(from_dpp_err)) } #[wasm_bindgen(js_name = getOwnerId)] pub fn get_owner_id(&self) -> IdentifierWrapper { - match &self.0 { - StateTransition::DataContractCreate(st) => (*st.get_owner_id()).into(), - StateTransition::DataContractUpdate(st) => (*st.get_owner_id()).into(), - StateTransition::DocumentsBatch(st) => (*st.get_owner_id()).into(), - StateTransition::IdentityCreate(st) => (*st.get_owner_id()).into(), - StateTransition::IdentityTopUp(st) => (*st.get_owner_id()).into(), - StateTransition::IdentityCreditWithdrawal(st) => (*st.get_owner_id()).into(), - StateTransition::IdentityUpdate(st) => (*st.get_owner_id()).into(), - } + either_st!(&self.0, st => (*st.get_owner_id()).into()) } #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self, options: JsValue) -> Result { // TODO: construct options - match &self.0 { - StateTransition::DataContractCreate(st) => st.to_json(false).map_err(from_dpp_err), - StateTransition::DataContractUpdate(st) => st.to_json(false).map_err(from_dpp_err), - StateTransition::DocumentsBatch(st) => st.to_json(false).map_err(from_dpp_err), - StateTransition::IdentityCreate(st) => st.to_json(false).map_err(from_dpp_err), - StateTransition::IdentityTopUp(st) => st.to_json(false).map_err(from_dpp_err), - StateTransition::IdentityCreditWithdrawal(st) => { - st.to_json(false).map_err(from_dpp_err) - } - StateTransition::IdentityUpdate(st) => st.to_json(false).map_err(from_dpp_err), - } + either_st!(&self.0, st => st.to_json(false).map_err(from_dpp_err)) } #[wasm_bindgen(js_name = toBuffer)] pub fn to_buffer(&self, options: JsValue) -> Result { // TODO: construct options - match &self.0 { - StateTransition::DataContractCreate(st) => st.to_buffer(false).map_err(from_dpp_err), - StateTransition::DataContractUpdate(st) => st.to_buffer(false).map_err(from_dpp_err), - StateTransition::DocumentsBatch(st) => st.to_buffer(false).map_err(from_dpp_err), - StateTransition::IdentityCreate(st) => st.to_buffer(false).map_err(from_dpp_err), - StateTransition::IdentityTopUp(st) => st.to_buffer(false).map_err(from_dpp_err), - StateTransition::IdentityCreditWithdrawal(st) => { - st.to_buffer(false).map_err(from_dpp_err) - } - StateTransition::IdentityUpdate(st) => st.to_buffer(false).map_err(from_dpp_err), - } + either_st!(&self.0, st => st.to_buffer(false).map_err(from_dpp_err)) } #[wasm_bindgen(js_name = hash)] pub fn hash(&self, options: JsValue) -> Result { // TODO: construct options - match &self.0 { - StateTransition::DataContractCreate(st) => st.hash(false).map_err(from_dpp_err), - StateTransition::DataContractUpdate(st) => st.hash(false).map_err(from_dpp_err), - StateTransition::DocumentsBatch(st) => st.hash(false).map_err(from_dpp_err), - StateTransition::IdentityCreate(st) => st.hash(false).map_err(from_dpp_err), - StateTransition::IdentityTopUp(st) => st.hash(false).map_err(from_dpp_err), - StateTransition::IdentityCreditWithdrawal(st) => st.hash(false).map_err(from_dpp_err), - StateTransition::IdentityUpdate(st) => st.hash(false).map_err(from_dpp_err), - } + either_st!(&self.0, st => st.hash(false).map_err(from_dpp_err)) } #[wasm_bindgen(js_name = signByPrivateKey)] pub fn sign_by_private_key(&self, private_key: Vec, key_type: u8) -> Result<(), JsValue> { - match &self.0 { - StateTransition::DataContractCreate(st) => st - .sign_by_private_key( - &private_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("pass correct BLS"), - ) - .map_err(from_dpp_err), - StateTransition::DataContractUpdate(st) => st - .sign_by_private_key( - &private_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("pass correct BLS"), - ) - .map_err(from_dpp_err), - StateTransition::DocumentsBatch(st) => st - .sign_by_private_key( - &private_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("pass correct BLS"), - ) - .map_err(from_dpp_err), - StateTransition::IdentityCreate(st) => st - .sign_by_private_key( - &private_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("pass correct BLS"), - ) - .map_err(from_dpp_err), - StateTransition::IdentityTopUp(st) => st + either_st!(&self.0, st => st .sign_by_private_key( &private_key, KeyType::try_from(key_type).map_err(from_dpp_err)?, todo!("pass correct BLS"), ) - .map_err(from_dpp_err), - StateTransition::IdentityCreditWithdrawal(st) => st - .sign_by_private_key( - &private_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("pass correct BLS"), - ) - .map_err(from_dpp_err), - StateTransition::IdentityUpdate(st) => st - .sign_by_private_key( - &private_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("pass correct BLS"), - ) - .map_err(from_dpp_err), - } + .map_err(from_dpp_err)) } #[wasm_bindgen(js_name = verifyByPublicKey)] pub fn verify_by_public_key(&self, public_key: Vec, key_type: u8) -> Result { - match &self.0 { - StateTransition::DataContractCreate(st) => st.verify_by_public_key( - &public_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("set up BLS"), - ), - StateTransition::DataContractUpdate(st) => st.verify_by_public_key( - &public_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("set up BLS"), - ), - StateTransition::DocumentsBatch(st) => st.verify_by_public_key( + either_st!(&self.0, st => st.verify_by_public_key( &public_key, KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("set up BLS"), - ), - StateTransition::IdentityCreate(st) => st.verify_by_public_key( - &public_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("set up BLS"), - ), - StateTransition::IdentityTopUp(st) => st.verify_by_public_key( - &public_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("set up BLS"), - ), - StateTransition::IdentityCreditWithdrawal(st) => st.verify_by_public_key( - &public_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("set up BLS"), - ), - StateTransition::IdentityUpdate(st) => st.verify_by_public_key( - &public_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("set up BLS"), - ), - } + todo!("set up BLS"))) } #[wasm_bindgen(js_name = getModifiedDataIds)] @@ -306,69 +165,28 @@ impl StateTransitionWasm { #[wasm_bindgen(js_name = isDocumentStateTransition)] pub fn is_document_state_transition(&self) -> bool { - match &self.0 { - StateTransition::DataContractCreate(st) => st.is_document_state_transition(), - StateTransition::DataContractUpdate(st) => st.is_document_state_transition(), - StateTransition::DocumentsBatch(st) => st.is_document_state_transition(), - StateTransition::IdentityCreate(st) => st.is_document_state_transition(), - StateTransition::IdentityTopUp(st) => st.is_document_state_transition(), - StateTransition::IdentityCreditWithdrawal(st) => st.is_document_state_transition(), - StateTransition::IdentityUpdate(st) => st.is_document_state_transition(), - } + either_st!(&self.0, st => st.is_document_state_transition()) } #[wasm_bindgen(js_name = isDataContractStateTransition)] pub fn is_data_contract_state_transition(&self) -> bool { - match &self.0 { - StateTransition::DataContractCreate(st) => st.is_data_contract_state_transition(), - StateTransition::DataContractUpdate(st) => st.is_data_contract_state_transition(), - StateTransition::DocumentsBatch(st) => st.is_data_contract_state_transition(), - StateTransition::IdentityCreate(st) => st.is_data_contract_state_transition(), - StateTransition::IdentityTopUp(st) => st.is_data_contract_state_transition(), - StateTransition::IdentityCreditWithdrawal(st) => st.is_data_contract_state_transition(), - StateTransition::IdentityUpdate(st) => st.is_data_contract_state_transition(), - } + either_st!(&self.0, st => st.is_data_contract_state_transition()) } #[wasm_bindgen(js_name = isIdentityStateTransition)] pub fn is_identity_state_transition(&self) -> bool { - match &self.0 { - StateTransition::DataContractCreate(st) => st.is_identity_state_transition(), - StateTransition::DataContractUpdate(st) => st.is_identity_state_transition(), - StateTransition::DocumentsBatch(st) => st.is_identity_state_transition(), - StateTransition::IdentityCreate(st) => st.is_identity_state_transition(), - StateTransition::IdentityTopUp(st) => st.is_identity_state_transition(), - StateTransition::IdentityCreditWithdrawal(st) => st.is_identity_state_transition(), - StateTransition::IdentityUpdate(st) => st.is_identity_state_transition(), - } + either_st!(&self.0, st => st.is_identity_state_transition()) } #[wasm_bindgen(js_name = setExecutionContext)] pub fn set_execution_context(&self, execution_context: StateTransitionExecutionContextWasm) { - match &self.0 { - StateTransition::DataContractCreate(st) => st.set_execution_context(execution_context.into()), - StateTransition::DataContractUpdate(st) => st.set_execution_context(execution_context.into()), - StateTransition::DocumentsBatch(st) => st.set_execution_context(execution_context.into()), - StateTransition::IdentityCreate(st) => st.set_execution_context(execution_context.into()), - StateTransition::IdentityTopUp(st) => st.set_execution_context(execution_context.into()), - StateTransition::IdentityCreditWithdrawal(st) => st.set_execution_context(execution_context.into()), - StateTransition::IdentityUpdate(st) => st.set_execution_context(execution_context.into()), - } + either_st!(&self.0, st => st.set_execution_context(execution_context.into())) } #[wasm_bindgen(js_name = getExecutionContext)] pub fn get_execution_context(&self) -> StateTransitionExecutionContextWasm { - match &self.0 { - StateTransition::DataContractCreate(st) => st.get_execution_context().into(), - StateTransition::DataContractUpdate(st) => st.get_execution_context().into(), - StateTransition::DocumentsBatch(st) => st.get_execution_context().into(), - StateTransition::IdentityCreate(st) => st.get_execution_context().into(), - StateTransition::IdentityTopUp(st) => st.get_execution_context().into(), - StateTransition::IdentityCreditWithdrawal(st) => st.get_execution_context().into(), - StateTransition::IdentityUpdate(st) => st.get_execution_context().into(), - } + either_st!(&self.0, st => st.get_execution_context().into()) } - } impl From for StateTransitionWasm { From 46eec30698e1d02d7d1dd87e2231f707b9592b9d Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 28 Feb 2023 00:39:46 +0500 Subject: [PATCH 15/35] chore: InvalidStateTransitionError --- .../errors/invalid_state_transition_error.rs | 32 +++++++++++++++++++ .../src/state_transition/errors/mod.rs | 1 + packages/wasm-dpp/src/state_transition/mod.rs | 1 + .../state_transition_factory.rs | 6 ++-- 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs create mode 100644 packages/wasm-dpp/src/state_transition/errors/mod.rs diff --git a/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs b/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs new file mode 100644 index 00000000000..e1224b15f70 --- /dev/null +++ b/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs @@ -0,0 +1,32 @@ +use dpp::{consensus::ConsensusError, identity::errors}; +use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; + +use crate::errors::consensus_error::from_consensus_error_ref; + +#[wasm_bindgen(js_name = InvalidStateTransitionError)] +pub struct InvalidStateTransitionError { + errors: Vec, + raw_state_transition: JsValue, +} + +impl InvalidStateTransitionError { + pub fn new(errors: Vec, raw_state_transition: JsValue) -> Self { + Self { + errors, + raw_state_transition, + } + } +} + +#[wasm_bindgen(js_class = InvalidStateTransitionError)] +impl InvalidStateTransitionError { + #[wasm_bindgen(js_name = getErrors)] + pub fn get_errors(&self) -> Vec { + self.errors.iter().map(from_consensus_error_ref).collect() + } + + #[wasm_bindgen(js_name = getRawStateTransition)] + pub fn get_raw_state_transition(&self) -> JsValue { + self.raw_state_transition.clone() + } +} diff --git a/packages/wasm-dpp/src/state_transition/errors/mod.rs b/packages/wasm-dpp/src/state_transition/errors/mod.rs new file mode 100644 index 00000000000..faafff66c26 --- /dev/null +++ b/packages/wasm-dpp/src/state_transition/errors/mod.rs @@ -0,0 +1 @@ +pub mod invalid_state_transition_error; diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 322c53e6da7..5303d393297 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -11,6 +11,7 @@ use wasm_bindgen::prelude::*; use crate::{buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper}; +pub mod errors; pub mod state_transition_factory; #[wasm_bindgen(js_name=StateTransitionExecutionContext)] diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index ec85a110b0b..f4ec60ddcbf 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -19,7 +19,7 @@ use crate::{ errors::{from_dpp_err, from_dpp_init_error}, identity_facade::FromObjectOptions, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - utils, with_js_error, StateTransitionWasm, + utils, with_js_error, StateTransitionWasm, state_transition::errors::invalid_state_transition_error::InvalidStateTransitionError, }; #[wasm_bindgen(js_name = StateTransitionFactory)] @@ -147,7 +147,7 @@ impl StateTransitionFactoryWasm { StateTransitionError::InvalidStateTransitionError { errors, raw_state_transition, - } => Err(InvalidStateTransitionError::new(errors, state_transition_object).into()), + } => Err(InvalidStateTransitionError::new(errors, raw_state_transition).into()), }, Err(other) => Err(from_dpp_err(other)), } @@ -181,7 +181,7 @@ impl StateTransitionFactoryWasm { StateTransitionError::InvalidStateTransitionError { errors, raw_state_transition, - } => Err(InvalidStateTransitionError::new(errors, state_transition_object).into()), + } => Err(InvalidStateTransitionError::new(errors, raw_state_transition).into()), }, Err(other) => Err(from_dpp_err(other)), } From 0e52a8490c625403636483e479514234d5b94b13 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 28 Feb 2023 09:48:58 +0500 Subject: [PATCH 16/35] chore: wip --- packages/wasm-dpp/src/identity/identity_factory.rs | 2 +- packages/wasm-dpp/src/state_transition/mod.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/wasm-dpp/src/identity/identity_factory.rs b/packages/wasm-dpp/src/identity/identity_factory.rs index 6c77e17b630..7b467552f05 100644 --- a/packages/wasm-dpp/src/identity/identity_factory.rs +++ b/packages/wasm-dpp/src/identity/identity_factory.rs @@ -72,7 +72,7 @@ impl IdentityFactoryWasm { }; let identity_json = utils::stringify(&identity_object)?; - let raw_identity: value = + let raw_identity: Value = serde_json::from_str(&identity_json).map_err(|e| e.to_string())?; let result = self diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 5303d393297..f690f3c7c67 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -158,11 +158,11 @@ impl StateTransitionWasm { todo!("set up BLS"))) } - #[wasm_bindgen(js_name = getModifiedDataIds)] - pub fn get_modified_data_ids(&self) -> Vec { - // TODO: implement! - vec![]; - } + // #[wasm_bindgen(js_name = getModifiedDataIds)] + // pub fn get_modified_data_ids(&self) -> Vec { + // // TODO: implement! + // vec![]; + // } #[wasm_bindgen(js_name = isDocumentStateTransition)] pub fn is_document_state_transition(&self) -> bool { From 545d96a1560bf2500175d60bb6e9cccf3288ce7b Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 28 Feb 2023 14:19:43 +0500 Subject: [PATCH 17/35] chore: wip --- packages/wasm-dpp/src/state_transition/mod.rs | 19 ++++++++++++++++--- .../state_transition_factory.rs | 3 ++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index f690f3c7c67..b11ef15b1cc 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -7,9 +7,10 @@ use dpp::{ StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, }, }; +use serde::Deserialize; use wasm_bindgen::prelude::*; -use crate::{buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper}; +use crate::{buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper, with_js_error}; pub mod errors; pub mod state_transition_factory; @@ -85,6 +86,13 @@ macro_rules! either_st { }; } +#[derive(Deserialize, Default)] +#[serde(rename_all = "camelCase")] +struct AbstractStateTransitionOptions { + skip_signature: Option, + skip_identifiers_conversion: Option, +} + #[wasm_bindgen(js_name = AbstractStateTransition)] pub struct StateTransitionWasm(StateTransition); @@ -112,8 +120,13 @@ impl StateTransitionWasm { #[wasm_bindgen(js_name = toObject)] pub fn to_object(&self, options: JsValue) -> Result { - // TODO: construct options - either_st!(&self.0, st => st.to_object(false).map_err(from_dpp_err)) + let options: AbstractStateTransitionOptions = if options.is_object() { + with_js_error!(serde_wasm_bindgen::from_value(options))? + } else { + Default::default() + }; + + either_st!(&self.0, st => st.to_object(options.skip_signature.unwrap_or_default()).map_err(from_dpp_err)) } #[wasm_bindgen(js_name = getOwnerId)] diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index f4ec60ddcbf..04b0033a859 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -19,7 +19,8 @@ use crate::{ errors::{from_dpp_err, from_dpp_init_error}, identity_facade::FromObjectOptions, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - utils, with_js_error, StateTransitionWasm, state_transition::errors::invalid_state_transition_error::InvalidStateTransitionError, + state_transition::errors::invalid_state_transition_error::InvalidStateTransitionError, + utils, with_js_error, StateTransitionWasm, }; #[wasm_bindgen(js_name = StateTransitionFactory)] From 1c5fe5e598f8d52a0dd64e91cf800fa93c2e10db Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 1 Mar 2023 23:46:54 +0500 Subject: [PATCH 18/35] chore: wip --- .../data_contract_create_transition/mod.rs | 10 +- .../data_contract_update_transition/mod.rs | 10 +- .../documents_batch_transition/mod.rs | 9 +- .../identity_create_transition.rs | 10 +- .../mod.rs | 9 +- .../identity_topup_transition.rs | 10 +- .../identity_update_transition.rs | 10 +- ...lidate_identity_update_transition_basic.rs | 5 +- .../abstract_state_transition.rs | 4 +- ...stract_state_transition_identity_signed.rs | 4 + .../rs-dpp/src/state_transition/example.rs | 4 + packages/rs-dpp/src/state_transition/mod.rs | 4 + ...ate_state_transition_identity_signature.rs | 4 + .../data_contract_create_transition/mod.rs | 2 +- .../data_contract_update_transition/mod.rs | 2 +- .../identity_create_transition.rs | 2 +- ...ntity_create_transition_basic_validator.rs | 2 +- .../identity_topup_transition.rs | 2 +- .../identity_update_transition.rs | 2 +- ...ntity_update_transition_basic_validator.rs | 2 +- packages/wasm-dpp/src/state_transition/mod.rs | 103 ++++++++++++------ .../state_transition_factory.rs | 24 ++-- 22 files changed, 147 insertions(+), 87 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 bd3d647b4df..1b0a4b9f1c1 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 @@ -91,11 +91,6 @@ impl DataContractCreateTransition { pub fn get_entropy(&self) -> &[u8; 32] { &self.entropy } - - /// Returns ID of the created contract - pub fn get_modified_data_ids(&self) -> Vec<&Identifier> { - vec![&self.data_contract.id] - } } impl StateTransitionIdentitySigned for DataContractCreateTransition { @@ -114,6 +109,11 @@ impl StateTransitionIdentitySigned for DataContractCreateTransition { } impl StateTransitionLike for DataContractCreateTransition { + /// Returns ID of the created contract + fn get_modified_data_ids(&self) -> Vec { + vec![self.data_contract.id] + } + fn get_protocol_version(&self) -> u32 { self.protocol_version } diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index 6392a036a0b..4fa1d703b4b 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 @@ -73,11 +73,6 @@ impl DataContractUpdateTransition { pub fn set_data_contract(&mut self, data_contract: DataContract) { self.data_contract = data_contract; } - - /// Returns ID of the created contract - pub fn get_modified_data_ids(&self) -> Vec<&Identifier> { - vec![&self.data_contract.id] - } } impl StateTransitionIdentitySigned for DataContractUpdateTransition { @@ -96,6 +91,11 @@ impl StateTransitionIdentitySigned for DataContractUpdateTransition { } impl StateTransitionLike for DataContractUpdateTransition { + /// Returns ID of the created contract + fn get_modified_data_ids(&self) -> Vec { + vec![self.data_contract.id] + } + fn get_protocol_version(&self) -> u32 { self.protocol_version } 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 0656b64672f..6e55139da35 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 @@ -191,11 +191,6 @@ impl DocumentsBatchTransition { pub fn get_transitions(&self) -> &Vec { &self.transitions } - - // TODO to decide if this should be a lazy iterator or a vector - pub fn get_modified_data_ids(&self) -> impl Iterator { - self.transitions.iter().map(|t| &t.base().id) - } } impl StateTransitionIdentitySigned for DocumentsBatchTransition { @@ -368,6 +363,10 @@ impl StateTransitionConvert for DocumentsBatchTransition { } impl StateTransitionLike for DocumentsBatchTransition { + fn get_modified_data_ids(&self) -> Vec { + self.transitions.iter().map(|t| t.base().id).collect() + } + fn get_protocol_version(&self) -> u32 { self.protocol_version } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index 236e5d7a23a..5e2bb659a28 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 @@ -237,11 +237,6 @@ impl IdentityCreateTransition { Ok(json_map) } - /// Returns ids of created identities - pub fn get_modified_data_ids(&self) -> Vec<&Identifier> { - vec![self.get_identity_id()] - } - pub fn set_protocol_version(&mut self, protocol_version: u32) { self.protocol_version = protocol_version; } @@ -321,6 +316,11 @@ impl StateTransitionConvert for IdentityCreateTransition { } impl StateTransitionLike for IdentityCreateTransition { + /// Returns ids of created identities + fn get_modified_data_ids(&self) -> Vec { + vec![*self.get_identity_id()] + } + fn get_protocol_version(&self) -> u32 { self.protocol_version } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_credit_withdrawal_transition/mod.rs index 04972f7f0b8..0c7b2107355 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 @@ -111,11 +111,6 @@ impl IdentityCreditWithdrawalTransition { Self::from_value(raw_object) } - /// Returns ID of the created contract - pub fn get_modified_data_ids(&self) -> Vec<&Identifier> { - vec![&self.identity_id] - } - pub fn set_revision(&mut self, revision: Revision) { self.revision = revision; } @@ -141,6 +136,10 @@ impl StateTransitionIdentitySigned for IdentityCreditWithdrawalTransition { } impl StateTransitionLike for IdentityCreditWithdrawalTransition { + fn get_modified_data_ids(&self) -> Vec { + vec![self.identity_id] + } + fn get_protocol_version(&self) -> u32 { self.protocol_version } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 4e5be8f1d87..64854f07beb 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 @@ -197,11 +197,6 @@ impl IdentityTopUpTransition { pub fn set_protocol_version(&mut self, protocol_version: u32) { self.protocol_version = protocol_version; } - - /// Returns ids of created identities - pub fn get_modified_data_ids(&self) -> Vec<&Identifier> { - vec![self.get_identity_id()] - } } impl StateTransitionConvert for IdentityTopUpTransition { @@ -268,6 +263,11 @@ impl StateTransitionLike for IdentityTopUpTransition { self.signature = signature } + /// Returns ids of created identities + fn get_modified_data_ids(&self) -> Vec { + vec![*self.get_identity_id()] + } + fn get_execution_context(&self) -> &StateTransitionExecutionContext { &self.execution_context } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index c04b570807b..fe674c5a32f 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 @@ -178,11 +178,6 @@ impl IdentityUpdateTransition { self.public_keys_disabled_at } - /// Returns ids of created identities - pub fn get_modified_data_ids(&self) -> Vec<&Identifier> { - vec![self.get_identity_id()] - } - pub fn set_protocol_version(&mut self, protocol_version: u32) { self.protocol_version = protocol_version; } @@ -295,6 +290,11 @@ impl StateTransitionConvert for IdentityUpdateTransition { } impl StateTransitionLike for IdentityUpdateTransition { + /// Returns ids of created identities + fn get_modified_data_ids(&self) -> Vec { + vec![*self.get_identity_id()] + } + fn get_protocol_version(&self) -> u32 { self.protocol_version } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs index 79141650f74..f0da388aca2 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic.rs @@ -27,8 +27,7 @@ pub struct ValidateIdentityUpdateTransitionBasic { protocol_version_validator: ProtocolVersionValidator, json_schema_validator: JsonSchemaValidator, public_keys_validator: Arc, - - public_keys_signatures_validator: SV, + public_keys_signatures_validator: Arc, } impl ValidateIdentityUpdateTransitionBasic @@ -39,7 +38,7 @@ where pub fn new( protocol_version_validator: ProtocolVersionValidator, public_keys_validator: Arc, - public_keys_signatures_validator: SV, + public_keys_signatures_validator: Arc, ) -> Result { let json_schema_validator = JsonSchemaValidator::new(IDENTITY_UPDATE_SCHEMA.clone()) .map_err(|e| { diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index fe87d540745..6f13620ac46 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -6,7 +6,7 @@ use serde_json::Value as JsonValue; use crate::{ identity::KeyType, - prelude::ProtocolError, + prelude::{Identifier, ProtocolError}, util::{ hash, json_value::{JsonValueExt, ReplaceWith}, @@ -55,6 +55,8 @@ pub trait StateTransitionLike: fn calculate_fee(&self) -> i64 { calculate_state_transition_fee(self) } + /// get modified ids list + fn get_modified_data_ids(&self) -> Vec; /// Signs data with the private key fn sign_by_private_key( diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition_identity_signed.rs index bb278eb96da..fee3c58c93d 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 @@ -249,6 +249,10 @@ mod test { fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext) { self.execution_context = execution_context } + + fn get_modified_data_ids(&self) -> Vec { + vec![] + } } impl StateTransitionIdentitySigned for ExampleStateTransition { diff --git a/packages/rs-dpp/src/state_transition/example.rs b/packages/rs-dpp/src/state_transition/example.rs index 60f942f2c57..e7d47113f65 100644 --- a/packages/rs-dpp/src/state_transition/example.rs +++ b/packages/rs-dpp/src/state_transition/example.rs @@ -52,6 +52,10 @@ impl StateTransitionLike for ExampleStateTransition { fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext) { self.execution_context = execution_context } + + fn get_modified_data_ids(&self) -> Vec { + vec![] + } } /// To implement the StateTransitionConvert is enough to implement the _property_paths methods diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 29f3474554f..8f6868d70d2 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -155,6 +155,10 @@ impl StateTransitionLike for StateTransition { fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext) { call_method!(self, set_execution_context, execution_context) } + + fn get_modified_data_ids(&self) -> Vec { + call_method!(self, get_modified_data_ids) + } } impl From for StateTransition { diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_identity_signature.rs index 108281a4bc9..75cdd2d6d00 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 @@ -219,6 +219,10 @@ mod test { fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContext) { self.execution_context = execution_context } + + fn get_modified_data_ids(&self) -> Vec { + vec![] + } } impl StateTransitionIdentitySigned for ExampleStateTransition { diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index 47c37767e1b..544c6bb5a57 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -112,7 +112,7 @@ impl DataContractCreateTransitionWasm { self.0 .get_modified_data_ids() .into_iter() - .map(|identifier| Into::::into(*identifier).into()) + .map(|identifier| Into::::into(identifier).into()) .collect() } diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index e4a8b6868a6..3943344feb5 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -111,7 +111,7 @@ impl DataContractUpdateTransitionWasm { self.0 .get_modified_data_ids() .into_iter() - .map(|identifier| Into::::into(*identifier).into()) + .map(|identifier| Into::::into(identifier).into()) .collect() } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs index cf7700c445e..9099828cf1a 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition.rs @@ -284,7 +284,7 @@ impl IdentityCreateTransitionWasm { let ids = self.0.get_modified_data_ids(); ids.into_iter() - .map(|id| >::from(*id).into()) + .map(|id| >::from(id).into()) .collect() } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs index 9d276588d5d..4117f1795c4 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_basic_validator.rs @@ -116,7 +116,7 @@ impl IdentityCreateTransitionBasicValidatorWasm { Arc::new(public_keys_transition_validator), Arc::new(asset_lock_proof_validator), BlsAdapter(js_bls), - public_keys_signature_validator, + Arc::new(public_keys_signature_validator), ) .map_err(|e| from_dpp_err(ProtocolError::Generic(e.to_string())))?; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs index 495f5bc4ccf..5630d35b55c 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition.rs @@ -225,7 +225,7 @@ impl IdentityTopUpTransitionWasm { let ids = self.0.get_modified_data_ids(); ids.into_iter() - .map(|id| >::from(*id).into()) + .map(|id| >::from(id).into()) .collect() } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs index d052b7e10ce..fcccf72c41a 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition.rs @@ -368,7 +368,7 @@ impl IdentityUpdateTransitionWasm { let ids = self.0.get_modified_data_ids(); ids.into_iter() - .map(|id| >::from(*id).into()) + .map(|id| >::from(id).into()) .collect() } diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs index 68c865298d8..5f64afffaae 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_update_transition/identity_update_transition_basic_validator.rs @@ -61,7 +61,7 @@ impl IdentityUpdateTransitionBasicValidatorWasm { let validator = ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(public_keys_validator), - public_keys_signatures_validator, + Arc::new(public_keys_signatures_validator), ) .map_err(|e| from_dpp_err(ProtocolError::Generic(e.to_string())))?; diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index b11ef15b1cc..4dddae889bd 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -1,16 +1,19 @@ -use std::{convert::TryFrom, ops::Deref}; +use std::{convert::TryFrom, sync::Arc}; use dpp::{ identity::KeyType, state_transition::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, - }, + }, prelude::Identifier, }; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; -use crate::{buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper, with_js_error}; +use crate::{ + bls_adapter::BlsAdapter, buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper, + with_js_error, +}; pub mod errors; pub mod state_transition_factory; @@ -94,28 +97,31 @@ struct AbstractStateTransitionOptions { } #[wasm_bindgen(js_name = AbstractStateTransition)] -pub struct StateTransitionWasm(StateTransition); +pub struct StateTransitionWasm { + inner: StateTransition, + bls_adapter: Arc, +} #[wasm_bindgen(js_class = AbstractStateTransition)] impl StateTransitionWasm { #[wasm_bindgen(js_name = getProtocolVersion)] pub fn get_protocol_version(&self) -> u32 { - either_st!(&self.0, st => st.get_protocol_version()) + either_st!(&self.inner, st => st.get_protocol_version()) } #[wasm_bindgen(js_name = getType)] pub fn get_type(&self) -> u8 { - either_st!(&self.0, st => st.get_type().into()) + either_st!(&self.inner, st => st.get_type().into()) } #[wasm_bindgen(js_name = getSignature)] pub fn get_signature(&self) -> Buffer { - either_st!(&self.0, st => Buffer::from_bytes(st.get_signature())) + either_st!(&self.inner, st => Buffer::from_bytes(st.get_signature())) } #[wasm_bindgen(js_name = setSignature)] pub fn set_signature(&self, signature: Vec) { - either_st!(&self.0, st => st.set_signature(signature)) + either_st!(&self.inner, st => st.set_signature(signature)) } #[wasm_bindgen(js_name = toObject)] @@ -126,80 +132,109 @@ impl StateTransitionWasm { Default::default() }; - either_st!(&self.0, st => st.to_object(options.skip_signature.unwrap_or_default()).map_err(from_dpp_err)) + let serializer = serde_wasm_bindgen::Serializer::json_compatible(); + + either_st!(&self.inner, st => { + let json_value = st + .to_object(options.skip_signature.unwrap_or_default()) + .map_err(from_dpp_err)?; + + self.inner.serialize(&serializer).map_err(|e| e.into()) + }) } #[wasm_bindgen(js_name = getOwnerId)] pub fn get_owner_id(&self) -> IdentifierWrapper { - either_st!(&self.0, st => (*st.get_owner_id()).into()) + either_st!(&self.inner, st => (*st.get_owner_id()).into()) } #[wasm_bindgen(js_name = toJSON)] pub fn to_json(&self, options: JsValue) -> Result { - // TODO: construct options - either_st!(&self.0, st => st.to_json(false).map_err(from_dpp_err)) + let options: AbstractStateTransitionOptions = if options.is_object() { + with_js_error!(serde_wasm_bindgen::from_value(options))? + } else { + Default::default() + }; + + either_st!(&self.inner, st => { + let json_value = st + .to_json(options.skip_signature.unwrap_or_default()) + .map_err(from_dpp_err)?; + + serde_wasm_bindgen::to_value(&json_value).map_err(|e| e.into()) + }) } #[wasm_bindgen(js_name = toBuffer)] pub fn to_buffer(&self, options: JsValue) -> Result { - // TODO: construct options - either_st!(&self.0, st => st.to_buffer(false).map_err(from_dpp_err)) + let options: AbstractStateTransitionOptions = if options.is_object() { + with_js_error!(serde_wasm_bindgen::from_value(options))? + } else { + Default::default() + }; + + either_st!(&self.inner, st => st.to_buffer(options.skip_signature.unwrap_or_default()).map(|v| Buffer::from_bytes(&v)).map_err(from_dpp_err)) } #[wasm_bindgen(js_name = hash)] pub fn hash(&self, options: JsValue) -> Result { - // TODO: construct options - either_st!(&self.0, st => st.hash(false).map_err(from_dpp_err)) + let options: AbstractStateTransitionOptions = if options.is_object() { + with_js_error!(serde_wasm_bindgen::from_value(options))? + } else { + Default::default() + }; + + either_st!(&self.inner, st => st.hash(options.skip_signature.unwrap_or_default()).map(|v| Buffer::from_bytes(&v)).map_err(from_dpp_err)) } #[wasm_bindgen(js_name = signByPrivateKey)] pub fn sign_by_private_key(&self, private_key: Vec, key_type: u8) -> Result<(), JsValue> { - either_st!(&self.0, st => st + either_st!(&self.inner, st => st .sign_by_private_key( &private_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("pass correct BLS"), + KeyType::try_from(key_type).map_err(|e| e.to_string())?, + self.bls_adapter.as_ref(), ) .map_err(from_dpp_err)) } #[wasm_bindgen(js_name = verifyByPublicKey)] pub fn verify_by_public_key(&self, public_key: Vec, key_type: u8) -> Result { - either_st!(&self.0, st => st.verify_by_public_key( - &public_key, - KeyType::try_from(key_type).map_err(from_dpp_err)?, - todo!("set up BLS"))) + either_st!(&self.inner, st => st + .verify_by_public_key( + &public_key, + KeyType::try_from(key_type).map_err(|e| e.to_string())?, + self.bls_adapter.as_ref()).map(|_| true).map_err(from_dpp_err)) } - // #[wasm_bindgen(js_name = getModifiedDataIds)] - // pub fn get_modified_data_ids(&self) -> Vec { - // // TODO: implement! - // vec![]; - // } + #[wasm_bindgen(js_name = getModifiedDataIds)] + pub fn get_modified_data_ids(&self) -> Vec { + either_st!(&self.inner, st => st.get_modified_data_ids().into_iter().map(|id| >::from(id).into()).collect()) + } #[wasm_bindgen(js_name = isDocumentStateTransition)] pub fn is_document_state_transition(&self) -> bool { - either_st!(&self.0, st => st.is_document_state_transition()) + either_st!(&self.inner, st => st.is_document_state_transition()) } #[wasm_bindgen(js_name = isDataContractStateTransition)] pub fn is_data_contract_state_transition(&self) -> bool { - either_st!(&self.0, st => st.is_data_contract_state_transition()) + either_st!(&self.inner, st => st.is_data_contract_state_transition()) } #[wasm_bindgen(js_name = isIdentityStateTransition)] pub fn is_identity_state_transition(&self) -> bool { - either_st!(&self.0, st => st.is_identity_state_transition()) + either_st!(&self.inner, st => st.is_identity_state_transition()) } #[wasm_bindgen(js_name = setExecutionContext)] pub fn set_execution_context(&self, execution_context: StateTransitionExecutionContextWasm) { - either_st!(&self.0, st => st.set_execution_context(execution_context.into())) + either_st!(&self.inner, st => st.set_execution_context(execution_context.into())) } #[wasm_bindgen(js_name = getExecutionContext)] pub fn get_execution_context(&self) -> StateTransitionExecutionContextWasm { - either_st!(&self.0, st => st.get_execution_context().into()) + either_st!(&self.inner, st => st.get_execution_context().into()) } } diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index 04b0033a859..8ac2e9fbc90 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -48,9 +48,11 @@ impl StateTransitionFactoryWasm { let state_repository_wrapper = ExternalStateRepositoryLikeWrapper::new(state_repository); let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); + let adapter = BlsAdapter(bls_adapter); + let pk_validator = - Arc::new(PublicKeysValidator::new(bls_adapter.into()).map_err(from_dpp_init_error)?); - let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(bls_adapter.into())); + Arc::new(PublicKeysValidator::new(adapter).map_err(from_dpp_init_error)?); + let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter)); let asset_lock_tx_validator = Arc::new(AssetLockTransactionValidator::new( state_repository_wrapper.into(), @@ -86,18 +88,18 @@ impl StateTransitionFactoryWasm { pk_validator, pk_validator, asset_lock_validator, - bls_adapter.into(), + adapter, pk_sig_validator, ) .map_err(from_dpp_init_error)?, ValidateIdentityUpdateTransitionBasic::new( - protocol_version_validator, + protocol_version_validator.deref().clone(), pk_validator, pk_sig_validator, ) .map_err(from_dpp_err)?, IdentityTopUpTransitionBasicValidator::new( - protocol_version_validator, + protocol_version_validator.deref().clone(), asset_lock_validator, ) .map_err(from_dpp_init_error)?, @@ -148,7 +150,11 @@ impl StateTransitionFactoryWasm { StateTransitionError::InvalidStateTransitionError { errors, raw_state_transition, - } => Err(InvalidStateTransitionError::new(errors, raw_state_transition).into()), + } => Err(InvalidStateTransitionError::new( + errors, + serde_wasm_bindgen::to_value(&raw_state_transition)?, + ) + .into()), }, Err(other) => Err(from_dpp_err(other)), } @@ -182,7 +188,11 @@ impl StateTransitionFactoryWasm { StateTransitionError::InvalidStateTransitionError { errors, raw_state_transition, - } => Err(InvalidStateTransitionError::new(errors, raw_state_transition).into()), + } => Err(InvalidStateTransitionError::new( + errors, + serde_wasm_bindgen::to_value(&raw_state_transition)?, + ) + .into()), }, Err(other) => Err(from_dpp_err(other)), } From 284ea96a31e0b8c86fb263871dfc5b4767aaece3 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Thu, 2 Mar 2023 15:31:11 +0500 Subject: [PATCH 19/35] chore: wip --- packages/wasm-dpp/src/state_transition/mod.rs | 24 ++++---- .../state_transition_factory.rs | 57 ++++++++++--------- 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 4dddae889bd..61bf1159d14 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -2,10 +2,11 @@ use std::{convert::TryFrom, sync::Arc}; use dpp::{ identity::KeyType, + prelude::Identifier, state_transition::{ state_transition_execution_context::StateTransitionExecutionContext, StateTransition, StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, - }, prelude::Identifier, + }, }; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; @@ -120,8 +121,9 @@ impl StateTransitionWasm { } #[wasm_bindgen(js_name = setSignature)] - pub fn set_signature(&self, signature: Vec) { - either_st!(&self.inner, st => st.set_signature(signature)) + pub fn set_signature(&mut self, signature: Vec) { + let inner = &mut self.inner; + either_st!(inner, st => st.set_signature(signature)) } #[wasm_bindgen(js_name = toObject)] @@ -135,10 +137,6 @@ impl StateTransitionWasm { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); either_st!(&self.inner, st => { - let json_value = st - .to_object(options.skip_signature.unwrap_or_default()) - .map_err(from_dpp_err)?; - self.inner.serialize(&serializer).map_err(|e| e.into()) }) } @@ -188,8 +186,9 @@ impl StateTransitionWasm { } #[wasm_bindgen(js_name = signByPrivateKey)] - pub fn sign_by_private_key(&self, private_key: Vec, key_type: u8) -> Result<(), JsValue> { - either_st!(&self.inner, st => st + pub fn sign_by_private_key(&mut self, private_key: Vec, key_type: u8) -> Result<(), JsValue> { + let inner = &mut self.inner; + either_st!(inner, st => st .sign_by_private_key( &private_key, KeyType::try_from(key_type).map_err(|e| e.to_string())?, @@ -209,7 +208,7 @@ impl StateTransitionWasm { #[wasm_bindgen(js_name = getModifiedDataIds)] pub fn get_modified_data_ids(&self) -> Vec { - either_st!(&self.inner, st => st.get_modified_data_ids().into_iter().map(|id| >::from(id).into()).collect()) + either_st!(&self.inner, st => st.get_modified_data_ids().into_iter().map(|id| >::from(id).into()).collect()) } #[wasm_bindgen(js_name = isDocumentStateTransition)] @@ -228,8 +227,9 @@ impl StateTransitionWasm { } #[wasm_bindgen(js_name = setExecutionContext)] - pub fn set_execution_context(&self, execution_context: StateTransitionExecutionContextWasm) { - either_st!(&self.inner, st => st.set_execution_context(execution_context.into())) + pub fn set_execution_context(&mut self, execution_context: StateTransitionExecutionContextWasm) { + let inner = &mut self.inner; + either_st!(inner, st => st.set_execution_context(execution_context.into())) } #[wasm_bindgen(js_name = getExecutionContext)] diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index 8ac2e9fbc90..fd2fde15638 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -45,71 +45,74 @@ impl StateTransitionFactoryWasm { state_repository: ExternalStateRepositoryLike, bls_adapter: JsBlsAdapter, ) -> Result { - let state_repository_wrapper = ExternalStateRepositoryLikeWrapper::new(state_repository); + let state_repository_wrapper = + Arc::new(ExternalStateRepositoryLikeWrapper::new(state_repository)); let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); let adapter = BlsAdapter(bls_adapter); let pk_validator = - Arc::new(PublicKeysValidator::new(adapter).map_err(from_dpp_init_error)?); - let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter)); + Arc::new(PublicKeysValidator::new(adapter.clone()).map_err(from_dpp_init_error)?); + let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter.clone())); let asset_lock_tx_validator = Arc::new(AssetLockTransactionValidator::new( - state_repository_wrapper.into(), + state_repository_wrapper.clone(), )); let asset_lock_validator = Arc::new(AssetLockProofValidator::new( InstantAssetLockProofStructureValidator::new( - state_repository_wrapper.into(), - asset_lock_tx_validator, + state_repository_wrapper.clone(), + asset_lock_tx_validator.clone(), ) .map_err(from_dpp_init_error)?, ChainAssetLockProofStructureValidator::new( - state_repository_wrapper.into(), - asset_lock_tx_validator, + state_repository_wrapper.clone(), + asset_lock_tx_validator.clone(), ) .map_err(from_dpp_init_error)?, )); let factory = StateTransitionFactory::new( - state_repository_wrapper.into(), + state_repository_wrapper.clone(), StateTransitionBasicValidator::new( - state_repository_wrapper.into(), + state_repository_wrapper.clone(), StateTransitionByTypeValidator::new( - DataContractCreateTransitionBasicValidator::new(protocol_version_validator) - .map_err(from_dpp_err)?, + DataContractCreateTransitionBasicValidator::new( + protocol_version_validator.clone(), + ) + .map_err(from_dpp_err)?, DataContractUpdateTransitionBasicValidator::new( - state_repository_wrapper.into(), - protocol_version_validator, + state_repository_wrapper.clone(), + protocol_version_validator.clone(), ) .map_err(from_dpp_init_error)?, IdentityCreateTransitionBasicValidator::new( protocol_version_validator.deref().clone(), - pk_validator, - pk_validator, - asset_lock_validator, - adapter, - pk_sig_validator, + pk_validator.clone(), + pk_validator.clone(), + asset_lock_validator.clone(), + adapter.clone(), + pk_sig_validator.clone(), ) .map_err(from_dpp_init_error)?, ValidateIdentityUpdateTransitionBasic::new( - protocol_version_validator.deref().clone(), - pk_validator, - pk_sig_validator, + ProtocolVersionValidator::default(), + pk_validator.clone(), + pk_sig_validator.clone(), ) .map_err(from_dpp_err)?, IdentityTopUpTransitionBasicValidator::new( - protocol_version_validator.deref().clone(), - asset_lock_validator, + ProtocolVersionValidator::default(), + asset_lock_validator.clone(), ) .map_err(from_dpp_init_error)?, IdentityCreditWithdrawalTransitionBasicValidator::new( - protocol_version_validator, + protocol_version_validator.clone(), ) .map_err(from_dpp_init_error)?, DocumentBatchTransitionBasicValidator::new( - state_repository_wrapper.into(), - protocol_version_validator, + state_repository_wrapper.clone(), + protocol_version_validator.clone(), ), ), ), From 05a3f7efdc409c6987581adde9526cea374e48fd Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Fri, 3 Mar 2023 13:27:41 +0000 Subject: [PATCH 20/35] fix: inconsistencies after merge --- .../basic/validate_data_contract_update_transition_basic.rs | 1 - .../data_contract_update_transition/validation.rs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 6d07e286219..88abdd21b83 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -8,7 +8,6 @@ use lazy_static::lazy_static; use serde_json::{json, Value as JsonValue}; use std::sync::Arc; -use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::validation::AsyncDataValidatorWithContext; use crate::{ consensus::basic::BasicError, diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs index dd342daf273..717abdd185b 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/validation.rs @@ -1,5 +1,6 @@ use std::{collections::BTreeMap, sync::Arc}; +use dpp::validation::AsyncDataValidatorWithContext; use dpp::{ data_contract::state_transition::data_contract_update_transition::validation::{ basic::{ From fae360231716fc5b2e70a3dde2ae8c49271b0067 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Mon, 6 Mar 2023 18:35:10 +0500 Subject: [PATCH 21/35] chore: fix tests --- ..._create_transition_basic_validator_spec.rs | 2 +- ...e_identity_update_transition_basic_spec.rs | 48 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs index e48d3c8cdb7..cf991aeee7d 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_create_transition/validation/basic/identity_create_transition_basic_validator_spec.rs @@ -71,7 +71,7 @@ pub fn setup_test( public_keys_transition_validator, asset_lock_proof_validator, NativeBlsModule::default(), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(), ) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs index 758c410f306..db024332a23 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/validate_identity_update_transition_basic_spec.rs @@ -125,7 +125,7 @@ fn property_should_be_present(property: &str) { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -159,7 +159,7 @@ fn property_should_be_byte_array(property_name: &str) { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -197,7 +197,7 @@ fn property_should_be_integer(property_name: &str) { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -230,7 +230,7 @@ fn signature_should_be_not_less_than_n_bytes(property_name: &str, n_bytes: usize ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -263,7 +263,7 @@ fn signature_should_be_not_longer_than_n_bytes(property_name: &str, n_bytes: usi ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -294,7 +294,7 @@ fn protocol_version_should_be_valid() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -320,7 +320,7 @@ fn raw_state_transition_type_should_be_valid() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -351,7 +351,7 @@ fn revision_should_be_greater_or_equal_0() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -389,7 +389,7 @@ fn add_public_keys_should_return_valid_result() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -421,7 +421,7 @@ fn add_public_keys_should_not_be_empty() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -461,7 +461,7 @@ fn add_public_keys_should_not_have_more_than_10_items() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -501,7 +501,7 @@ fn add_public_keys_should_be_unique() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -543,7 +543,7 @@ fn add_public_keys_should_be_valid() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -577,7 +577,7 @@ fn disable_public_keys_should_be_used_only_with_public_keys_disabled_at() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -616,7 +616,7 @@ fn disable_public_keys_should_be_valid() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -647,7 +647,7 @@ fn disable_public_keys_should_contain_number_greater_or_equal_0() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -684,7 +684,7 @@ fn disable_public_keys_should_contain_integers() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -721,7 +721,7 @@ fn disable_public_keys_should_not_have_more_than_10_items() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -758,7 +758,7 @@ fn disable_public_keys_should_be_unique() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -794,7 +794,7 @@ fn public_keys_disabled_at_should_be_used_only_with_disable_public_keys() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -833,7 +833,7 @@ fn public_keys_disabled_at_should_be_greater_or_equal_0() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -868,7 +868,7 @@ fn public_keys_disabled_at_should_return_valid_result() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -895,7 +895,7 @@ fn should_return_valid_result() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); @@ -927,7 +927,7 @@ fn should_have_either_add_public_keys_or_disable_public_keys() { ValidateIdentityUpdateTransitionBasic::new( protocol_version_validator, Arc::new(validate_public_keys_mock), - SignaturesValidatorMock::default(), + Arc::new(SignaturesValidatorMock::default()), ) .unwrap(); From 48410a832f502752c4a41caf280d180090cc6885 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Mon, 6 Mar 2023 18:40:45 +0500 Subject: [PATCH 22/35] chore: clippy --- packages/wasm-dpp/src/state_transition/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 9bacd334bd2..cf59e2a7d39 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -133,7 +133,7 @@ impl StateTransitionWasm { #[wasm_bindgen(js_name = toObject)] pub fn to_object(&self, options: JsValue) -> Result { - let options: AbstractStateTransitionOptions = if options.is_object() { + let _options: AbstractStateTransitionOptions = if options.is_object() { with_js_error!(serde_wasm_bindgen::from_value(options))? } else { Default::default() @@ -141,7 +141,7 @@ impl StateTransitionWasm { let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - either_st!(&self.inner, st => { + either_st!(&self.inner, _ => { self.inner.serialize(&serializer).map_err(|e| e.into()) }) } From 97dd2f5ad907e3e80a0ae2c0b6dff4032ee43e84 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 7 Mar 2023 14:39:23 +0500 Subject: [PATCH 23/35] chore: ST factor test --- .../StateTransitionFactory.spec.js | 141 ++++-------------- 1 file changed, 27 insertions(+), 114 deletions(-) diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js index b8bbe8519ad..4ca9d68e399 100644 --- a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js @@ -1,160 +1,73 @@ -const getDataContractFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); - -const DataContractCreateTransition = require('@dashevo/dpp/lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition'); +const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); -const ValidationResult = require('@dashevo/dpp/lib/validation/ValidationResult'); +const getDataContractFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); -const InvalidStateTransitionError = require('@dashevo/dpp/lib/stateTransition/errors/InvalidStateTransitionError'); +const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); -const SerializedObjectParsingError = require('@dashevo/dpp/lib/errors/consensus/basic/decode/SerializedObjectParsingError'); +const { default: loadWasmDpp } = require('../../../dist'); +const getBlsAdapterMock = require('../../../lib/test/mocks/getBlsAdapterMock'); -const createDPPMock = require('@dashevo/dpp/lib/test/mocks/createDPPMock'); -const StateTransitionFactory = require('@dashevo/dpp/lib/stateTransition/StateTransitionFactory'); -const SomeConsensusError = require('@dashevo/dpp/lib/test/mocks/SomeConsensusError'); +describe('StateTransitionFactory', function main() { + this.timeout(10000); -describe('StateTransitionFactory', () => { - let validateStateTransitionBasicMock; - let createStateTransitionMock; let factory; let stateTransition; let rawStateTransition; - let decodeProtocolEntityMock; - let dppMock; + let stateRepositoryMock; + let StateTransitionFactory; + + before(async () => { + ({ + DataContractCreateTransition, StateTransitionFactory, + UnsupportedProtocolVersionError, SerializedObjectParsingError, + } = await loadWasmDpp()); + }); - beforeEach(function beforeEach() { + beforeEach(async function beforeEach() { const dataContract = getDataContractFixture(); + const rawDataContract = dataContract.toObject(); + stateTransition = new DataContractCreateTransition({ - dataContract: dataContract.toObject(), + protocolVersion: protocolVersion.latestVersion, + dataContract: rawDataContract, entropy: dataContract.getEntropy(), + signature: Buffer.alloc(65), + signaturePublicKeyId: 0, }); rawStateTransition = stateTransition.toObject(); - decodeProtocolEntityMock = this.sinonSandbox.stub(); + stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); - validateStateTransitionBasicMock = this.sinonSandbox.stub(); - createStateTransitionMock = this.sinonSandbox.stub().returns(stateTransition); - - dppMock = createDPPMock(); + const blsAdapter = await getBlsAdapterMock(); factory = new StateTransitionFactory( - validateStateTransitionBasicMock, - createStateTransitionMock, - dppMock, - decodeProtocolEntityMock, + stateRepositoryMock, + blsAdapter, ); }); describe('createFromObject', () => { it('should return new State Transition with data from passed object', async () => { - validateStateTransitionBasicMock.returns(new ValidationResult()); - const result = await factory.createFromObject(rawStateTransition); expect(result).to.equal(stateTransition); - - expect(validateStateTransitionBasicMock).to.have.been.calledOnceWith(rawStateTransition); - - expect(createStateTransitionMock).to.have.been.calledOnceWith(rawStateTransition); }); it('should return new State Transition without validation if "skipValidation" option is passed', async () => { const result = await factory.createFromObject(rawStateTransition, { skipValidation: true }); expect(result).to.equal(stateTransition); - - expect(validateStateTransitionBasicMock).to.have.not.been.called(); - - expect(createStateTransitionMock).to.have.been.calledOnceWith(rawStateTransition); - }); - - it('should throw InvalidStateTransitionError if passed object is not valid', async () => { - const validationError = new SomeConsensusError('test'); - - validateStateTransitionBasicMock.returns(new ValidationResult([validationError])); - - try { - await factory.createFromObject(rawStateTransition); - - expect.fail('InvalidStateTransitionError is not thrown'); - } catch (e) { - expect(e).to.be.an.instanceOf(InvalidStateTransitionError); - expect(e.getRawStateTransition()).to.equal(rawStateTransition); - - expect(e.getErrors()).to.have.length(1); - - const [consensusError] = e.getErrors(); - - expect(consensusError).to.equal(validationError); - - expect(validateStateTransitionBasicMock).to.have.been.calledOnceWith( - rawStateTransition, - ); - } }); }); describe('createFromBuffer', () => { let serializedStateTransition; - beforeEach(function beforeEach() { - this.sinonSandbox.stub(factory, 'createFromObject'); - - serializedStateTransition = stateTransition.toBuffer(); - }); - - afterEach(() => { - factory.createFromObject.restore(); - }); - it('should return new State Transition from serialized contract', async () => { - decodeProtocolEntityMock.returns([rawStateTransition.protocolVersion, rawStateTransition]); - - factory.createFromObject.resolves(stateTransition); - const result = await factory.createFromBuffer(serializedStateTransition); expect(result).to.equal(stateTransition); - - expect(factory.createFromObject).to.have.been.calledOnceWith(rawStateTransition); - - expect(decodeProtocolEntityMock).to.have.been.calledOnceWith( - serializedStateTransition, - ); - }); - - it('should throw InvalidStateTransitionError if the decoding fails with consensus error', async () => { - const parsingError = new SerializedObjectParsingError( - serializedStateTransition, - new Error(), - ); - - decodeProtocolEntityMock.throws(parsingError); - - try { - await factory.createFromBuffer(serializedStateTransition); - - expect.fail('should throw InvalidStateTransitionError'); - } catch (e) { - expect(e).to.be.an.instanceOf(InvalidStateTransitionError); - - const [innerError] = e.getErrors(); - expect(innerError).to.be.equal(parsingError); - } - }); - - it('should throw an error if decoding fails with any other error', async () => { - const otherParsingError = new Error(); - - decodeProtocolEntityMock.throws(otherParsingError); - - try { - await factory.createFromBuffer(serializedStateTransition); - - expect.fail('should throw an error'); - } catch (e) { - expect(e).to.be.equal(otherParsingError); - } }); }); }); From 3f5058401312cb608531e49885f09c741fae241a Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 7 Mar 2023 20:53:40 +0500 Subject: [PATCH 24/35] chore: messy wip --- .../StateTransitionFactory.spec.js | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js index 4ca9d68e399..ff1ade648e8 100644 --- a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js @@ -8,7 +8,7 @@ const { default: loadWasmDpp } = require('../../../dist'); const getBlsAdapterMock = require('../../../lib/test/mocks/getBlsAdapterMock'); describe('StateTransitionFactory', function main() { - this.timeout(10000); + this.timeout(100000); let factory; let stateTransition; @@ -39,6 +39,34 @@ describe('StateTransitionFactory', function main() { stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); + stateRepositoryMock.fetchDataContract.resolves(dataContract); + stateRepositoryMock.createDataContract.resolves(); + stateRepositoryMock.updateDataContract.resolves(); + stateRepositoryMock.fetchDocuments.resolves(); + stateRepositoryMock.createDocument.resolves(); + stateRepositoryMock.updateDocument.resolves(); + stateRepositoryMock.removeDocument.resolves(); + stateRepositoryMock.fetchTransaction.resolves(); + stateRepositoryMock.fetchIdentity.resolves(); + stateRepositoryMock.createIdentity.resolves(); + stateRepositoryMock.addKeysToIdentity.resolves(); + stateRepositoryMock.disableIdentityKeys.resolves(); + stateRepositoryMock.updateIdentityRevision.resolves(); + stateRepositoryMock.addToIdentityBalance.resolves(); + stateRepositoryMock.fetchIdentityBalance.resolves(); + stateRepositoryMock.fetchIdentityBalanceWithDebt.resolves(); + stateRepositoryMock.addToSystemCredits.resolves(); + stateRepositoryMock.fetchLatestPlatformBlockHeight.resolves(); + stateRepositoryMock.fetchLatestPlatformCoreChainLockedHeight.resolves(); + stateRepositoryMock.verifyInstantLock.resolves(); + stateRepositoryMock.markAssetLockTransactionOutPointAsUsed.resolves(); + stateRepositoryMock.verifyChainLockHeight.resolves(); + stateRepositoryMock.isAssetLockTransactionOutPointAlreadyUsed.resolves(); + stateRepositoryMock.fetchSMLStore.resolves(); + stateRepositoryMock.fetchLatestWithdrawalTransactionIndex.resolves(); + stateRepositoryMock.enqueueWithdrawalTransaction.resolves(); + stateRepositoryMock.fetchLatestPlatformBlockTime.resolves(); + const blsAdapter = await getBlsAdapterMock(); factory = new StateTransitionFactory( From 99df902cd449006c20cd6ad29865ea6dd1eec414 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Tue, 7 Mar 2023 16:51:13 +0000 Subject: [PATCH 25/35] feat(wasm-dpp): StateTransitionFactory return wasm instances of state transitions --- .../state_transition_factory.rs | 71 +++++++++++-------- .../StateTransitionFactory.spec.js | 8 +-- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index fd2fde15638..cdf9c0abb3c 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -2,25 +2,25 @@ use std::{ops::Deref, sync::Arc}; use serde_json::Value as JsonValue; -use dpp::{ - state_transition::{ - validation::{ - validate_state_transition_basic::StateTransitionBasicValidator, - validate_state_transition_by_type::StateTransitionByTypeValidator, - }, - StateTransitionFactory, StateTransitionFactoryOptions, StateTransition, errors::StateTransitionError, +use dpp::{state_transition::{ + validation::{ + validate_state_transition_basic::StateTransitionBasicValidator, + validate_state_transition_by_type::StateTransitionByTypeValidator, }, - version::ProtocolVersionValidator, data_contract::state_transition::{data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, self}, identity::{state_transition::{identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, validate_public_key_signatures::{PublicKeysSignaturesValidator, TPublicKeysSignaturesValidator}, asset_lock_proof::{AssetLockProofValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator, AssetLockTransactionValidator}, identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic}, validation::PublicKeysValidator}, document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, -}; + StateTransitionFactory, StateTransitionFactoryOptions, StateTransition, errors::StateTransitionError, +}, version::ProtocolVersionValidator, data_contract::state_transition::{data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, self}, identity::{state_transition::{identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, validate_public_key_signatures::{PublicKeysSignaturesValidator, TPublicKeysSignaturesValidator}, asset_lock_proof::{AssetLockProofValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator, AssetLockTransactionValidator}, identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic}, validation::PublicKeysValidator}, document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, ProtocolError}; use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; +use crate::utils::ToSerdeJSONExt; use crate::{ bls_adapter::{BlsAdapter, JsBlsAdapter}, errors::{from_dpp_err, from_dpp_init_error}, identity_facade::FromObjectOptions, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, state_transition::errors::invalid_state_transition_error::InvalidStateTransitionError, - utils, with_js_error, StateTransitionWasm, + utils, with_js_error, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, + DocumentsBatchTransitionWASM, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, + IdentityUpdateTransitionWasm, StateTransitionWasm, }; #[wasm_bindgen(js_name = StateTransitionFactory)] @@ -126,16 +126,14 @@ impl StateTransitionFactoryWasm { &self, state_transition_object: JsValue, options: JsValue, - ) -> Result { + ) -> Result { let options: FromObjectOptions = if options.is_object() { with_js_error!(serde_wasm_bindgen::from_value(options))? } else { Default::default() }; - let state_transition_json_string = utils::stringify(&state_transition_object)?; - let raw_state_transition: JsonValue = - serde_json::from_str(&state_transition_json_string).map_err(|e| e.to_string())?; + let raw_state_transition: JsonValue = state_transition_object.with_serde_to_json_value()?; let result = self .0 @@ -147,20 +145,7 @@ impl StateTransitionFactoryWasm { ) .await; - match result { - Ok(state_transition) => Ok(StateTransitionWasm::from(state_transition)), - Err(dpp::ProtocolError::StateTransitionError(e)) => match e { - StateTransitionError::InvalidStateTransitionError { - errors, - raw_state_transition, - } => Err(InvalidStateTransitionError::new( - errors, - serde_wasm_bindgen::to_value(&raw_state_transition)?, - ) - .into()), - }, - Err(other) => Err(from_dpp_err(other)), - } + Self::state_transition_wasm_from_factory_result(result) } #[wasm_bindgen(js_name=createFromBuffer)] @@ -168,7 +153,7 @@ impl StateTransitionFactoryWasm { &self, buffer: Vec, options: JsValue, - ) -> Result { + ) -> Result { let options: FromObjectOptions = if options.is_object() { with_js_error!(serde_wasm_bindgen::from_value(options))? } else { @@ -185,8 +170,34 @@ impl StateTransitionFactoryWasm { ) .await; + Self::state_transition_wasm_from_factory_result(result) + } + + fn state_transition_wasm_from_factory_result( + result: Result, + ) -> Result { match result { - Ok(state_transition) => Ok(StateTransitionWasm::from(state_transition)), + Ok(state_transition) => match state_transition { + StateTransition::DataContractCreate(st) => { + Ok(DataContractCreateTransitionWasm::from(st).into()) + } + StateTransition::DataContractUpdate(st) => { + Ok(DataContractUpdateTransitionWasm::from(st).into()) + } + StateTransition::IdentityCreate(st) => { + Ok(IdentityCreateTransitionWasm::from(st).into()) + } + StateTransition::IdentityUpdate(st) => { + Ok(IdentityUpdateTransitionWasm::from(st).into()) + } + StateTransition::IdentityTopUp(st) => { + Ok(IdentityTopUpTransitionWasm::from(st).into()) + } + StateTransition::DocumentsBatch(st) => { + Ok(DocumentsBatchTransitionWASM::from(st).into()) + } + _ => Err("Unsupported state transition type".into()), + }, Err(dpp::ProtocolError::StateTransitionError(e)) => match e { StateTransitionError::InvalidStateTransitionError { errors, diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js index ff1ade648e8..b87882fefb3 100644 --- a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js @@ -79,23 +79,23 @@ describe('StateTransitionFactory', function main() { it('should return new State Transition with data from passed object', async () => { const result = await factory.createFromObject(rawStateTransition); - expect(result).to.equal(stateTransition); + expect(result.toObject()).to.deep.equal(stateTransition.toObject()); }); it('should return new State Transition without validation if "skipValidation" option is passed', async () => { const result = await factory.createFromObject(rawStateTransition, { skipValidation: true }); - expect(result).to.equal(stateTransition); + expect(result.toObject()).to.deep.equal(stateTransition.toObject()); }); }); - describe('createFromBuffer', () => { + describe.skip('createFromBuffer', () => { let serializedStateTransition; it('should return new State Transition from serialized contract', async () => { const result = await factory.createFromBuffer(serializedStateTransition); - expect(result).to.equal(stateTransition); + expect(result.toObject()).to.deep.equal(stateTransition.toObject()); }); }); }); From 87c6247e326091cc2e1436afe95e6763a240e250 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 8 Mar 2023 11:15:02 +0500 Subject: [PATCH 26/35] chore: fix --- .../unit/stateTransition/StateTransitionFactory.spec.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js index b87882fefb3..29126f3b11e 100644 --- a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js @@ -89,11 +89,9 @@ describe('StateTransitionFactory', function main() { }); }); - describe.skip('createFromBuffer', () => { - let serializedStateTransition; - + describe('createFromBuffer', () => { it('should return new State Transition from serialized contract', async () => { - const result = await factory.createFromBuffer(serializedStateTransition); + const result = await factory.createFromBuffer(stateTransition.toBuffer()); expect(result.toObject()).to.deep.equal(stateTransition.toObject()); }); From 41c66f020c1373a911d08cd7b47d9a63b856fe2d Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 8 Mar 2023 17:06:10 +0500 Subject: [PATCH 27/35] chore: remove StateTransitionWasm --- packages/wasm-dpp/src/state_transition/mod.rs | 168 ------------------ .../state_transition_factory.rs | 2 +- 2 files changed, 1 insertion(+), 169 deletions(-) diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index cf59e2a7d39..0d955790539 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -81,177 +81,9 @@ impl StateTransitionExecutionContextWasm { } } -macro_rules! either_st { - ($value:expr, $pattern:pat => $result:expr) => { - match $value { - StateTransition::DataContractCreate($pattern) => $result, - StateTransition::DataContractUpdate($pattern) => $result, - StateTransition::DocumentsBatch($pattern) => $result, - StateTransition::IdentityCreate($pattern) => $result, - StateTransition::IdentityTopUp($pattern) => $result, - StateTransition::IdentityCreditWithdrawal($pattern) => $result, - StateTransition::IdentityUpdate($pattern) => $result, - } - }; -} - #[derive(Deserialize, Default)] #[serde(rename_all = "camelCase")] struct AbstractStateTransitionOptions { skip_signature: Option, skip_identifiers_conversion: Option, } - -#[wasm_bindgen(js_name = AbstractStateTransition)] -pub struct StateTransitionWasm { - inner: StateTransition, - bls_adapter: Arc, -} - -#[wasm_bindgen(js_class = AbstractStateTransition)] -impl StateTransitionWasm { - #[wasm_bindgen(js_name = getProtocolVersion)] - pub fn get_protocol_version(&self) -> u32 { - either_st!(&self.inner, st => st.get_protocol_version()) - } - - #[wasm_bindgen(js_name = getType)] - pub fn get_type(&self) -> u8 { - either_st!(&self.inner, st => st.get_type().into()) - } - - #[wasm_bindgen(js_name = getSignature)] - pub fn get_signature(&self) -> Buffer { - either_st!(&self.inner, st => Buffer::from_bytes(st.get_signature())) - } - - #[wasm_bindgen(js_name = setSignature)] - pub fn set_signature(&mut self, signature: Vec) { - let inner = &mut self.inner; - either_st!(inner, st => st.set_signature(signature)) - } - - #[wasm_bindgen(js_name = toObject)] - pub fn to_object(&self, options: JsValue) -> Result { - let _options: AbstractStateTransitionOptions = if options.is_object() { - with_js_error!(serde_wasm_bindgen::from_value(options))? - } else { - Default::default() - }; - - let serializer = serde_wasm_bindgen::Serializer::json_compatible(); - - either_st!(&self.inner, _ => { - self.inner.serialize(&serializer).map_err(|e| e.into()) - }) - } - - #[wasm_bindgen(js_name = getOwnerId)] - pub fn get_owner_id(&self) -> IdentifierWrapper { - either_st!(&self.inner, st => (*st.get_owner_id()).into()) - } - - #[wasm_bindgen(js_name = toJSON)] - pub fn to_json(&self, options: JsValue) -> Result { - let options: AbstractStateTransitionOptions = if options.is_object() { - with_js_error!(serde_wasm_bindgen::from_value(options))? - } else { - Default::default() - }; - - either_st!(&self.inner, st => { - let json_value = st - .to_json(options.skip_signature.unwrap_or_default()) - .map_err(from_dpp_err)?; - - serde_wasm_bindgen::to_value(&json_value).map_err(|e| e.into()) - }) - } - - #[wasm_bindgen(js_name = toBuffer)] - pub fn to_buffer(&self, options: JsValue) -> Result { - let options: AbstractStateTransitionOptions = if options.is_object() { - with_js_error!(serde_wasm_bindgen::from_value(options))? - } else { - Default::default() - }; - - either_st!(&self.inner, st => st.to_buffer(options.skip_signature.unwrap_or_default()).map(|v| Buffer::from_bytes(&v)).map_err(from_dpp_err)) - } - - #[wasm_bindgen(js_name = hash)] - pub fn hash(&self, options: JsValue) -> Result { - let options: AbstractStateTransitionOptions = if options.is_object() { - with_js_error!(serde_wasm_bindgen::from_value(options))? - } else { - Default::default() - }; - - either_st!(&self.inner, st => st.hash(options.skip_signature.unwrap_or_default()).map(|v| Buffer::from_bytes(&v)).map_err(from_dpp_err)) - } - - #[wasm_bindgen(js_name = signByPrivateKey)] - pub fn sign_by_private_key( - &mut self, - private_key: Vec, - key_type: u8, - ) -> Result<(), JsValue> { - let inner = &mut self.inner; - either_st!(inner, st => st - .sign_by_private_key( - &private_key, - KeyType::try_from(key_type).map_err(|e| e.to_string())?, - self.bls_adapter.as_ref(), - ) - .map_err(from_dpp_err)) - } - - #[wasm_bindgen(js_name = verifyByPublicKey)] - pub fn verify_by_public_key(&self, public_key: Vec, key_type: u8) -> Result { - either_st!(&self.inner, st => st - .verify_by_public_key( - &public_key, - KeyType::try_from(key_type).map_err(|e| e.to_string())?, - self.bls_adapter.as_ref()).map(|_| true).map_err(from_dpp_err)) - } - - #[wasm_bindgen(js_name = getModifiedDataIds)] - pub fn get_modified_data_ids(&self) -> Vec { - either_st!(&self.inner, st => st.get_modified_data_ids().into_iter().map(|id| >::from(id).into()).collect()) - } - - #[wasm_bindgen(js_name = isDocumentStateTransition)] - pub fn is_document_state_transition(&self) -> bool { - either_st!(&self.inner, st => st.is_document_state_transition()) - } - - #[wasm_bindgen(js_name = isDataContractStateTransition)] - pub fn is_data_contract_state_transition(&self) -> bool { - either_st!(&self.inner, st => st.is_data_contract_state_transition()) - } - - #[wasm_bindgen(js_name = isIdentityStateTransition)] - pub fn is_identity_state_transition(&self) -> bool { - either_st!(&self.inner, st => st.is_identity_state_transition()) - } - - #[wasm_bindgen(js_name = setExecutionContext)] - pub fn set_execution_context( - &mut self, - execution_context: StateTransitionExecutionContextWasm, - ) { - let inner = &mut self.inner; - either_st!(inner, st => st.set_execution_context(execution_context.into())) - } - - #[wasm_bindgen(js_name = getExecutionContext)] - pub fn get_execution_context(&self) -> StateTransitionExecutionContextWasm { - either_st!(&self.inner, st => st.get_execution_context().into()) - } -} - -impl From for StateTransitionWasm { - fn from(value: StateTransition) -> Self { - value.into() - } -} diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index cdf9c0abb3c..8cfca68e66f 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -20,7 +20,7 @@ use crate::{ state_transition::errors::invalid_state_transition_error::InvalidStateTransitionError, utils, with_js_error, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, DocumentsBatchTransitionWASM, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, - IdentityUpdateTransitionWasm, StateTransitionWasm, + IdentityUpdateTransitionWasm, }; #[wasm_bindgen(js_name = StateTransitionFactory)] From ffe7695a7073ca15b407d24a201659656e3b6f5c Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 8 Mar 2023 17:07:47 +0500 Subject: [PATCH 28/35] chore: remove unused code --- packages/wasm-dpp/src/state_transition/mod.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 0d955790539..cd15b63117a 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -80,10 +80,3 @@ impl StateTransitionExecutionContextWasm { self.0.disable_dry_run(); } } - -#[derive(Deserialize, Default)] -#[serde(rename_all = "camelCase")] -struct AbstractStateTransitionOptions { - skip_signature: Option, - skip_identifiers_conversion: Option, -} From 9b2eccd8b7e9858a059c89a99babe98462e117d0 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Wed, 8 Mar 2023 15:28:40 +0000 Subject: [PATCH 29/35] fix(dpp): inconsistencies after merge --- ...e_data_contract_update_transition_basic.rs | 2 + ...lidate_documents_batch_transition_basic.rs | 130 +++++++----------- packages/rs-dpp/src/errors/errors.rs | 3 +- .../rs-dpp/src/state_transition/errors/mod.rs | 2 + ...ransition.rs => state_transition_error.rs} | 0 packages/rs-dpp/src/state_transition/mod.rs | 1 - .../validate_state_transition_basic.rs | 11 +- ...lidate_documents_batch_transition_basic.rs | 3 +- packages/wasm-dpp/src/state_transition/mod.rs | 1 + 9 files changed, 63 insertions(+), 90 deletions(-) rename packages/rs-dpp/src/state_transition/errors/{state_transition.rs => state_transition_error.rs} (100%) diff --git a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs index 8ea260c6373..bfb96411b34 100644 --- a/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs +++ b/packages/rs-dpp/src/data_contract/state_transition/data_contract_update_transition/validation/basic/validate_data_contract_update_transition_basic.rs @@ -7,6 +7,7 @@ use crate::consensus::basic::decode::ProtocolVersionParsingError; use crate::consensus::basic::invalid_data_contract_version_error::InvalidDataContractVersionError; use crate::consensus::ConsensusError; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use crate::validation::AsyncDataValidatorWithContext; use crate::{ consensus::basic::BasicError, data_contract::{ @@ -22,6 +23,7 @@ use crate::{ }; use anyhow::anyhow; use anyhow::Context; +use async_trait::async_trait; use json_patch::PatchOperation; use lazy_static::lazy_static; use serde_json::{json, Value as JsonValue}; diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index e3e93a4d9c9..6997521a029 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -85,14 +85,44 @@ where raw_state_transition: &JsonValue, execution_context: &StateTransitionExecutionContext, ) -> Result, ProtocolError> { - let mut result = ValidationResult::default(); - let validator = JsonSchemaValidator::new(DOCUMENTS_BATCH_TRANSITIONS_SCHEMA.clone()) - .map_err(|e| { - anyhow!( - "unable to compile the batch transitions schema: {}", - e.to_string() - ) - })?; + // TODO: move validation code into function body to avoid cloning of state_repository + validate_documents_batch_transition_basic( + &self.protocol_version_validator, + raw_state_transition, + self.state_repository.clone(), + execution_context, + ) + .await + } +} + +pub async fn validate_documents_batch_transition_basic( + protocol_version_validator: &ProtocolVersionValidator, + raw_state_transition: &JsonValue, + state_repository: Arc, + execution_context: &StateTransitionExecutionContext, +) -> Result, ProtocolError> { + let mut result = ValidationResult::default(); + let validator = + JsonSchemaValidator::new(DOCUMENTS_BATCH_TRANSITIONS_SCHEMA.clone()).map_err(|e| { + anyhow!( + "unable to compile the batch transitions schema: {}", + e.to_string() + ) + })?; + + let validation_result = validator.validate(raw_state_transition)?; + result.merge(validation_result); + if !result.is_valid() { + return Ok(result); + } + + let protocol_version = raw_state_transition.get_u64("protocolVersion")? as u32; + let validation_result = protocol_version_validator.validate(protocol_version)?; + result.merge(validation_result); + if !result.is_valid() { + return Ok(result); + } let raw_document_transitions = raw_state_transition .get("transitions") @@ -145,82 +175,22 @@ where return Ok(result); } - let protocol_version = raw_state_transition.get_u64("protocolVersion")? as u32; - let validation_result = self.protocol_version_validator.validate(protocol_version)?; - result.merge(validation_result); - if !result.is_valid() { - return Ok(result); - } - - let raw_document_transitions = raw_state_transition - .get("transitions") - .ok_or_else(|| anyhow!("transitions property doesn't exist"))? - .as_array() - .ok_or_else(|| anyhow!("transitions property isn't an array"))?; - let mut document_transitions_by_contracts: HashMap> = - HashMap::new(); - - for raw_document_transition in raw_document_transitions { - let data_contract_id_bytes = match raw_document_transition.get_bytes("$dataContractId") - { - Err(_) => { - result.add_error(BasicError::MissingDataContractIdError); - continue; - } - Ok(id) => id, - }; - - let identifier = match Identifier::from_bytes(&data_contract_id_bytes) { - Ok(identifier) => identifier, - Err(e) => { - result.add_error(BasicError::InvalidIdentifierError { - identifier_name: String::from("$dataContractId"), - error: e.to_string(), - }); - continue; - } - }; - - match document_transitions_by_contracts.entry(identifier) { - Entry::Vacant(vacant) => { - vacant.insert(vec![raw_document_transition]); - } - Entry::Occupied(mut identifiers) => { - identifiers.get_mut().push(raw_document_transition); - } - }; - } - - for (data_contract_id, transitions) in document_transitions_by_contracts { - let maybe_data_contract = self - .state_repository - .fetch_data_contract(&data_contract_id, execution_context) - .await? - .map(TryInto::try_into) - .transpose() - .map_err(Into::into)?; - - if execution_context.is_dry_run() { - return Ok(result); + let data_contract = match maybe_data_contract { + None => { + result.add_error(BasicError::DataContractNotPresent { data_contract_id }); + continue; } + Some(data_contract) => data_contract, + }; - let data_contract = match maybe_data_contract { - None => { - result.add_error(BasicError::DataContractNotPresent { data_contract_id }); - continue; - } - Some(data_contract) => data_contract, - }; - - let owner_id = Identifier::from_bytes(&raw_state_transition.get_bytes("ownerId")?)?; - - let validation_result = - validate_document_transitions(&data_contract, &owner_id, transitions)?; - result.merge(validation_result); - } + let owner_id = Identifier::from_bytes(&raw_state_transition.get_bytes("ownerId")?)?; - Ok(result) + let validation_result = + validate_document_transitions(&data_contract, &owner_id, transitions)?; + result.merge(validation_result); } + + Ok(result) } fn validate_document_transitions<'a>( diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index ed4de0de236..7f5b6f796d7 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -10,7 +10,8 @@ use crate::data_contract::state_transition::errors::PublicKeyIsDisabledError; use crate::document::errors::*; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, InvalidSignaturePublicKeyError, PublicKeyMismatchError, - PublicKeySecurityLevelNotMetError, StateTransitionIsNotSignedError, WrongPublicKeyPurposeError, + PublicKeySecurityLevelNotMetError, StateTransitionError, StateTransitionIsNotSignedError, + WrongPublicKeyPurposeError, }; use crate::{CompatibleProtocolVersionIsNotDefinedError, NonConsensusError, SerdeParsingError}; use platform_value::Error as ValueError; diff --git a/packages/rs-dpp/src/state_transition/errors/mod.rs b/packages/rs-dpp/src/state_transition/errors/mod.rs index ab7d02480ad..8ff49c909e4 100644 --- a/packages/rs-dpp/src/state_transition/errors/mod.rs +++ b/packages/rs-dpp/src/state_transition/errors/mod.rs @@ -2,6 +2,7 @@ mod invalid_identity_public_key_type_error; mod invalid_signature_public_key_error; mod public_key_mismatch_error; mod public_key_security_level_not_met_error; +mod state_transition_error; mod state_transition_is_not_signed_error; mod wrong_public_key_purpose_error; @@ -9,5 +10,6 @@ pub use invalid_identity_public_key_type_error::*; pub use invalid_signature_public_key_error::*; pub use public_key_mismatch_error::*; pub use public_key_security_level_not_met_error::*; +pub use state_transition_error::*; pub use state_transition_is_not_signed_error::*; pub use wrong_public_key_purpose_error::*; diff --git a/packages/rs-dpp/src/state_transition/errors/state_transition.rs b/packages/rs-dpp/src/state_transition/errors/state_transition_error.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/errors/state_transition.rs rename to packages/rs-dpp/src/state_transition/errors/state_transition_error.rs diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 4fe80411090..8f6868d70d2 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -29,7 +29,6 @@ pub mod errors; pub mod fee; pub mod state_transition_execution_context; -pub mod errors; mod example; macro_rules! call_method { ($state_transition:expr, $method:ident, $args:tt ) => { 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 25a5d01bb1e..955797b79bc 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 @@ -72,9 +72,7 @@ where result.add_error( ConsensusError::BasicError( Box::new( - BasicError::InvalidStateTransitionTypeError { - transition_type: state_transition_type - } + BasicError::InvalidStateTransitionTypeError(InvalidStateTransitionTypeError::new(state_transition_type)) ) ) ); @@ -106,10 +104,9 @@ where payload, }) = state_transition.to_buffer(false) { - result.add_error(BasicError::StateTransitionMaxSizeExceededError { - actual_size_kbytes: payload.len() / 1024, - max_size_kbytes, - }); + result.add_error(BasicError::StateTransitionMaxSizeExceededError( + StateTransitionMaxSizeExceededError::new(payload.len() / 1024, max_size_kbytes), + )); } Ok(result) diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs index 999a8404d57..33be4d4fb7a 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs @@ -1,4 +1,5 @@ use dpp::document::validation::basic::validate_documents_batch_transition_basic; +use std::sync::Arc; use wasm_bindgen::prelude::*; use crate::{ @@ -23,7 +24,7 @@ pub async fn validate_documents_batch_transition_basic_wasm( validate_documents_batch_transition_basic::validate_documents_batch_transition_basic( &protocol_version_validator.into(), &raw_state_transition, - &wrapped_state_repository, + Arc::new(wrapped_state_repository), &execution_context.into(), ) .await diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index 330fba8c227..e3a31b15963 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -20,6 +20,7 @@ pub mod errors; pub mod state_transition_factory; pub mod validation; +use crate::utils::Inner; pub use validation::*; pub(crate) mod conversion; From 419b49f85582d14585e90b756ce67c40f89958ef Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Thu, 9 Mar 2023 14:50:40 +0500 Subject: [PATCH 30/35] chore: linter fix --- .../test/unit/stateTransition/StateTransitionFactory.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js index b87882fefb3..92631796180 100644 --- a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js @@ -15,11 +15,11 @@ describe('StateTransitionFactory', function main() { let rawStateTransition; let stateRepositoryMock; let StateTransitionFactory; + let DataContractCreateTransition; before(async () => { ({ DataContractCreateTransition, StateTransitionFactory, - UnsupportedProtocolVersionError, SerializedObjectParsingError, } = await loadWasmDpp()); }); From c15a66284da62d8ce02ba1104e7214a936604ad6 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Thu, 9 Mar 2023 15:27:28 +0500 Subject: [PATCH 31/35] chore: cargo fmt --- packages/wasm-dpp/src/errors/from.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/src/errors/from.rs b/packages/wasm-dpp/src/errors/from.rs index c6c2de04015..8736681a46d 100644 --- a/packages/wasm-dpp/src/errors/from.rs +++ b/packages/wasm-dpp/src/errors/from.rs @@ -1,5 +1,5 @@ -use dpp::DashPlatformProtocolInitError; use dpp::data_contract::errors::DataContractNotPresentError; +use dpp::DashPlatformProtocolInitError; use wasm_bindgen::JsValue; From 0d4580c081cfac55ee77382911e7064e57b1a121 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Thu, 9 Mar 2023 16:45:31 +0000 Subject: [PATCH 32/35] chore(wasm-dpp): clippy --- .../data_contract_create_transition/mod.rs | 1 - .../data_contract_update_transition/mod.rs | 1 - packages/wasm-dpp/src/errors/from.rs | 1 - .../errors/invalid_state_transition_error.rs | 2 +- packages/wasm-dpp/src/state_transition/mod.rs | 18 ++---------------- .../state_transition_factory.rs | 16 ++++++++-------- 6 files changed, 11 insertions(+), 28 deletions(-) diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs index eff61ab49c6..ebb3605e5bb 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_create_transition/mod.rs @@ -6,7 +6,6 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; -use dpp::identity::KeyID; use dpp::{ data_contract::state_transition::data_contract_create_transition::DataContractCreateTransition, state_transition::{ diff --git a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs index efc4fb24bbe..4d0e0cf8db0 100644 --- a/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs +++ b/packages/wasm-dpp/src/data_contract/state_transition/data_contract_update_transition/mod.rs @@ -6,7 +6,6 @@ use std::collections::HashMap; pub use apply::*; pub use validation::*; -use dpp::identity::KeyID; use dpp::{ data_contract::state_transition::data_contract_update_transition::DataContractUpdateTransition, state_transition::{ diff --git a/packages/wasm-dpp/src/errors/from.rs b/packages/wasm-dpp/src/errors/from.rs index 8736681a46d..aecfa000d2e 100644 --- a/packages/wasm-dpp/src/errors/from.rs +++ b/packages/wasm-dpp/src/errors/from.rs @@ -1,4 +1,3 @@ -use dpp::data_contract::errors::DataContractNotPresentError; use dpp::DashPlatformProtocolInitError; use wasm_bindgen::JsValue; diff --git a/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs b/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs index e1224b15f70..522da8cf4bc 100644 --- a/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs +++ b/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs @@ -1,4 +1,4 @@ -use dpp::{consensus::ConsensusError, identity::errors}; +use dpp::consensus::ConsensusError; use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; use crate::errors::consensus_error::from_consensus_error_ref; diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index e3a31b15963..bf2a695a324 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -1,20 +1,6 @@ -use std::{convert::TryFrom, sync::Arc}; - -use dpp::{ - identity::KeyType, - prelude::Identifier, - state_transition::{ - state_transition_execution_context::StateTransitionExecutionContext, StateTransition, - StateTransitionConvert, StateTransitionIdentitySigned, StateTransitionLike, - }, -}; -use serde::{Deserialize, Serialize}; -use wasm_bindgen::prelude::*; +use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; -use crate::{ - bls_adapter::BlsAdapter, buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper, - with_js_error, -}; +use wasm_bindgen::prelude::*; pub mod errors; pub mod state_transition_factory; diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index 8cfca68e66f..ef2389344cc 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -8,7 +8,7 @@ use dpp::{state_transition::{ validate_state_transition_by_type::StateTransitionByTypeValidator, }, StateTransitionFactory, StateTransitionFactoryOptions, StateTransition, errors::StateTransitionError, -}, version::ProtocolVersionValidator, data_contract::state_transition::{data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator, self}, identity::{state_transition::{identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, validate_public_key_signatures::{PublicKeysSignaturesValidator, TPublicKeysSignaturesValidator}, asset_lock_proof::{AssetLockProofValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator, AssetLockTransactionValidator}, identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic}, validation::PublicKeysValidator}, document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, ProtocolError}; +}, version::ProtocolVersionValidator, data_contract::state_transition::{data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator, data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator}, identity::{state_transition::{identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator, validate_public_key_signatures::{PublicKeysSignaturesValidator}, asset_lock_proof::{AssetLockProofValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator, AssetLockTransactionValidator}, identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator, identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator, identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic}, validation::PublicKeysValidator}, document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator, ProtocolError}; use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; use crate::utils::ToSerdeJSONExt; @@ -18,7 +18,7 @@ use crate::{ identity_facade::FromObjectOptions, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, state_transition::errors::invalid_state_transition_error::InvalidStateTransitionError, - utils, with_js_error, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, + with_js_error, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, DocumentsBatchTransitionWASM, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, IdentityUpdateTransitionWasm, }; @@ -67,7 +67,7 @@ impl StateTransitionFactoryWasm { .map_err(from_dpp_init_error)?, ChainAssetLockProofStructureValidator::new( state_repository_wrapper.clone(), - asset_lock_tx_validator.clone(), + asset_lock_tx_validator, ) .map_err(from_dpp_init_error)?, )); @@ -91,19 +91,19 @@ impl StateTransitionFactoryWasm { pk_validator.clone(), pk_validator.clone(), asset_lock_validator.clone(), - adapter.clone(), + adapter, pk_sig_validator.clone(), ) .map_err(from_dpp_init_error)?, ValidateIdentityUpdateTransitionBasic::new( ProtocolVersionValidator::default(), - pk_validator.clone(), - pk_sig_validator.clone(), + pk_validator, + pk_sig_validator, ) .map_err(from_dpp_err)?, IdentityTopUpTransitionBasicValidator::new( ProtocolVersionValidator::default(), - asset_lock_validator.clone(), + asset_lock_validator, ) .map_err(from_dpp_init_error)?, IdentityCreditWithdrawalTransitionBasicValidator::new( @@ -111,7 +111,7 @@ impl StateTransitionFactoryWasm { ) .map_err(from_dpp_init_error)?, DocumentBatchTransitionBasicValidator::new( - state_repository_wrapper.clone(), + state_repository_wrapper, protocol_version_validator.clone(), ), ), From ad755016a5f63a4822110a5673532ec161c0b84d Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 14 Mar 2023 16:46:32 +0500 Subject: [PATCH 33/35] chore: rename error --- .../errors/invalid_state_transition_error.rs | 6 +++--- .../src/state_transition/state_transition_factory.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs b/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs index 522da8cf4bc..ebf1fb6d59e 100644 --- a/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs +++ b/packages/wasm-dpp/src/state_transition/errors/invalid_state_transition_error.rs @@ -4,12 +4,12 @@ use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; use crate::errors::consensus_error::from_consensus_error_ref; #[wasm_bindgen(js_name = InvalidStateTransitionError)] -pub struct InvalidStateTransitionError { +pub struct InvalidStateTransitionErrorWasm { errors: Vec, raw_state_transition: JsValue, } -impl InvalidStateTransitionError { +impl InvalidStateTransitionErrorWasm { pub fn new(errors: Vec, raw_state_transition: JsValue) -> Self { Self { errors, @@ -19,7 +19,7 @@ impl InvalidStateTransitionError { } #[wasm_bindgen(js_class = InvalidStateTransitionError)] -impl InvalidStateTransitionError { +impl InvalidStateTransitionErrorWasm { #[wasm_bindgen(js_name = getErrors)] pub fn get_errors(&self) -> Vec { self.errors.iter().map(from_consensus_error_ref).collect() diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index ef2389344cc..7df0c38d751 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -17,7 +17,7 @@ use crate::{ errors::{from_dpp_err, from_dpp_init_error}, identity_facade::FromObjectOptions, state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, - state_transition::errors::invalid_state_transition_error::InvalidStateTransitionError, + state_transition::errors::invalid_state_transition_error::InvalidStateTransitionErrorWasm, with_js_error, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, DocumentsBatchTransitionWASM, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, IdentityUpdateTransitionWasm, @@ -202,7 +202,7 @@ impl StateTransitionFactoryWasm { StateTransitionError::InvalidStateTransitionError { errors, raw_state_transition, - } => Err(InvalidStateTransitionError::new( + } => Err(InvalidStateTransitionErrorWasm::new( errors, serde_wasm_bindgen::to_value(&raw_state_transition)?, ) From 109956aa957d02979c552b73f83c90276a78d6f1 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 14 Mar 2023 17:46:02 +0500 Subject: [PATCH 34/35] chore: add tests --- .../StateTransitionFactory.spec.js | 67 +++++++++++-------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js index f030fa0d35f..d6f1265bdd3 100644 --- a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js @@ -19,7 +19,10 @@ describe('StateTransitionFactory', function main() { before(async () => { ({ - DataContractCreateTransition, StateTransitionFactory, + DataContractCreateTransition, + StateTransitionFactory, + InvalidStateTransitionError, + MissingStateTransitionTypeError, } = await loadWasmDpp()); }); @@ -39,34 +42,6 @@ describe('StateTransitionFactory', function main() { stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); - stateRepositoryMock.fetchDataContract.resolves(dataContract); - stateRepositoryMock.createDataContract.resolves(); - stateRepositoryMock.updateDataContract.resolves(); - stateRepositoryMock.fetchDocuments.resolves(); - stateRepositoryMock.createDocument.resolves(); - stateRepositoryMock.updateDocument.resolves(); - stateRepositoryMock.removeDocument.resolves(); - stateRepositoryMock.fetchTransaction.resolves(); - stateRepositoryMock.fetchIdentity.resolves(); - stateRepositoryMock.createIdentity.resolves(); - stateRepositoryMock.addKeysToIdentity.resolves(); - stateRepositoryMock.disableIdentityKeys.resolves(); - stateRepositoryMock.updateIdentityRevision.resolves(); - stateRepositoryMock.addToIdentityBalance.resolves(); - stateRepositoryMock.fetchIdentityBalance.resolves(); - stateRepositoryMock.fetchIdentityBalanceWithDebt.resolves(); - stateRepositoryMock.addToSystemCredits.resolves(); - stateRepositoryMock.fetchLatestPlatformBlockHeight.resolves(); - stateRepositoryMock.fetchLatestPlatformCoreChainLockedHeight.resolves(); - stateRepositoryMock.verifyInstantLock.resolves(); - stateRepositoryMock.markAssetLockTransactionOutPointAsUsed.resolves(); - stateRepositoryMock.verifyChainLockHeight.resolves(); - stateRepositoryMock.isAssetLockTransactionOutPointAlreadyUsed.resolves(); - stateRepositoryMock.fetchSMLStore.resolves(); - stateRepositoryMock.fetchLatestWithdrawalTransactionIndex.resolves(); - stateRepositoryMock.enqueueWithdrawalTransaction.resolves(); - stateRepositoryMock.fetchLatestPlatformBlockTime.resolves(); - const blsAdapter = await getBlsAdapterMock(); factory = new StateTransitionFactory( @@ -87,6 +62,22 @@ describe('StateTransitionFactory', function main() { expect(result.toObject()).to.deep.equal(stateTransition.toObject()); }); + + it('should throw InvalidStateTransition error in case validation failed', async () => { + rawStateTransition.type = undefined; + + let result; + try { + result = await factory.createFromObject(rawStateTransition); + expect.fail('should throw an error'); + } catch (e) { + expect(e).to.be.an.instanceOf(InvalidStateTransitionError); + + const [error] = e.getErrors(); + + expect(error).to.be.an.instanceOf(MissingStateTransitionTypeError); + } + }); }); describe('createFromBuffer', () => { @@ -95,5 +86,23 @@ describe('StateTransitionFactory', function main() { expect(result.toObject()).to.deep.equal(stateTransition.toObject()); }); + + it('should throw InvalidStateTransition error in case validation failed', async () => { + // CBOR that have invalid "type" property + const stateTransitionHex = "01a56c64617461436f6e7472616374a66f70726f746f636f6c56657273696f6e0163246964982018a318b611186f184718781848187d186318441830182c185518fe18e318ff188b18eb185918490218ac1831187b1873184a182c18d9189b1886182418bf6724736368656d61783468747470733a2f2f736368656d612e646173682e6f72672f6470702d302d342d302f6d6574612f646174612d636f6e74726163746776657273696f6e01676f776e657249649820187618a6185c189e18651833183d18aa02189e0d18a61869182818c107183e188908184f183818d018220418c01839161860187418ae18dd189969646f63756d656e7473a76f696e6465786564446f63756d656e74a56474797065666f626a65637467696e646963657386a3646e616d6566696e646578316a70726f7065727469657382a168246f776e6572496463617363a16966697273744e616d656361736366756e69717565f5a3646e616d6566696e646578326a70726f7065727469657382a168246f776e6572496463617363a1686c6173744e616d656361736366756e69717565f5a3646e616d6566696e646578336a70726f7065727469657381a1686c6173744e616d656361736366756e69717565f4a2646e616d6566696e646578346a70726f7065727469657382a16a2463726561746564417463617363a16a2475706461746564417463617363a2646e616d6566696e646578356a70726f7065727469657381a16a2475706461746564417463617363a2646e616d6566696e646578366a70726f7065727469657381a16a24637265617465644174636173636a70726f70657274696573a36966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f6d6f7468657250726f7065727479a2647479706566737472696e67696d61784c656e677468182a687265717569726564846966697273744e616d656a246372656174656441746a24757064617465644174686c6173744e616d65746164646974696f6e616c50726f70657274696573f46c6e696365446f63756d656e74a46474797065666f626a6563746a70726f70657274696573a1646e616d65a1647479706566737472696e67687265717569726564816a24637265617465644174746164646974696f6e616c50726f70657274696573f46e6e6f54696d65446f63756d656e74a36474797065666f626a6563746a70726f70657274696573a1646e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f4781d6f7074696f6e616c556e69717565496e6465786564446f63756d656e74a56474797065666f626a6563746a70726f70657274696573a46966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f67636f756e747279a2647479706566737472696e67696d61784c656e677468183f6463697479a2647479706566737472696e67696d61784c656e677468183f67696e646963657383a3646e616d6566696e646578316a70726f7065727469657381a16966697273744e616d656361736366756e69717565f5a3646e616d6566696e646578326a70726f7065727469657383a168246f776e6572496463617363a16966697273744e616d6563617363a1686c6173744e616d656361736366756e69717565f5a3646e616d6566696e646578336a70726f7065727469657382a167636f756e74727963617363a164636974796361736366756e69717565f5687265717569726564826966697273744e616d65686c6173744e616d65746164646974696f6e616c50726f70657274696573f46e707265747479446f63756d656e74a46474797065666f626a6563746a70726f70657274696573a1686c6173744e616d65a1647479706566737472696e6768726571756972656482686c6173744e616d656a24757064617465644174746164646974696f6e616c50726f70657274696573f46b756e697175654461746573a56474797065666f626a65637467696e646963657382a3646e616d6566696e646578316a70726f7065727469657382a16a2463726561746564417463617363a16a247570646174656441746361736366756e69717565f5a2646e616d6566696e646578326a70726f7065727469657381a16a24757064617465644174636173636a70726f70657274696573a26966697273744e616d65a1647479706566737472696e67686c6173744e616d65a1647479706566737472696e67687265717569726564836966697273744e616d656a246372656174656441746a24757064617465644174746164646974696f6e616c50726f70657274696573f46e7769746842797465417272617973a56474797065666f626a65637467696e646963657381a2646e616d6566696e646578316a70726f7065727469657381a16e6279746541727261794669656c64636173636a70726f70657274696573a26e6279746541727261794669656c64a3647479706565617272617969627974654172726179f5686d61784974656d73106f6964656e7469666965724669656c64a5647479706565617272617969627974654172726179f570636f6e74656e744d656469615479706578216170706c69636174696f6e2f782e646173682e6470702e6964656e746966696572686d696e4974656d731820686d61784974656d731820687265717569726564816e6279746541727261794669656c64746164646974696f6e616c50726f70657274696573f464747970652267656e74726f70799820189618d10418b2071882188e188818fc18b7189818dd185c18811881189b1867187912183d184d187118ff1866181d185f1839188718ea1824185113747369676e61747572655075626c69634b6579496400697369676e617475726598410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const stateTransitionBuffer = Buffer.from(stateTransitionHex, 'hex'); + + let result; + try { + result = await factory.createFromBuffer(stateTransitionBuffer); + expect.fail('should throw an error'); + } catch (e) { + expect(e).to.be.an.instanceOf(InvalidStateTransitionError); + + const [error] = e.getErrors(); + + expect(error).to.be.an.instanceOf(MissingStateTransitionTypeError); + } + }); }); }); From 9179400efc96078cf90ddfad722df5ae198d9b78 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Tue, 14 Mar 2023 17:47:49 +0500 Subject: [PATCH 35/35] chore: linter fix --- .../stateTransition/StateTransitionFactory.spec.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js index d6f1265bdd3..b12036924b0 100644 --- a/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js +++ b/packages/wasm-dpp/test/unit/stateTransition/StateTransitionFactory.spec.js @@ -16,6 +16,8 @@ describe('StateTransitionFactory', function main() { let stateRepositoryMock; let StateTransitionFactory; let DataContractCreateTransition; + let InvalidStateTransitionError; + let MissingStateTransitionTypeError; before(async () => { ({ @@ -66,9 +68,8 @@ describe('StateTransitionFactory', function main() { it('should throw InvalidStateTransition error in case validation failed', async () => { rawStateTransition.type = undefined; - let result; try { - result = await factory.createFromObject(rawStateTransition); + await factory.createFromObject(rawStateTransition); expect.fail('should throw an error'); } catch (e) { expect(e).to.be.an.instanceOf(InvalidStateTransitionError); @@ -89,12 +90,11 @@ describe('StateTransitionFactory', function main() { it('should throw InvalidStateTransition error in case validation failed', async () => { // CBOR that have invalid "type" property - const stateTransitionHex = "01a56c64617461436f6e7472616374a66f70726f746f636f6c56657273696f6e0163246964982018a318b611186f184718781848187d186318441830182c185518fe18e318ff188b18eb185918490218ac1831187b1873184a182c18d9189b1886182418bf6724736368656d61783468747470733a2f2f736368656d612e646173682e6f72672f6470702d302d342d302f6d6574612f646174612d636f6e74726163746776657273696f6e01676f776e657249649820187618a6185c189e18651833183d18aa02189e0d18a61869182818c107183e188908184f183818d018220418c01839161860187418ae18dd189969646f63756d656e7473a76f696e6465786564446f63756d656e74a56474797065666f626a65637467696e646963657386a3646e616d6566696e646578316a70726f7065727469657382a168246f776e6572496463617363a16966697273744e616d656361736366756e69717565f5a3646e616d6566696e646578326a70726f7065727469657382a168246f776e6572496463617363a1686c6173744e616d656361736366756e69717565f5a3646e616d6566696e646578336a70726f7065727469657381a1686c6173744e616d656361736366756e69717565f4a2646e616d6566696e646578346a70726f7065727469657382a16a2463726561746564417463617363a16a2475706461746564417463617363a2646e616d6566696e646578356a70726f7065727469657381a16a2475706461746564417463617363a2646e616d6566696e646578366a70726f7065727469657381a16a24637265617465644174636173636a70726f70657274696573a36966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f6d6f7468657250726f7065727479a2647479706566737472696e67696d61784c656e677468182a687265717569726564846966697273744e616d656a246372656174656441746a24757064617465644174686c6173744e616d65746164646974696f6e616c50726f70657274696573f46c6e696365446f63756d656e74a46474797065666f626a6563746a70726f70657274696573a1646e616d65a1647479706566737472696e67687265717569726564816a24637265617465644174746164646974696f6e616c50726f70657274696573f46e6e6f54696d65446f63756d656e74a36474797065666f626a6563746a70726f70657274696573a1646e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f4781d6f7074696f6e616c556e69717565496e6465786564446f63756d656e74a56474797065666f626a6563746a70726f70657274696573a46966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f67636f756e747279a2647479706566737472696e67696d61784c656e677468183f6463697479a2647479706566737472696e67696d61784c656e677468183f67696e646963657383a3646e616d6566696e646578316a70726f7065727469657381a16966697273744e616d656361736366756e69717565f5a3646e616d6566696e646578326a70726f7065727469657383a168246f776e6572496463617363a16966697273744e616d6563617363a1686c6173744e616d656361736366756e69717565f5a3646e616d6566696e646578336a70726f7065727469657382a167636f756e74727963617363a164636974796361736366756e69717565f5687265717569726564826966697273744e616d65686c6173744e616d65746164646974696f6e616c50726f70657274696573f46e707265747479446f63756d656e74a46474797065666f626a6563746a70726f70657274696573a1686c6173744e616d65a1647479706566737472696e6768726571756972656482686c6173744e616d656a24757064617465644174746164646974696f6e616c50726f70657274696573f46b756e697175654461746573a56474797065666f626a65637467696e646963657382a3646e616d6566696e646578316a70726f7065727469657382a16a2463726561746564417463617363a16a247570646174656441746361736366756e69717565f5a2646e616d6566696e646578326a70726f7065727469657381a16a24757064617465644174636173636a70726f70657274696573a26966697273744e616d65a1647479706566737472696e67686c6173744e616d65a1647479706566737472696e67687265717569726564836966697273744e616d656a246372656174656441746a24757064617465644174746164646974696f6e616c50726f70657274696573f46e7769746842797465417272617973a56474797065666f626a65637467696e646963657381a2646e616d6566696e646578316a70726f7065727469657381a16e6279746541727261794669656c64636173636a70726f70657274696573a26e6279746541727261794669656c64a3647479706565617272617969627974654172726179f5686d61784974656d73106f6964656e7469666965724669656c64a5647479706565617272617969627974654172726179f570636f6e74656e744d656469615479706578216170706c69636174696f6e2f782e646173682e6470702e6964656e746966696572686d696e4974656d731820686d61784974656d731820687265717569726564816e6279746541727261794669656c64746164646974696f6e616c50726f70657274696573f464747970652267656e74726f70799820189618d10418b2071882188e188818fc18b7189818dd185c18811881189b1867187912183d184d187118ff1866181d185f1839188718ea1824185113747369676e61747572655075626c69634b6579496400697369676e617475726598410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + const stateTransitionHex = '01a56c64617461436f6e7472616374a66f70726f746f636f6c56657273696f6e0163246964982018a318b611186f184718781848187d186318441830182c185518fe18e318ff188b18eb185918490218ac1831187b1873184a182c18d9189b1886182418bf6724736368656d61783468747470733a2f2f736368656d612e646173682e6f72672f6470702d302d342d302f6d6574612f646174612d636f6e74726163746776657273696f6e01676f776e657249649820187618a6185c189e18651833183d18aa02189e0d18a61869182818c107183e188908184f183818d018220418c01839161860187418ae18dd189969646f63756d656e7473a76f696e6465786564446f63756d656e74a56474797065666f626a65637467696e646963657386a3646e616d6566696e646578316a70726f7065727469657382a168246f776e6572496463617363a16966697273744e616d656361736366756e69717565f5a3646e616d6566696e646578326a70726f7065727469657382a168246f776e6572496463617363a1686c6173744e616d656361736366756e69717565f5a3646e616d6566696e646578336a70726f7065727469657381a1686c6173744e616d656361736366756e69717565f4a2646e616d6566696e646578346a70726f7065727469657382a16a2463726561746564417463617363a16a2475706461746564417463617363a2646e616d6566696e646578356a70726f7065727469657381a16a2475706461746564417463617363a2646e616d6566696e646578366a70726f7065727469657381a16a24637265617465644174636173636a70726f70657274696573a36966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f6d6f7468657250726f7065727479a2647479706566737472696e67696d61784c656e677468182a687265717569726564846966697273744e616d656a246372656174656441746a24757064617465644174686c6173744e616d65746164646974696f6e616c50726f70657274696573f46c6e696365446f63756d656e74a46474797065666f626a6563746a70726f70657274696573a1646e616d65a1647479706566737472696e67687265717569726564816a24637265617465644174746164646974696f6e616c50726f70657274696573f46e6e6f54696d65446f63756d656e74a36474797065666f626a6563746a70726f70657274696573a1646e616d65a1647479706566737472696e67746164646974696f6e616c50726f70657274696573f4781d6f7074696f6e616c556e69717565496e6465786564446f63756d656e74a56474797065666f626a6563746a70726f70657274696573a46966697273744e616d65a2647479706566737472696e67696d61784c656e677468183f686c6173744e616d65a2647479706566737472696e67696d61784c656e677468183f67636f756e747279a2647479706566737472696e67696d61784c656e677468183f6463697479a2647479706566737472696e67696d61784c656e677468183f67696e646963657383a3646e616d6566696e646578316a70726f7065727469657381a16966697273744e616d656361736366756e69717565f5a3646e616d6566696e646578326a70726f7065727469657383a168246f776e6572496463617363a16966697273744e616d6563617363a1686c6173744e616d656361736366756e69717565f5a3646e616d6566696e646578336a70726f7065727469657382a167636f756e74727963617363a164636974796361736366756e69717565f5687265717569726564826966697273744e616d65686c6173744e616d65746164646974696f6e616c50726f70657274696573f46e707265747479446f63756d656e74a46474797065666f626a6563746a70726f70657274696573a1686c6173744e616d65a1647479706566737472696e6768726571756972656482686c6173744e616d656a24757064617465644174746164646974696f6e616c50726f70657274696573f46b756e697175654461746573a56474797065666f626a65637467696e646963657382a3646e616d6566696e646578316a70726f7065727469657382a16a2463726561746564417463617363a16a247570646174656441746361736366756e69717565f5a2646e616d6566696e646578326a70726f7065727469657381a16a24757064617465644174636173636a70726f70657274696573a26966697273744e616d65a1647479706566737472696e67686c6173744e616d65a1647479706566737472696e67687265717569726564836966697273744e616d656a246372656174656441746a24757064617465644174746164646974696f6e616c50726f70657274696573f46e7769746842797465417272617973a56474797065666f626a65637467696e646963657381a2646e616d6566696e646578316a70726f7065727469657381a16e6279746541727261794669656c64636173636a70726f70657274696573a26e6279746541727261794669656c64a3647479706565617272617969627974654172726179f5686d61784974656d73106f6964656e7469666965724669656c64a5647479706565617272617969627974654172726179f570636f6e74656e744d656469615479706578216170706c69636174696f6e2f782e646173682e6470702e6964656e746966696572686d696e4974656d731820686d61784974656d731820687265717569726564816e6279746541727261794669656c64746164646974696f6e616c50726f70657274696573f464747970652267656e74726f70799820189618d10418b2071882188e188818fc18b7189818dd185c18811881189b1867187912183d184d187118ff1866181d185f1839188718ea1824185113747369676e61747572655075626c69634b6579496400697369676e617475726598410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'; const stateTransitionBuffer = Buffer.from(stateTransitionHex, 'hex'); - let result; try { - result = await factory.createFromBuffer(stateTransitionBuffer); + await factory.createFromBuffer(stateTransitionBuffer); expect.fail('should throw an error'); } catch (e) { expect(e).to.be.an.instanceOf(InvalidStateTransitionError);