diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index 344de28e3f2..6d295c7a702 100644 --- a/packages/rs-dpp/src/data_contract/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/mod.rs @@ -72,6 +72,12 @@ impl DataContractV0Getters for DataContract { } } + fn document_types_mut(&mut self) -> &mut BTreeMap { + match self { + DataContract::V0(v0) => v0.document_types_mut(), + } + } + fn metadata(&self) -> Option<&Metadata> { match self { DataContract::V0(v0) => v0.metadata(), diff --git a/packages/rs-dpp/src/data_contract/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v0/mod.rs index f5b276d1cf6..b0809d41e51 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v0/mod.rs @@ -30,6 +30,9 @@ pub trait DataContractV0Getters { /// Returns a mapping of document names to their corresponding document types. fn document_types(&self) -> &BTreeMap; + /// Returns a mapping of document names to their corresponding document types as mutable. + fn document_types_mut(&mut self) -> &mut BTreeMap; + /// Returns optional metadata associated with the contract. fn metadata(&self) -> Option<&Metadata>; diff --git a/packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs b/packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs index a4362c4bec6..4240da16b2d 100644 --- a/packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs +++ b/packages/rs-dpp/src/data_contract/document_type/v0/random_document_type.rs @@ -191,10 +191,17 @@ impl DocumentTypeV0 { } }; - let optional_field_count = - rng.gen_range(parameters.new_fields_optional_count_range.clone()); - let required_field_count = - rng.gen_range(parameters.new_fields_required_count_range.clone()); + let optional_field_count = if parameters.new_fields_optional_count_range.is_empty() { + 0 + } else { + rng.gen_range(parameters.new_fields_optional_count_range.clone()) + }; + + let required_field_count = if parameters.new_fields_required_count_range.is_empty() { + 0 + } else { + rng.gen_range(parameters.new_fields_required_count_range.clone()) + }; let mut properties = IndexMap::new(); let mut required_fields = BTreeSet::new(); @@ -210,7 +217,12 @@ impl DocumentTypeV0 { required_fields.insert(field_name); } - let index_count = rng.gen_range(parameters.new_indexes_count_range.clone()); + let index_count = if parameters.new_indexes_count_range.is_empty() { + 0 + } else { + rng.gen_range(parameters.new_indexes_count_range.clone()) + }; + let field_names: Vec = properties.keys().cloned().collect(); // DPP only allows 10 properties per index (v1.0-dev) let ten_field_names = field_names @@ -419,4 +431,167 @@ impl DocumentTypeV0 { json_schema_validator: StatelessJsonSchemaLazyValidator::new(), }) } + + /// This is used to create an invalid random document type, often for testing + pub fn invalid_random_document_type( + parameters: RandomDocumentTypeParameters, + data_contract_id: Identifier, + rng: &mut StdRng, + platform_version: &PlatformVersion, + ) -> Result { + // Call the validation function at the beginning + parameters.validate_parameters()?; + + let field_weights = ¶meters.field_weights; + + let total_weight = field_weights.string_weight + + field_weights.float_weight + + field_weights.integer_weight + + field_weights.date_weight + + field_weights.boolean_weight + + field_weights.byte_array_weight; + + let random_field = |required: bool, rng: &mut StdRng| -> DocumentProperty { + let random_weight = rng.gen_range(0..total_weight); + let document_type = if random_weight < field_weights.string_weight { + let has_min_len = rng.gen_bool(parameters.field_bounds.string_has_min_len_chance); + let min_len = if has_min_len { + Some(rng.gen_range(parameters.field_bounds.string_min_len.clone())) + } else { + None + }; + // If a string property is used in an index it must have maxLength 63 or less (v1.0-dev) + let max_len = Some(63); + DocumentPropertyType::String(min_len, max_len) + } else if random_weight < field_weights.string_weight + field_weights.integer_weight { + DocumentPropertyType::Integer + } else if random_weight + < field_weights.string_weight + + field_weights.integer_weight + + field_weights.float_weight + { + DocumentPropertyType::Number + } else if random_weight + < field_weights.string_weight + + field_weights.integer_weight + + field_weights.float_weight + + field_weights.date_weight + { + DocumentPropertyType::Date + } else if random_weight + < field_weights.string_weight + + field_weights.integer_weight + + field_weights.float_weight + + field_weights.date_weight + + field_weights.boolean_weight + { + DocumentPropertyType::Boolean + } else { + let has_min_len = + rng.gen_bool(parameters.field_bounds.byte_array_has_min_len_chance); + let min_len = if has_min_len { + Some(rng.gen_range(parameters.field_bounds.byte_array_min_len.clone())) + } else { + None + }; + // Indexed arrays must have maxItems 255 or less (v1.0-dev) + let max_len = Some(255); + DocumentPropertyType::ByteArray(min_len, max_len) + }; + + DocumentProperty { + property_type: document_type, + required, + } + }; + + let optional_field_count = if parameters.new_fields_optional_count_range.is_empty() { + 0 + } else { + rng.gen_range(parameters.new_fields_optional_count_range.clone()) + }; + + let required_field_count = if parameters.new_fields_required_count_range.is_empty() { + 0 + } else { + rng.gen_range(parameters.new_fields_required_count_range.clone()) + }; + + let mut properties = IndexMap::new(); + let mut required_fields = BTreeSet::new(); + + for _ in 0..optional_field_count { + let field_name = format!("field_{}", rng.gen::()); + properties.insert(field_name, random_field(false, rng)); + } + + for _ in 0..required_field_count { + let field_name = format!("field_{}", rng.gen::()); + properties.insert(field_name.clone(), random_field(true, rng)); + required_fields.insert(field_name); + } + + let index_count = if parameters.new_indexes_count_range.is_empty() { + 0 + } else { + rng.gen_range(parameters.new_indexes_count_range.clone()) + }; + + let field_names: Vec = properties.keys().cloned().collect(); + // DPP only allows 10 properties per index (v1.0-dev) + let ten_field_names = field_names + .choose_multiple(&mut rand::thread_rng(), 10) + .cloned() + .collect_vec(); + + let mut indices = Vec::with_capacity(index_count as usize); + + for _ in 0..index_count { + match Index::random(&ten_field_names, &indices, rng) { + Ok(index) => indices.push(index), + Err(_) => break, + } + } + + let documents_keep_history = rng.gen_bool(parameters.keep_history_chance); + let documents_mutable = rng.gen_bool(parameters.documents_mutable_chance); + + let name = format!("doc_type_{}", rng.gen::()); + + let index_structure = + IndexLevel::try_from_indices(indices.as_slice(), name.as_str(), platform_version)?; + let (identifier_paths, binary_paths) = DocumentType::find_identifier_and_binary_paths( + &properties, + &PlatformVersion::latest() + .dpp + .contract_versions + .document_type_versions, + )?; + + // Combine everything into the final schema + let schema = json!({ + "invalid": "yo", + }); + + // TODO: It might not work properly + Ok(DocumentTypeV0 { + name, + schema: schema.into(), + indices, + index_structure, + flattened_properties: properties.clone(), + properties, + identifier_paths, + binary_paths, + required_fields, + documents_keep_history, + documents_mutable, + data_contract_id, + requires_identity_encryption_bounded_key: None, + requires_identity_decryption_bounded_key: None, + security_level_requirement: SecurityLevel::HIGH, + #[cfg(feature = "validation")] + json_schema_validator: StatelessJsonSchemaLazyValidator::new(), + }) + } } diff --git a/packages/rs-dpp/src/data_contract/v0/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v0/accessors/mod.rs index 461037c65b6..1706792a577 100644 --- a/packages/rs-dpp/src/data_contract/v0/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v0/accessors/mod.rs @@ -62,6 +62,10 @@ impl DataContractV0Getters for DataContractV0 { &self.document_types } + fn document_types_mut(&mut self) -> &mut BTreeMap { + &mut self.document_types + } + fn metadata(&self) -> Option<&Metadata> { self.metadata.as_ref() } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/mod.rs index 1ea016bdfa9..efbac4ea413 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/mod.rs @@ -183,7 +183,8 @@ mod test { .validation_and_processing .state_transitions .contract_create_state_transition - .base_structure, + .basic_structure + .unwrap(), ), ), ( diff --git a/packages/rs-dpp/src/tests/fixtures/get_dashpay_contract_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_dashpay_contract_fixture.rs index b4aed770c28..5a0320c2089 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_dashpay_contract_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_dashpay_contract_fixture.rs @@ -17,13 +17,13 @@ pub fn get_dashpay_contract_fixture( let platform_version = PlatformVersion::get(protocol_version).expect("expected to get version"); - let dpns_schema = SystemDataContract::Dashpay + let dashpay_schema = SystemDataContract::Dashpay .source(platform_version) .expect("DPNS contract must be defined") .document_schemas; let owner_id = owner_id.unwrap_or_else(generate_random_identifier_struct); factory - .create_with_value_config(owner_id, identity_nonce, dpns_schema.into(), None, None) + .create_with_value_config(owner_id, identity_nonce, dashpay_schema.into(), None, None) .expect("data in fixture should be correct") } diff --git a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs index 4ad51c685e7..387e4b29479 100644 --- a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs @@ -192,6 +192,11 @@ mod tests { use dpp::NativeBlsModule; use crate::execution::check_tx::CheckTxLevel::{FirstTimeCheck, Recheck}; + use dpp::data_contract::document_type::v0::random_document_type::{ + FieldMinMaxBounds, FieldTypeWeights, RandomDocumentTypeParameters, + }; + use dpp::data_contract::document_type::v0::DocumentTypeV0; + use dpp::data_contract::document_type::DocumentType; use dpp::identity::contract_bounds::ContractBounds::SingleContractDocumentType; use dpp::platform_value::Bytes32; use dpp::system_data_contracts::dashpay_contract; @@ -423,6 +428,192 @@ mod tests { assert!(check_result.is_valid()); // it should still be valid, because we don't validate state } + #[test] + fn data_contract_create_check_tx_for_invalid_contract() { + let mut platform = TestPlatformBuilder::new() + .with_config(PlatformConfig::default()) + .build_with_mock_rpc(); + + platform + .core_rpc + .expect_verify_instant_lock() + .returning(|_, _| Ok(true)); + + let platform_state = platform.state.load(); + let protocol_version = platform_state.current_protocol_version_in_consensus(); + let platform_version = PlatformVersion::get(protocol_version).unwrap(); + + let (key, private_key) = IdentityPublicKey::random_ecdsa_critical_level_authentication_key( + 1, + Some(1), + platform_version, + ) + .expect("expected to get key pair"); + + platform + .drive + .create_initial_state_structure(None, platform_version) + .expect("expected to create state structure"); + let identity: Identity = IdentityV0 { + id: Identifier::new([ + 158, 113, 180, 126, 91, 83, 62, 44, 83, 54, 97, 88, 240, 215, 84, 139, 167, 156, + 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, + ]), + public_keys: BTreeMap::from([(1, key.clone())]), + balance: 1000000000, + revision: 0, + } + .into(); + + let mut dashpay = get_dashpay_contract_fixture(Some(identity.id()), 1, protocol_version); + + let dashpay_id = dashpay.data_contract().id(); + // we need to alter dashpay to make it invalid + + let document_types = dashpay.data_contract_mut().document_types_mut(); + + let parameters = RandomDocumentTypeParameters { + new_fields_optional_count_range: 5..6, + new_fields_required_count_range: 3..4, + new_indexes_count_range: Default::default(), + field_weights: FieldTypeWeights { + string_weight: 5, + float_weight: 3, + integer_weight: 2, + date_weight: 0, + boolean_weight: 1, + byte_array_weight: 0, + }, + field_bounds: FieldMinMaxBounds { + string_min_len: Default::default(), + string_has_min_len_chance: 0.0, + string_max_len: Default::default(), + string_has_max_len_chance: 0.0, + integer_min: Default::default(), + integer_has_min_chance: 0.0, + integer_max: Default::default(), + integer_has_max_chance: 0.0, + float_min: Default::default(), + float_has_min_chance: 0.0, + float_max: Default::default(), + float_has_max_chance: 0.0, + date_min: 0, + date_max: 100, + byte_array_min_len: Default::default(), + byte_array_has_min_len_chance: 0.0, + byte_array_max_len: Default::default(), + byte_array_has_max_len_chance: 0.0, + }, + keep_history_chance: 0.0, + documents_mutable_chance: 0.0, + }; + + let mut rng = StdRng::seed_from_u64(6); + + document_types.insert( + "invalid".to_string(), + DocumentType::V0( + DocumentTypeV0::invalid_random_document_type( + parameters, + dashpay_id, + &mut rng, + platform_version, + ) + .expect("expected an invalid document type"), + ), + ); + + let mut create_contract_state_transition: StateTransition = dashpay + .try_into_platform_versioned(platform_version) + .expect("expected a state transition"); + create_contract_state_transition + .sign(&key, private_key.as_slice(), &NativeBlsModule) + .expect("expected to sign transition"); + let serialized = create_contract_state_transition + .serialize_to_bytes() + .expect("serialized state transition"); + platform + .drive + .add_new_identity( + identity, + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert identity"); + + let validation_result = platform + .check_tx( + serialized.as_slice(), + FirstTimeCheck, + &platform_state, + platform_version, + ) + .expect("expected to check tx"); + + assert!(validation_result.errors.is_empty()); + + let check_result = platform + .check_tx( + serialized.as_slice(), + Recheck, + &platform_state, + platform_version, + ) + .expect("expected to check tx"); + + assert!(check_result.is_valid()); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![serialized.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + ) + .expect("expected to process state transition"); + + // We have one invalid paid for state transition + assert_eq!(processing_result.invalid_paid_count(), 1); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 736520); + + let check_result = platform + .check_tx( + serialized.as_slice(), + Recheck, + &platform_state, + platform_version, + ) + .expect("expected to check tx"); + + assert!(check_result.is_valid()); // it should still be valid, because we didn't commit the transaction + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + let check_result = platform + .check_tx( + serialized.as_slice(), + Recheck, + &platform_state, + platform_version, + ) + .expect("expected to check tx"); + + assert!(check_result.is_valid()); // it should still be valid, because we don't validate state + } + #[test] fn data_contract_create_check_tx_priority() { let mut platform = TestPlatformBuilder::new() diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/v0/mod.rs index cfed56c58b9..4ca9f9705cb 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/make_sure_core_is_synced_to_chain_lock/v0/mod.rs @@ -1,9 +1,9 @@ use crate::error::Error; +use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus; use crate::platform_types::platform::Platform; use crate::rpc::core::CoreRPCLike; use dashcore_rpc::dashcore::ChainLock; use dpp::version::PlatformVersion; -use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus; impl Platform where diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/v0/mod.rs index 5344e179376..240f1718e17 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_chain_lock/verify_chain_lock_through_core/v0/mod.rs @@ -1,7 +1,7 @@ use crate::error::Error; +use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus; use dpp::dashcore::ChainLock; use dpp::version::PlatformVersion; -use crate::execution::platform_events::core_chain_lock::make_sure_core_is_synced_to_chain_lock::CoreSyncStatus; use crate::platform_types::platform::Platform; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs index 368bfffe1cd..1ff3545a764 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs @@ -15,6 +15,7 @@ use crate::execution::types::state_transition_execution_context::StateTransition use crate::execution::validation::state_transition::common::asset_lock::proof::verify_is_not_spent::AssetLockProofVerifyIsNotSpent; use crate::execution::validation::state_transition::processor::process_state_transition; use crate::execution::validation::state_transition::processor::v0::{StateTransitionBalanceValidationV0, StateTransitionBasicStructureValidationV0, StateTransitionNonceValidationV0, StateTransitionSignatureValidationV0, StateTransitionStructureKnownInStateValidationV0}; +use crate::execution::validation::state_transition::ValidationMode; /// A trait for validating state transitions within a blockchain. pub(crate) trait StateTransitionCheckTxValidationV0 { @@ -74,10 +75,11 @@ pub(super) fn state_transition_to_execution_event_for_check_tx_v0<'a, C: CoreRPC ); } - let action = if state_transition.requires_advance_structure_validation() { + let action = if state_transition.requires_advance_structure_validation_from_state() + { let state_transition_action_result = state_transition.transform_into_action( platform, - true, + ValidationMode::CheckTx, &mut state_transition_execution_context, None, )?; @@ -120,7 +122,7 @@ pub(super) fn state_transition_to_execution_event_for_check_tx_v0<'a, C: CoreRPC let state_transition_action_result = state_transition .transform_into_action( platform, - true, + ValidationMode::CheckTx, &mut state_transition_execution_context, None, )?; @@ -176,7 +178,7 @@ pub(super) fn state_transition_to_execution_event_for_check_tx_v0<'a, C: CoreRPC } else { let state_transition_action_result = state_transition.transform_into_action( platform, - true, + ValidationMode::CheckTx, &mut state_transition_execution_context, None, )?; @@ -230,7 +232,7 @@ pub(super) fn state_transition_to_execution_event_for_check_tx_v0<'a, C: CoreRPC let state_transition_action_result = state_transition.transform_into_action( platform, - true, + ValidationMode::RecheckTx, &mut state_transition_execution_context, None, )?; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_unique_identity_public_key_hashes_in_state/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_unique_identity_public_key_hashes_in_state/mod.rs index 830dca757a9..84398f0dde9 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_unique_identity_public_key_hashes_in_state/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_unique_identity_public_key_hashes_in_state/mod.rs @@ -6,11 +6,11 @@ use dpp::version::PlatformVersion; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::common::validate_unique_identity_public_key_hashes_in_state::v0::validate_unique_identity_public_key_hashes_in_state_v0; +use crate::execution::validation::state_transition::common::validate_unique_identity_public_key_hashes_in_state::v0::validate_unique_identity_public_key_hashes_not_in_state_v0; pub mod v0; -pub(crate) fn validate_unique_identity_public_key_hashes_in_state( +pub(crate) fn validate_unique_identity_public_key_hashes_not_in_state( identity_public_keys_with_witness: &[IdentityPublicKeyInCreation], drive: &Drive, execution_context: &mut StateTransitionExecutionContext, @@ -24,7 +24,7 @@ pub(crate) fn validate_unique_identity_public_key_hashes_in_state( .common_validation_methods .validate_unique_identity_public_key_hashes_in_state { - 0 => validate_unique_identity_public_key_hashes_in_state_v0( + 0 => validate_unique_identity_public_key_hashes_not_in_state_v0( identity_public_keys_with_witness, drive, execution_context, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_unique_identity_public_key_hashes_in_state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_unique_identity_public_key_hashes_in_state/v0/mod.rs index 7d533821be6..ff1f78ef018 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_unique_identity_public_key_hashes_in_state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_unique_identity_public_key_hashes_in_state/v0/mod.rs @@ -18,7 +18,7 @@ use dpp::version::PlatformVersion; use std::collections::HashMap; /// This will validate that all keys are valid against the state -pub(super) fn validate_unique_identity_public_key_hashes_in_state_v0( +pub(super) fn validate_unique_identity_public_key_hashes_not_in_state_v0( identity_public_keys_with_witness: &[IdentityPublicKeyInCreation], drive: &Drive, _execution_context: &mut StateTransitionExecutionContext, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs index 3c180e5890b..a4dc72983ed 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs @@ -22,6 +22,7 @@ use crate::execution::validation::state_transition::common::validate_state_trans use crate::execution::validation::state_transition::state_transitions::identity_update::identity_and_signatures::v0::IdentityUpdateStateTransitionIdentityAndSignaturesValidationV0; use crate::execution::validation::state_transition::state_transitions::identity_create::identity_and_signatures::v0::IdentityCreateStateTransitionIdentityAndSignaturesValidationV0; use crate::execution::validation::state_transition::state_transitions::identity_top_up::identity_retrieval::v0::IdentityTopUpStateTransitionIdentityRetrievalV0; +use crate::execution::validation::state_transition::ValidationMode; pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( platform: &'a PlatformRef, @@ -32,20 +33,10 @@ pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( let mut state_transition_execution_context = StateTransitionExecutionContext::default_for_platform_version(platform_version)?; - // We start with basic structure validation, this is structure validation that does not require - // state. - let consensus_result = state_transition.validate_basic_structure(platform_version)?; - - if !consensus_result.is_valid() { - return Ok( - ConsensusValidationResult::::new_with_errors(consensus_result.errors), - ); - } - - let action = if state_transition.requires_advance_structure_validation() { + let action = if state_transition.requires_state_to_validate_identity_and_signatures() { let state_transition_action_result = state_transition.transform_into_action( platform, - true, + ValidationMode::Validator, &mut state_transition_execution_context, transaction, )?; @@ -61,23 +52,67 @@ pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( None }; - // Validating structure - let result = state_transition.validate_advanced_structure_from_state( - &platform.into(), + // Validating signatures + let result = state_transition.validate_identity_and_signatures( + platform.drive, action.as_ref(), + transaction, + &mut state_transition_execution_context, platform_version, )?; + if !result.is_valid() { return Ok(ConsensusValidationResult::::new_with_errors(result.errors)); } - let action = if state_transition.requires_state_to_validate_identity_and_signatures() { + let mut maybe_identity = result.into_data()?; + + // Validating identity contract nonce, this must happen after validating the signature + let result = state_transition.validate_nonces( + &platform.into(), + platform.state.last_block_info(), + transaction, + platform_version, + )?; + + if !result.is_valid() { + return Ok(ConsensusValidationResult::::new_with_errors(result.errors)); + } + + // We validate basic structure validation after verifying the identity, + // this is structure validation that does not require state and is already checked on check_tx + let consensus_result = state_transition.validate_basic_structure(platform_version)?; + + if !consensus_result.is_valid() { + return Ok( + ConsensusValidationResult::::new_with_errors(consensus_result.errors), + ); + } + + // Next we have advanced structure validation, this is structure validation that does not require + // state but isn't checked on check_tx. If advanced structure fails identity nonces or identity + // contract nonces will be bumped + let consensus_result = state_transition.validate_advanced_structure(platform_version)?; + + if !consensus_result.is_valid() { + return consensus_result.map_result(|action| { + ExecutionEvent::create_from_state_transition_action( + action, + maybe_identity, + platform.state.last_committed_block_epoch_ref(), + state_transition_execution_context, + platform_version, + ) + }); + } + + let action = if state_transition.requires_advance_structure_validation_from_state() { if let Some(action) = action { Some(action) } else { let state_transition_action_result = state_transition.transform_into_action( platform, - true, + ValidationMode::Validator, &mut state_transition_execution_context, transaction, )?; @@ -94,22 +129,18 @@ pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( None }; - // Validating signatures - let result = state_transition.validate_identity_and_signatures( - platform.drive, + // Validating structure + let result = state_transition.validate_advanced_structure_from_state( + &platform.into(), action.as_ref(), - transaction, - &mut state_transition_execution_context, platform_version, )?; - if !result.is_valid() { return Ok(ConsensusValidationResult::::new_with_errors(result.errors)); } - let mut maybe_identity = result.into_data()?; - - // Validating identity contract nonce, this must happen after validating the signature + // Validating that we have sufficient balance for a transfer or withdrawal, + // this must happen after validating the signature let result = state_transition.validate_balance( maybe_identity.as_mut(), &platform.into(), @@ -122,22 +153,11 @@ pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( return Ok(ConsensusValidationResult::::new_with_errors(result.errors)); } - // Validating identity contract nonce, this must happen after validating the signature - let result = state_transition.validate_nonces( - &platform.into(), - platform.state.last_block_info(), - transaction, - platform_version, - )?; - - if !result.is_valid() { - return Ok(ConsensusValidationResult::::new_with_errors(result.errors)); - } - // Validating state let result = state_transition.validate_state( action, platform, + ValidationMode::Validator, &mut state_transition_execution_context, transaction, )?; @@ -203,6 +223,26 @@ pub(crate) trait StateTransitionBasicStructureValidationV0 { ) -> Result; } +/// A trait for validating state transitions within a blockchain. +/// The advanced structure validation should always happen in a block +/// and not in check_tx +pub(crate) trait StateTransitionAdvancedStructureValidationV0 { + /// Validates the structure of a transaction by checking its basic elements. + /// + /// # Arguments + /// + /// * `platform` - A reference to the platform state ref. + /// * `platform_version` - The platform version. + /// + /// # Returns + /// + /// * `Result` - A result with either a SimpleConsensusValidationResult or an Error. + fn validate_advanced_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result, Error>; +} + /// A trait for validating state transitions within a blockchain. pub(crate) trait StateTransitionNonceValidationV0 { /// Validates the structure of a transaction by checking its basic elements. @@ -244,7 +284,7 @@ pub(crate) trait StateTransitionStructureKnownInStateValidationV0 { ) -> Result; /// This means we should transform into the action before validation of the structure - fn requires_advance_structure_validation(&self) -> bool { + fn requires_advance_structure_validation_from_state(&self) -> bool { false } } @@ -297,6 +337,7 @@ pub(crate) trait StateTransitionStateValidationV0: &self, action: Option, platform: &PlatformRef, + validation_mode: ValidationMode, execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error>; @@ -311,8 +352,9 @@ impl StateTransitionBasicStructureValidationV0 for StateTransition { StateTransition::DataContractCreate(st) => { st.validate_basic_structure(platform_version) } - StateTransition::DataContractUpdate(st) => { - st.validate_basic_structure(platform_version) + StateTransition::DataContractUpdate(_) => { + // no basic structure validation + Ok(SimpleConsensusValidationResult::new()) } StateTransition::IdentityCreate(st) => st.validate_basic_structure(platform_version), StateTransition::IdentityUpdate(st) => st.validate_basic_structure(platform_version), @@ -381,6 +423,23 @@ impl StateTransitionBalanceValidationV0 for StateTransition { } } +impl StateTransitionAdvancedStructureValidationV0 for StateTransition { + fn validate_advanced_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match self { + StateTransition::DataContractCreate(st) => { + st.validate_advanced_structure(platform_version) + } + StateTransition::DataContractUpdate(st) => { + st.validate_advanced_structure(platform_version) + } + _ => Ok(ConsensusValidationResult::::new()), + } + } +} + impl StateTransitionStructureKnownInStateValidationV0 for StateTransition { fn validate_advanced_structure_from_state( &self, @@ -397,7 +456,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for StateTransition { } /// This means we should transform into the action before validation of the structure - fn requires_advance_structure_validation(&self) -> bool { + fn requires_advance_structure_validation_from_state(&self) -> bool { matches!(self, StateTransition::DocumentsBatch(_)) } } @@ -557,36 +616,37 @@ impl StateTransitionStateValidationV0 for StateTransition { &self, action: Option, platform: &PlatformRef, + validation_mode: ValidationMode, execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { match self { // The replay attack is prevented by checking if a data contract exists with this id first StateTransition::DataContractCreate(st) => { - st.validate_state(action, platform, execution_context, tx) + st.validate_state(action, platform, validation_mode, execution_context, tx) } // The replay attack is prevented by identity data contract nonce StateTransition::DataContractUpdate(st) => { - st.validate_state(action, platform, execution_context, tx) + st.validate_state(action, platform, validation_mode, execution_context, tx) } StateTransition::IdentityCreate(st) => { - st.validate_state(action, platform, execution_context, tx) + st.validate_state(action, platform, validation_mode, execution_context, tx) } StateTransition::IdentityUpdate(st) => { - st.validate_state(action, platform, execution_context, tx) + st.validate_state(action, platform, validation_mode, execution_context, tx) } StateTransition::IdentityTopUp(st) => { - st.validate_state(action, platform, execution_context, tx) + st.validate_state(action, platform, validation_mode, execution_context, tx) } StateTransition::IdentityCreditWithdrawal(st) => { - st.validate_state(action, platform, execution_context, tx) + st.validate_state(action, platform, validation_mode, execution_context, tx) } // The replay attack is prevented by identity data contract nonce StateTransition::DocumentsBatch(st) => { - st.validate_state(action, platform, execution_context, tx) + st.validate_state(action, platform, validation_mode, execution_context, tx) } StateTransition::IdentityCreditTransfer(st) => { - st.validate_state(action, platform, execution_context, tx) + st.validate_state(action, platform, validation_mode, execution_context, tx) } } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/advanced_structure/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/advanced_structure/mod.rs new file mode 100644 index 00000000000..025d570014f --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/advanced_structure/mod.rs @@ -0,0 +1,36 @@ +use crate::error::execution::ExecutionError; +use crate::error::Error; +use crate::execution::validation::state_transition::data_contract_create::advanced_structure::v0::DataContractCreatedStateTransitionAdvancedStructureValidationV0; +use crate::execution::validation::state_transition::processor::v0::StateTransitionAdvancedStructureValidationV0; +use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; +use dpp::validation::ConsensusValidationResult; +use dpp::version::PlatformVersion; +use drive::state_transition_action::StateTransitionAction; + +pub(crate) mod v0; + +impl StateTransitionAdvancedStructureValidationV0 for DataContractCreateTransition { + fn validate_advanced_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .contract_create_state_transition + .advanced_structure + { + Some(0) => self.validate_advanced_structure_v0(platform_version), + Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "data contract create transition: validate_advanced_structure".to_string(), + known_versions: vec![0], + received: version, + })), + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "data contract create transition: validate_advanced_structure".to_string(), + known_versions: vec![0], + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/advanced_structure/v0/mod.rs new file mode 100644 index 00000000000..f310f0bb344 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/advanced_structure/v0/mod.rs @@ -0,0 +1,46 @@ +use crate::error::Error; +use dpp::prelude::DataContract; +use dpp::state_transition::data_contract_create_transition::accessors::DataContractCreateTransitionAccessorsV0; +use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; +use dpp::validation::ConsensusValidationResult; +use dpp::version::PlatformVersion; +use dpp::ProtocolError; +use drive::state_transition_action::system::bump_identity_nonce_action::BumpIdentityNonceAction; +use drive::state_transition_action::StateTransitionAction; + +pub(in crate::execution::validation::state_transition::state_transitions::data_contract_create) trait DataContractCreatedStateTransitionAdvancedStructureValidationV0 { + fn validate_advanced_structure_v0(&self, platform_version: &PlatformVersion) -> Result, Error>; +} + +impl DataContractCreatedStateTransitionAdvancedStructureValidationV0 + for DataContractCreateTransition +{ + fn validate_advanced_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result, Error> { + // Validate data contract + let result = DataContract::try_from_platform_versioned( + self.data_contract().clone(), + true, + platform_version, + ); + + // Return validation result if any consensus errors happened + // during data contract validation + match result { + Err(ProtocolError::ConsensusError(consensus_error)) => { + let bump_action = StateTransitionAction::BumpIdentityNonceAction( + BumpIdentityNonceAction::from_borrowed_data_contract_create_transition(self)?, + ); + + Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + vec![*consensus_error], + )) + } + Err(protocol_error) => Err(protocol_error.into()), + Ok(_) => Ok(ConsensusValidationResult::new()), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/structure/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/structure/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/v0/mod.rs similarity index 63% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/structure/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/v0/mod.rs index 5261b3e5c9e..51772a0043c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/basic_structure/v0/mod.rs @@ -6,36 +6,16 @@ use dpp::state_transition::data_contract_create_transition::accessors::DataContr use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; use dpp::validation::SimpleConsensusValidationResult; use dpp::version::PlatformVersion; -use dpp::ProtocolError; -pub(in crate::execution::validation::state_transition::state_transitions::data_contract_create) trait DataContractCreatedStateTransitionStructureValidationV0 { +pub(in crate::execution::validation::state_transition::state_transitions::data_contract_create) trait DataContractCreatedStateTransitionBasicStructureValidationV0 { fn validate_base_structure_v0(&self, platform_version: &PlatformVersion) -> Result; } -impl DataContractCreatedStateTransitionStructureValidationV0 for DataContractCreateTransition { +impl DataContractCreatedStateTransitionBasicStructureValidationV0 for DataContractCreateTransition { fn validate_base_structure_v0( &self, - platform_version: &PlatformVersion, + _platform_version: &PlatformVersion, ) -> Result { - // Validate data contract - let result = DataContract::try_from_platform_versioned( - self.data_contract().clone(), - true, - platform_version, - ); - - // Return validation result if any consensus errors happened - // during data contract validation - match result { - Err(ProtocolError::ConsensusError(consensus_error)) => { - return Ok(SimpleConsensusValidationResult::new_with_error( - *consensus_error, - )) - } - Err(protocol_error) => return Err(protocol_error.into()), - Ok(_) => {} - } - // Validate data contract id let generated_id = DataContract::generate_data_contract_id_v0( self.data_contract().owner_id(), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs index 06ab5da2820..5628c924a8c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/mod.rs @@ -1,6 +1,7 @@ +mod advanced_structure; +mod basic_structure; mod identity_nonce; mod state; -mod structure; use dpp::prelude::ConsensusValidationResult; use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; @@ -14,8 +15,8 @@ use crate::error::execution::ExecutionError; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::data_contract_create::basic_structure::v0::DataContractCreatedStateTransitionBasicStructureValidationV0; use crate::execution::validation::state_transition::data_contract_create::state::v0::DataContractCreateStateTransitionStateValidationV0; -use crate::execution::validation::state_transition::data_contract_create::structure::v0::DataContractCreatedStateTransitionStructureValidationV0; use crate::platform_types::platform::PlatformRef; use crate::rpc::core::CoreRPCLike; @@ -23,12 +24,24 @@ use crate::execution::validation::state_transition::processor::v0::{ StateTransitionBasicStructureValidationV0, StateTransitionStateValidationV0, }; use crate::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; + +impl ValidationMode { + /// Returns if we should validate the contract when we transform it from its serialized form + pub fn should_validate_contract_on_transform_into_action(&self) -> bool { + match self { + ValidationMode::CheckTx => false, + ValidationMode::RecheckTx => false, + ValidationMode::Validator => true, + } + } +} impl StateTransitionActionTransformerV0 for DataContractCreateTransition { fn transform_into_action( &self, platform: &PlatformRef, - _validate: bool, + validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, _tx: TransactionArg, ) -> Result, Error> { @@ -41,7 +54,7 @@ impl StateTransitionActionTransformerV0 for DataContractCreateTransition { .contract_create_state_transition .transform_into_action { - 0 => self.transform_into_action_v0::(platform_version), + 0 => self.transform_into_action_v0::(validation_mode, platform_version), version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "data contract create transition: transform_into_action".to_string(), known_versions: vec![0], @@ -61,14 +74,18 @@ impl StateTransitionBasicStructureValidationV0 for DataContractCreateTransition .validation_and_processing .state_transitions .contract_create_state_transition - .base_structure + .basic_structure { - 0 => self.validate_base_structure_v0(platform_version), - version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + Some(0) => self.validate_base_structure_v0(platform_version), + Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "data contract create transition: validate_basic_structure".to_string(), known_versions: vec![0], received: version, })), + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "data contract create transition: validate_basic_structure".to_string(), + known_versions: vec![0], + })), } } } @@ -78,6 +95,7 @@ impl StateTransitionStateValidationV0 for DataContractCreateTransition { &self, _action: Option, platform: &PlatformRef, + validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { @@ -90,7 +108,7 @@ impl StateTransitionStateValidationV0 for DataContractCreateTransition { .contract_create_state_transition .state { - 0 => self.validate_state_v0(platform, tx, platform_version), + 0 => self.validate_state_v0(platform, tx, validation_mode, platform_version), version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "data contract create transition: validate_state".to_string(), known_versions: vec![0], diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs index 15e656dce8b..21f5c48df2c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs @@ -8,7 +8,8 @@ use dpp::prelude::ConsensusValidationResult; use dpp::state_transition::data_contract_create_transition::accessors::DataContractCreateTransitionAccessorsV0; use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; -use dpp::version::{PlatformVersion, TryIntoPlatformVersioned}; +use crate::execution::validation::state_transition::ValidationMode; +use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use drive::state_transition_action::contract::data_contract_create::DataContractCreateTransitionAction; use drive::state_transition_action::StateTransitionAction; @@ -18,11 +19,13 @@ pub(in crate::execution::validation::state_transition::state_transitions::data_c &self, platform: &PlatformRef, tx: TransactionArg, + validation_mode: ValidationMode, platform_version: &PlatformVersion, ) -> Result, Error>; fn transform_into_action_v0( &self, + validation_mode: ValidationMode, platform_version: &PlatformVersion, ) -> Result, Error>; } @@ -32,6 +35,7 @@ impl DataContractCreateStateTransitionStateValidationV0 for DataContractCreateTr &self, platform: &PlatformRef, tx: TransactionArg, + validation_mode: ValidationMode, platform_version: &PlatformVersion, ) -> Result, Error> { let drive = platform.drive; @@ -54,16 +58,21 @@ impl DataContractCreateStateTransitionStateValidationV0 for DataContractCreateTr .into(), ])) } else { - self.transform_into_action_v0::(platform_version) + self.transform_into_action_v0::(validation_mode, platform_version) } } fn transform_into_action_v0( &self, + validation_mode: ValidationMode, platform_version: &PlatformVersion, ) -> Result, Error> { let create_action: DataContractCreateTransitionAction = - self.try_into_platform_versioned(platform_version)?; + DataContractCreateTransitionAction::try_from_borrowed_platform_versioned( + self, + validation_mode.should_validate_contract_on_transform_into_action(), + platform_version, + )?; let action: StateTransitionAction = create_action.into(); Ok(action.into()) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/advanced_structure/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/advanced_structure/mod.rs new file mode 100644 index 00000000000..547d60e115a --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/advanced_structure/mod.rs @@ -0,0 +1,36 @@ +use crate::error::execution::ExecutionError; +use crate::error::Error; +use crate::execution::validation::state_transition::data_contract_update::advanced_structure::v0::DataContractUpdateStateTransitionAdvancedStructureValidationV0; +use crate::execution::validation::state_transition::processor::v0::StateTransitionAdvancedStructureValidationV0; +use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; +use dpp::validation::ConsensusValidationResult; +use dpp::version::PlatformVersion; +use drive::state_transition_action::StateTransitionAction; + +pub(crate) mod v0; + +impl StateTransitionAdvancedStructureValidationV0 for DataContractUpdateTransition { + fn validate_advanced_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .contract_update_state_transition + .advanced_structure + { + Some(0) => self.validate_advanced_structure_v0(platform_version), + Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "data contract update transition: validate_basic_structure".to_string(), + known_versions: vec![0], + received: version, + })), + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "data contract update transition: validate_basic_structure".to_string(), + known_versions: vec![0], + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/advanced_structure/v0/mod.rs new file mode 100644 index 00000000000..1eed199665a --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/advanced_structure/v0/mod.rs @@ -0,0 +1,42 @@ +use crate::error::Error; +use dpp::data_contract::DataContract; +use dpp::state_transition::data_contract_update_transition::accessors::DataContractUpdateTransitionAccessorsV0; +use dpp::ProtocolError; + +use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; +use dpp::validation::ConsensusValidationResult; +use dpp::version::PlatformVersion; +use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; +use drive::state_transition_action::StateTransitionAction; + +pub(in crate::execution::validation::state_transition::state_transitions::data_contract_update) trait DataContractUpdateStateTransitionAdvancedStructureValidationV0 { + fn validate_advanced_structure_v0(&self, platform_version: &PlatformVersion) -> Result, Error>; +} + +impl DataContractUpdateStateTransitionAdvancedStructureValidationV0 + for DataContractUpdateTransition +{ + fn validate_advanced_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match DataContract::try_from_platform_versioned( + self.data_contract().clone(), + true, + platform_version, + ) { + Err(ProtocolError::ConsensusError(consensus_error)) => { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition(self)?, + ); + + Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + vec![*consensus_error], + )) + } + Err(protocol_error) => Err(protocol_error.into()), + Ok(_) => Ok(ConsensusValidationResult::new()), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs index 008e292a09f..b41661607b5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/mod.rs @@ -1,6 +1,6 @@ +mod advanced_structure; mod identity_contract_nonce; mod state; -mod structure; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; use dpp::validation::ConsensusValidationResult; @@ -16,6 +16,7 @@ use drive::state_transition_action::StateTransitionAction; use crate::execution::validation::state_transition::data_contract_update::state::v0::DataContractUpdateStateTransitionStateValidationV0; use crate::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; use crate::platform_types::platform::PlatformRef; use crate::rpc::core::CoreRPCLike; @@ -23,7 +24,7 @@ impl StateTransitionActionTransformerV0 for DataContractUpdateTransition { fn transform_into_action( &self, platform: &PlatformRef, - _validate: bool, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, _tx: TransactionArg, ) -> Result, Error> { @@ -132,6 +133,7 @@ mod tests { use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; + use crate::execution::validation::state_transition::ValidationMode; use dpp::version::TryFromPlatformVersioned; use platform_version::version::LATEST_PLATFORM_VERSION; use platform_version::{DefaultForPlatformVersion, TryIntoPlatformVersioned}; @@ -197,7 +199,13 @@ mod tests { .expect("expected a platform version"); let result = DataContractUpdateTransition::V0(state_transition) - .validate_state(None, &platform_ref, &mut execution_context, None) + .validate_state( + None, + &platform_ref, + ValidationMode::Validator, + &mut execution_context, + None, + ) .expect("state transition to be validated"); assert!(!result.is_valid()); @@ -278,7 +286,13 @@ mod tests { .expect("expected a platform version"); let result = DataContractUpdateTransition::V0(state_transition) - .validate_state(None, &platform_ref, &mut execution_context, None) + .validate_state( + None, + &platform_ref, + ValidationMode::Validator, + &mut execution_context, + None, + ) .expect("state transition to be validated"); assert!(result.is_valid()); @@ -428,7 +442,13 @@ mod tests { .expect("expected a platform version"); let result = state_transition - .validate_state(None, &platform_ref, &mut execution_context, None) + .validate_state( + None, + &platform_ref, + ValidationMode::Validator, + &mut execution_context, + None, + ) .expect("state transition to be validated"); assert!(!result.is_valid()); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/mod.rs index 81b2af66a76..ac7dd03f151 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/mod.rs @@ -3,6 +3,7 @@ use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::execution::validation::state_transition::data_contract_update::state::v0::DataContractUpdateStateTransitionStateValidationV0; use crate::execution::validation::state_transition::processor::v0::StateTransitionStateValidationV0; +use crate::execution::validation::state_transition::ValidationMode; use crate::platform_types::platform::PlatformRef; use crate::rpc::core::CoreRPCLike; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; @@ -17,6 +18,7 @@ impl StateTransitionStateValidationV0 for DataContractUpdateTransition { &self, _action: Option, platform: &PlatformRef, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/structure/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/structure/mod.rs deleted file mode 100644 index b4f95f7e298..00000000000 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/structure/mod.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::error::execution::ExecutionError; -use crate::error::Error; -use crate::execution::validation::state_transition::data_contract_update::structure::v0::DataContractUpdateStateTransitionStructureValidationV0; -use crate::execution::validation::state_transition::processor::v0::StateTransitionBasicStructureValidationV0; -use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; -use dpp::validation::SimpleConsensusValidationResult; -use dpp::version::PlatformVersion; - -pub(crate) mod v0; - -impl StateTransitionBasicStructureValidationV0 for DataContractUpdateTransition { - fn validate_basic_structure( - &self, - platform_version: &PlatformVersion, - ) -> Result { - match platform_version - .drive_abci - .validation_and_processing - .state_transitions - .contract_update_state_transition - .base_structure - { - 0 => self.validate_base_structure_v0(platform_version), - version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { - method: "data contract update transition: validate_basic_structure".to_string(), - known_versions: vec![0], - received: version, - })), - } - } -} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/structure/v0/mod.rs deleted file mode 100644 index 20853351aeb..00000000000 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/structure/v0/mod.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::error::Error; -use dpp::data_contract::DataContract; -use dpp::state_transition::data_contract_update_transition::accessors::DataContractUpdateTransitionAccessorsV0; -use dpp::ProtocolError; - -use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; -use dpp::validation::SimpleConsensusValidationResult; -use dpp::version::PlatformVersion; - -pub(in crate::execution::validation::state_transition::state_transitions::data_contract_update) trait DataContractUpdateStateTransitionStructureValidationV0 { - fn validate_base_structure_v0(&self, platform_version: &PlatformVersion) -> Result; -} - -impl DataContractUpdateStateTransitionStructureValidationV0 for DataContractUpdateTransition { - fn validate_base_structure_v0( - &self, - platform_version: &PlatformVersion, - ) -> Result { - match DataContract::try_from_platform_versioned( - self.data_contract().clone(), - true, - platform_version, - ) { - Ok(_) => Ok(SimpleConsensusValidationResult::default()), - Err(ProtocolError::ConsensusError(e)) => Ok( - SimpleConsensusValidationResult::new_with_error(e.as_ref().clone()), - ), - Err(e) => Err(e.into()), - } - } -} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs index a618e7404ce..c351f33b3d5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs @@ -30,12 +30,24 @@ use crate::execution::validation::state_transition::processor::v0::{ StateTransitionStateValidationV0, StateTransitionStructureKnownInStateValidationV0, }; use crate::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; + +impl ValidationMode { + /// Returns a bool on whether we should validate that documents are valid against the state + pub fn should_validate_document_valid_against_state(&self) -> bool { + match self { + ValidationMode::CheckTx => false, + ValidationMode::RecheckTx => false, + ValidationMode::Validator => true, + } + } +} impl StateTransitionActionTransformerV0 for DocumentsBatchTransition { fn transform_into_action( &self, platform: &PlatformRef, - validate: bool, + validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { @@ -48,7 +60,7 @@ impl StateTransitionActionTransformerV0 for DocumentsBatchTransition { .documents_batch_state_transition .transform_into_action { - 0 => self.transform_into_action_v0(&platform.into(), validate, tx), + 0 => self.transform_into_action_v0(&platform.into(), validation_mode, tx), version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "documents batch transition: transform_into_action".to_string(), known_versions: vec![0], @@ -152,7 +164,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for DocumentsBatchTransiti } } - fn requires_advance_structure_validation(&self) -> bool { + fn requires_advance_structure_validation_from_state(&self) -> bool { true } } @@ -162,6 +174,7 @@ impl StateTransitionStateValidationV0 for DocumentsBatchTransition { &self, action: Option, platform: &PlatformRef, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs index ac3ccabd4be..e28e432d644 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs @@ -18,6 +18,7 @@ use crate::execution::validation::state_transition::documents_batch::action_vali use crate::execution::validation::state_transition::documents_batch::data_triggers::{data_trigger_bindings_list, DataTriggerExecutionContext, DataTriggerExecutor}; use crate::platform_types::platform::{PlatformStateRef}; use crate::execution::validation::state_transition::state_transitions::documents_batch::transformer::v0::DocumentsBatchTransitionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; mod data_triggers; pub mod fetch_documents; @@ -35,7 +36,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::docume fn transform_into_action_v0( &self, platform: &PlatformStateRef, - validate: bool, + validation_mode: ValidationMode, tx: TransactionArg, ) -> Result, Error>; } @@ -153,7 +154,7 @@ impl DocumentsBatchStateTransitionStateValidationV0 for DocumentsBatchTransition fn transform_into_action_v0( &self, platform: &PlatformStateRef, - validate: bool, + validation_mode: ValidationMode, tx: TransactionArg, ) -> Result, Error> { let platform_version = platform.state.current_platform_version()?; @@ -161,8 +162,12 @@ impl DocumentsBatchStateTransitionStateValidationV0 for DocumentsBatchTransition let mut execution_context = StateTransitionExecutionContext::default_for_platform_version(platform_version)?; - let validation_result = - self.try_into_action_v0(platform, validate, tx, &mut execution_context)?; + let validation_result = self.try_into_action_v0( + platform, + validation_mode.should_validate_document_valid_against_state(), + tx, + &mut execution_context, + )?; Ok(validation_result.map(Into::into)) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs index 8ba97782e98..d64ec65d746 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs @@ -98,7 +98,7 @@ impl DocumentsBatchTransitionTransformerV0 for DocumentsBatchTransition { fn try_into_action_v0( &self, platform: &PlatformStateRef, - validate: bool, + validate_against_state: bool, transaction: TransactionArg, execution_context: &mut StateTransitionExecutionContext, ) -> Result, Error> { @@ -139,7 +139,7 @@ impl DocumentsBatchTransitionTransformerV0 for DocumentsBatchTransition { |(data_contract_id, document_transitions_by_document_type)| { Self::transform_document_transitions_within_contract_v0( platform, - validate, + validate_against_state, data_contract_id, owner_id, document_transitions_by_document_type, @@ -173,7 +173,7 @@ impl DocumentsBatchTransitionTransformerV0 for DocumentsBatchTransition { impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition { fn transform_document_transitions_within_contract_v0( platform: &PlatformStateRef, - validate: bool, + validate_against_state: bool, data_contract_id: &Identifier, owner_id: Identifier, document_transitions: &BTreeMap<&String, Vec<&DocumentTransition>>, @@ -206,7 +206,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition .map(|(document_type_name, document_transitions)| { Self::transform_document_transitions_within_document_type_v0( platform, - validate, + validate_against_state, data_contract_fetch_info.clone(), document_type_name, owner_id, @@ -223,7 +223,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition fn transform_document_transitions_within_document_type_v0( platform: &PlatformStateRef, - validate: bool, + validate_against_state: bool, data_contract_fetch_info: Arc, document_type_name: &str, owner_id: Identifier, @@ -286,7 +286,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition .map(|transition| { // we validate every transition in this document type Self::transform_transition_v0( - validate, + validate_against_state, data_contract_fetch_info.clone(), transition, &replaced_documents, @@ -321,7 +321,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition /// The data contract can be of multiple difference versions fn transform_transition_v0<'a>( - validate: bool, + validate_against_state: bool, data_contract_fetch_info: Arc, transition: &DocumentTransition, replaced_documents: &[Document], @@ -369,7 +369,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition return Ok(result); } - if validate { + if validate_against_state { //there are situations where we don't want to validate this against the state // for example when we already applied the state transition action // and we are just validating it happened diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs index 531d3f7eb8f..43201f4e2f9 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/mod.rs @@ -23,6 +23,7 @@ use dpp::validation::SimpleConsensusValidationResult; use dpp::version::PlatformVersion; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::ValidationMode; use drive::grovedb::TransactionArg; use drive::state_transition_action::StateTransitionAction; @@ -30,7 +31,7 @@ impl StateTransitionActionTransformerV0 for IdentityCreateTransition { fn transform_into_action( &self, platform: &PlatformRef, - _validate: bool, + _validation_mode: ValidationMode, execution_context: &mut StateTransitionExecutionContext, _tx: TransactionArg, ) -> Result, Error> { @@ -62,14 +63,18 @@ impl StateTransitionBasicStructureValidationV0 for IdentityCreateTransition { .validation_and_processing .state_transitions .identity_create_state_transition - .base_structure + .basic_structure { - 0 => self.validate_base_structure_v0(platform_version), - version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + Some(0) => self.validate_base_structure_v0(platform_version), + Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "identity create transition: validate_basic_structure".to_string(), known_versions: vec![0], received: version, })), + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "identity create transition: validate_basic_structure".to_string(), + known_versions: vec![0], + })), } } } @@ -79,6 +84,7 @@ impl StateTransitionStateValidationV0 for IdentityCreateTransition { &self, _action: Option, platform: &PlatformRef, + _validation_mode: ValidationMode, execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/state/v0/mod.rs index c8da55d588b..d48fc7d1ac8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/state/v0/mod.rs @@ -33,7 +33,7 @@ use dpp::version::DefaultForPlatformVersion; use drive::grovedb::TransactionArg; use crate::execution::validation::state_transition::common::asset_lock::transaction::fetch_asset_lock_transaction_output_sync::fetch_asset_lock_transaction_output_sync; -use crate::execution::validation::state_transition::common::validate_unique_identity_public_key_hashes_in_state::validate_unique_identity_public_key_hashes_in_state; +use crate::execution::validation::state_transition::common::validate_unique_identity_public_key_hashes_in_state::validate_unique_identity_public_key_hashes_not_in_state; pub(in crate::execution::validation::state_transition::state_transitions::identity_create) trait IdentityCreateStateTransitionStateValidationV0 { @@ -90,7 +90,7 @@ impl IdentityCreateStateTransitionStateValidationV0 for IdentityCreateTransition // Now we should check the state of added keys to make sure there aren't any that already exist validation_result.add_errors( - validate_unique_identity_public_key_hashes_in_state( + validate_unique_identity_public_key_hashes_not_in_state( self.public_keys(), drive, &mut state_transition_execution_context, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs index 790735d9460..5c95785d113 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/mod.rs @@ -22,12 +22,13 @@ use crate::execution::validation::state_transition::processor::v0::{ StateTransitionBasicStructureValidationV0, StateTransitionStateValidationV0, }; use crate::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; impl StateTransitionActionTransformerV0 for IdentityCreditTransferTransition { fn transform_into_action( &self, platform: &PlatformRef, - _validate: bool, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, _tx: TransactionArg, ) -> Result, Error> { @@ -60,14 +61,18 @@ impl StateTransitionBasicStructureValidationV0 for IdentityCreditTransferTransit .validation_and_processing .state_transitions .identity_credit_transfer_state_transition - .base_structure + .basic_structure { - 0 => self.validate_base_structure_v0(), - version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { - method: "identity credit transfer transition: validate_structure".to_string(), + Some(0) => self.validate_base_structure_v0(), + Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "identity credit transfer transition: validate_basic_structure".to_string(), known_versions: vec![0], received: version, })), + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "identity credit transfer transition: validate_basic_structure".to_string(), + known_versions: vec![0], + })), } } } @@ -77,6 +82,7 @@ impl StateTransitionStateValidationV0 for IdentityCreditTransferTransition { &self, _action: Option, platform: &PlatformRef, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/structure/v0/mod.rs index 9a0951d43aa..7d0784624b7 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_transfer/structure/v0/mod.rs @@ -8,7 +8,7 @@ use dpp::state_transition::identity_credit_transfer_transition::accessors::Ident use dpp::state_transition::identity_credit_transfer_transition::IdentityCreditTransferTransition; use dpp::validation::SimpleConsensusValidationResult; -const MIN_TRANSFER_AMOUNT: u64 = 1000; +const MIN_TRANSFER_AMOUNT: u64 = 100000; pub(in crate::execution::validation::state_transition::state_transitions::identity_credit_transfer) trait IdentityCreditTransferStateTransitionStructureValidationV0 { fn validate_base_structure_v0(&self) -> Result; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs index d619e777601..d9a41cb229d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_credit_withdrawal/mod.rs @@ -23,12 +23,13 @@ use crate::execution::validation::state_transition::processor::v0::{ StateTransitionBasicStructureValidationV0, StateTransitionStateValidationV0, }; use crate::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; impl StateTransitionActionTransformerV0 for IdentityCreditWithdrawalTransition { fn transform_into_action( &self, platform: &PlatformRef, - _validate: bool, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, _tx: TransactionArg, ) -> Result, Error> { @@ -61,15 +62,20 @@ impl StateTransitionBasicStructureValidationV0 for IdentityCreditWithdrawalTrans .validation_and_processing .state_transitions .identity_credit_withdrawal_state_transition - .base_structure + .basic_structure { - 0 => self.validate_base_structure_v0(), - version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + Some(0) => self.validate_base_structure_v0(), + Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "identity credit withdrawal transition: validate_basic_structure" .to_string(), known_versions: vec![0], received: version, })), + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "identity credit withdrawal transition: validate_basic_structure" + .to_string(), + known_versions: vec![0], + })), } } } @@ -79,6 +85,7 @@ impl StateTransitionStateValidationV0 for IdentityCreditWithdrawalTransition { &self, _action: Option, platform: &PlatformRef, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up/mod.rs index c3b5f611526..bdf37ebdc8f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_top_up/mod.rs @@ -23,12 +23,13 @@ use crate::execution::validation::state_transition::processor::v0::{ }; use crate::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; impl StateTransitionActionTransformerV0 for IdentityTopUpTransition { fn transform_into_action( &self, platform: &PlatformRef, - _validate: bool, + _validation_mode: ValidationMode, execution_context: &mut StateTransitionExecutionContext, _tx: TransactionArg, ) -> Result, Error> { @@ -61,14 +62,18 @@ impl StateTransitionBasicStructureValidationV0 for IdentityTopUpTransition { .validation_and_processing .state_transitions .identity_top_up_state_transition - .base_structure + .basic_structure { - 0 => self.validate_base_structure_v0(platform_version), - version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + Some(0) => self.validate_base_structure_v0(platform_version), + Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "identity top up transition: validate_basic_structure".to_string(), known_versions: vec![0], received: version, })), + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "identity top up transition: validate_basic_structure".to_string(), + known_versions: vec![0], + })), } } } @@ -78,6 +83,7 @@ impl StateTransitionStateValidationV0 for IdentityTopUpTransition { &self, _action: Option, platform: &PlatformRef, + _validation_mode: ValidationMode, execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs index 2fd5093131a..4363faab6fe 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs @@ -24,12 +24,13 @@ use crate::execution::validation::state_transition::processor::v0::{ }; use crate::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; impl StateTransitionActionTransformerV0 for IdentityUpdateTransition { fn transform_into_action( &self, platform: &PlatformRef, - _validate: bool, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, _tx: TransactionArg, ) -> Result, Error> { @@ -62,14 +63,18 @@ impl StateTransitionBasicStructureValidationV0 for IdentityUpdateTransition { .validation_and_processing .state_transitions .identity_update_state_transition - .base_structure + .basic_structure { - 0 => self.validate_base_structure_v0(platform_version), - version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + Some(0) => self.validate_base_structure_v0(platform_version), + Some(version) => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "identity update transition: validate_basic_structure".to_string(), known_versions: vec![0], received: version, })), + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "identity update transition: validate_basic_structure".to_string(), + known_versions: vec![0], + })), } } } @@ -79,6 +84,7 @@ impl StateTransitionStateValidationV0 for IdentityUpdateTransition { &self, _action: Option, platform: &PlatformRef, + _validation_mode: ValidationMode, _execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs index 41b6a6c94ae..078374d64aa 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs @@ -24,7 +24,7 @@ use crate::execution::types::state_transition_execution_context::StateTransition use crate::execution::validation::state_transition::common::validate_identity_public_key_contract_bounds::validate_identity_public_keys_contract_bounds; use crate::execution::validation::state_transition::common::validate_identity_public_key_ids_dont_exist_in_state::validate_identity_public_key_ids_dont_exist_in_state; use crate::execution::validation::state_transition::common::validate_identity_public_key_ids_exist_in_state::validate_identity_public_key_ids_exist_in_state; -use crate::execution::validation::state_transition::common::validate_unique_identity_public_key_hashes_in_state::validate_unique_identity_public_key_hashes_in_state; +use crate::execution::validation::state_transition::common::validate_unique_identity_public_key_hashes_in_state::validate_unique_identity_public_key_hashes_not_in_state; use crate::platform_types::platform_state::v0::PlatformStateV0Methods; pub(in crate::execution::validation::state_transition::state_transitions::identity_update) trait IdentityUpdateStateTransitionStateValidationV0 @@ -55,7 +55,7 @@ impl IdentityUpdateStateTransitionStateValidationV0 for IdentityUpdateTransition // Now we should check the state of added keys to make sure there aren't any that already exist validation_result.add_errors( - validate_unique_identity_public_key_hashes_in_state( + validate_unique_identity_public_key_hashes_not_in_state( self.public_keys_to_add(), drive, &mut state_transition_execution_context, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs index 39b3dee515e..c9dcaf4a8b6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs @@ -21,3 +21,13 @@ pub mod data_contract_create; /// Module for updating an existing data contract entity. pub mod data_contract_update; + +/// The validation mode we are using +pub enum ValidationMode { + /// The basic checktx before the state transition is put into mempool + CheckTx, + /// Rechecking a state transition every block + RecheckTx, + /// The validation of the validator + Validator, +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/transformer/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/transformer/mod.rs index 700f73381d6..05ca80fc96b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/transformer/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/transformer/mod.rs @@ -1,5 +1,6 @@ use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::ValidationMode; use crate::platform_types::platform::PlatformRef; use crate::rpc::core::CoreRPCLike; use dpp::prelude::ConsensusValidationResult; @@ -28,7 +29,7 @@ pub trait StateTransitionActionTransformerV0 { fn transform_into_action( &self, platform: &PlatformRef, - validate: bool, + validation_mode: ValidationMode, execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error>; @@ -38,34 +39,34 @@ impl StateTransitionActionTransformerV0 for StateTransition { fn transform_into_action( &self, platform: &PlatformRef, - validate: bool, + validation_mode: ValidationMode, execution_context: &mut StateTransitionExecutionContext, tx: TransactionArg, ) -> Result, Error> { match self { StateTransition::DataContractCreate(st) => { - st.transform_into_action(platform, validate, execution_context, tx) + st.transform_into_action(platform, validation_mode, execution_context, tx) } StateTransition::DataContractUpdate(st) => { - st.transform_into_action(platform, validate, execution_context, tx) + st.transform_into_action(platform, validation_mode, execution_context, tx) } StateTransition::IdentityCreate(st) => { - st.transform_into_action(platform, validate, execution_context, tx) + st.transform_into_action(platform, validation_mode, execution_context, tx) } StateTransition::IdentityUpdate(st) => { - st.transform_into_action(platform, validate, execution_context, tx) + st.transform_into_action(platform, validation_mode, execution_context, tx) } StateTransition::IdentityTopUp(st) => { - st.transform_into_action(platform, validate, execution_context, tx) + st.transform_into_action(platform, validation_mode, execution_context, tx) } StateTransition::IdentityCreditWithdrawal(st) => { - st.transform_into_action(platform, validate, execution_context, tx) + st.transform_into_action(platform, validation_mode, execution_context, tx) } StateTransition::DocumentsBatch(st) => { - st.transform_into_action(platform, validate, execution_context, tx) + st.transform_into_action(platform, validation_mode, execution_context, tx) } StateTransition::IdentityCreditTransfer(st) => { - st.transform_into_action(platform, validate, execution_context, tx) + st.transform_into_action(platform, validation_mode, execution_context, tx) } } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/verify_state_transitions.rs b/packages/rs-drive-abci/tests/strategy_tests/verify_state_transitions.rs index ed7d7f3bad1..5a9618717c6 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/verify_state_transitions.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/verify_state_transitions.rs @@ -24,6 +24,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentFromReplaceTransitionAction; use drive_abci::abci::app::FullAbciApplication; use drive_abci::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use drive_abci::execution::validation::state_transition::ValidationMode; use drive_abci::platform_types::platform_state::v0::PlatformStateV0Methods; use platform_version::DefaultForPlatformVersion; @@ -59,7 +60,7 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( let consensus_validation_result = match state_transition.transform_into_action( &platform, - false, + ValidationMode::CheckTx, //using check_tx so we don't validate state &mut execution_context, None, ) { diff --git a/packages/rs-drive/src/state_transition_action/contract/data_contract_create/transformer.rs b/packages/rs-drive/src/state_transition_action/contract/data_contract_create/transformer.rs index 4c04b4b762c..4644d28d314 100644 --- a/packages/rs-drive/src/state_transition_action/contract/data_contract_create/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/contract/data_contract_create/transformer.rs @@ -3,40 +3,42 @@ use crate::state_transition_action::contract::data_contract_create::DataContract use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; use dpp::ProtocolError; use platform_version::version::PlatformVersion; -use platform_version::TryFromPlatformVersioned; -impl TryFromPlatformVersioned for DataContractCreateTransitionAction { - type Error = ProtocolError; - - fn try_from_platform_versioned( +impl DataContractCreateTransitionAction { + /// tries to transform the DataContractCreateTransition into a DataContractCreateTransitionAction + /// if validation is true the data contract transformation verifies that the data contract is valid + /// if validation is false, the data contract base structure is created regardless of if it is valid + pub fn try_from_platform_versioned( value: DataContractCreateTransition, + validate: bool, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result { match value { DataContractCreateTransition::V0(v0) => Ok( DataContractCreateTransitionActionV0::try_from_platform_versioned( v0, + validate, platform_version, )? .into(), ), } } -} -impl TryFromPlatformVersioned<&DataContractCreateTransition> - for DataContractCreateTransitionAction -{ - type Error = ProtocolError; + /// tries to transform the borrowed DataContractCreateTransition into a DataContractCreateTransitionAction + /// if validation is true the data contract transformation verifies that the data contract is valid + /// if validation is false, the data contract base structure is created regardless of if it is valid - fn try_from_platform_versioned( + pub fn try_from_borrowed_platform_versioned( value: &DataContractCreateTransition, + validate: bool, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result { match value { DataContractCreateTransition::V0(v0) => Ok( - DataContractCreateTransitionActionV0::try_from_platform_versioned( + DataContractCreateTransitionActionV0::try_from_borrowed_platform_versioned( v0, + validate, platform_version, )? .into(), diff --git a/packages/rs-drive/src/state_transition_action/contract/data_contract_create/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/contract/data_contract_create/v0/transformer.rs index 9291d787372..a4c0c1a6cb2 100644 --- a/packages/rs-drive/src/state_transition_action/contract/data_contract_create/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/contract/data_contract_create/v0/transformer.rs @@ -3,42 +3,33 @@ use dpp::prelude::DataContract; use dpp::state_transition::data_contract_create_transition::DataContractCreateTransitionV0; use dpp::ProtocolError; use platform_version::version::PlatformVersion; -use platform_version::TryFromPlatformVersioned; -impl TryFromPlatformVersioned - for DataContractCreateTransitionActionV0 -{ - type Error = ProtocolError; - - fn try_from_platform_versioned( +impl DataContractCreateTransitionActionV0 { + pub(in crate::state_transition_action::contract::data_contract_create) fn try_from_platform_versioned( value: DataContractCreateTransitionV0, + validate: bool, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result { Ok(DataContractCreateTransitionActionV0 { data_contract: DataContract::try_from_platform_versioned( value.data_contract, - true, + validate, platform_version, )?, identity_nonce: value.identity_nonce, user_fee_increase: value.user_fee_increase, }) } -} - -impl TryFromPlatformVersioned<&DataContractCreateTransitionV0> - for DataContractCreateTransitionActionV0 -{ - type Error = ProtocolError; - fn try_from_platform_versioned( + pub(in crate::state_transition_action::contract::data_contract_create) fn try_from_borrowed_platform_versioned( value: &DataContractCreateTransitionV0, + validate: bool, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result { Ok(DataContractCreateTransitionActionV0 { data_contract: DataContract::try_from_platform_versioned( value.data_contract.clone(), - true, + validate, platform_version, )?, identity_nonce: value.identity_nonce, diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/transformer.rs index 14fbe1091e6..ec75a3ffed2 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/transformer.rs @@ -1,9 +1,11 @@ +use crate::state_transition_action::contract::data_contract_create::DataContractCreateTransitionAction; use crate::state_transition_action::identity::identity_credit_transfer::IdentityCreditTransferTransitionAction; use crate::state_transition_action::identity::identity_credit_withdrawal::IdentityCreditWithdrawalTransitionAction; use crate::state_transition_action::identity::identity_update::IdentityUpdateTransitionAction; use crate::state_transition_action::system::bump_identity_nonce_action::{ BumpIdentityNonceAction, BumpIdentityNonceActionV0, }; +use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; use dpp::state_transition::identity_credit_transfer_transition::IdentityCreditTransferTransition; use dpp::state_transition::identity_credit_withdrawal_transition::IdentityCreditWithdrawalTransition; use dpp::state_transition::identity_update_transition::IdentityUpdateTransition; @@ -54,6 +56,50 @@ impl BumpIdentityNonceAction { } } + /// from data contract create transition + pub fn from_data_contract_create_transition( + value: DataContractCreateTransition, + ) -> Result { + match value { + DataContractCreateTransition::V0(v0) => { + Ok(BumpIdentityNonceActionV0::try_from_contract_create(v0)?.into()) + } + } + } + + /// from borrowed data contract create transition + pub fn from_borrowed_data_contract_create_transition( + value: &DataContractCreateTransition, + ) -> Result { + match value { + DataContractCreateTransition::V0(v0) => { + Ok(BumpIdentityNonceActionV0::try_from_borrowed_contract_create(v0)?.into()) + } + } + } + + /// from data contract create transition action + pub fn from_data_contract_create_action( + value: DataContractCreateTransitionAction, + ) -> Result { + match value { + DataContractCreateTransitionAction::V0(v0) => { + Ok(BumpIdentityNonceActionV0::try_from_contract_create_action(v0)?.into()) + } + } + } + + /// from borrowed data contract create transition action + pub fn from_borrowed_data_contract_create_action( + value: &DataContractCreateTransitionAction, + ) -> Result { + match value { + DataContractCreateTransitionAction::V0(v0) => { + Ok(BumpIdentityNonceActionV0::try_from_borrowed_contract_create_action(v0)?.into()) + } + } + } + /// from identity transfer pub fn from_identity_credit_transfer_transition( value: IdentityCreditTransferTransition, diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/v0/transformer.rs index 9c99de49239..5c626a336f2 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/v0/transformer.rs @@ -1,7 +1,10 @@ +use crate::state_transition_action::contract::data_contract_create::v0::DataContractCreateTransitionActionV0; use crate::state_transition_action::identity::identity_credit_transfer::v0::IdentityCreditTransferTransitionActionV0; use crate::state_transition_action::identity::identity_credit_withdrawal::v0::IdentityCreditWithdrawalTransitionActionV0; use crate::state_transition_action::identity::identity_update::v0::IdentityUpdateTransitionActionV0; use crate::state_transition_action::system::bump_identity_nonce_action::BumpIdentityNonceActionV0; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::state_transition::data_contract_create_transition::DataContractCreateTransitionV0; use dpp::state_transition::identity_credit_transfer_transition::v0::IdentityCreditTransferTransitionV0; use dpp::state_transition::identity_credit_withdrawal_transition::v0::IdentityCreditWithdrawalTransitionV0; use dpp::state_transition::identity_update_transition::v0::IdentityUpdateTransitionV0; @@ -76,6 +79,74 @@ impl BumpIdentityNonceActionV0 { }) } + /// try from contract create + pub fn try_from_contract_create( + value: DataContractCreateTransitionV0, + ) -> Result { + let DataContractCreateTransitionV0 { + data_contract, + identity_nonce, + user_fee_increase, + .. + } = value; + Ok(BumpIdentityNonceActionV0 { + identity_id: data_contract.owner_id(), + identity_nonce, + user_fee_increase, + }) + } + + /// try from contract create + pub fn try_from_borrowed_contract_create( + value: &DataContractCreateTransitionV0, + ) -> Result { + let DataContractCreateTransitionV0 { + data_contract, + identity_nonce, + user_fee_increase, + .. + } = value; + Ok(BumpIdentityNonceActionV0 { + identity_id: data_contract.owner_id(), + identity_nonce: *identity_nonce, + user_fee_increase: *user_fee_increase, + }) + } + + /// try from contract create action + pub fn try_from_contract_create_action( + value: DataContractCreateTransitionActionV0, + ) -> Result { + let DataContractCreateTransitionActionV0 { + data_contract, + identity_nonce, + user_fee_increase, + .. + } = value; + Ok(BumpIdentityNonceActionV0 { + identity_id: data_contract.owner_id(), + identity_nonce, + user_fee_increase, + }) + } + + /// try from contract create + pub fn try_from_borrowed_contract_create_action( + value: &DataContractCreateTransitionActionV0, + ) -> Result { + let DataContractCreateTransitionActionV0 { + data_contract, + identity_nonce, + user_fee_increase, + .. + } = value; + Ok(BumpIdentityNonceActionV0 { + identity_id: data_contract.owner_id(), + identity_nonce: *identity_nonce, + user_fee_increase: *user_fee_increase, + }) + } + /// try from identity credit transfer pub fn try_from_identity_credit_transfer( value: IdentityCreditTransferTransitionV0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions.rs b/packages/rs-platform-version/src/version/drive_abci_versions.rs index a24ef3b2149..902094ddec0 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions.rs @@ -121,7 +121,7 @@ pub struct DriveAbciValidationDataTriggerVersions { #[derive(Clone, Debug, Default)] pub struct DriveAbciStateTransitionValidationVersion { - pub base_structure: FeatureVersion, + pub basic_structure: OptionalFeatureVersion, pub advanced_structure: OptionalFeatureVersion, pub identity_signatures: OptionalFeatureVersion, pub balance: OptionalFeatureVersion, diff --git a/packages/rs-platform-version/src/version/mocks/v2_test.rs b/packages/rs-platform-version/src/version/mocks/v2_test.rs index 608bdfcc1fe..b7103809020 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -595,7 +595,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { validate_unique_identity_public_key_hashes_in_state: 0, }, identity_create_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -604,7 +604,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { transform_into_action: 0, }, identity_update_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -613,7 +613,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { transform_into_action: 0, }, identity_top_up_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -623,7 +623,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { }, identity_credit_withdrawal_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: None, balance: Some(0), @@ -633,7 +633,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { }, identity_credit_transfer_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: None, balance: Some(0), @@ -642,8 +642,8 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { transform_into_action: 0, }, contract_create_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, - advanced_structure: None, + basic_structure: Some(0), + advanced_structure: Some(0), identity_signatures: None, balance: None, nonce: Some(0), @@ -651,8 +651,8 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { transform_into_action: 0, }, contract_update_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, - advanced_structure: None, + basic_structure: None, + advanced_structure: Some(0), identity_signatures: None, balance: None, nonce: Some(0), diff --git a/packages/rs-platform-version/src/version/mocks/v3_test.rs b/packages/rs-platform-version/src/version/mocks/v3_test.rs index b780f4e7dee..f423c2400fa 100644 --- a/packages/rs-platform-version/src/version/mocks/v3_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v3_test.rs @@ -595,7 +595,7 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { validate_unique_identity_public_key_hashes_in_state: 0, }, identity_create_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -604,7 +604,7 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { transform_into_action: 0, }, identity_update_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -613,7 +613,7 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { transform_into_action: 0, }, identity_top_up_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -623,7 +623,7 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { }, identity_credit_withdrawal_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: None, balance: Some(0), @@ -633,7 +633,7 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { }, identity_credit_transfer_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: None, balance: Some(0), @@ -642,8 +642,8 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { transform_into_action: 0, }, contract_create_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, - advanced_structure: None, + basic_structure: Some(0), + advanced_structure: Some(0), identity_signatures: None, balance: None, nonce: Some(0), @@ -651,8 +651,8 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { transform_into_action: 0, }, contract_update_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, - advanced_structure: None, + basic_structure: None, + advanced_structure: Some(0), identity_signatures: None, balance: None, nonce: Some(0), diff --git a/packages/rs-platform-version/src/version/v1.rs b/packages/rs-platform-version/src/version/v1.rs index 4f1b649e233..0666b2a9c28 100644 --- a/packages/rs-platform-version/src/version/v1.rs +++ b/packages/rs-platform-version/src/version/v1.rs @@ -592,7 +592,7 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { validate_unique_identity_public_key_hashes_in_state: 0, }, identity_create_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -601,7 +601,7 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { transform_into_action: 0, }, identity_update_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -610,7 +610,7 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { transform_into_action: 0, }, identity_top_up_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: Some(0), balance: None, @@ -620,7 +620,7 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { }, identity_credit_withdrawal_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: None, balance: Some(0), @@ -630,7 +630,7 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { }, identity_credit_transfer_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, + basic_structure: Some(0), advanced_structure: None, identity_signatures: None, balance: Some(0), @@ -639,8 +639,8 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { transform_into_action: 0, }, contract_create_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, - advanced_structure: None, + basic_structure: Some(0), + advanced_structure: Some(0), identity_signatures: None, balance: None, nonce: Some(0), @@ -648,8 +648,8 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { transform_into_action: 0, }, contract_update_state_transition: DriveAbciStateTransitionValidationVersion { - base_structure: 0, - advanced_structure: None, + basic_structure: None, + advanced_structure: Some(0), identity_signatures: None, balance: None, nonce: Some(0), diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index 106cea4f5bd..79f57f2dc2a 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -428,7 +428,7 @@ impl Strategy { updated_contract_data.set_owner_id(contract.owner_id()); } } - + // Update any document transitions that registered to the old contract id for op in self.operations.iter_mut() { if let OperationType::Document(document_op) = &mut op.op_type { @@ -438,7 +438,7 @@ impl Strategy { document_op.document_type = document_type; } } - + DataContractCreateTransition::new_from_data_contract( contract.clone(), *identity_nonce, diff --git a/packages/strategy-tests/src/operations.rs b/packages/strategy-tests/src/operations.rs index 9ad6a08d0ee..933fe417ea6 100644 --- a/packages/strategy-tests/src/operations.rs +++ b/packages/strategy-tests/src/operations.rs @@ -353,10 +353,7 @@ enum OperationTypeInSerializationFormat { IdentityTopUp, IdentityUpdate(IdentityUpdateOp), IdentityWithdrawal, - ContractCreate( - RandomDocumentTypeParameters, - DocumentTypeCount, - ), + ContractCreate(RandomDocumentTypeParameters, DocumentTypeCount), ContractUpdate(Vec), IdentityTransfer, } @@ -379,12 +376,11 @@ impl PlatformSerializableWithPlatformVersion for OperationType { let op = match self { OperationType::Document(document_op) => { // let's just serialize it to make things easier - let document_op_in_serialization_format = document_op.serialize_consume_to_bytes_with_platform_version(platform_version)?; + let document_op_in_serialization_format = document_op + .serialize_consume_to_bytes_with_platform_version(platform_version)?; OperationTypeInSerializationFormat::Document(document_op_in_serialization_format) } - OperationType::IdentityTopUp => { - OperationTypeInSerializationFormat::IdentityTopUp - } + OperationType::IdentityTopUp => OperationTypeInSerializationFormat::IdentityTopUp, OperationType::IdentityUpdate(identity_update_op) => { OperationTypeInSerializationFormat::IdentityUpdate(identity_update_op) } @@ -396,12 +392,13 @@ impl PlatformSerializableWithPlatformVersion for OperationType { } OperationType::ContractUpdate(update_op) => { // let's just serialize it to make things easier - let contract_op_in_serialization_format = update_op.serialize_consume_to_bytes_with_platform_version(platform_version)?; - OperationTypeInSerializationFormat::ContractUpdate(contract_op_in_serialization_format) - } - OperationType::IdentityTransfer => { - OperationTypeInSerializationFormat::IdentityTransfer + let contract_op_in_serialization_format = + update_op.serialize_consume_to_bytes_with_platform_version(platform_version)?; + OperationTypeInSerializationFormat::ContractUpdate( + contract_op_in_serialization_format, + ) } + OperationType::IdentityTransfer => OperationTypeInSerializationFormat::IdentityTransfer, }; let config = bincode::config::standard() .with_big_endian() @@ -432,12 +429,14 @@ impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for Ope .0; Ok(match operation_type { OperationTypeInSerializationFormat::Document(serialized_op) => { - let document_op = DocumentOp::versioned_deserialize(serialized_op.as_slice(), validate, platform_version)?; + let document_op = DocumentOp::versioned_deserialize( + serialized_op.as_slice(), + validate, + platform_version, + )?; OperationType::Document(document_op) } - OperationTypeInSerializationFormat::IdentityTopUp => { - OperationType::IdentityTopUp - } + OperationTypeInSerializationFormat::IdentityTopUp => OperationType::IdentityTopUp, OperationTypeInSerializationFormat::IdentityUpdate(identity_update_op) => { OperationType::IdentityUpdate(identity_update_op) } @@ -448,12 +447,14 @@ impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for Ope OperationType::ContractCreate(p, c) } OperationTypeInSerializationFormat::ContractUpdate(serialized_op) => { - let update_op = DataContractUpdateOp::versioned_deserialize(serialized_op.as_slice(), validate, platform_version)?; + let update_op = DataContractUpdateOp::versioned_deserialize( + serialized_op.as_slice(), + validate, + platform_version, + )?; OperationType::ContractUpdate(update_op) } - OperationTypeInSerializationFormat::IdentityTransfer => { - OperationType::IdentityTransfer - } + OperationTypeInSerializationFormat::IdentityTransfer => OperationType::IdentityTransfer, }) } } diff --git a/packages/wasm-dpp/src/errors/consensus/state/identity/invalid_identity_contract_nonce_error.rs b/packages/wasm-dpp/src/errors/consensus/state/identity/invalid_identity_contract_nonce_error.rs index 0a28526e2c4..ef4f2e9266f 100644 --- a/packages/wasm-dpp/src/errors/consensus/state/identity/invalid_identity_contract_nonce_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/state/identity/invalid_identity_contract_nonce_error.rs @@ -26,8 +26,7 @@ impl InvalidIdentityNonceErrorWasm { #[wasm_bindgen(js_name=getCurrentIdentityContractNonce)] pub fn current_identity_contract_nonce(&self) -> Option { - self.inner - .current_identity_contract_nonce().copied() + self.inner.current_identity_contract_nonce().copied() } #[wasm_bindgen(js_name=getSettingIdentityContractNonce)]