diff --git a/packages/dpns-contract/src/v1/mod.rs b/packages/dpns-contract/src/v1/mod.rs index fb2117245e0..4c4ea7aa402 100644 --- a/packages/dpns-contract/src/v1/mod.rs +++ b/packages/dpns-contract/src/v1/mod.rs @@ -13,6 +13,7 @@ pub mod document_types { pub const PREORDER_SALT: &str = "preorderSalt"; pub const ALLOW_SUBDOMAINS: &str = "subdomainRules.allowSubdomains"; pub const RECORDS: &str = "records"; + pub const IDENTITY: &str = "identity"; pub const DASH_UNIQUE_IDENTITY_ID: &str = "dashUniqueIdentityId"; pub const DASH_ALIAS_IDENTITY_ID: &str = "dashAliasIdentityId"; } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/mod.rs index 52c0d8c55b4..e3e6a001427 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/mod.rs @@ -3,6 +3,7 @@ use dpp::version::PlatformVersion; use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; mod v0; +mod v1; pub fn data_trigger_bindings_list( platform_version: &PlatformVersion, @@ -19,9 +20,13 @@ pub fn data_trigger_bindings_list( .into_iter() .map(|binding| binding.into()) .collect()), + 1 => Ok(v1::data_trigger_bindings_list_v1()? + .into_iter() + .map(|binding| binding.into()) + .collect()), version => Err(ProtocolError::UnknownVersionMismatch { method: "data_trigger_bindings".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v1/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v1/mod.rs new file mode 100644 index 00000000000..7be7f2e20fb --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v1/mod.rs @@ -0,0 +1,101 @@ +use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBindingV0; +use crate::execution::validation::state_transition::batch::data_triggers::triggers::dashpay::create_contact_request_data_trigger; +use crate::execution::validation::state_transition::batch::data_triggers::triggers::dpns::create_domain_data_trigger; +use crate::execution::validation::state_transition::batch::data_triggers::triggers::reject::reject_data_trigger; +use crate::execution::validation::state_transition::batch::data_triggers::triggers::withdrawals::delete_withdrawal_data_trigger; + +use dpp::errors::ProtocolError; +use dpp::system_data_contracts::withdrawals_contract::v1::document_types::withdrawal; +use dpp::system_data_contracts::{dashpay_contract, dpns_contract, SystemDataContract}; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionActionType; + +/// Retrieves a list of data triggers binding with matching params. +/// +/// This function gets all known data triggers which are then returned +/// as a vector of `DataTrigger` structs. +/// +/// v1 (PROTOCOL_VERSION_13): DPNS `domain` documents no longer reject +/// `Transfer`, `Purchase` and `UpdatePrice`, enabling username transfers +/// and sales. The DPNS contract has declared `transferable: 1` and +/// `tradeMode: 1` (direct purchase) since genesis, so the generic document +/// validation paths accept these transitions once the reject bindings are +/// gone. `Replace` and `Delete` stay rejected: name records remain +/// immutable and permanent. On transfer and purchase, drive rewrites the +/// domain's `records.identity` to the new owner so the name resolves to +/// the buyer (see the v1 document transfer/purchase high-level operation +/// conversions in rs-drive). +/// +/// # Returns +/// +/// A `Vec` containing all known data triggers. +/// +/// # Errors +/// +/// Returns a `ProtocolError` if there was an error. +#[inline(always)] +pub(super) fn data_trigger_bindings_list_v1() -> Result, ProtocolError> { + let data_triggers = vec![ + DataTriggerBindingV0 { + data_contract_id: dpns_contract::ID, + document_type: "domain".to_string(), + transition_action_type: DocumentTransitionActionType::Create, + data_trigger: create_domain_data_trigger, + }, + // Domain documents can never be modified or deleted, but since + // protocol version 13 they can be transferred and sold + DataTriggerBindingV0 { + data_contract_id: dpns_contract::ID, + document_type: "domain".to_string(), + transition_action_type: DocumentTransitionActionType::Replace, + data_trigger: reject_data_trigger, + }, + DataTriggerBindingV0 { + data_contract_id: dpns_contract::ID, + document_type: "domain".to_string(), + transition_action_type: DocumentTransitionActionType::Delete, + data_trigger: reject_data_trigger, + }, + DataTriggerBindingV0 { + data_contract_id: dashpay_contract::ID, + document_type: "contactRequest".to_string(), + transition_action_type: DocumentTransitionActionType::Create, + data_trigger: create_contact_request_data_trigger, + }, + // Only masternodes will be able to update it + DataTriggerBindingV0 { + data_contract_id: SystemDataContract::MasternodeRewards.id(), + document_type: "rewardShare".to_string(), + transition_action_type: DocumentTransitionActionType::Create, + data_trigger: reject_data_trigger, + }, + // Only masternodes will be able to update it + DataTriggerBindingV0 { + data_contract_id: SystemDataContract::MasternodeRewards.id(), + document_type: "rewardShare".to_string(), + transition_action_type: DocumentTransitionActionType::Replace, + data_trigger: reject_data_trigger, + }, + // Only masternodes will be able to update it + DataTriggerBindingV0 { + data_contract_id: SystemDataContract::MasternodeRewards.id(), + document_type: "rewardShare".to_string(), + transition_action_type: DocumentTransitionActionType::Delete, + data_trigger: reject_data_trigger, + }, + // We can't use mutability flag otherwise documents won't have revision + DataTriggerBindingV0 { + data_contract_id: SystemDataContract::Withdrawals.id(), + document_type: withdrawal::NAME.to_string(), + transition_action_type: DocumentTransitionActionType::Replace, + data_trigger: reject_data_trigger, + }, + DataTriggerBindingV0 { + data_contract_id: SystemDataContract::Withdrawals.id(), + document_type: withdrawal::NAME.to_string(), + transition_action_type: DocumentTransitionActionType::Delete, + data_trigger: delete_withdrawal_data_trigger, + }, + ]; + + Ok(data_triggers) +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs index 51afcb0fd7d..c8c7906c58c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/document/dpns.rs @@ -956,3 +956,841 @@ mod dpns_tests { assert_eq!(documents.len(), 2); } } + +mod dpns_username_transfer_tests { + use super::*; + use dpp::consensus::basic::BasicError; + use dpp::consensus::state::data_trigger::DataTriggerError; + use dpp::data_contract::DataContract; + use dpp::document::Document; + use dpp::identity::{Identity, IdentityPublicKey}; + use dpp::util::hash::hash_double; + use dpp::util::strings::convert_to_homograph_safe_chars; + use drive::query::{InternalClauses, WhereClause, WhereOperator}; + use simple_signer::signer::SimpleSigner; + use std::collections::BTreeMap; + use std::sync::Arc; + + use crate::rpc::core::MockCoreRPCLike; + use crate::test::helpers::setup::TempPlatform; + use dpp::prelude::Identifier; + use dpp::version::ProtocolVersion; + + /// Registers `