From 450205e0a6e98cbcc668c6e0853a1fa65c500f98 Mon Sep 17 00:00:00 2001 From: Djavid Gabibiyan Date: Wed, 1 Feb 2023 16:14:30 +0500 Subject: [PATCH 01/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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/54] 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 64e4c0cea5630de20c253e7360a17dd538dd51f5 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Fri, 3 Mar 2023 13:32:54 +0000 Subject: [PATCH 33/54] rebase to feat/st-factory --- packages/rs-dpp/src/state_transition/mod.rs | 2 + .../state_transition_facade.rs | 137 ++++++++++++++++++ .../wasm-dpp/src/dash_platform_protocol.rs | 45 ++++-- packages/wasm-dpp/src/state_transition/mod.rs | 1 + .../state_transition_facade.rs | 30 ++++ 5 files changed, 205 insertions(+), 10 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/state_transition_facade.rs create mode 100644 packages/wasm-dpp/src/state_transition/state_transition_facade.rs diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 8f6868d70d2..2fe8842692a 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -17,7 +17,9 @@ use crate::identity::state_transition::identity_update_transition::identity_upda mod abstract_state_transition; mod abstract_state_transition_identity_signed; +mod state_transition_facade; mod state_transition_factory; +pub use state_transition_facade::*; pub use state_transition_factory::*; use self::state_transition_execution_context::StateTransitionExecutionContext; diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs new file mode 100644 index 00000000000..e6f236f6f9a --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -0,0 +1,137 @@ +use std::ops::Deref; +use std::rc::Rc; +use std::sync::Arc; +use crate::{BlsModule, ProtocolError}; +use crate::data_contract::state_transition::data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator; +use crate::data_contract::state_transition::data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator; +use crate::document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator; +use crate::identity::state_transition::asset_lock_proof::{AssetLockProofValidator, AssetLockTransactionValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator}; +use crate::identity::state_transition::identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator; +use crate::identity::state_transition::identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator; +use crate::identity::state_transition::identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator; +use crate::identity::state_transition::identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic; +use crate::identity::state_transition::validate_public_key_signatures::PublicKeysSignaturesValidator; +use crate::identity::validation::PublicKeysValidator; +use crate::state_repository::StateRepositoryLike; +use crate::state_transition::{StateTransition, StateTransitionFactory}; +use crate::state_transition::validation::validate_state_transition_basic::StateTransitionBasicValidator; +use crate::state_transition::validation::validate_state_transition_by_type::StateTransitionByTypeValidator; +use crate::version::ProtocolVersionValidator; + +#[derive(Clone)] +pub struct StateTransitionFacade +where + SR: StateRepositoryLike, + BLS: BlsModule + Clone, +{ + state_repository: Arc, + basic_validator: + Arc>>, + // factory: StateTransitionFactory, + // state_transition_validator: StateTransitionValidator, +} + +impl StateTransitionFacade +where + SR: StateRepositoryLike, + BLS: BlsModule + Clone, +{ + pub fn new(state_repository: Arc, adapter: BLS) -> Result { + let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); + + let pk_validator = Arc::new(PublicKeysValidator::new(adapter.clone()).map_err(|_| { + ProtocolError::Generic(String::from("Unable to initialize PublicKeysValidator")) + })?); + let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter.clone())); + + let asset_lock_tx_validator = + Arc::new(AssetLockTransactionValidator::new(state_repository.clone())); + + let asset_lock_validator = Arc::new(AssetLockProofValidator::new( + InstantAssetLockProofStructureValidator::new( + state_repository.clone(), + asset_lock_tx_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize InstantAssetLockProofStructureValidator", + )) + })?, + ChainAssetLockProofStructureValidator::new( + state_repository.clone(), + asset_lock_tx_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize ChainAssetLockProofStructureValidator", + )) + })?, + )); + + let state_transition_basic_validator = StateTransitionBasicValidator::new( + state_repository.clone(), + StateTransitionByTypeValidator::new( + DataContractCreateTransitionBasicValidator::new( + protocol_version_validator.clone(), + )?, + DataContractUpdateTransitionBasicValidator::new( + state_repository.clone(), + protocol_version_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize DataContractUpdateTransitionBasicValidator", + )) + })?, + IdentityCreateTransitionBasicValidator::new( + protocol_version_validator.deref().clone(), + pk_validator.clone(), + pk_validator.clone(), + asset_lock_validator.clone(), + adapter.clone(), + pk_sig_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize IdentityCreateTransitionBasicValidator", + )) + })?, + ValidateIdentityUpdateTransitionBasic::new( + ProtocolVersionValidator::default(), + pk_validator.clone(), + pk_sig_validator.clone(), + )?, + IdentityTopUpTransitionBasicValidator::new( + ProtocolVersionValidator::default(), + asset_lock_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize IdentityTopUpTransitionBasicValidator", + )) + })?, + IdentityCreditWithdrawalTransitionBasicValidator::new( + protocol_version_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize IdentityCreditWithdrawalTransitionBasicValidator", + )) + })?, + DocumentBatchTransitionBasicValidator::new( + state_repository.clone(), + protocol_version_validator.clone(), + ), + ), + ); + + Ok(Self { + state_repository, + basic_validator: Arc::new(state_transition_basic_validator), + }) + } + + pub fn validate_basic(&self, state_transition: &StateTransition) { + // self.state_transition_validator.validate(state_transition) + } +} diff --git a/packages/wasm-dpp/src/dash_platform_protocol.rs b/packages/wasm-dpp/src/dash_platform_protocol.rs index 25117d6fb0c..7e97d99320a 100644 --- a/packages/wasm-dpp/src/dash_platform_protocol.rs +++ b/packages/wasm-dpp/src/dash_platform_protocol.rs @@ -7,33 +7,49 @@ use crate::document_facade::DocumentFacadeWasm; use crate::fetch_and_validate_data_contract::DataContractFetcherAndValidatorWasm; use crate::identity_facade::IdentityFacadeWasm; use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; -use crate::DataContractFacadeWasm; +use crate::{with_js_error, DataContractFacadeWasm}; use crate::{DocumentFactoryWASM, DocumentValidatorWasm}; use dpp::identity::validation::PublicKeysValidator; -use dpp::version::{ProtocolVersionValidator, LATEST_VERSION}; +use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; +use crate::state_transition_facade::StateTransitionFacadeWasm; +use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; + +use serde::{Deserialize, Serialize}; #[wasm_bindgen(js_name=DashPlatformProtocol)] pub struct DashPlatformProtocol { identity: IdentityFacadeWasm, document: DocumentFacadeWasm, data_contract: DataContractFacadeWasm, + state_transition: StateTransitionFacadeWasm, +} + +#[derive(Serialize, Deserialize)] +pub struct DPPOptions { + #[serde(rename = "protocolVersion")] + pub current_protocol_version: Option, } #[wasm_bindgen(js_class=DashPlatformProtocol)] impl DashPlatformProtocol { #[wasm_bindgen(constructor)] pub fn new( + options: JsValue, bls_adapter: JsBlsAdapter, state_repository: ExternalStateRepositoryLike, - ) -> DashPlatformProtocol { + ) -> Result { + // TODO: wrap around rs-dpp/dash_platform_protocol? + let options: DPPOptions = with_js_error!(serde_wasm_bindgen::from_value(options))?; let wrapped_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository); - let bls = BlsAdapter(bls_adapter); + let bls = BlsAdapter(bls_adapter.clone()); - // TODO: add protocol version to the constructor - let protocol_version = LATEST_VERSION; - // TODO: remove default validator and make a real one instead - let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); + let protocol_version = options.current_protocol_version.unwrap_or(LATEST_VERSION); + let protocol_version_validator = Arc::new(ProtocolVersionValidator::new( + protocol_version, + LATEST_VERSION, + COMPATIBILITY_MAP.clone(), + )); let public_keys_validator = Arc::new(PublicKeysValidator::new(bls).unwrap()); let identity_facade = @@ -48,11 +64,15 @@ impl DashPlatformProtocol { let data_contract_facade = DataContractFacadeWasm::new(protocol_version, protocol_version_validator); - Self { + let state_transition_facade = + StateTransitionFacadeWasm::new(state_repository, bls_adapter)?; + + Ok(Self { document: document_facade, identity: identity_facade, data_contract: data_contract_facade, - } + state_transition: state_transition_facade, + }) } #[wasm_bindgen(getter = dataContract)] @@ -69,6 +89,11 @@ impl DashPlatformProtocol { pub fn identity(&self) -> IdentityFacadeWasm { self.identity.clone() } + + #[wasm_bindgen(getter = stateTransition)] + pub fn state_transition(&self) -> StateTransitionFacadeWasm { + self.state_transition.clone() + } } fn init_document_facade( diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index bf2a695a324..a755f3db21a 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -3,6 +3,7 @@ use dpp::state_transition::state_transition_execution_context::StateTransitionEx use wasm_bindgen::prelude::*; pub mod errors; +pub mod state_transition_facade; pub mod state_transition_factory; pub mod validation; diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs new file mode 100644 index 00000000000..4b5ad5b17c2 --- /dev/null +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -0,0 +1,30 @@ +use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; +use crate::errors::from_dpp_err; +use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; +use dpp::state_transition::StateTransitionFacade; +use std::sync::Arc; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsValue; + +#[derive(Clone)] +#[wasm_bindgen(js_name = StateTransitionFacade)] +pub struct StateTransitionFacadeWasm( + StateTransitionFacade, +); + +impl StateTransitionFacadeWasm { + pub fn new( + state_repository: ExternalStateRepositoryLike, + bls_adapter: JsBlsAdapter, + ) -> Result { + let state_repository_wrapper = + Arc::new(ExternalStateRepositoryLikeWrapper::new(state_repository)); + + let adapter = BlsAdapter(bls_adapter); + + let state_transition_facade = + StateTransitionFacade::new(state_repository_wrapper, adapter).map_err(from_dpp_err)?; + + Ok(StateTransitionFacadeWasm(state_transition_facade)) + } +} From 15403305b5d270337674beded765578a3c2b7c60 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Fri, 3 Mar 2023 13:37:17 +0000 Subject: [PATCH 34/54] fix: inconsistency after rebase --- packages/wasm-dpp/src/dash_platform_protocol.rs | 4 ++-- packages/wasm-dpp/src/state_repository.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/wasm-dpp/src/dash_platform_protocol.rs b/packages/wasm-dpp/src/dash_platform_protocol.rs index 7e97d99320a..db62de1fe86 100644 --- a/packages/wasm-dpp/src/dash_platform_protocol.rs +++ b/packages/wasm-dpp/src/dash_platform_protocol.rs @@ -11,7 +11,6 @@ use crate::{with_js_error, DataContractFacadeWasm}; use crate::{DocumentFactoryWASM, DocumentValidatorWasm}; use dpp::identity::validation::PublicKeysValidator; -use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; use crate::state_transition_facade::StateTransitionFacadeWasm; use dpp::version::{ProtocolVersionValidator, COMPATIBILITY_MAP, LATEST_VERSION}; @@ -41,7 +40,8 @@ impl DashPlatformProtocol { ) -> Result { // TODO: wrap around rs-dpp/dash_platform_protocol? let options: DPPOptions = with_js_error!(serde_wasm_bindgen::from_value(options))?; - let wrapped_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository); + let wrapped_state_repository = + ExternalStateRepositoryLikeWrapper::new(state_repository.clone()); let bls = BlsAdapter(bls_adapter.clone()); let protocol_version = options.current_protocol_version.unwrap_or(LATEST_VERSION); diff --git a/packages/wasm-dpp/src/state_repository.rs b/packages/wasm-dpp/src/state_repository.rs index 31774661635..ac2b6a7db3a 100644 --- a/packages/wasm-dpp/src/state_repository.rs +++ b/packages/wasm-dpp/src/state_repository.rs @@ -36,6 +36,7 @@ use crate::{ #[wasm_bindgen] extern "C" { + #[derive(Clone)] pub type ExternalStateRepositoryLike; #[wasm_bindgen(catch, structural, method, js_name=fetchDataContract)] From 18b19ba6c8b7a1da6b4554af438085e8f8d2aa8b Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Fri, 3 Mar 2023 18:26:21 +0000 Subject: [PATCH 35/54] fix(rs-dpp): set entropy for data contract in data contract factory create --- packages/rs-dpp/src/data_contract/data_contract_factory.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 b47b12e7f9b..fe30ef7590f 100644 --- a/packages/rs-dpp/src/data_contract/data_contract_factory.rs +++ b/packages/rs-dpp/src/data_contract/data_contract_factory.rs @@ -100,7 +100,9 @@ impl DataContractFactory { let cbor = value_to_cbor(JsonValue::Object(root_map), Some(1))?; - DataContract::from_cbor(cbor) + let mut data_contract = DataContract::from_cbor(cbor)?; + data_contract.set_entropy(entropy); + Ok(data_contract) } /// Create Data Contract from plain object From 0f7f31f0b1647381f6938646261f0c0b9bdc7a92 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Fri, 3 Mar 2023 18:27:43 +0000 Subject: [PATCH 36/54] fix(rs-dpp): set entropy for data contract in data contract factory create --- packages/rs-dpp/src/data_contract/data_contract.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/rs-dpp/src/data_contract/data_contract.rs b/packages/rs-dpp/src/data_contract/data_contract.rs index 3d00fbd2791..cd248c5be96 100644 --- a/packages/rs-dpp/src/data_contract/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/data_contract.rs @@ -270,6 +270,10 @@ impl DataContract { self.entropy } + pub fn set_entropy(&mut self, entropy: [u8; 32]) { + self.entropy = entropy; + } + pub fn owner_id(&self) -> &Identifier { &self.owner_id } From e09b1b24fb82e8575d56343b04dd823df866e4c1 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Fri, 3 Mar 2023 18:39:16 +0000 Subject: [PATCH 37/54] feat(wasm-dpp): StateTransitionFacade validateBasic --- .../state_transition_facade.rs | 13 ++- .../test/fixtures/getDataContractFixture.js | 7 +- .../lib/test/fixtures/getDocumentsFixture.js | 41 +++++++++ .../wasm-dpp/src/dash_platform_protocol.rs | 2 +- .../data_contract_create_transition/mod.rs | 21 ++++- .../wasm-dpp/src/document/document_facade.rs | 2 +- packages/wasm-dpp/src/document/factory.rs | 4 +- .../document_batch_transition/mod.rs | 6 +- .../identity_update_transition.rs | 8 +- .../src/state_transition/conversion.rs | 11 +++ .../state_transition_facade.rs | 40 ++++++++- .../StateTransitionFacade.spec.js | 84 +++++++++++++------ 12 files changed, 200 insertions(+), 39 deletions(-) create mode 100644 packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index e6f236f6f9a..9612d803b11 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -1,6 +1,7 @@ use std::ops::Deref; use std::rc::Rc; use std::sync::Arc; +use serde_json::Value; use crate::{BlsModule, ProtocolError}; use crate::data_contract::state_transition::data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator; use crate::data_contract::state_transition::data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator; @@ -14,8 +15,10 @@ use crate::identity::state_transition::validate_public_key_signatures::PublicKey use crate::identity::validation::PublicKeysValidator; use crate::state_repository::StateRepositoryLike; use crate::state_transition::{StateTransition, StateTransitionFactory}; +use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::state_transition::validation::validate_state_transition_basic::StateTransitionBasicValidator; use crate::state_transition::validation::validate_state_transition_by_type::StateTransitionByTypeValidator; +use crate::validation::{AsyncDataValidatorWithContext, SimpleValidationResult}; use crate::version::ProtocolVersionValidator; #[derive(Clone)] @@ -131,7 +134,13 @@ where }) } - pub fn validate_basic(&self, state_transition: &StateTransition) { - // self.state_transition_validator.validate(state_transition) + pub async fn validate_basic( + &self, + state_transition: &Value, + execution_context: &StateTransitionExecutionContext, + ) -> Result { + self.basic_validator + .validate(state_transition, execution_context) + .await } } diff --git a/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js b/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js index e8fb1b3ae24..f5d5d8fcdf6 100644 --- a/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js +++ b/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js @@ -1,7 +1,8 @@ const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); +const JsIdentifier = require('@dashevo/dpp/lib/Identifier/Identifier'); const generateRandomIdentifierAsync = require('../utils/generateRandomIdentifierAsync'); const { default: loadWasmDpp } = require('../../..'); -let { DataContractFactory, Identifier, DataContractValidator } = require('../../..'); +let { DataContractFactory, DataContractValidator } = require('../../..'); let randomOwnerId = null; @@ -11,7 +12,7 @@ let randomOwnerId = null; * @return {Promise} */ module.exports = async function getDataContractFixture(ownerId = randomOwnerId) { - ({ DataContractFactory, Identifier, DataContractValidator } = await loadWasmDpp()); + ({ DataContractFactory, DataContractValidator } = await loadWasmDpp()); if (!randomOwnerId) { randomOwnerId = await generateRandomIdentifierAsync(); @@ -189,7 +190,7 @@ module.exports = async function getDataContractFixture(ownerId = randomOwnerId) identifierField: { type: 'array', byteArray: true, - contentMediaType: Identifier.MEDIA_TYPE, + contentMediaType: JsIdentifier.MEDIA_TYPE, minItems: 32, maxItems: 32, }, diff --git a/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js b/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js new file mode 100644 index 00000000000..436c12607be --- /dev/null +++ b/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js @@ -0,0 +1,41 @@ +// const crypto = require('crypto'); + +const getDataContractFixture = require('./getDataContractFixture'); + +const { default: loadWasmDpp } = require('../../..'); +let { DocumentFactory, DocumentValidator, ProtocolVersionValidator } = require('../../..'); +const generateRandomIdentifierAsync = require('../utils/generateRandomIdentifierAsync'); + +/** + * @param {DataContract} [dataContract] + * @return {Promise} + */ +module.exports = async function getDocumentsFixture( + dataContract, +) { + if (!dataContract) { + // eslint-disable-next-line no-param-reassign + dataContract = await getDataContractFixture(); + } + + ({ DocumentFactory, DocumentValidator, ProtocolVersionValidator } = await loadWasmDpp()); + + const documentValidator = new DocumentValidator(new ProtocolVersionValidator()); + const factory = new DocumentFactory(1, documentValidator, {}); + + const ownerId = await generateRandomIdentifierAsync(); + + return [ + factory.create(dataContract, ownerId, 'niceDocument', { name: 'Cutie' }), + factory.create(dataContract, ownerId, 'prettyDocument', { lastName: 'Shiny' }), + factory.create(dataContract, ownerId, 'prettyDocument', { lastName: 'Sweety' }), + factory.create(dataContract, ownerId, 'indexedDocument', { firstName: 'William', lastName: 'Birkin' }), + factory.create(dataContract, ownerId, 'indexedDocument', { firstName: 'Leon', lastName: 'Kennedy' }), + factory.create(dataContract, ownerId, 'noTimeDocument', { name: 'ImOutOfTime' }), + factory.create(dataContract, ownerId, 'uniqueDates', { firstName: 'John' }), + factory.create(dataContract, ownerId, 'indexedDocument', { firstName: 'Bill', lastName: 'Gates' }), + // TODO: something strange is happening in case byte field is anything but "byteArrayField" + // factory.create(dataContract, ownerId, 'withByteArrays', { byteArrayField: crypto.randomBytes(10), identifierFields: await generateRandomIdentifierAsync() }), + factory.create(dataContract, ownerId, 'optionalUniqueIndexedDocument', { firstName: 'Jacques-Yves', lastName: 'Cousteau' }), + ]; +}; diff --git a/packages/wasm-dpp/src/dash_platform_protocol.rs b/packages/wasm-dpp/src/dash_platform_protocol.rs index db62de1fe86..8ff140961e6 100644 --- a/packages/wasm-dpp/src/dash_platform_protocol.rs +++ b/packages/wasm-dpp/src/dash_platform_protocol.rs @@ -38,7 +38,7 @@ impl DashPlatformProtocol { bls_adapter: JsBlsAdapter, state_repository: ExternalStateRepositoryLike, ) -> Result { - // TODO: wrap around rs-dpp/dash_platform_protocol? + // TODO: wrap whole thing around rs-dpp/dash_platform_protocol? let options: DPPOptions = with_js_error!(serde_wasm_bindgen::from_value(options))?; let wrapped_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository.clone()); 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 ebb3605e5bb..30cce3f6b4c 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 @@ -15,10 +15,12 @@ use dpp::{ use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; +use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::protocol_error::from_protocol_error; use crate::{ buffer::Buffer, errors::from_dpp_err, identifier::IdentifierWrapper, with_js_error, - DataContractParameters, DataContractWasm, StateTransitionExecutionContextWasm, + DataContractParameters, DataContractWasm, IdentityPublicKeyWasm, + StateTransitionExecutionContextWasm, }; #[derive(Clone)] @@ -147,4 +149,21 @@ impl DataContractCreateTransitionWasm { .serialize(&serde_wasm_bindgen::Serializer::json_compatible()) .map_err(|e| e.into()) } + + #[wasm_bindgen] + pub fn sign( + &mut self, + identity_public_key: &IdentityPublicKeyWasm, + private_key: Vec, + bls: JsBlsAdapter, + ) -> Result<(), JsValue> { + let bls_adapter = BlsAdapter(bls); + self.0 + .sign( + &identity_public_key.to_owned().into(), + &private_key, + &bls_adapter, + ) + .map_err(from_dpp_err) + } } diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index af569de9742..198a14cc284 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -50,7 +50,7 @@ impl DocumentFacadeWasm { #[wasm_bindgen(js_name=create)] pub fn create( &self, - data_contract: DataContractWasm, + data_contract: &DataContractWasm, js_owner_id: &JsValue, document_type: &str, data: &JsValue, diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 0cfb07c3839..070d2064133 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -96,7 +96,7 @@ impl DocumentFactoryWASM { #[wasm_bindgen(js_name=create)] pub fn create( &self, - data_contract: DataContractWasm, + data_contract: &DataContractWasm, js_owner_id: &JsValue, document_type: &str, data: &JsValue, @@ -106,7 +106,7 @@ impl DocumentFactoryWASM { let document = self .0 .create( - data_contract.into(), + data_contract.to_owned().into(), owner_id, document_type.to_string(), dynamic_data, diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index c74c48af9c4..4d17d07acf5 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -244,7 +244,11 @@ impl DocumentsBatchTransitionWASM { bls: JsBlsAdapter, ) -> Result<(), JsValue> { self.0 - .sign(identity_public_key.inner(), private_key, &BlsAdapter(bls)) + .sign( + &identity_public_key.to_owned().into(), + private_key, + &BlsAdapter(bls), + ) .with_js_error() } 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 fcccf72c41a..1047dcbcd9d 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 @@ -432,13 +432,17 @@ impl IdentityUpdateTransitionWasm { #[wasm_bindgen] pub fn sign( &mut self, - identity_public_key: IdentityPublicKeyWasm, + identity_public_key: &IdentityPublicKeyWasm, private_key: Vec, bls: JsBlsAdapter, ) -> Result<(), JsValue> { let bls_adapter = BlsAdapter(bls); self.0 - .sign(&identity_public_key.into(), &private_key, &bls_adapter) + .sign( + &identity_public_key.to_owned().into(), + &private_key, + &bls_adapter, + ) .map_err(from_dpp_err) } } diff --git a/packages/wasm-dpp/src/state_transition/conversion.rs b/packages/wasm-dpp/src/state_transition/conversion.rs index 80266630705..ec09354f3d3 100644 --- a/packages/wasm-dpp/src/state_transition/conversion.rs +++ b/packages/wasm-dpp/src/state_transition/conversion.rs @@ -9,6 +9,17 @@ use std::convert::TryInto; use wasm_bindgen::__rt::Ref; use wasm_bindgen::{JsCast, JsError, JsValue}; +pub fn state_transition_wasm_to_object(state_transition: &JsValue) -> Result { + let to_object_value = js_sys::Reflect::get(state_transition, &JsValue::from_str("toObject")) + .map_err(|_| JsError::new("No 'toObject' property present in state transition"))?; + + let to_object_function: &js_sys::Function = to_object_value + .dyn_ref::() + .ok_or_else(|| JsError::new("'toObject' is not a function"))?; + + to_object_function.call0(state_transition) +} + pub fn create_state_transition_from_wasm_instance( js_value: &JsValue, ) -> Result { diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index 4b5ad5b17c2..b6b14dee1db 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -1,7 +1,11 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; -use dpp::state_transition::StateTransitionFacade; +use crate::utils::ToSerdeJSONExt; +use crate::validation::ValidationResultWasm; +use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; +use dpp::state_transition::{StateTransitionConvert, StateTransitionFacade, StateTransitionLike}; +use serde_json::Value; use std::sync::Arc; use wasm_bindgen::prelude::*; use wasm_bindgen::JsValue; @@ -28,3 +32,37 @@ impl StateTransitionFacadeWasm { Ok(StateTransitionFacadeWasm(state_transition_facade)) } } + +#[wasm_bindgen(js_class = StateTransitionFacade)] +impl StateTransitionFacadeWasm { + #[wasm_bindgen(js_name = validateBasic)] + pub async fn validate_basic( + &self, + raw_state_transition: JsValue, + ) -> Result { + let state_transition_json; + let execution_context; + + if let Ok(state_transition) = + super::super::conversion::create_state_transition_from_wasm_instance( + &raw_state_transition, + ) + { + execution_context = state_transition.get_execution_context().to_owned(); + state_transition_json = + super::super::conversion::state_transition_wasm_to_object(&raw_state_transition)? + .with_serde_to_json_value()?; + } else { + state_transition_json = raw_state_transition.with_serde_to_json_value()?; + execution_context = StateTransitionExecutionContext::default(); + } + + let validation_result = self + .0 + .validate_basic(&state_transition_json, &execution_context) + .await + .map_err(from_dpp_err)?; + + Ok(validation_result.map(|_| JsValue::undefined()).into()) + } +} diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index d0a93bef855..2f0d072cab5 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -1,25 +1,28 @@ const { PrivateKey } = require('@dashevo/dashcore-lib'); -const DashPlatformProtocol = require('@dashevo/dpp/lib/DashPlatformProtocol'); +// const DashPlatformProtocol = require('@dashevo/dpp/lib/DashPlatformProtocol'); const DataContractCreateTransition = require('@dashevo/dpp/lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition'); -const ValidationResult = require('@dashevo/dpp/lib/validation/ValidationResult'); +// const ValidationResult = require('@dashevo/dpp/lib/validation/ValidationResult'); -const getDataContractFixture = require('@dashevo/dpp/lib/test/fixtures/getDataContractFixture'); -const getDocumentsFixture = require('@dashevo/dpp/lib/test/fixtures/getDocumentsFixture'); const getIdentityCreateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityCreateTransitionFixture'); const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); -const DataContractFactory = require('@dashevo/dpp/lib/dataContract/DataContractFactory'); -const DocumentFactory = require('@dashevo/dpp/lib/document/DocumentFactory'); +// const DataContractFactory = require('@dashevo/dpp/lib/dataContract/DataContractFactory'); +// const DocumentFactory = require('@dashevo/dpp/lib/document/DocumentFactory'); -const IdentityPublicKey = require('@dashevo/dpp/lib/identity/IdentityPublicKey'); +// const IdentityPublicKey = require('@dashevo/dpp/lib/identity/IdentityPublicKey'); const MissingOptionError = require('@dashevo/dpp/lib/errors/MissingOptionError'); const createDPPMock = require('@dashevo/dpp/lib/test/mocks/createDPPMock'); const SomeConsensusError = require('@dashevo/dpp/lib/test/mocks/SomeConsensusError'); +const getDocumentsFixture = require('../../../lib/test/fixtures/getDocumentsFixture'); +const getDataContractFixture = require('../../../lib/test/fixtures/getDataContractFixture'); + +const { default: loadWasmDpp } = require('../../../dist'); +const getBlsAdapterMock = require('../../../lib/test/mocks/getBlsAdapterMock'); describe('StateTransitionFacade', () => { let dpp; @@ -29,32 +32,63 @@ describe('StateTransitionFacade', () => { let dataContract; let identityPublicKey; + let DashPlatformProtocol; + let DataContractFactory; + let DataContractValidator; + let DataContract; + let ValidationResult; + let IdentityPublicKey; + let DocumentFactory; + let DocumentValidator; + let ProtocolVersionValidator; + + before(async () => { + ({ + DashPlatformProtocol, + ValidationResult, + DataContract, + DataContractValidator, + DataContractFactory, + IdentityPublicKey, + DocumentFactory, + DocumentValidator, + ProtocolVersionValidator, + } = await loadWasmDpp()); + }); + beforeEach(async function beforeEach() { const privateKeyModel = new PrivateKey(); - const privateKey = privateKeyModel.toWIF(); + const privateKey = privateKeyModel.toBuffer(); const publicKey = privateKeyModel.toPublicKey().toBuffer(); const publicKeyId = 1; - identityPublicKey = new IdentityPublicKey() - .setId(publicKeyId) - .setType(IdentityPublicKey.TYPES.ECDSA_SECP256K1) - .setData(publicKey) - .setPurpose(IdentityPublicKey.PURPOSES.AUTHENTICATION) - .setSecurityLevel(IdentityPublicKey.PURPOSES.MASTER); + // TODO: check security level. It says it needs HIGH instead of MASTER + identityPublicKey = new IdentityPublicKey({ + id: publicKeyId, + type: IdentityPublicKey.TYPES.ECDSA_SECP256K1, + data: publicKey, + purpose: IdentityPublicKey.PURPOSES.AUTHENTICATION, + securityLevel: IdentityPublicKey.SECURITY_LEVELS.HIGH, + readOnly: false, + }); - dataContract = getDataContractFixture(); + dataContract = await getDataContractFixture(); - const dataContractFactory = new DataContractFactory(createDPPMock(), undefined); + const dataContractValidator = new DataContractValidator(); + const dataContractFactory = new DataContractFactory(1, dataContractValidator); - dataContractCreateTransition = dataContractFactory.createDataContractCreateTransition( + dataContractCreateTransition = await dataContractFactory.createDataContractCreateTransition( dataContract, ); + await dataContractCreateTransition.sign(identityPublicKey, privateKey); - const documentFactory = new DocumentFactory(createDPPMock(), undefined, undefined); + const documentValidator = new DocumentValidator(new ProtocolVersionValidator()); + const documentFactory = new DocumentFactory(1, documentValidator, stateRepositoryMock); + const docs = await getDocumentsFixture(dataContract); documentsBatchTransition = documentFactory.createStateTransition({ - create: getDocumentsFixture(dataContract), + create: await getDocumentsFixture(dataContract), }); await documentsBatchTransition.sign(identityPublicKey, privateKey); @@ -73,11 +107,9 @@ describe('StateTransitionFacade', () => { stateRepositoryMock.fetchIdentity.resolves(identity); stateRepositoryMock.fetchLatestPlatformBlockTime.resolves(blockTime); - dpp = new DashPlatformProtocol({ - stateRepository: stateRepositoryMock, - }); + const blsAdapter = await getBlsAdapterMock(); - await dpp.initialize(); + dpp = new DashPlatformProtocol({}, blsAdapter, stateRepositoryMock); }); describe('createFromObject', () => { @@ -284,8 +316,10 @@ describe('StateTransitionFacade', () => { }); }); - describe('validateBasic', () => { - it('should throw MissingOption if stateRepository is not set', async () => { + describe.only('validateBasic', () => { + // TODO: can we remove it because stateRepository is mandatory argument + // in wasm-dpp DashPlatformProtocol constructor? + it.skip('should throw MissingOption if stateRepository is not set', async () => { dpp = new DashPlatformProtocol(); await dpp.initialize(); From 022933cecddb4f66a3909ef24158f9c9dc1b7f99 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Mon, 6 Mar 2023 12:57:51 +0000 Subject: [PATCH 38/54] feat(wasm-dpp): StateTransitionFacade validateSignatures --- ...stract_state_transition_identity_signed.rs | 12 +- .../state_transition_facade.rs | 234 ++++++++++++------ ...ate_state_transition_identity_signature.rs | 3 +- .../state_transition_facade.rs | 21 ++ .../StateTransitionFacade.spec.js | 70 ++---- 5 files changed, 210 insertions(+), 130 deletions(-) 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 1ad538becef..309f062e3de 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 @@ -42,9 +42,9 @@ where // the compressed key stored in the identity if public_key_compressed.to_vec() != identity_public_key.data { - return Err(ProtocolError::InvalidSignaturePublicKeyError( - InvalidSignaturePublicKeyError::new(identity_public_key.data.to_owned()), - )); + return Err(ProtocolError::InvalidSignaturePublicKeyError { + public_key: identity_public_key.data.to_owned(), + }); } self.sign_by_private_key(private_key, identity_public_key.key_type, bls) @@ -77,7 +77,11 @@ where KeyType::BIP13_SCRIPT_HASH => Err(ProtocolError::InvalidIdentityPublicKeyTypeError( InvalidIdentityPublicKeyTypeError::new(identity_public_key.key_type), )), - } + }?; + + self.set_signature_public_key_id(identity_public_key.id); + + Ok(()) } fn verify_signature( diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index 9612d803b11..bc3fb0e333c 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -6,19 +6,23 @@ use crate::{BlsModule, ProtocolError}; use crate::data_contract::state_transition::data_contract_create_transition::validation::state::validate_data_contract_create_transition_basic::DataContractCreateTransitionBasicValidator; use crate::data_contract::state_transition::data_contract_update_transition::validation::basic::DataContractUpdateTransitionBasicValidator; use crate::document::validation::basic::validate_documents_batch_transition_basic::DocumentBatchTransitionBasicValidator; -use crate::identity::state_transition::asset_lock_proof::{AssetLockProofValidator, AssetLockTransactionValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator}; +use crate::identity::state_transition::asset_lock_proof::{AssetLockProofValidator, AssetLockPublicKeyHashFetcher, AssetLockTransactionOutputFetcher, AssetLockTransactionValidator, ChainAssetLockProofStructureValidator, InstantAssetLockProofStructureValidator}; use crate::identity::state_transition::identity_create_transition::validation::basic::IdentityCreateTransitionBasicValidator; use crate::identity::state_transition::identity_credit_withdrawal_transition::validation::basic::validate_identity_credit_withdrawal_transition_basic::IdentityCreditWithdrawalTransitionBasicValidator; use crate::identity::state_transition::identity_topup_transition::validation::basic::IdentityTopUpTransitionBasicValidator; use crate::identity::state_transition::identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic; use crate::identity::state_transition::validate_public_key_signatures::PublicKeysSignaturesValidator; use crate::identity::validation::PublicKeysValidator; +use crate::prelude::ValidationResult; use crate::state_repository::StateRepositoryLike; -use crate::state_transition::{StateTransition, StateTransitionFactory}; +use crate::state_transition::{StateTransition, StateTransitionFactory, StateTransitionIdentitySigned, StateTransitionLike}; +use crate::state_transition::fee::operations::{DeleteOperation, Operation}; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::state_transition::validation::validate_state_transition_basic::StateTransitionBasicValidator; use crate::state_transition::validation::validate_state_transition_by_type::StateTransitionByTypeValidator; -use crate::validation::{AsyncDataValidatorWithContext, SimpleValidationResult}; +use crate::state_transition::validation::validate_state_transition_identity_signature::validate_state_transition_identity_signature; +use crate::state_transition::validation::validate_state_transition_key_signature::StateTransitionKeySignatureValidator; +use crate::validation::{AsyncDataValidator, AsyncDataValidatorWithContext, SimpleValidationResult}; use crate::version::ProtocolVersionValidator; #[derive(Clone)] @@ -30,8 +34,9 @@ where state_repository: Arc, basic_validator: Arc>>, - // factory: StateTransitionFactory, - // state_transition_validator: StateTransitionValidator, + key_signature_validator: Arc>, + bls: BLS, // factory: StateTransitionFactory, + // state_transition_validator: StateTransitionValidator, } impl StateTransitionFacade @@ -40,97 +45,120 @@ where BLS: BlsModule + Clone, { pub fn new(state_repository: Arc, adapter: BLS) -> Result { - let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); + let state_transition_basic_validator; + let state_transition_key_signature_validator; - let pk_validator = Arc::new(PublicKeysValidator::new(adapter.clone()).map_err(|_| { - ProtocolError::Generic(String::from("Unable to initialize PublicKeysValidator")) - })?); - let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter.clone())); + { + let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); - let asset_lock_tx_validator = - Arc::new(AssetLockTransactionValidator::new(state_repository.clone())); + let pk_validator = + Arc::new(PublicKeysValidator::new(adapter.clone()).map_err(|_| { + ProtocolError::Generic(String::from("Unable to initialize PublicKeysValidator")) + })?); + let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter.clone())); - let asset_lock_validator = Arc::new(AssetLockProofValidator::new( - InstantAssetLockProofStructureValidator::new( - state_repository.clone(), - asset_lock_tx_validator.clone(), - ) - .map_err(|_| { - ProtocolError::Generic(String::from( - "Unable to initialize InstantAssetLockProofStructureValidator", - )) - })?, - ChainAssetLockProofStructureValidator::new( - state_repository.clone(), - asset_lock_tx_validator.clone(), - ) - .map_err(|_| { - ProtocolError::Generic(String::from( - "Unable to initialize ChainAssetLockProofStructureValidator", - )) - })?, - )); + let asset_lock_tx_validator = + Arc::new(AssetLockTransactionValidator::new(state_repository.clone())); - let state_transition_basic_validator = StateTransitionBasicValidator::new( - state_repository.clone(), - StateTransitionByTypeValidator::new( - DataContractCreateTransitionBasicValidator::new( - protocol_version_validator.clone(), - )?, - DataContractUpdateTransitionBasicValidator::new( + let asset_lock_validator = Arc::new(AssetLockProofValidator::new( + InstantAssetLockProofStructureValidator::new( state_repository.clone(), - protocol_version_validator.clone(), - ) - .map_err(|_| { - ProtocolError::Generic(String::from( - "Unable to initialize DataContractUpdateTransitionBasicValidator", - )) - })?, - IdentityCreateTransitionBasicValidator::new( - protocol_version_validator.deref().clone(), - pk_validator.clone(), - pk_validator.clone(), - asset_lock_validator.clone(), - adapter.clone(), - pk_sig_validator.clone(), + asset_lock_tx_validator.clone(), ) .map_err(|_| { ProtocolError::Generic(String::from( - "Unable to initialize IdentityCreateTransitionBasicValidator", + "Unable to initialize InstantAssetLockProofStructureValidator", )) })?, - ValidateIdentityUpdateTransitionBasic::new( - ProtocolVersionValidator::default(), - pk_validator.clone(), - pk_sig_validator.clone(), - )?, - IdentityTopUpTransitionBasicValidator::new( - ProtocolVersionValidator::default(), - asset_lock_validator.clone(), - ) - .map_err(|_| { - ProtocolError::Generic(String::from( - "Unable to initialize IdentityTopUpTransitionBasicValidator", - )) - })?, - IdentityCreditWithdrawalTransitionBasicValidator::new( - protocol_version_validator.clone(), + ChainAssetLockProofStructureValidator::new( + state_repository.clone(), + asset_lock_tx_validator.clone(), ) .map_err(|_| { ProtocolError::Generic(String::from( - "Unable to initialize IdentityCreditWithdrawalTransitionBasicValidator", + "Unable to initialize ChainAssetLockProofStructureValidator", )) })?, - DocumentBatchTransitionBasicValidator::new( - state_repository.clone(), - protocol_version_validator.clone(), + )); + + state_transition_basic_validator = StateTransitionBasicValidator::new( + state_repository.clone(), + StateTransitionByTypeValidator::new( + DataContractCreateTransitionBasicValidator::new( + protocol_version_validator.clone(), + )?, + DataContractUpdateTransitionBasicValidator::new( + state_repository.clone(), + protocol_version_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize DataContractUpdateTransitionBasicValidator", + )) + })?, + IdentityCreateTransitionBasicValidator::new( + protocol_version_validator.deref().clone(), + pk_validator.clone(), + pk_validator.clone(), + asset_lock_validator.clone(), + adapter.clone(), + pk_sig_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize IdentityCreateTransitionBasicValidator", + )) + })?, + ValidateIdentityUpdateTransitionBasic::new( + ProtocolVersionValidator::default(), + pk_validator.clone(), + pk_sig_validator.clone(), + )?, + IdentityTopUpTransitionBasicValidator::new( + ProtocolVersionValidator::default(), + asset_lock_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize IdentityTopUpTransitionBasicValidator", + )) + })?, + IdentityCreditWithdrawalTransitionBasicValidator::new( + protocol_version_validator.clone(), + ) + .map_err(|_| { + ProtocolError::Generic(String::from( + "Unable to initialize IdentityCreditWithdrawalTransitionBasicValidator", + )) + })?, + DocumentBatchTransitionBasicValidator::new( + state_repository.clone(), + protocol_version_validator.clone(), + ), ), - ), - ); + ); + } + + { + let asset_lock_transaction_output_fetcher = + AssetLockTransactionOutputFetcher::new(state_repository.clone()); + + let asset_public_key_hash_fetcher = AssetLockPublicKeyHashFetcher::new( + state_repository.clone(), + asset_lock_transaction_output_fetcher, + ); + + state_transition_key_signature_validator = StateTransitionKeySignatureValidator::new( + state_repository.clone(), + asset_public_key_hash_fetcher, + ); + } Ok(Self { state_repository, basic_validator: Arc::new(state_transition_basic_validator), + key_signature_validator: Arc::new(state_transition_key_signature_validator), + bls: adapter, }) } @@ -143,4 +171,58 @@ where .validate(state_transition, execution_context) .await } + + pub async fn validate_signature( + &self, + mut state_transition: StateTransition, + ) -> Result { + // TODO: can we avoid duplicated code here? + return match state_transition { + StateTransition::DataContractCreate(ref mut st) => { + validate_state_transition_identity_signature( + self.state_repository.clone(), + st, + &self.bls, + ) + .await + } + StateTransition::DataContractUpdate(ref mut st) => { + validate_state_transition_identity_signature( + self.state_repository.clone(), + st, + &self.bls, + ) + .await + } + StateTransition::DocumentsBatch(ref mut st) => { + validate_state_transition_identity_signature( + self.state_repository.clone(), + st, + &self.bls, + ) + .await + } + StateTransition::IdentityCreditWithdrawal(ref mut st) => { + validate_state_transition_identity_signature( + self.state_repository.clone(), + st, + &self.bls, + ) + .await + } + StateTransition::IdentityUpdate(ref mut st) => { + validate_state_transition_identity_signature( + self.state_repository.clone(), + st, + &self.bls, + ) + .await + } + _ => { + self.key_signature_validator + .validate(&state_transition) + .await + } + }; + } } 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 0db9ef7601f..d53dc1e946f 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 @@ -1,3 +1,4 @@ +use std::sync::Arc; use std::{collections::HashSet, convert::TryInto}; use anyhow::Context; @@ -31,7 +32,7 @@ lazy_static! { } pub async fn validate_state_transition_identity_signature( - state_repository: &impl StateRepositoryLike, + state_repository: Arc, state_transition: &mut impl StateTransitionIdentitySigned, bls: &impl BlsModule, ) -> Result, ProtocolError> { diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index b6b14dee1db..d15484cde1c 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -65,4 +65,25 @@ impl StateTransitionFacadeWasm { Ok(validation_result.map(|_| JsValue::undefined()).into()) } + + #[wasm_bindgen(js_name = validateSignature)] + pub async fn validate_signature( + &self, + raw_state_transition: JsValue, + ) -> Result { + let state_transition = + super::super::conversion::create_state_transition_from_wasm_instance( + &raw_state_transition, + )?; + + let validation_result = self + .0 + .validate_signature(state_transition) + .await + .map_err(from_dpp_err)?; + + web_sys::console::log_1(&"Validated st".into()); + + Ok(validation_result.map(|_| JsValue::undefined()).into()) + } } diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 2f0d072cab5..51327609c2a 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -18,11 +18,13 @@ const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createSta const MissingOptionError = require('@dashevo/dpp/lib/errors/MissingOptionError'); const createDPPMock = require('@dashevo/dpp/lib/test/mocks/createDPPMock'); const SomeConsensusError = require('@dashevo/dpp/lib/test/mocks/SomeConsensusError'); +const getIdentityFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityFixture'); const getDocumentsFixture = require('../../../lib/test/fixtures/getDocumentsFixture'); const getDataContractFixture = require('../../../lib/test/fixtures/getDataContractFixture'); const { default: loadWasmDpp } = require('../../../dist'); const getBlsAdapterMock = require('../../../lib/test/mocks/getBlsAdapterMock'); +const generateRandomIdentifierAsync = require('../../../lib/test/utils/generateRandomIdentifierAsync'); describe('StateTransitionFacade', () => { let dpp; @@ -36,23 +38,27 @@ describe('StateTransitionFacade', () => { let DataContractFactory; let DataContractValidator; let DataContract; + let Identity; let ValidationResult; let IdentityPublicKey; let DocumentFactory; let DocumentValidator; let ProtocolVersionValidator; + let IdentityCreateTransition; before(async () => { ({ DashPlatformProtocol, ValidationResult, DataContract, + Identity, DataContractValidator, DataContractFactory, IdentityPublicKey, DocumentFactory, DocumentValidator, ProtocolVersionValidator, + IdentityCreateTransition, } = await loadWasmDpp()); }); @@ -80,26 +86,23 @@ describe('StateTransitionFacade', () => { dataContractCreateTransition = await dataContractFactory.createDataContractCreateTransition( dataContract, ); - - await dataContractCreateTransition.sign(identityPublicKey, privateKey); + await dataContractCreateTransition.sign( + identityPublicKey, + privateKey, + ); const documentValidator = new DocumentValidator(new ProtocolVersionValidator()); const documentFactory = new DocumentFactory(1, documentValidator, stateRepositoryMock); - const docs = await getDocumentsFixture(dataContract); documentsBatchTransition = documentFactory.createStateTransition({ create: await getDocumentsFixture(dataContract), }); await documentsBatchTransition.sign(identityPublicKey, privateKey); - const getPublicKeyById = this.sinonSandbox.stub().returns(identityPublicKey); - const getBalance = this.sinonSandbox.stub().returns(10000); - - const identity = { - getPublicKeyById, - type: 2, - getBalance, - }; + const identityObjectJS = getIdentityFixture().toObject(); + identityObjectJS.id = await generateRandomIdentifierAsync(); + const identity = new Identity(identityObjectJS); + identity.setPublicKeys([identityPublicKey]); const blockTime = Date.now(); @@ -316,25 +319,7 @@ describe('StateTransitionFacade', () => { }); }); - describe.only('validateBasic', () => { - // TODO: can we remove it because stateRepository is mandatory argument - // in wasm-dpp DashPlatformProtocol constructor? - it.skip('should throw MissingOption if stateRepository is not set', async () => { - dpp = new DashPlatformProtocol(); - await dpp.initialize(); - - try { - await dpp.stateTransition.validateBasic( - dataContractCreateTransition.toObject(), - ); - - expect.fail('MissingOption should be thrown'); - } catch (e) { - expect(e).to.be.an.instanceOf(MissingOptionError); - expect(e.getOptionName()).to.equal('stateRepository'); - } - }); - + describe('validateBasic', () => { it('should validate State Transition', async () => { const result = await dpp.stateTransition.validateBasic( dataContractCreateTransition.toObject(), @@ -345,23 +330,7 @@ describe('StateTransitionFacade', () => { }); }); - describe('validateSignature', () => { - it('should throw MissingOption if stateRepository is not set', async () => { - dpp = new DashPlatformProtocol(); - await dpp.initialize(); - - try { - await dpp.stateTransition.validateSignature( - dataContractCreateTransition, - ); - - expect.fail('MissingOption should be thrown'); - } catch (e) { - expect(e).to.be.an.instanceOf(MissingOptionError); - expect(e.getOptionName()).to.equal('stateRepository'); - } - }); - + describe.only('validateSignature', () => { it('should validate identity signed State Transition', async () => { const result = await dpp.stateTransition.validateSignature( dataContractCreateTransition, @@ -376,10 +345,13 @@ describe('StateTransitionFacade', () => { 'af432c476f65211f45f48f1d42c9c0b497e56696aa1736b40544ef1a496af837', ); - const identityCreateTransition = getIdentityCreateTransitionFixture(oneTimePrivateKey); + const identityCreateTransitionJS = getIdentityCreateTransitionFixture(oneTimePrivateKey); + const identityCreateTransition = new IdentityCreateTransition( + identityCreateTransitionJS.toObject(), + ); await identityCreateTransition.signByPrivateKey( - oneTimePrivateKey, + oneTimePrivateKey.toBuffer(), IdentityPublicKey.TYPES.ECDSA_SECP256K1, ); From 4bfc1f765c4ce1569785ff130b3240231a00480a Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Mon, 6 Mar 2023 13:04:14 +0000 Subject: [PATCH 39/54] feat(wasm-dpp): StateTransitionFacade validateFee --- .../state_transition_facade.rs | 13 ++++++++++++ .../validate_state_transition_fee.rs | 2 +- .../state_transition_facade.rs | 19 ++++++++++++++++++ .../StateTransitionFacade.spec.js | 20 ++----------------- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index bc3fb0e333c..fd186607d5c 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -20,6 +20,7 @@ use crate::state_transition::fee::operations::{DeleteOperation, Operation}; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::state_transition::validation::validate_state_transition_basic::StateTransitionBasicValidator; use crate::state_transition::validation::validate_state_transition_by_type::StateTransitionByTypeValidator; +use crate::state_transition::validation::validate_state_transition_fee::StateTransitionFeeValidator; use crate::state_transition::validation::validate_state_transition_identity_signature::validate_state_transition_identity_signature; use crate::state_transition::validation::validate_state_transition_key_signature::StateTransitionKeySignatureValidator; use crate::validation::{AsyncDataValidator, AsyncDataValidatorWithContext, SimpleValidationResult}; @@ -35,6 +36,7 @@ where basic_validator: Arc>>, key_signature_validator: Arc>, + fee_validator: Arc>, bls: BLS, // factory: StateTransitionFactory, // state_transition_validator: StateTransitionValidator, } @@ -47,6 +49,7 @@ where pub fn new(state_repository: Arc, adapter: BLS) -> Result { let state_transition_basic_validator; let state_transition_key_signature_validator; + let state_transition_fee_validator; { let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); @@ -154,10 +157,13 @@ where ); } + state_transition_fee_validator = StateTransitionFeeValidator::new(state_repository.clone()); + Ok(Self { state_repository, basic_validator: Arc::new(state_transition_basic_validator), key_signature_validator: Arc::new(state_transition_key_signature_validator), + fee_validator: Arc::new(state_transition_fee_validator), bls: adapter, }) } @@ -225,4 +231,11 @@ where } }; } + + pub async fn validate_fee( + &self, + state_transition: &StateTransition, + ) -> Result { + self.fee_validator.validate(state_transition).await + } } 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 9c246c6a166..68452bee026 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 @@ -26,7 +26,7 @@ impl StateTransitionFeeValidator where SR: StateRepositoryLike, { - fn new(state_repository: Arc) -> Self { + pub fn new(state_repository: Arc) -> Self { let asset_lock_transition_output_fetcher = AssetLockTransactionOutputFetcher::new(state_repository.clone()); StateTransitionFeeValidator { diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index d15484cde1c..ee218254027 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -86,4 +86,23 @@ impl StateTransitionFacadeWasm { Ok(validation_result.map(|_| JsValue::undefined()).into()) } + + #[wasm_bindgen(js_name = validateFee)] + pub async fn validate_fee( + &self, + raw_state_transition: JsValue, + ) -> Result { + let state_transition = + super::super::conversion::create_state_transition_from_wasm_instance( + &raw_state_transition, + )?; + + let validation_result = self + .0 + .validate_fee(&state_transition) + .await + .map_err(from_dpp_err)?; + + Ok(validation_result.map(|_| JsValue::undefined()).into()) + } } diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 51327609c2a..a99c6c92f1a 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -330,7 +330,7 @@ describe('StateTransitionFacade', () => { }); }); - describe.only('validateSignature', () => { + describe('validateSignature', () => { it('should validate identity signed State Transition', async () => { const result = await dpp.stateTransition.validateSignature( dataContractCreateTransition, @@ -364,23 +364,7 @@ describe('StateTransitionFacade', () => { }); }); - describe('validateFee', () => { - it('should throw MissingOption if stateRepository is not set', async () => { - dpp = new DashPlatformProtocol(); - await dpp.initialize(); - - try { - await dpp.stateTransition.validateFee( - dataContractCreateTransition, - ); - - expect.fail('MissingOption should be thrown'); - } catch (e) { - expect(e).to.be.an.instanceOf(MissingOptionError); - expect(e.getOptionName()).to.equal('stateRepository'); - } - }); - + describe.only('validateFee', () => { it('should validate State Transition', async () => { const result = await dpp.stateTransition.validateFee( dataContractCreateTransition, From 63307d270561e8887842e4f2e4a15c16043e916e Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Mon, 6 Mar 2023 18:20:53 +0000 Subject: [PATCH 40/54] feat(wasm-dpp): StateTransitionFacade validateState --- ...lidate_documents_batch_transition_state.rs | 39 ++++++++ .../validation/state/mod.rs | 49 +++++++++- .../validation/state/mod.rs | 44 ++++++++- .../state_transition_facade.rs | 50 +++++++--- .../src/state_transition/validation/mod.rs | 1 + .../validate_state_transition_state.rs | 94 +++++++++++++++++++ .../lib/test/fixtures/getDocumentsFixture.js | 10 +- ...ntity_create_transition_state_validator.rs | 2 +- ...entity_topup_transition_state_validator.rs | 2 +- .../state_transition_facade.rs | 24 ++++- .../StateTransitionFacade.spec.js | 25 +---- 11 files changed, 290 insertions(+), 50 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/validation/validate_state_transition_state.rs diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index 111c1348f55..fdf295c1b5e 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -1,9 +1,11 @@ use std::convert::TryInto; +use async_trait::async_trait; use futures::future::join_all; use itertools::Itertools; use crate::data_contract::errors::DataContractNotPresentError; +use crate::validation::{AsyncDataValidator, SimpleValidationResult}; use crate::{ block_time_window::validate_time_in_block_time_window::validate_time_in_block_time_window, consensus::ConsensusError, @@ -27,6 +29,43 @@ use super::{ validate_documents_uniqueness_by_indices::validate_documents_uniqueness_by_indices, }; +pub struct DocumentsBatchTransitionStateValidator +where + SR: StateRepositoryLike, +{ + state_repository: SR, +} + +#[async_trait(?Send)] +impl AsyncDataValidator for DocumentsBatchTransitionStateValidator +where + SR: StateRepositoryLike, +{ + type Item = DocumentsBatchTransition; + + async fn validate( + &self, + data: &DocumentsBatchTransition, + ) -> Result { + validate_document_batch_transition_state(&self.state_repository, data) + .await + .map(|result| result.into()) + .map_err(|err| err.into()) + } +} + +impl DocumentsBatchTransitionStateValidator +where + SR: StateRepositoryLike, +{ + pub fn new(state_repository: SR) -> DocumentsBatchTransitionStateValidator + where + SR: StateRepositoryLike, + { + DocumentsBatchTransitionStateValidator { state_repository } + } +} + pub async fn validate_document_batch_transition_state( state_repository: &impl StateRepositoryLike, state_transition: &DocumentsBatchTransition, diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs index de412a90ad6..02108ad78bb 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs @@ -2,8 +2,47 @@ use crate::consensus::state::identity::IdentityAlreadyExistsError; use crate::identity::state_transition::identity_create_transition::IdentityCreateTransition; use crate::state_repository::StateRepositoryLike; use crate::state_transition::StateTransitionLike; -use crate::validation::ValidationResult; -use crate::NonConsensusError; +use crate::validation::{AsyncDataValidator, SimpleValidationResult, ValidationResult}; +use crate::{NonConsensusError, ProtocolError}; +use async_trait::async_trait; +use std::sync::Arc; + +pub struct IdentityCreateTransitionStateValidator +where + SR: StateRepositoryLike, +{ + state_repository: SR, +} + +#[async_trait(?Send)] +impl AsyncDataValidator for IdentityCreateTransitionStateValidator +where + SR: StateRepositoryLike, +{ + type Item = IdentityCreateTransition; + + async fn validate( + &self, + data: &IdentityCreateTransition, + ) -> Result { + validate_identity_create_transition_state(&self.state_repository, data) + .await + .map(|result| result.into()) + .map_err(|err| err.into()) + } +} + +impl IdentityCreateTransitionStateValidator +where + SR: StateRepositoryLike, +{ + pub fn new(state_repository: SR) -> IdentityCreateTransitionStateValidator + where + SR: StateRepositoryLike, + { + IdentityCreateTransitionStateValidator { state_repository } + } +} /// Validate that identity exists /// @@ -14,8 +53,9 @@ use crate::NonConsensusError; /// 2. Verify ownership proof signature, as it requires special transaction to be implemented pub async fn validate_identity_create_transition_state( state_repository: &impl StateRepositoryLike, - state_transition: IdentityCreateTransition, + state_transition: &IdentityCreateTransition, ) -> Result, NonConsensusError> { + // TODO: refactor to return ProtocolError? let mut result = ValidationResult::default(); let identity_id = state_transition.get_identity_id(); @@ -56,7 +96,8 @@ mod test { .expect_fetch_identity_balance() .return_once(|_, _| Ok(Some(1))); - let result = validate_identity_create_transition_state(&state_repository, transition).await; + let result = + validate_identity_create_transition_state(&state_repository, &transition).await; assert!(result.is_ok()); } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/state/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/state/mod.rs index c1374d5186d..fd2dd71381c 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/state/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_topup_transition/validation/state/mod.rs @@ -1,7 +1,45 @@ use crate::identity::state_transition::identity_topup_transition::IdentityTopUpTransition; use crate::state_repository::StateRepositoryLike; -use crate::validation::ValidationResult; -use crate::NonConsensusError; +use crate::validation::{AsyncDataValidator, SimpleValidationResult, ValidationResult}; +use crate::{NonConsensusError, ProtocolError}; +use async_trait::async_trait; + +pub struct IdentityTopUpTransitionStateValidator +where + SR: StateRepositoryLike, +{ + state_repository: SR, +} + +#[async_trait(?Send)] +impl AsyncDataValidator for IdentityTopUpTransitionStateValidator +where + SR: StateRepositoryLike, +{ + type Item = IdentityTopUpTransition; + + async fn validate( + &self, + data: &IdentityTopUpTransition, + ) -> Result { + validate_identity_topup_transition_state(data, &self.state_repository) + .await + .map(|result| result.into()) + .map_err(|err| err.into()) + } +} + +impl IdentityTopUpTransitionStateValidator +where + SR: StateRepositoryLike, +{ + pub fn new(state_repository: SR) -> IdentityTopUpTransitionStateValidator + where + SR: StateRepositoryLike, + { + IdentityTopUpTransitionStateValidator { state_repository } + } +} /// Validate that identity exists /// @@ -11,7 +49,7 @@ use crate::NonConsensusError; /// 1. We need to check that outpoint exists (not now) /// 2. Verify ownership proof signature, as it requires special transaction to be implemented pub async fn validate_identity_topup_transition_state( - _state_transition: IdentityTopUpTransition, + _state_transition: &IdentityTopUpTransition, _state_repository: &impl StateRepositoryLike, ) -> Result, NonConsensusError> { Ok(ValidationResult::default()) diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index fd186607d5c..cb19dd7cc09 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -23,18 +23,20 @@ use crate::state_transition::validation::validate_state_transition_by_type::Stat use crate::state_transition::validation::validate_state_transition_fee::StateTransitionFeeValidator; use crate::state_transition::validation::validate_state_transition_identity_signature::validate_state_transition_identity_signature; use crate::state_transition::validation::validate_state_transition_key_signature::StateTransitionKeySignatureValidator; +use crate::state_transition::validation::validate_state_transition_state::StateTransitionStateValidator; use crate::validation::{AsyncDataValidator, AsyncDataValidatorWithContext, SimpleValidationResult}; use crate::version::ProtocolVersionValidator; #[derive(Clone)] pub struct StateTransitionFacade where - SR: StateRepositoryLike, + SR: StateRepositoryLike + Clone, BLS: BlsModule + Clone, { state_repository: Arc, basic_validator: Arc>>, + state_validator: Arc>, key_signature_validator: Arc>, fee_validator: Arc>, bls: BLS, // factory: StateTransitionFactory, @@ -43,11 +45,14 @@ where impl StateTransitionFacade where - SR: StateRepositoryLike, + SR: StateRepositoryLike + Clone, BLS: BlsModule + Clone, { - pub fn new(state_repository: Arc, adapter: BLS) -> Result { + pub fn new(state_repository: SR, adapter: BLS) -> Result { + let wrapped_state_repository = Arc::new(state_repository.clone()); + let state_transition_basic_validator; + let state_transition_state_validator; let state_transition_key_signature_validator; let state_transition_fee_validator; @@ -60,12 +65,13 @@ where })?); let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter.clone())); - let asset_lock_tx_validator = - Arc::new(AssetLockTransactionValidator::new(state_repository.clone())); + let asset_lock_tx_validator = Arc::new(AssetLockTransactionValidator::new( + wrapped_state_repository.clone(), + )); let asset_lock_validator = Arc::new(AssetLockProofValidator::new( InstantAssetLockProofStructureValidator::new( - state_repository.clone(), + wrapped_state_repository.clone(), asset_lock_tx_validator.clone(), ) .map_err(|_| { @@ -74,7 +80,7 @@ where )) })?, ChainAssetLockProofStructureValidator::new( - state_repository.clone(), + wrapped_state_repository.clone(), asset_lock_tx_validator.clone(), ) .map_err(|_| { @@ -85,13 +91,13 @@ where )); state_transition_basic_validator = StateTransitionBasicValidator::new( - state_repository.clone(), + wrapped_state_repository.clone(), StateTransitionByTypeValidator::new( DataContractCreateTransitionBasicValidator::new( protocol_version_validator.clone(), )?, DataContractUpdateTransitionBasicValidator::new( - state_repository.clone(), + wrapped_state_repository.clone(), protocol_version_validator.clone(), ) .map_err(|_| { @@ -135,7 +141,7 @@ where )) })?, DocumentBatchTransitionBasicValidator::new( - state_repository.clone(), + wrapped_state_repository.clone(), protocol_version_validator.clone(), ), ), @@ -144,26 +150,31 @@ where { let asset_lock_transaction_output_fetcher = - AssetLockTransactionOutputFetcher::new(state_repository.clone()); + AssetLockTransactionOutputFetcher::new(wrapped_state_repository.clone()); let asset_public_key_hash_fetcher = AssetLockPublicKeyHashFetcher::new( - state_repository.clone(), + wrapped_state_repository.clone(), asset_lock_transaction_output_fetcher, ); state_transition_key_signature_validator = StateTransitionKeySignatureValidator::new( - state_repository.clone(), + wrapped_state_repository.clone(), asset_public_key_hash_fetcher, ); } - state_transition_fee_validator = StateTransitionFeeValidator::new(state_repository.clone()); + state_transition_fee_validator = + StateTransitionFeeValidator::new(wrapped_state_repository.clone()); + + state_transition_state_validator = + StateTransitionStateValidator::new(state_repository.clone()); Ok(Self { - state_repository, + state_repository: wrapped_state_repository, basic_validator: Arc::new(state_transition_basic_validator), key_signature_validator: Arc::new(state_transition_key_signature_validator), fee_validator: Arc::new(state_transition_fee_validator), + state_validator: Arc::new(state_transition_state_validator), bls: adapter, }) } @@ -238,4 +249,13 @@ where ) -> Result { self.fee_validator.validate(state_transition).await } + + pub async fn validate_state( + &self, + state_transition: &StateTransition, + ) -> Result { + self.state_validator.validate(state_transition).await + } + + // pub async fn validate() -> Result {} } diff --git a/packages/rs-dpp/src/state_transition/validation/mod.rs b/packages/rs-dpp/src/state_transition/validation/mod.rs index 5a938c7adea..d44e7c550db 100644 --- a/packages/rs-dpp/src/state_transition/validation/mod.rs +++ b/packages/rs-dpp/src/state_transition/validation/mod.rs @@ -3,3 +3,4 @@ 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; +pub mod validate_state_transition_state; diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_state.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_state.rs new file mode 100644 index 00000000000..773feaefe97 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_state.rs @@ -0,0 +1,94 @@ +use crate::state_repository::StateRepositoryLike; +use std::sync::Arc; +use crate::data_contract::state_transition::data_contract_create_transition::validation::state::validate_data_contract_create_transition_state::DataContractCreateTransitionStateValidator; +use crate::data_contract::state_transition::data_contract_update_transition::validation::state::validate_data_contract_update_transition_state::DataContractUpdateTransitionStateValidator; +use crate::document::validation::state::validate_documents_batch_transition_state::DocumentsBatchTransitionStateValidator; +use crate::identity::state_transition::identity_create_transition::validation::state::IdentityCreateTransitionStateValidator; +use crate::identity::state_transition::identity_credit_withdrawal_transition::validation::state::validate_identity_credit_withdrawal_transition_state::IdentityCreditWithdrawalTransitionValidator; +use crate::identity::state_transition::identity_topup_transition::validation::state::IdentityTopUpTransitionStateValidator; +use crate::identity::state_transition::identity_update_transition::validate_identity_update_transition_state::IdentityUpdateTransitionStateValidator; +use crate::identity::state_transition::identity_update_transition::validate_public_keys::IdentityUpdatePublicKeysValidator; +use crate::ProtocolError; +use crate::state_transition::StateTransition; +use crate::validation::{AsyncDataValidator, SimpleValidationResult}; + +pub struct StateTransitionStateValidator +where + SR: StateRepositoryLike + Clone, +{ + state_repository: SR, + data_contract_create_validator: DataContractCreateTransitionStateValidator, + data_contract_update_validator: DataContractUpdateTransitionStateValidator, + identity_create_validator: IdentityCreateTransitionStateValidator, + identity_update_validator: + IdentityUpdateTransitionStateValidator, + identity_top_up_validator: IdentityTopUpTransitionStateValidator, + identity_credit_withdrawal_validator: IdentityCreditWithdrawalTransitionValidator, + document_batch_validator: DocumentsBatchTransitionStateValidator, +} + +impl StateTransitionStateValidator +where + SR: StateRepositoryLike + Clone, +{ + pub fn new(state_repository: SR) -> Self { + let wrapped_state_repository = Arc::new(state_repository.clone()); + + let data_contract_create_validator = + DataContractCreateTransitionStateValidator::new(state_repository.clone()); + let data_contract_update_validator = + DataContractUpdateTransitionStateValidator::new(state_repository.clone()); + let identity_create_validator = + IdentityCreateTransitionStateValidator::new(state_repository.clone()); + let identity_update_validator = IdentityUpdateTransitionStateValidator::new( + wrapped_state_repository.clone(), + Arc::new(IdentityUpdatePublicKeysValidator {}), + ); + let identity_top_up_validator = + IdentityTopUpTransitionStateValidator::new(state_repository.clone()); + let identity_credit_withdrawal_validator = + IdentityCreditWithdrawalTransitionValidator::new(wrapped_state_repository.clone()); + let document_batch_validator = + DocumentsBatchTransitionStateValidator::new(state_repository.clone()); + + StateTransitionStateValidator { + state_repository, + 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, + } + } + + pub async fn validate( + &self, + state_transition: &StateTransition, + ) -> Result { + match state_transition { + StateTransition::DataContractCreate(st) => { + self.data_contract_create_validator.validate(st).await + } + StateTransition::DataContractUpdate(st) => { + self.data_contract_update_validator.validate(st).await + } + StateTransition::IdentityCreate(st) => { + self.identity_create_validator.validate(st).await + } + StateTransition::IdentityUpdate(st) => self + .identity_update_validator + .validate(st) + .await + .map_err(|e| ProtocolError::from(e)), + StateTransition::IdentityTopUp(st) => self.identity_top_up_validator.validate(st).await, + StateTransition::IdentityCreditWithdrawal(st) => self + .identity_credit_withdrawal_validator + .validate_identity_credit_withdrawal_transition_state(st) + .await + .map_err(|e| ProtocolError::from(e)), + StateTransition::DocumentsBatch(st) => self.document_batch_validator.validate(st).await, + } + } +} diff --git a/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js b/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js index 436c12607be..15c363badbd 100644 --- a/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js +++ b/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js @@ -34,8 +34,14 @@ module.exports = async function getDocumentsFixture( factory.create(dataContract, ownerId, 'noTimeDocument', { name: 'ImOutOfTime' }), factory.create(dataContract, ownerId, 'uniqueDates', { firstName: 'John' }), factory.create(dataContract, ownerId, 'indexedDocument', { firstName: 'Bill', lastName: 'Gates' }), - // TODO: something strange is happening in case byte field is anything but "byteArrayField" - // factory.create(dataContract, ownerId, 'withByteArrays', { byteArrayField: crypto.randomBytes(10), identifierFields: await generateRandomIdentifierAsync() }), + // TODO: something strange is happening in case byte field's + // name is anything but "byteArrayField". + // adding "identifierFields" crashes factory.create + // factory.create(dataContract, ownerId, 'withByteArrays', + // { + // byteArrayField: crypto.randomBytes(10), + // identifierFields: await generateRandomIdentifierAsync() } + // ), factory.create(dataContract, ownerId, 'optionalUniqueIndexedDocument', { firstName: 'Jacques-Yves', lastName: 'Cousteau' }), ]; }; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_state_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_state_validator.rs index 6f240cb7775..e4f5f7abd7c 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_state_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_create_transition/identity_create_transition_state_validator.rs @@ -27,7 +27,7 @@ impl IdentityCreateTransitionStateValidator { ) -> Result { let validation_result = validate_identity_create_transition_state( &self.state_repository, - state_transition.to_owned().into(), + &state_transition.to_owned().into(), ) .await .map_err(|e| from_dpp_err(e.into()))?; diff --git a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition_state_validator.rs b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition_state_validator.rs index 04ad94d491c..b8e38429c99 100644 --- a/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition_state_validator.rs +++ b/packages/wasm-dpp/src/identity/state_transition/identity_topup_transition/identity_topup_transition_state_validator.rs @@ -26,7 +26,7 @@ impl IdentityTopUpTransitionStateValidator { state_transition: &IdentityTopUpTransitionWasm, ) -> Result { let validation_result = validate_identity_topup_transition_state( - state_transition.to_owned().into(), + &state_transition.to_owned().into(), &self.state_repository, ) .await diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index ee218254027..ee9beac3359 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -21,8 +21,7 @@ impl StateTransitionFacadeWasm { state_repository: ExternalStateRepositoryLike, bls_adapter: JsBlsAdapter, ) -> Result { - let state_repository_wrapper = - Arc::new(ExternalStateRepositoryLikeWrapper::new(state_repository)); + let state_repository_wrapper = ExternalStateRepositoryLikeWrapper::new(state_repository); let adapter = BlsAdapter(bls_adapter); @@ -82,8 +81,6 @@ impl StateTransitionFacadeWasm { .await .map_err(from_dpp_err)?; - web_sys::console::log_1(&"Validated st".into()); - Ok(validation_result.map(|_| JsValue::undefined()).into()) } @@ -105,4 +102,23 @@ impl StateTransitionFacadeWasm { Ok(validation_result.map(|_| JsValue::undefined()).into()) } + + #[wasm_bindgen(js_name = validateState)] + pub async fn validate_state( + &self, + raw_state_transition: JsValue, + ) -> Result { + let state_transition = + super::super::conversion::create_state_transition_from_wasm_instance( + &raw_state_transition, + )?; + + let validation_result = self + .0 + .validate_state(&state_transition) + .await + .map_err(from_dpp_err)?; + + Ok(validation_result.map(|_| JsValue::undefined()).into()) + } } diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index a99c6c92f1a..7616ad8a4b3 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -109,13 +109,14 @@ describe('StateTransitionFacade', () => { stateRepositoryMock = createStateRepositoryMock(this.sinonSandbox); stateRepositoryMock.fetchIdentity.resolves(identity); stateRepositoryMock.fetchLatestPlatformBlockTime.resolves(blockTime); + stateRepositoryMock.fetchDataContract.resolves(null); const blsAdapter = await getBlsAdapterMock(); dpp = new DashPlatformProtocol({}, blsAdapter, stateRepositoryMock); }); - describe('createFromObject', () => { + describe.skip('createFromObject', () => { it('should throw MissingOption if stateRepository is not set', async () => { dpp = new DashPlatformProtocol(); await dpp.initialize(); @@ -153,7 +154,7 @@ describe('StateTransitionFacade', () => { }); }); - describe('createFromBuffer', () => { + describe.skip('createFromBuffer', () => { it('should throw MissingOption if stateRepository is not set', async () => { dpp = new DashPlatformProtocol(); await dpp.initialize(); @@ -191,7 +192,7 @@ describe('StateTransitionFacade', () => { }); }); - describe('validate', () => { + describe.skip('validate', () => { let validateBasicSpy; let validateSignatureSpy; let validateFeeSpy; @@ -364,7 +365,7 @@ describe('StateTransitionFacade', () => { }); }); - describe.only('validateFee', () => { + describe('validateFee', () => { it('should validate State Transition', async () => { const result = await dpp.stateTransition.validateFee( dataContractCreateTransition, @@ -376,22 +377,6 @@ describe('StateTransitionFacade', () => { }); describe('validateState', () => { - it('should throw MissingOption if stateRepository is not set', async () => { - dpp = new DashPlatformProtocol(); - await dpp.initialize(); - - try { - await dpp.stateTransition.validateState( - dataContractCreateTransition, - ); - - expect.fail('MissingOption should be thrown'); - } catch (e) { - expect(e).to.be.an.instanceOf(MissingOptionError); - expect(e.getOptionName()).to.equal('stateRepository'); - } - }); - it('should validate State Transition', async () => { const result = await dpp.stateTransition.validateState( dataContractCreateTransition, From 457153e717cc63d15ed8c9013ab6820f9889bd67 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Wed, 8 Mar 2023 17:32:47 +0000 Subject: [PATCH 41/54] fix(rs-dpp): inconsistencies after rebase --- .../abstract_state_transition_identity_signed.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 309f062e3de..b97a716e659 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 @@ -42,9 +42,9 @@ where // the compressed key stored in the identity if public_key_compressed.to_vec() != identity_public_key.data { - return Err(ProtocolError::InvalidSignaturePublicKeyError { - public_key: identity_public_key.data.to_owned(), - }); + return Err(ProtocolError::InvalidSignaturePublicKeyError( + InvalidSignaturePublicKeyError::new(identity_public_key.data.to_owned()), + )); } self.sign_by_private_key(private_key, identity_public_key.key_type, bls) From 8d3689d01ebc26db5df7acc406de43e5da1f9e6a Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Wed, 8 Mar 2023 18:32:15 +0000 Subject: [PATCH 42/54] feat(wasm-dpp): integrated factory into StateTransitionFacade --- packages/rs-dpp/src/errors/errors.rs | 11 +- .../state_transition_facade.rs | 107 +++++++++++++++++- .../wasm-dpp/src/dash_platform_protocol.rs | 9 +- .../state_transition_facade.rs | 71 +++++++++++- .../state_transition_factory.rs | 80 ++++++------- .../StateTransitionFacade.spec.js | 62 +--------- 6 files changed, 233 insertions(+), 107 deletions(-) diff --git a/packages/rs-dpp/src/errors/errors.rs b/packages/rs-dpp/src/errors/errors.rs index 7f5b6f796d7..66e6dde4f13 100644 --- a/packages/rs-dpp/src/errors/errors.rs +++ b/packages/rs-dpp/src/errors/errors.rs @@ -13,7 +13,10 @@ use crate::state_transition::errors::{ PublicKeySecurityLevelNotMetError, StateTransitionError, StateTransitionIsNotSignedError, WrongPublicKeyPurposeError, }; -use crate::{CompatibleProtocolVersionIsNotDefinedError, NonConsensusError, SerdeParsingError}; +use crate::{ + CompatibleProtocolVersionIsNotDefinedError, DashPlatformProtocolInitError, NonConsensusError, + SerdeParsingError, +}; use platform_value::Error as ValueError; #[derive(Error, Debug)] @@ -170,3 +173,9 @@ impl From for ProtocolError { ProtocolError::ParsingError(e.to_string()) } } + +impl From for ProtocolError { + fn from(e: DashPlatformProtocolInitError) -> Self { + ProtocolError::Generic(e.to_string()) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index cb19dd7cc09..ad792d1551a 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -15,7 +15,7 @@ use crate::identity::state_transition::validate_public_key_signatures::PublicKey use crate::identity::validation::PublicKeysValidator; use crate::prelude::ValidationResult; use crate::state_repository::StateRepositoryLike; -use crate::state_transition::{StateTransition, StateTransitionFactory, StateTransitionIdentitySigned, StateTransitionLike}; +use crate::state_transition::{StateTransition, StateTransitionFactory, StateTransitionFactoryOptions, StateTransitionIdentitySigned, StateTransitionLike}; use crate::state_transition::fee::operations::{DeleteOperation, Operation}; use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::state_transition::validation::validate_state_transition_basic::StateTransitionBasicValidator; @@ -39,8 +39,8 @@ where state_validator: Arc>, key_signature_validator: Arc>, fee_validator: Arc>, - bls: BLS, // factory: StateTransitionFactory, - // state_transition_validator: StateTransitionValidator, + bls: BLS, + factory: Arc>, } impl StateTransitionFacade @@ -48,13 +48,85 @@ where SR: StateRepositoryLike + Clone, BLS: BlsModule + Clone, { - pub fn new(state_repository: SR, adapter: BLS) -> Result { + pub fn new( + state_repository: SR, + adapter: BLS, + protocol_version_validator: Arc, + ) -> Result { let wrapped_state_repository = Arc::new(state_repository.clone()); let state_transition_basic_validator; let state_transition_state_validator; let state_transition_key_signature_validator; let state_transition_fee_validator; + let state_transition_factory; + + { + let pk_validator = + Arc::new(PublicKeysValidator::new(adapter.clone()).map_err(ProtocolError::from)?); + let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter.clone())); + + let asset_lock_tx_validator = Arc::new(AssetLockTransactionValidator::new( + wrapped_state_repository.clone(), + )); + + let asset_lock_validator = Arc::new(AssetLockProofValidator::new( + InstantAssetLockProofStructureValidator::new( + wrapped_state_repository.clone(), + asset_lock_tx_validator.clone(), + ) + .map_err(ProtocolError::from)?, + ChainAssetLockProofStructureValidator::new( + wrapped_state_repository.clone(), + asset_lock_tx_validator.clone(), + ) + .map_err(ProtocolError::from)?, + )); + + state_transition_factory = StateTransitionFactory::new( + wrapped_state_repository.clone(), + StateTransitionBasicValidator::new( + wrapped_state_repository.clone(), + StateTransitionByTypeValidator::new( + DataContractCreateTransitionBasicValidator::new( + protocol_version_validator.clone(), + )?, + DataContractUpdateTransitionBasicValidator::new( + wrapped_state_repository.clone(), + protocol_version_validator.clone(), + ) + .map_err(ProtocolError::from)?, + IdentityCreateTransitionBasicValidator::new( + protocol_version_validator.deref().clone(), + pk_validator.clone(), + pk_validator.clone(), + asset_lock_validator.clone(), + adapter.clone(), + pk_sig_validator.clone(), + ) + .map_err(ProtocolError::from)?, + ValidateIdentityUpdateTransitionBasic::new( + ProtocolVersionValidator::default(), + pk_validator.clone(), + pk_sig_validator.clone(), + )?, + IdentityTopUpTransitionBasicValidator::new( + ProtocolVersionValidator::default(), + asset_lock_validator.clone(), + ) + .map_err(ProtocolError::from)?, + IdentityCreditWithdrawalTransitionBasicValidator::new( + protocol_version_validator.clone(), + ) + .map_err(ProtocolError::from)?, + DocumentBatchTransitionBasicValidator::new( + wrapped_state_repository.clone(), + protocol_version_validator.clone(), + ), + ), + ), + ); + } { let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); @@ -171,6 +243,7 @@ where Ok(Self { state_repository: wrapped_state_repository, + factory: Arc::new(state_transition_factory), basic_validator: Arc::new(state_transition_basic_validator), key_signature_validator: Arc::new(state_transition_key_signature_validator), fee_validator: Arc::new(state_transition_fee_validator), @@ -179,6 +252,32 @@ where }) } + pub async fn create_from_object( + &self, + state_transition: Value, + skip_validation: bool, + ) -> Result { + self.factory + .create_from_object( + state_transition, + Some(StateTransitionFactoryOptions { skip_validation }), + ) + .await + } + + pub async fn create_from_buffer( + &self, + buffer: &[u8], + skip_validation: bool, + ) -> Result { + self.factory + .create_from_buffer( + buffer, + Some(StateTransitionFactoryOptions { skip_validation }), + ) + .await + } + pub async fn validate_basic( &self, state_transition: &Value, diff --git a/packages/wasm-dpp/src/dash_platform_protocol.rs b/packages/wasm-dpp/src/dash_platform_protocol.rs index 8ff140961e6..b71ca7948ca 100644 --- a/packages/wasm-dpp/src/dash_platform_protocol.rs +++ b/packages/wasm-dpp/src/dash_platform_protocol.rs @@ -62,10 +62,13 @@ impl DashPlatformProtocol { ); let data_contract_facade = - DataContractFacadeWasm::new(protocol_version, protocol_version_validator); + DataContractFacadeWasm::new(protocol_version, protocol_version_validator.clone()); - let state_transition_facade = - StateTransitionFacadeWasm::new(state_repository, bls_adapter)?; + let state_transition_facade = StateTransitionFacadeWasm::new( + state_repository, + bls_adapter, + protocol_version_validator, + )?; Ok(Self { document: document_facade, diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index ee9beac3359..ee485dc15d9 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -1,10 +1,16 @@ use crate::bls_adapter::{BlsAdapter, JsBlsAdapter}; use crate::errors::from_dpp_err; use crate::state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}; +use crate::state_transition_factory::StateTransitionFactoryWasm; use crate::utils::ToSerdeJSONExt; use crate::validation::ValidationResultWasm; +use crate::with_js_error; use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; -use dpp::state_transition::{StateTransitionConvert, StateTransitionFacade, StateTransitionLike}; +use dpp::state_transition::{ + StateTransitionConvert, StateTransitionFacade, StateTransitionFactory, StateTransitionLike, +}; +use dpp::version::ProtocolVersionValidator; +use serde::{Deserialize, Serialize}; use serde_json::Value; use std::sync::Arc; use wasm_bindgen::prelude::*; @@ -20,20 +26,79 @@ impl StateTransitionFacadeWasm { pub fn new( state_repository: ExternalStateRepositoryLike, bls_adapter: JsBlsAdapter, + protocol_version_validator: Arc, ) -> Result { let state_repository_wrapper = ExternalStateRepositoryLikeWrapper::new(state_repository); let adapter = BlsAdapter(bls_adapter); - let state_transition_facade = - StateTransitionFacade::new(state_repository_wrapper, adapter).map_err(from_dpp_err)?; + let state_transition_facade = StateTransitionFacade::new( + state_repository_wrapper, + adapter, + protocol_version_validator, + ) + .map_err(from_dpp_err)?; Ok(StateTransitionFacadeWasm(state_transition_facade)) } } +#[derive(Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct FromObjectOptions { + pub skip_validation: Option, +} + #[wasm_bindgen(js_class = StateTransitionFacade)] impl StateTransitionFacadeWasm { + #[wasm_bindgen(js_name = createFromObject)] + pub async fn create_from_object( + &self, + raw_state_transition: JsValue, + options: JsValue, + ) -> Result { + let options: FromObjectOptions = if options.is_object() { + with_js_error!(serde_wasm_bindgen::from_value(options))? + } else { + Default::default() + }; + + let raw_state_transition = raw_state_transition.with_serde_to_json_value()?; + + let result = self + .0 + .create_from_object( + raw_state_transition, + options.skip_validation.unwrap_or(false), + ) + .await; + + StateTransitionFactoryWasm::state_transition_wasm_from_factory_result(result) + } + + #[wasm_bindgen(js_name = createFromBuffer)] + pub async fn create_from_buffer( + &self, + state_transition_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( + &state_transition_buffer, + options.skip_validation.unwrap_or(false), + ) + .await; + + StateTransitionFactoryWasm::state_transition_wasm_from_factory_result(result) + } + #[wasm_bindgen(js_name = validateBasic)] pub async fn validate_basic( &self, 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..8a5596bb79d 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -38,6 +38,47 @@ impl From } } +impl StateTransitionFactoryWasm { + pub fn state_transition_wasm_from_factory_result( + result: Result, + ) -> Result { + match result { + 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, + raw_state_transition, + } => Err(InvalidStateTransitionError::new( + errors, + serde_wasm_bindgen::to_value(&raw_state_transition)?, + ) + .into()), + }, + Err(other) => Err(from_dpp_err(other)), + } + } +} + #[wasm_bindgen(js_class = StateTransitionFactory)] impl StateTransitionFactoryWasm { #[wasm_bindgen(constructor)] @@ -172,43 +213,4 @@ impl StateTransitionFactoryWasm { Self::state_transition_wasm_from_factory_result(result) } - - fn state_transition_wasm_from_factory_result( - result: Result, - ) -> Result { - match result { - 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, - raw_state_transition, - } => Err(InvalidStateTransitionError::new( - errors, - serde_wasm_bindgen::to_value(&raw_state_transition)?, - ) - .into()), - }, - Err(other) => Err(from_dpp_err(other)), - } - } } diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 7616ad8a4b3..5205578cdc2 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -2,7 +2,7 @@ const { PrivateKey } = require('@dashevo/dashcore-lib'); // const DashPlatformProtocol = require('@dashevo/dpp/lib/DashPlatformProtocol'); -const DataContractCreateTransition = require('@dashevo/dpp/lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition'); +// const DataContractCreateTransition = require('@dashevo/dpp/lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition'); // const ValidationResult = require('@dashevo/dpp/lib/validation/ValidationResult'); @@ -37,7 +37,7 @@ describe('StateTransitionFacade', () => { let DashPlatformProtocol; let DataContractFactory; let DataContractValidator; - let DataContract; + let DataContractCreateTransition; let Identity; let ValidationResult; let IdentityPublicKey; @@ -50,7 +50,7 @@ describe('StateTransitionFacade', () => { ({ DashPlatformProtocol, ValidationResult, - DataContract, + DataContractCreateTransition, Identity, DataContractValidator, DataContractFactory, @@ -116,33 +116,7 @@ describe('StateTransitionFacade', () => { dpp = new DashPlatformProtocol({}, blsAdapter, stateRepositoryMock); }); - describe.skip('createFromObject', () => { - it('should throw MissingOption if stateRepository is not set', async () => { - dpp = new DashPlatformProtocol(); - await dpp.initialize(); - - try { - await dpp.stateTransition.createFromObject( - dataContractCreateTransition.toObject(), - ); - - expect.fail('MissingOption should be thrown'); - } catch (e) { - expect(e).to.be.an.instanceOf(MissingOptionError); - expect(e.getOptionName()).to.equal('stateRepository'); - } - }); - - it('should skip checking for state repository if skipValidation is set', async () => { - dpp = new DashPlatformProtocol(); - await dpp.initialize(); - - await dpp.stateTransition.createFromObject( - dataContractCreateTransition.toObject(), - { skipValidation: true }, - ); - }); - + describe('createFromObject', () => { it('should create State Transition from plain object', async () => { const result = await dpp.stateTransition.createFromObject( dataContractCreateTransition.toObject(), @@ -154,33 +128,7 @@ describe('StateTransitionFacade', () => { }); }); - describe.skip('createFromBuffer', () => { - it('should throw MissingOption if stateRepository is not set', async () => { - dpp = new DashPlatformProtocol(); - await dpp.initialize(); - - try { - await dpp.stateTransition.createFromBuffer( - dataContractCreateTransition.toBuffer(), - ); - - expect.fail('MissingOption should be thrown'); - } catch (e) { - expect(e).to.be.an.instanceOf(MissingOptionError); - expect(e.getOptionName()).to.equal('stateRepository'); - } - }); - - it('should skip checking for state repository if skipValidation is set', async () => { - dpp = new DashPlatformProtocol(); - await dpp.initialize(); - - await dpp.stateTransition.createFromBuffer( - dataContractCreateTransition.toBuffer(), - { skipValidation: true }, - ); - }); - + describe('createFromBuffer', () => { it('should create State Transition from string', async () => { const result = await dpp.stateTransition.createFromBuffer( dataContractCreateTransition.toBuffer(), From 799ccb46901fe6bb27d408d896feff77d6764a4a Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Thu, 9 Mar 2023 13:01:16 +0000 Subject: [PATCH 43/54] fix(dpp): missing error mapping for failed signature verification --- .../abstract_state_transition.rs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index 11944eaf417..da7e2ae8e68 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -4,6 +4,8 @@ use dashcore::signer; use serde::Serialize; use serde_json::Value as JsonValue; +use crate::consensus::ConsensusError; +use crate::errors::consensus::signature::SignatureError; use crate::state_transition::errors::{ InvalidIdentityPublicKeyTypeError, StateTransitionIsNotSignedError, }; @@ -118,11 +120,11 @@ pub trait StateTransitionLike: )); } let data_hash = self.hash(true)?; - Ok(signer::verify_hash_signature( - &data_hash, - self.get_signature(), - public_key_hash, - )?) + signer::verify_hash_signature(&data_hash, self.get_signature(), public_key_hash).or(Err( + ProtocolError::from(ConsensusError::SignatureError( + SignatureError::InvalidStateTransitionSignatureError, + )), + )) } /// Verifies an ECDSA signature with the public key @@ -133,11 +135,12 @@ pub trait StateTransitionLike: )); } let data = self.to_buffer(true)?; - Ok(signer::verify_data_signature( - &data, - self.get_signature(), - public_key, - )?) + + signer::verify_data_signature(&data, self.get_signature(), public_key).or(Err( + ProtocolError::from(ConsensusError::SignatureError( + SignatureError::InvalidStateTransitionSignatureError, + )), + )) } /// Verifies a BLS signature with the public key @@ -156,6 +159,9 @@ pub trait StateTransitionLike: bls.verify_signature(self.get_signature(), &data, public_key) .map(|_| ()) + .or(Err(ProtocolError::from(ConsensusError::SignatureError( + SignatureError::InvalidStateTransitionSignatureError, + )))) } /// returns true if state transition is a document state transition From 1efa4d518bbfdcdd3377aaa578be37ad102af03c Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Thu, 9 Mar 2023 15:11:00 +0000 Subject: [PATCH 44/54] fix(dpp): missing signature public key id in signature property paths --- .../state_transition/documents_batch_transition/mod.rs | 5 ++++- .../identity_update_transition/identity_update_transition.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/mod.rs index 6e55139da35..d19b2ed19a6 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 @@ -243,7 +243,10 @@ impl StateTransitionConvert for DocumentsBatchTransition { } fn signature_property_paths() -> Vec<&'static str> { - vec![property_names::SIGNATURE] + vec![ + property_names::SIGNATURE, + property_names::SIGNATURE_PUBLIC_KEY_ID, + ] } fn to_json(&self, skip_signature: bool) -> Result { 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 fe674c5a32f..3d45a8ff519 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 @@ -241,7 +241,10 @@ impl StateTransitionConvert for IdentityUpdateTransition { } fn signature_property_paths() -> Vec<&'static str> { - vec![property_names::SIGNATURE] + vec![ + property_names::SIGNATURE, + property_names::SIGNATURE_PUBLIC_KEY_ID, + ] } fn to_object(&self, skip_signature: bool) -> Result { From d9e32969366bfce8b92e0fdfa38923b2790d4de6 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Thu, 9 Mar 2023 15:18:18 +0000 Subject: [PATCH 45/54] feat(wasm-dpp): state_transition_facade validate --- .../state_transition_facade.rs | 64 ++++++++++- .../state_transition_facade.rs | 89 ++++++++++++++- .../StateTransitionFacade.spec.js | 103 ++++++------------ 3 files changed, 177 insertions(+), 79 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index ad792d1551a..bd2299fc09d 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -278,6 +278,52 @@ where .await } + pub async fn validate( + &self, + state_transition: &StateTransition, + // TODO: revisit after https://github.com/dashpay/platform/pull/809 is merged + // we need to pass state_transition_json here because `StateTransition#to_object` output + // does not pass basic validation, and we use other means of producing JSON value for validation + state_transition_json: &Value, + execution_context: &StateTransitionExecutionContext, + options: ValidateOptions, + ) -> Result { + let mut result = SimpleValidationResult::default(); + + if options.basic { + result.merge( + self.validate_basic(state_transition_json, execution_context) + .await?, + ); + } + + if !result.is_valid() { + return Ok(result); + } + + if options.signature { + result.merge(self.validate_signature(state_transition.clone()).await?); + } + + if !result.is_valid() { + return Ok(result); + } + + if options.fee { + result.merge(self.validate_fee(state_transition).await?); + } + + if !result.is_valid() { + return Ok(result); + } + + if options.state { + result.merge(self.validate_state(state_transition).await?); + } + + Ok(result) + } + pub async fn validate_basic( &self, state_transition: &Value, @@ -355,6 +401,22 @@ where ) -> Result { self.state_validator.validate(state_transition).await } +} + +pub struct ValidateOptions { + pub basic: bool, + pub signature: bool, + pub fee: bool, + pub state: bool, +} - // pub async fn validate() -> Result {} +impl Default for ValidateOptions { + fn default() -> Self { + Self { + basic: true, + signature: true, + fee: true, + state: true, + } + } } diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index ee485dc15d9..b735a47689f 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -8,6 +8,7 @@ use crate::with_js_error; use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use dpp::state_transition::{ StateTransitionConvert, StateTransitionFacade, StateTransitionFactory, StateTransitionLike, + ValidateOptions, }; use dpp::version::ProtocolVersionValidator; use serde::{Deserialize, Serialize}; @@ -43,12 +44,6 @@ impl StateTransitionFacadeWasm { } } -#[derive(Deserialize, Default)] -#[serde(rename_all = "camelCase")] -pub struct FromObjectOptions { - pub skip_validation: Option, -} - #[wasm_bindgen(js_class = StateTransitionFacade)] impl StateTransitionFacadeWasm { #[wasm_bindgen(js_name = createFromObject)] @@ -99,6 +94,59 @@ impl StateTransitionFacadeWasm { StateTransitionFactoryWasm::state_transition_wasm_from_factory_result(result) } + #[wasm_bindgen] + pub async fn validate( + &self, + raw_state_transition: JsValue, + options: JsValue, + ) -> Result { + let options: ValidateOptionsWasm = if options.is_object() { + with_js_error!(serde_wasm_bindgen::from_value(options))? + } else { + Default::default() + }; + + let (state_transition, state_transition_json, execution_context) = + if let Ok(state_transition) = + super::super::conversion::create_state_transition_from_wasm_instance( + &raw_state_transition, + ) + { + let execution_context = state_transition.get_execution_context().to_owned(); + // TODO: revisit after https://github.com/dashpay/platform/pull/809 is merged + // we use this workaround to produce JSON value for validation because + // state_transition.to_object() returns value that does not pass basic validation + let state_transition_json = + super::super::conversion::state_transition_wasm_to_object( + &raw_state_transition, + )? + .with_serde_to_json_value()?; + (state_transition, state_transition_json, execution_context) + } else { + let state_transition_json = raw_state_transition.with_serde_to_json_value()?; + let execution_context = StateTransitionExecutionContext::default(); + let state_transition = self + .0 + .create_from_object(state_transition_json.clone(), true) + .await + .map_err(from_dpp_err)?; + (state_transition, state_transition_json, execution_context) + }; + + let validation_result = self + .0 + .validate( + &state_transition, + &state_transition_json, + &execution_context, + options.into(), + ) + .await + .map_err(from_dpp_err)?; + + Ok(validation_result.map(|_| JsValue::undefined()).into()) + } + #[wasm_bindgen(js_name = validateBasic)] pub async fn validate_basic( &self, @@ -113,6 +161,9 @@ impl StateTransitionFacadeWasm { ) { execution_context = state_transition.get_execution_context().to_owned(); + // TODO: revisit after https://github.com/dashpay/platform/pull/809 is merged + // we use this workaround to produce JSON value for validation because + // state_transition.to_object() returns value that does not pass basic validation state_transition_json = super::super::conversion::state_transition_wasm_to_object(&raw_state_transition)? .with_serde_to_json_value()?; @@ -187,3 +238,29 @@ impl StateTransitionFacadeWasm { Ok(validation_result.map(|_| JsValue::undefined()).into()) } } + +#[derive(Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct FromObjectOptions { + pub skip_validation: Option, +} + +#[derive(Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct ValidateOptionsWasm { + pub basic: Option, + pub signature: Option, + pub fee: Option, + pub state: Option, +} + +impl From for ValidateOptions { + fn from(options: ValidateOptionsWasm) -> Self { + Self { + basic: options.basic.unwrap_or(true), + signature: options.signature.unwrap_or(true), + fee: options.fee.unwrap_or(true), + state: options.state.unwrap_or(true), + } + } +} diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 5205578cdc2..81f1aabe5d9 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -33,6 +33,7 @@ describe('StateTransitionFacade', () => { let stateRepositoryMock; let dataContract; let identityPublicKey; + let identity; let DashPlatformProtocol; let DataContractFactory; @@ -45,6 +46,10 @@ describe('StateTransitionFacade', () => { let DocumentValidator; let ProtocolVersionValidator; let IdentityCreateTransition; + let UnsupportedProtocolVersionError; + let InvalidStateTransitionSignatureError; + let DataContractAlreadyPresentError; + let BalanceIsNotEnoughError; before(async () => { ({ @@ -59,6 +64,10 @@ describe('StateTransitionFacade', () => { DocumentValidator, ProtocolVersionValidator, IdentityCreateTransition, + UnsupportedProtocolVersionError, + InvalidStateTransitionSignatureError, + DataContractAlreadyPresentError, + BalanceIsNotEnoughError, } = await loadWasmDpp()); }); @@ -101,7 +110,8 @@ describe('StateTransitionFacade', () => { const identityObjectJS = getIdentityFixture().toObject(); identityObjectJS.id = await generateRandomIdentifierAsync(); - const identity = new Identity(identityObjectJS); + identityObjectJS.balance = 10000000; + identity = new Identity(identityObjectJS); identity.setPublicKeys([identityPublicKey]); const blockTime = Date.now(); @@ -140,95 +150,59 @@ describe('StateTransitionFacade', () => { }); }); - describe.skip('validate', () => { + describe('validate', () => { let validateBasicSpy; let validateSignatureSpy; let validateFeeSpy; let validateStateSpy; - beforeEach(function beforeEach() { - validateBasicSpy = this.sinonSandbox.spy( - dpp.stateTransition, - 'validateBasic', - ); - - validateSignatureSpy = this.sinonSandbox.spy( - dpp.stateTransition, - 'validateSignature', - ); - - validateFeeSpy = this.sinonSandbox.spy( - dpp.stateTransition, - 'validateFee', - ); - - validateStateSpy = this.sinonSandbox.spy( - dpp.stateTransition, - 'validateState', - ); - }); - it('should return invalid result if State Transition structure is invalid', async () => { const rawStateTransition = dataContractCreateTransition.toObject(); - delete rawStateTransition.protocolVersion; + rawStateTransition.protocolVersion = 100; const result = await dpp.stateTransition.validate(rawStateTransition); expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.false(); - - expect(validateBasicSpy).to.be.calledOnceWithExactly(rawStateTransition); - expect(validateSignatureSpy).to.not.be.called(); - expect(validateFeeSpy).to.not.be.called(); - expect(validateStateSpy).to.not.be.called(); + const errors = result.getErrors(); + expect(errors).to.have.lengthOf(1); + expect(errors[0]).to.be.instanceOf(UnsupportedProtocolVersionError); }); it('should return invalid result if State Transition signature is invalid', async () => { - dataContractCreateTransition.signature = Buffer.alloc(65).fill(1); + const rawStateTransition = dataContractCreateTransition.toObject(); + rawStateTransition.signature = Buffer.alloc(65).fill(1); - const result = await dpp.stateTransition.validate(dataContractCreateTransition); + const result = await dpp.stateTransition.validate(rawStateTransition); expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.false(); - - expect(validateBasicSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateSignatureSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateFeeSpy).to.not.be.called(); - expect(validateStateSpy).to.not.be.called(); + const errors = result.getErrors(); + expect(errors).to.have.lengthOf(1); + expect(errors[0]).to.be.instanceOf(InvalidStateTransitionSignatureError); }); it('should return invalid result if not enough balance to pay fee for State Transition', async () => { - const consensusError = new SomeConsensusError('error'); - - dpp.stateTransition.validateStateTransitionFee = () => new ValidationResult([consensusError]); - + identity.setBalance(0); const result = await dpp.stateTransition.validate(dataContractCreateTransition); expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.false(); - - expect(validateBasicSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateSignatureSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateFeeSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateStateSpy).to.not.be.called(); + const errors = result.getErrors(); + expect(errors).to.have.lengthOf(1); + expect(errors[0]).to.be.instanceOf(BalanceIsNotEnoughError); }); it('should return invalid result if State Transition is invalid against state', async () => { - const consensusError = new SomeConsensusError('error'); - - dpp.stateTransition.validateStateTransitionState = () => ( - new ValidationResult([consensusError]) - ); + stateRepositoryMock.fetchDataContract.resolves(dataContract); const result = await dpp.stateTransition.validate(dataContractCreateTransition); expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.false(); - - expect(validateBasicSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateSignatureSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateFeeSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateStateSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); + const errors = result.getErrors(); + expect(errors).to.have.lengthOf(1); + expect(errors[0]).to.be.instanceOf(DataContractAlreadyPresentError); }); it('should validate DataContractCreateTransition', async () => { @@ -238,33 +212,18 @@ describe('StateTransitionFacade', () => { expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); - - expect(validateBasicSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateSignatureSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateFeeSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); - expect(validateStateSpy).to.be.calledOnceWithExactly(dataContractCreateTransition); }); - it('should validate DocumentsBatchTransition', async function it() { + it('should validate DocumentsBatchTransition', async () => { stateRepositoryMock.fetchDocuments.resolves([]); stateRepositoryMock.fetchDataContract.resolves(dataContract); - stateRepositoryMock.fetchIdentity.resolves({ - getPublicKeyById: this.sinonSandbox.stub().returns(identityPublicKey), - getBalance: this.sinonSandbox.stub().returns(10000), - }); - const result = await dpp.stateTransition.validate( documentsBatchTransition, ); expect(result).to.be.an.instanceOf(ValidationResult); expect(result.isValid()).to.be.true(); - - expect(validateBasicSpy).to.be.calledOnceWithExactly(documentsBatchTransition); - expect(validateSignatureSpy).to.be.calledOnceWithExactly(documentsBatchTransition); - expect(validateFeeSpy).to.be.calledOnceWithExactly(documentsBatchTransition); - expect(validateStateSpy).to.be.calledOnceWithExactly(documentsBatchTransition); }); }); From 5a3813dc8cded98316192d6accfbfaac1bc0ae6e Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Thu, 9 Mar 2023 15:43:29 +0000 Subject: [PATCH 46/54] test(rs-dpp): fix failing tests --- ...lidate_state_transition_identity_signature.rs | 16 ++++++++-------- .../identity_update_transition_spec.rs | 1 - 2 files changed, 8 insertions(+), 9 deletions(-) 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 d53dc1e946f..4ee297966b1 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 @@ -318,7 +318,7 @@ mod test { .returning(move |_, _| Ok(Some(identity.clone()))); let result = validate_state_transition_identity_signature( - &state_repository_mock, + Arc::new(state_repository_mock), &mut state_transition, &bls, ) @@ -343,7 +343,7 @@ mod test { .returning(move |_, _| Ok(None)); let result = validate_state_transition_identity_signature( - &state_repository_mock, + Arc::new(state_repository_mock), &mut state_transition, &bls, ) @@ -376,7 +376,7 @@ mod test { .returning(move |_, _| Ok(Some(identity.clone()))); let result = validate_state_transition_identity_signature( - &state_repository_mock, + Arc::new(state_repository_mock), &mut state_transition, &bls, ) @@ -408,7 +408,7 @@ mod test { state_transition.return_error = Some(0); let result = validate_state_transition_identity_signature( - &state_repository_mock, + Arc::new(state_repository_mock), &mut state_transition, &bls, ) @@ -441,7 +441,7 @@ mod test { state_transition.return_error = Some(1); let result = validate_state_transition_identity_signature( - &state_repository_mock, + Arc::new(state_repository_mock), &mut state_transition, &bls, ) @@ -472,7 +472,7 @@ mod test { state_transition.get_execution_context().enable_dry_run(); let result = validate_state_transition_identity_signature( - &state_repository_mock, + Arc::new(state_repository_mock), &mut state_transition, &bls, ) @@ -499,7 +499,7 @@ mod test { state_transition.return_error = Some(2); let result = validate_state_transition_identity_signature( - &state_repository_mock, + Arc::new(state_repository_mock), &mut state_transition, &bls, ) @@ -530,7 +530,7 @@ mod test { state_transition.return_error = Some(3); let result = validate_state_transition_identity_signature( - &state_repository_mock, + Arc::new(state_repository_mock), &mut state_transition, &bls, ) diff --git a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs index 60ddaf9290c..32ca4d6b002 100644 --- a/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs +++ b/packages/rs-dpp/src/tests/identity/state_transition/identity_update_transition/identity_update_transition_spec.rs @@ -170,7 +170,6 @@ fn to_object_with_signature_skipped() { let expected_raw_state_transition = json!({ "protocolVersion" : 1, "type" : 5, - "signaturePublicKeyId": 0, "identityId" : transition.identity_id.to_buffer(), "revision": 0, "disablePublicKeys" : [0], From a000041562ac81a43ab8b2f5e2a484585db84797 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Thu, 9 Mar 2023 15:43:37 +0000 Subject: [PATCH 47/54] test(wasm-dpp): fix failing tests --- .../wasm-dpp/test/integration/document/DocumentFacade.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js index e99cb705041..3dda287b469 100644 --- a/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js +++ b/packages/wasm-dpp/test/integration/document/DocumentFacade.spec.js @@ -45,7 +45,7 @@ describe('DocumentFacade', () => { stateRepositoryMock.fetchDataContract.resolves(dataContract); blsAdapter = await getBlsAdapterMock(); - dpp = new DashPlatformProtocol(blsAdapter, stateRepositoryMock); + dpp = new DashPlatformProtocol({}, blsAdapter, stateRepositoryMock); documentsJs = getDocumentsFixture(dataContractJs); documents = documentsJs.map((d) => { From e20a3d8bdd87ed3a5480f22352688c3c418688cd Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Thu, 9 Mar 2023 16:51:15 +0000 Subject: [PATCH 48/54] chore: clippy and eslint --- ...lidate_documents_batch_transition_state.rs | 5 +-- .../validation/state/mod.rs | 2 -- .../state_transition_facade.rs | 33 ++++++++++--------- .../validate_state_transition_state.rs | 2 +- .../state_transition_facade.rs | 9 ++--- .../StateTransitionFacade.spec.js | 19 ----------- 6 files changed, 23 insertions(+), 47 deletions(-) diff --git a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs index fdf295c1b5e..0ec38c12942 100644 --- a/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs +++ b/packages/rs-dpp/src/document/state_transition/documents_batch_transition/validation/state/validate_documents_batch_transition_state.rs @@ -47,10 +47,7 @@ where &self, data: &DocumentsBatchTransition, ) -> Result { - validate_document_batch_transition_state(&self.state_repository, data) - .await - .map(|result| result.into()) - .map_err(|err| err.into()) + validate_document_batch_transition_state(&self.state_repository, data).await } } diff --git a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs index 02108ad78bb..680867e8774 100644 --- a/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/identity_create_transition/validation/state/mod.rs @@ -5,7 +5,6 @@ use crate::state_transition::StateTransitionLike; use crate::validation::{AsyncDataValidator, SimpleValidationResult, ValidationResult}; use crate::{NonConsensusError, ProtocolError}; use async_trait::async_trait; -use std::sync::Arc; pub struct IdentityCreateTransitionStateValidator where @@ -27,7 +26,6 @@ where ) -> Result { validate_identity_create_transition_state(&self.state_repository, data) .await - .map(|result| result.into()) .map_err(|err| err.into()) } } diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index bd2299fc09d..690aa49a9b3 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -1,5 +1,5 @@ use std::ops::Deref; -use std::rc::Rc; + use std::sync::Arc; use serde_json::Value; use crate::{BlsModule, ProtocolError}; @@ -13,10 +13,12 @@ use crate::identity::state_transition::identity_topup_transition::validation::ba use crate::identity::state_transition::identity_update_transition::validate_identity_update_transition_basic::ValidateIdentityUpdateTransitionBasic; use crate::identity::state_transition::validate_public_key_signatures::PublicKeysSignaturesValidator; use crate::identity::validation::PublicKeysValidator; -use crate::prelude::ValidationResult; + use crate::state_repository::StateRepositoryLike; -use crate::state_transition::{StateTransition, StateTransitionFactory, StateTransitionFactoryOptions, StateTransitionIdentitySigned, StateTransitionLike}; -use crate::state_transition::fee::operations::{DeleteOperation, Operation}; +use crate::state_transition::{ + StateTransition, StateTransitionFactory, StateTransitionFactoryOptions, +}; + use crate::state_transition::state_transition_execution_context::StateTransitionExecutionContext; use crate::state_transition::validation::validate_state_transition_basic::StateTransitionBasicValidator; use crate::state_transition::validation::validate_state_transition_by_type::StateTransitionByTypeValidator; @@ -24,7 +26,9 @@ use crate::state_transition::validation::validate_state_transition_fee::StateTra use crate::state_transition::validation::validate_state_transition_identity_signature::validate_state_transition_identity_signature; use crate::state_transition::validation::validate_state_transition_key_signature::StateTransitionKeySignatureValidator; use crate::state_transition::validation::validate_state_transition_state::StateTransitionStateValidator; -use crate::validation::{AsyncDataValidator, AsyncDataValidatorWithContext, SimpleValidationResult}; +use crate::validation::{ + AsyncDataValidator, AsyncDataValidatorWithContext, SimpleValidationResult, +}; use crate::version::ProtocolVersionValidator; #[derive(Clone)] @@ -78,7 +82,7 @@ where .map_err(ProtocolError::from)?, ChainAssetLockProofStructureValidator::new( wrapped_state_repository.clone(), - asset_lock_tx_validator.clone(), + asset_lock_tx_validator, ) .map_err(ProtocolError::from)?, )); @@ -107,12 +111,12 @@ where .map_err(ProtocolError::from)?, ValidateIdentityUpdateTransitionBasic::new( ProtocolVersionValidator::default(), - pk_validator.clone(), - pk_sig_validator.clone(), + pk_validator, + pk_sig_validator, )?, IdentityTopUpTransitionBasicValidator::new( ProtocolVersionValidator::default(), - asset_lock_validator.clone(), + asset_lock_validator, ) .map_err(ProtocolError::from)?, IdentityCreditWithdrawalTransitionBasicValidator::new( @@ -153,7 +157,7 @@ where })?, ChainAssetLockProofStructureValidator::new( wrapped_state_repository.clone(), - asset_lock_tx_validator.clone(), + asset_lock_tx_validator, ) .map_err(|_| { ProtocolError::Generic(String::from( @@ -192,12 +196,12 @@ where })?, ValidateIdentityUpdateTransitionBasic::new( ProtocolVersionValidator::default(), - pk_validator.clone(), - pk_sig_validator.clone(), + pk_validator, + pk_sig_validator, )?, IdentityTopUpTransitionBasicValidator::new( ProtocolVersionValidator::default(), - asset_lock_validator.clone(), + asset_lock_validator, ) .map_err(|_| { ProtocolError::Generic(String::from( @@ -238,8 +242,7 @@ where state_transition_fee_validator = StateTransitionFeeValidator::new(wrapped_state_repository.clone()); - state_transition_state_validator = - StateTransitionStateValidator::new(state_repository.clone()); + state_transition_state_validator = StateTransitionStateValidator::new(state_repository); Ok(Self { state_repository: wrapped_state_repository, diff --git a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_state.rs b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_state.rs index 773feaefe97..c827c5e6706 100644 --- a/packages/rs-dpp/src/state_transition/validation/validate_state_transition_state.rs +++ b/packages/rs-dpp/src/state_transition/validation/validate_state_transition_state.rs @@ -47,7 +47,7 @@ where let identity_top_up_validator = IdentityTopUpTransitionStateValidator::new(state_repository.clone()); let identity_credit_withdrawal_validator = - IdentityCreditWithdrawalTransitionValidator::new(wrapped_state_repository.clone()); + IdentityCreditWithdrawalTransitionValidator::new(wrapped_state_repository); let document_batch_validator = DocumentsBatchTransitionStateValidator::new(state_repository.clone()); diff --git a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs index b735a47689f..c28ab38385e 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_facade.rs @@ -6,13 +6,10 @@ use crate::utils::ToSerdeJSONExt; use crate::validation::ValidationResultWasm; use crate::with_js_error; use dpp::state_transition::state_transition_execution_context::StateTransitionExecutionContext; -use dpp::state_transition::{ - StateTransitionConvert, StateTransitionFacade, StateTransitionFactory, StateTransitionLike, - ValidateOptions, -}; +use dpp::state_transition::{StateTransitionFacade, StateTransitionLike, ValidateOptions}; use dpp::version::ProtocolVersionValidator; -use serde::{Deserialize, Serialize}; -use serde_json::Value; +use serde::Deserialize; + use std::sync::Arc; use wasm_bindgen::prelude::*; use wasm_bindgen::JsValue; diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 81f1aabe5d9..51186e34170 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -1,23 +1,9 @@ const { PrivateKey } = require('@dashevo/dashcore-lib'); -// const DashPlatformProtocol = require('@dashevo/dpp/lib/DashPlatformProtocol'); - -// const DataContractCreateTransition = require('@dashevo/dpp/lib/dataContract/stateTransition/DataContractCreateTransition/DataContractCreateTransition'); - -// const ValidationResult = require('@dashevo/dpp/lib/validation/ValidationResult'); - const getIdentityCreateTransitionFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityCreateTransitionFixture'); const createStateRepositoryMock = require('@dashevo/dpp/lib/test/mocks/createStateRepositoryMock'); -// const DataContractFactory = require('@dashevo/dpp/lib/dataContract/DataContractFactory'); -// const DocumentFactory = require('@dashevo/dpp/lib/document/DocumentFactory'); - -// const IdentityPublicKey = require('@dashevo/dpp/lib/identity/IdentityPublicKey'); - -const MissingOptionError = require('@dashevo/dpp/lib/errors/MissingOptionError'); -const createDPPMock = require('@dashevo/dpp/lib/test/mocks/createDPPMock'); -const SomeConsensusError = require('@dashevo/dpp/lib/test/mocks/SomeConsensusError'); const getIdentityFixture = require('@dashevo/dpp/lib/test/fixtures/getIdentityFixture'); const getDocumentsFixture = require('../../../lib/test/fixtures/getDocumentsFixture'); const getDataContractFixture = require('../../../lib/test/fixtures/getDataContractFixture'); @@ -151,11 +137,6 @@ describe('StateTransitionFacade', () => { }); describe('validate', () => { - let validateBasicSpy; - let validateSignatureSpy; - let validateFeeSpy; - let validateStateSpy; - it('should return invalid result if State Transition structure is invalid', async () => { const rawStateTransition = dataContractCreateTransition.toObject(); rawStateTransition.protocolVersion = 100; From 8ede01968285da49fff3bb40710caebd79ac0021 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Thu, 9 Mar 2023 17:00:39 +0000 Subject: [PATCH 49/54] test: fix identifier field --- .../lib/test/fixtures/getDocumentsFixture.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js b/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js index 15c363badbd..33e2bd06f15 100644 --- a/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js +++ b/packages/wasm-dpp/lib/test/fixtures/getDocumentsFixture.js @@ -1,4 +1,4 @@ -// const crypto = require('crypto'); +const crypto = require('crypto'); const getDataContractFixture = require('./getDataContractFixture'); @@ -34,14 +34,10 @@ module.exports = async function getDocumentsFixture( factory.create(dataContract, ownerId, 'noTimeDocument', { name: 'ImOutOfTime' }), factory.create(dataContract, ownerId, 'uniqueDates', { firstName: 'John' }), factory.create(dataContract, ownerId, 'indexedDocument', { firstName: 'Bill', lastName: 'Gates' }), - // TODO: something strange is happening in case byte field's - // name is anything but "byteArrayField". - // adding "identifierFields" crashes factory.create - // factory.create(dataContract, ownerId, 'withByteArrays', - // { - // byteArrayField: crypto.randomBytes(10), - // identifierFields: await generateRandomIdentifierAsync() } - // ), + factory.create(dataContract, ownerId, 'withByteArrays', { + byteArrayField: crypto.randomBytes(10), + identifierField: (await generateRandomIdentifierAsync()).toBuffer(), + }), factory.create(dataContract, ownerId, 'optionalUniqueIndexedDocument', { firstName: 'Jacques-Yves', lastName: 'Cousteau' }), ]; }; From 4b8f8c2822a987af956134926d67bfde47228370 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Wed, 15 Mar 2023 11:00:18 +0000 Subject: [PATCH 50/54] fix(wasm-dpp): inconsistencies after merge --- packages/wasm-dpp/src/state_transition/mod.rs | 1 + .../wasm-dpp/src/state_transition/state_transition_factory.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/wasm-dpp/src/state_transition/mod.rs b/packages/wasm-dpp/src/state_transition/mod.rs index bf2a695a324..a755f3db21a 100644 --- a/packages/wasm-dpp/src/state_transition/mod.rs +++ b/packages/wasm-dpp/src/state_transition/mod.rs @@ -3,6 +3,7 @@ use dpp::state_transition::state_transition_execution_context::StateTransitionEx use wasm_bindgen::prelude::*; pub mod errors; +pub mod state_transition_facade; pub mod state_transition_factory; pub mod validation; 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 77221d62ea6..9994c0adef6 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -68,7 +68,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 d46d39377bb7c78feaaedeaf25ff923f4238dccb Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Wed, 15 Mar 2023 11:04:59 +0000 Subject: [PATCH 51/54] refactor(wasm-dpp): rename DocumentsBatchTransitionWASM to DocumentsBatchTransitionWasm --- packages/wasm-dpp/src/document/document_facade.rs | 4 ++-- packages/wasm-dpp/src/document/factory.rs | 4 ++-- packages/wasm-dpp/src/document/mod.rs | 2 +- .../apply_document_batch_transition.rs | 4 ++-- .../document_batch_transition/mod.rs | 14 +++++++------- .../validate_documents_batch_transitions_state.rs | 4 ++-- .../wasm-dpp/src/state_transition/conversion.rs | 6 +++--- .../state_transition/state_transition_factory.rs | 4 ++-- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index 198a14cc284..2aac27780b9 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -7,7 +7,7 @@ use crate::{ utils::{get_class_name, IntoWasm}, validation::ValidationResultWasm, DataContractWasm, DocumentFactoryWASM, DocumentValidatorWasm, DocumentWasm, - DocumentsBatchTransitionWASM, + DocumentsBatchTransitionWasm, }; #[derive(Clone)] @@ -84,7 +84,7 @@ impl DocumentFacadeWasm { pub fn create_state_transition( &self, documents: &JsValue, // documents_container: DocumentsContainer, - ) -> Result { + ) -> Result { self.factory.create_state_transition(documents) } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 070d2064133..f6ef0fc8da6 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -19,7 +19,7 @@ use crate::{ utils::{ replace_identifiers_with_bytes_without_failing, IntoWasm, ToSerdeJSONExt, WithJsError, }, - DataContractWasm, DocumentWasm, DocumentsBatchTransitionWASM, + DataContractWasm, DocumentWasm, DocumentsBatchTransitionWasm, }; use super::validator::DocumentValidatorWasm; @@ -120,7 +120,7 @@ impl DocumentFactoryWASM { pub fn create_state_transition( &self, documents: &JsValue, - ) -> Result { + ) -> Result { let documents_by_action = extract_documents_by_action(documents)?; let batch_transition = self .0 diff --git a/packages/wasm-dpp/src/document/mod.rs b/packages/wasm-dpp/src/document/mod.rs index cdab208fd96..8904ac2651c 100644 --- a/packages/wasm-dpp/src/document/mod.rs +++ b/packages/wasm-dpp/src/document/mod.rs @@ -28,7 +28,7 @@ pub mod generate_document_id; pub mod state_transition; mod validator; -pub use document_batch_transition::DocumentsBatchTransitionWASM; +pub use document_batch_transition::DocumentsBatchTransitionWasm; pub use factory::DocumentFactoryWASM; pub use validator::DocumentValidatorWasm; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/apply_document_batch_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/apply_document_batch_transition.rs index 41db5053094..86d2a564906 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/apply_document_batch_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/apply_document_batch_transition.rs @@ -4,13 +4,13 @@ use wasm_bindgen::prelude::*; use crate::{ state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, utils::WithJsError, - DocumentsBatchTransitionWASM, + DocumentsBatchTransitionWasm, }; #[wasm_bindgen(js_name=applyDocumentsBatchTransition)] pub async fn apply_documents_batch_transition_wasm( state_repository: ExternalStateRepositoryLike, - transition: &DocumentsBatchTransitionWASM, + transition: &DocumentsBatchTransitionWasm, ) -> Result<(), JsValue> { let wrapped_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository); diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index 4d17d07acf5..37e76fec7b2 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -35,7 +35,7 @@ pub mod validation; #[derive(Clone, Debug)] #[wasm_bindgen(js_name = DocumentsBatchTransition)] -pub struct DocumentsBatchTransitionWASM(DocumentsBatchTransition); +pub struct DocumentsBatchTransitionWasm(DocumentsBatchTransition); #[derive(Debug, Serialize, Deserialize, Default, Clone, Copy)] #[serde(rename_all = "camelCase")] @@ -47,12 +47,12 @@ pub struct ToObjectOptions { } #[wasm_bindgen(js_class=DocumentsBatchTransition)] -impl DocumentsBatchTransitionWASM { +impl DocumentsBatchTransitionWasm { #[wasm_bindgen(constructor)] pub fn from_raw_object( js_raw_transition: JsValue, data_contracts: Array, - ) -> Result { + ) -> Result { let data_contracts_array_js = Array::from(&data_contracts); let mut data_contracts: Vec = vec![]; @@ -366,14 +366,14 @@ impl DocumentsBatchTransitionWASM { } } -impl From for DocumentsBatchTransitionWASM { +impl From for DocumentsBatchTransitionWasm { fn from(t: DocumentsBatchTransition) -> Self { - DocumentsBatchTransitionWASM(t) + DocumentsBatchTransitionWasm(t) } } -impl From for DocumentsBatchTransition { - fn from(t: DocumentsBatchTransitionWASM) -> Self { +impl From for DocumentsBatchTransition { + fn from(t: DocumentsBatchTransitionWasm) -> Self { t.0 } } diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/validate_documents_batch_transitions_state.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/validate_documents_batch_transitions_state.rs index ca199406405..11aeffa8e03 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/validate_documents_batch_transitions_state.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/validate_documents_batch_transitions_state.rs @@ -5,13 +5,13 @@ use crate::{ state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, utils::WithJsError, validation::ValidationResultWasm, - DocumentsBatchTransitionWASM, + DocumentsBatchTransitionWasm, }; #[wasm_bindgen(js_name = "validateDocumentsBatchTransitionState")] pub async fn validate_documents_batch_transition_state_wasm( state_repository: ExternalStateRepositoryLike, - state_transition: &DocumentsBatchTransitionWASM, + state_transition: &DocumentsBatchTransitionWasm, ) -> Result { let wrapped_state_repository = ExternalStateRepositoryLikeWrapper::new(state_repository); diff --git a/packages/wasm-dpp/src/state_transition/conversion.rs b/packages/wasm-dpp/src/state_transition/conversion.rs index ec09354f3d3..2a95be7f025 100644 --- a/packages/wasm-dpp/src/state_transition/conversion.rs +++ b/packages/wasm-dpp/src/state_transition/conversion.rs @@ -1,7 +1,7 @@ use crate::utils::generic_of_js_val; use crate::{ DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, - DocumentsBatchTransitionWASM, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, + DocumentsBatchTransitionWasm, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, IdentityUpdateTransitionWasm, }; use dpp::state_transition::{StateTransition, StateTransitionType}; @@ -55,8 +55,8 @@ pub fn create_state_transition_from_wasm_instance( Ok(StateTransition::DataContractCreate(st.clone().into())) } StateTransitionType::DocumentsBatch => { - let st: Ref = generic_of_js_val::< - DocumentsBatchTransitionWASM, + let st: Ref = generic_of_js_val::< + DocumentsBatchTransitionWasm, >( js_value, "DocumentsBatchTransition" )?; 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 9994c0adef6..4da5f6d42e4 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::{ state_repository::{ExternalStateRepositoryLike, ExternalStateRepositoryLikeWrapper}, state_transition::errors::invalid_state_transition_error::InvalidStateTransitionErrorWasm, with_js_error, DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm, - DocumentsBatchTransitionWASM, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, + DocumentsBatchTransitionWasm, IdentityCreateTransitionWasm, IdentityTopUpTransitionWasm, IdentityUpdateTransitionWasm, }; @@ -60,7 +60,7 @@ impl StateTransitionFactoryWasm { Ok(IdentityTopUpTransitionWasm::from(st).into()) } StateTransition::DocumentsBatch(st) => { - Ok(DocumentsBatchTransitionWASM::from(st).into()) + Ok(DocumentsBatchTransitionWasm::from(st).into()) } _ => Err("Unsupported state transition type".into()), }, From 8c268a2b26e5758a76fe193001c65bedfc5211c6 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Wed, 15 Mar 2023 11:19:40 +0000 Subject: [PATCH 52/54] refactor(wasm-dpp): or_else and code blocks --- .../abstract_state_transition.rs | 28 ++++++++------- .../state_transition_facade.rs | 34 ++++++++----------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs index da7e2ae8e68..4102c763bf3 100644 --- a/packages/rs-dpp/src/state_transition/abstract_state_transition.rs +++ b/packages/rs-dpp/src/state_transition/abstract_state_transition.rs @@ -120,11 +120,13 @@ pub trait StateTransitionLike: )); } let data_hash = self.hash(true)?; - signer::verify_hash_signature(&data_hash, self.get_signature(), public_key_hash).or(Err( - ProtocolError::from(ConsensusError::SignatureError( - SignatureError::InvalidStateTransitionSignatureError, - )), - )) + signer::verify_hash_signature(&data_hash, self.get_signature(), public_key_hash).or_else( + |_| { + Err(ProtocolError::from(ConsensusError::SignatureError( + SignatureError::InvalidStateTransitionSignatureError, + ))) + }, + ) } /// Verifies an ECDSA signature with the public key @@ -136,11 +138,11 @@ pub trait StateTransitionLike: } let data = self.to_buffer(true)?; - signer::verify_data_signature(&data, self.get_signature(), public_key).or(Err( - ProtocolError::from(ConsensusError::SignatureError( + signer::verify_data_signature(&data, self.get_signature(), public_key).or_else(|_| { + Err(ProtocolError::from(ConsensusError::SignatureError( SignatureError::InvalidStateTransitionSignatureError, - )), - )) + ))) + }) } /// Verifies a BLS signature with the public key @@ -159,9 +161,11 @@ pub trait StateTransitionLike: bls.verify_signature(self.get_signature(), &data, public_key) .map(|_| ()) - .or(Err(ProtocolError::from(ConsensusError::SignatureError( - SignatureError::InvalidStateTransitionSignatureError, - )))) + .or_else(|_| { + Err(ProtocolError::from(ConsensusError::SignatureError( + SignatureError::InvalidStateTransitionSignatureError, + ))) + }) } /// returns true if state transition is a document state transition diff --git a/packages/rs-dpp/src/state_transition/state_transition_facade.rs b/packages/rs-dpp/src/state_transition/state_transition_facade.rs index 690aa49a9b3..f1d1bc031a7 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_facade.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_facade.rs @@ -59,13 +59,7 @@ where ) -> Result { let wrapped_state_repository = Arc::new(state_repository.clone()); - let state_transition_basic_validator; - let state_transition_state_validator; - let state_transition_key_signature_validator; - let state_transition_fee_validator; - let state_transition_factory; - - { + let state_transition_factory = { let pk_validator = Arc::new(PublicKeysValidator::new(adapter.clone()).map_err(ProtocolError::from)?); let pk_sig_validator = Arc::new(PublicKeysSignaturesValidator::new(adapter.clone())); @@ -87,7 +81,7 @@ where .map_err(ProtocolError::from)?, )); - state_transition_factory = StateTransitionFactory::new( + StateTransitionFactory::new( wrapped_state_repository.clone(), StateTransitionBasicValidator::new( wrapped_state_repository.clone(), @@ -129,10 +123,10 @@ where ), ), ), - ); - } + ) + }; - { + let state_transition_basic_validator = { let protocol_version_validator = Arc::new(ProtocolVersionValidator::default()); let pk_validator = @@ -166,7 +160,7 @@ where })?, )); - state_transition_basic_validator = StateTransitionBasicValidator::new( + StateTransitionBasicValidator::new( wrapped_state_repository.clone(), StateTransitionByTypeValidator::new( DataContractCreateTransitionBasicValidator::new( @@ -221,10 +215,10 @@ where protocol_version_validator.clone(), ), ), - ); - } + ) + }; - { + let state_transition_key_signature_validator = { let asset_lock_transaction_output_fetcher = AssetLockTransactionOutputFetcher::new(wrapped_state_repository.clone()); @@ -233,16 +227,16 @@ where asset_lock_transaction_output_fetcher, ); - state_transition_key_signature_validator = StateTransitionKeySignatureValidator::new( + StateTransitionKeySignatureValidator::new( wrapped_state_repository.clone(), asset_public_key_hash_fetcher, - ); - } + ) + }; - state_transition_fee_validator = + let state_transition_fee_validator = StateTransitionFeeValidator::new(wrapped_state_repository.clone()); - state_transition_state_validator = StateTransitionStateValidator::new(state_repository); + let state_transition_state_validator = StateTransitionStateValidator::new(state_repository); Ok(Self { state_repository: wrapped_state_repository, From a4b20ca0bc776cece41c44557d8b093f543e41f5 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Wed, 15 Mar 2023 11:35:02 +0000 Subject: [PATCH 53/54] cleanup --- .../integration/stateTransition/StateTransitionFacade.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js index 51186e34170..16674bd4125 100644 --- a/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js +++ b/packages/wasm-dpp/test/integration/stateTransition/StateTransitionFacade.spec.js @@ -63,7 +63,6 @@ describe('StateTransitionFacade', () => { const publicKey = privateKeyModel.toPublicKey().toBuffer(); const publicKeyId = 1; - // TODO: check security level. It says it needs HIGH instead of MASTER identityPublicKey = new IdentityPublicKey({ id: publicKeyId, type: IdentityPublicKey.TYPES.ECDSA_SECP256K1, From 82430ccb33d83c28cda43ac36fd37ce97d508733 Mon Sep 17 00:00:00 2001 From: "markin.io" Date: Wed, 15 Mar 2023 12:42:03 +0000 Subject: [PATCH 54/54] test(wasm-dpp): fix identifier path --- packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js b/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js index f5d5d8fcdf6..01ef859a448 100644 --- a/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js +++ b/packages/wasm-dpp/lib/test/fixtures/getDataContractFixture.js @@ -1,5 +1,5 @@ const protocolVersion = require('@dashevo/dpp/lib/version/protocolVersion'); -const JsIdentifier = require('@dashevo/dpp/lib/Identifier/Identifier'); +const JsIdentifier = require('@dashevo/dpp/lib/identifier/Identifier'); const generateRandomIdentifierAsync = require('../utils/generateRandomIdentifierAsync'); const { default: loadWasmDpp } = require('../../..'); let { DataContractFactory, DataContractValidator } = require('../../..');