From 5e9c441a8c2055694f19e2c3f5ccc65e9f2c5a39 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 May 2024 14:14:12 +0700 Subject: [PATCH 01/61] worked on token support --- .../src/data_contract/associated_token/mod.rs | 1 + .../token_configuration/methods/mod.rs | 1 + .../mod.rs | 30 ++++ .../v0/mod.rs | 139 ++++++++++++++++++ .../token_configuration/mod.rs | 13 ++ .../token_configuration/v0/mod.rs | 25 ++++ .../methods/validate_config_update/mod.rs | 2 +- .../methods/validate_update/mod.rs | 2 +- packages/rs-dpp/src/data_contract/mod.rs | 3 +- packages/rs-dpp/src/lib.rs | 1 + packages/rs-dpp/src/tokens/mod.rs | 1 + 11 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 packages/rs-dpp/src/data_contract/associated_token/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs create mode 100644 packages/rs-dpp/src/tokens/mod.rs diff --git a/packages/rs-dpp/src/data_contract/associated_token/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/mod.rs new file mode 100644 index 00000000000..f09c33dc596 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/mod.rs @@ -0,0 +1 @@ +mod token_configuration; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/mod.rs new file mode 100644 index 00000000000..5e5a7181a50 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/mod.rs @@ -0,0 +1 @@ +mod validate_token_configuration_update; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs new file mode 100644 index 00000000000..13ec39714c5 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs @@ -0,0 +1,30 @@ +use crate::data_contract::config::DataContractConfig; +use crate::validation::SimpleConsensusValidationResult; +use crate::ProtocolError; +use platform_value::Identifier; +use platform_version::version::PlatformVersion; + +mod v0; + +impl DataContractConfig { + pub fn validate_config_update( + &self, + new_config: &DataContractConfig, + contract_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .dpp + .validation + .data_contract + .validate_config_update + { + 0 => Ok(self.validate_config_update_v0(new_config, contract_id)), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "validate_token_configuration_update".to_string(), + known_versions: vec![0], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs new file mode 100644 index 00000000000..90cc1ef73cd --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -0,0 +1,139 @@ +use crate::consensus::state::data_contract::data_contract_config_update_error::DataContractConfigUpdateError; +use crate::consensus::state::data_contract::data_contract_is_readonly_error::DataContractIsReadonlyError; +use crate::data_contract::config::v0::DataContractConfigGettersV0; +use crate::data_contract::config::DataContractConfig; +use crate::validation::SimpleConsensusValidationResult; +use platform_value::Identifier; + +impl DataContractConfig { + #[inline(always)] + pub(super) fn validate_config_update_v0( + &self, + new_config: &DataContractConfig, + contract_id: Identifier, + ) -> SimpleConsensusValidationResult { + // Validate: Old contract is not read_only + + if self.readonly() { + return SimpleConsensusValidationResult::new_with_error( + DataContractIsReadonlyError::new(contract_id).into(), + ); + } + + // Validate: New contract is not read_only + + if new_config.readonly() { + return SimpleConsensusValidationResult::new_with_error( + DataContractConfigUpdateError::new( + contract_id, + "contract can not be changed to readonly", + ) + .into(), + ); + } + + // Validate: Keeps history did not change + + if new_config.keeps_history() != self.keeps_history() { + return SimpleConsensusValidationResult::new_with_error( + DataContractConfigUpdateError::new( + contract_id, + format!( + "contract can not change whether it keeps history: changing from {} to {}", + self.keeps_history(), + new_config.keeps_history() + ), + ) + .into(), + ); + } + + // Validate: Can be deleted did not change + + if new_config.can_be_deleted() != self.can_be_deleted() { + return SimpleConsensusValidationResult::new_with_error( + DataContractConfigUpdateError::new( + contract_id, + format!( + "contract can not change whether it can be delete: changing from {} to {}", + self.can_be_deleted(), + new_config.can_be_deleted() + ), + ) + .into(), + ); + } + + // Validate: Documents keep history did not change + + if new_config.documents_keep_history_contract_default() + != self.documents_keep_history_contract_default() + { + return SimpleConsensusValidationResult::new_with_error( + DataContractConfigUpdateError::new( + contract_id, + "contract can not change the default of whether documents keeps history", + ) + .into(), + ); + } + + // Validate: Documents mutable contract default did not change + + if new_config.documents_mutable_contract_default() + != self.documents_mutable_contract_default() + { + return SimpleConsensusValidationResult::new_with_error( + DataContractConfigUpdateError::new( + contract_id, + "contract can not change the default of whether documents are mutable", + ) + .into(), + ); + } + + // Validate: Documents can be deleted contract default did not change + + if new_config.documents_can_be_deleted_contract_default() + != self.documents_can_be_deleted_contract_default() + { + return SimpleConsensusValidationResult::new_with_error( + DataContractConfigUpdateError::new( + contract_id, + "contract can not change the default of whether documents can be deleted", + ) + .into(), + ); + } + + // Validate: Requires identity encryption bounded key did not change + + if new_config.requires_identity_encryption_bounded_key() + != self.requires_identity_encryption_bounded_key() + { + return SimpleConsensusValidationResult::new_with_error( + DataContractConfigUpdateError::new( + contract_id, + "contract can not change the requirement of needing a document encryption bounded key", + ) + .into(), + ); + } + + // Validate: Requires identity decryption bounded key did not change + + if new_config.requires_identity_decryption_bounded_key() + != self.requires_identity_decryption_bounded_key() + { + return SimpleConsensusValidationResult::new_with_error( + DataContractConfigUpdateError::new( + contract_id, + "contract can not change the requirement of needing a document decryption bounded key", + ) + .into(), + ); + } + + SimpleConsensusValidationResult::new() + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs new file mode 100644 index 00000000000..44a9f0a652d --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs @@ -0,0 +1,13 @@ +use derive_more::From; +use serde::{Deserialize, Serialize}; +use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; +use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; + +mod v0; + +#[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, From)] +#[serde(tag = "$format_version")] +pub enum TokenConfiguration { + #[serde(rename = "0")] + V0(TokenConfigurationV0) +} \ No newline at end of file diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs new file mode 100644 index 00000000000..2dd7be9ba18 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -0,0 +1,25 @@ +use serde::{Deserialize, Serialize}; +use platform_value::Identifier; +use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; + +pub type RequiredSigners = u8; +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +pub enum AuthorizedActionTakers { + None, + ContractOwner, + MainGroup, + SpecifiedIdentities(Vec, RequiredSigners) +} + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct TokenConfigurationV0 { + pub max_supply: u64, + pub max_supply_can_be_increased: AuthorizedActionTakers, + pub main_control_group: Option<(Vec, RequiredSigners)>, + pub main_control_group_can_be_modified: AuthorizedActionTakers, + pub balance_can_be_increased: AuthorizedActionTakers, + pub balance_can_be_destroyed: AuthorizedActionTakers, + pub authorized_action_takers_level_can_be_changed: AuthorizedActionTakers, + pub authorized_action_takers_ +} \ No newline at end of file diff --git a/packages/rs-dpp/src/data_contract/config/methods/validate_config_update/mod.rs b/packages/rs-dpp/src/data_contract/config/methods/validate_config_update/mod.rs index be4557d7248..13ec39714c5 100644 --- a/packages/rs-dpp/src/data_contract/config/methods/validate_config_update/mod.rs +++ b/packages/rs-dpp/src/data_contract/config/methods/validate_config_update/mod.rs @@ -21,7 +21,7 @@ impl DataContractConfig { { 0 => Ok(self.validate_config_update_v0(new_config, contract_id)), version => Err(ProtocolError::UnknownVersionMismatch { - method: "validate_config_update".to_string(), + method: "validate_token_configuration_update".to_string(), known_versions: vec![0], received: version, }), diff --git a/packages/rs-dpp/src/data_contract/document_type/methods/validate_update/mod.rs b/packages/rs-dpp/src/data_contract/document_type/methods/validate_update/mod.rs index 2cc81554c1a..c275a00c20c 100644 --- a/packages/rs-dpp/src/data_contract/document_type/methods/validate_update/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/methods/validate_update/mod.rs @@ -19,7 +19,7 @@ impl<'a> DocumentTypeRef<'a> { { 0 => Ok(self.validate_update_v0(new_document_type)), version => Err(ProtocolError::UnknownVersionMismatch { - method: "validate_config_update".to_string(), + method: "validate_token_configuration_update".to_string(), known_versions: vec![0], received: version, }), diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index beffa0b2893..ff20f00360d 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -34,11 +34,12 @@ pub use methods::*; pub mod accessors; pub mod config; pub mod storage_requirements; +mod associated_token; pub use v0::*; use crate::data_contract::serialized_version::{ - DataContractInSerializationFormat, CONTRACT_DESERIALIZATION_LIMIT, + CONTRACT_DESERIALIZATION_LIMIT, DataContractInSerializationFormat, }; use crate::util::hash::hash_double_to_vec; diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index c9eb000abb4..9801c2cda13 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -49,6 +49,7 @@ pub mod signing; #[cfg(feature = "system_contracts")] pub mod system_data_contracts; pub mod withdrawal; +mod tokens; pub use async_trait; diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -0,0 +1 @@ + From 13f867421e337d38e338f9573b1d6f430dc1d999 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 May 2024 16:03:21 +0700 Subject: [PATCH 02/61] more work --- .../mod.rs | 14 ++-- .../v0/mod.rs | 13 ++-- .../token_configuration/mod.rs | 1 + .../token_configuration/v0/mod.rs | 68 ++++++++++++++++--- packages/rs-dpp/src/lib.rs | 1 + .../rs-dpp/src/multi_identity_events/mod.rs | 7 ++ .../src/version/dpp_versions.rs | 1 + 7 files changed, 86 insertions(+), 19 deletions(-) create mode 100644 packages/rs-dpp/src/multi_identity_events/mod.rs diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs index 13ec39714c5..54b7e3873fd 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs @@ -1,16 +1,18 @@ -use crate::data_contract::config::DataContractConfig; use crate::validation::SimpleConsensusValidationResult; use crate::ProtocolError; use platform_value::Identifier; use platform_version::version::PlatformVersion; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::multi_identity_events::ActionTaker; mod v0; -impl DataContractConfig { - pub fn validate_config_update( +impl TokenConfiguration { + pub fn validate_token_config_update( &self, - new_config: &DataContractConfig, + new_config: &TokenConfiguration, contract_id: Identifier, + action_taker: ActionTaker, platform_version: &PlatformVersion, ) -> Result { match platform_version @@ -19,9 +21,9 @@ impl DataContractConfig { .data_contract .validate_config_update { - 0 => Ok(self.validate_config_update_v0(new_config, contract_id)), + 0 => Ok(self.validate_token_config_update_v0(new_config, contract_id, action_taker)), version => Err(ProtocolError::UnknownVersionMismatch { - method: "validate_token_configuration_update".to_string(), + method: "validate_token_config_update".to_string(), known_versions: vec![0], received: version, }), diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index 90cc1ef73cd..30198a70084 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -1,17 +1,22 @@ use crate::consensus::state::data_contract::data_contract_config_update_error::DataContractConfigUpdateError; use crate::consensus::state::data_contract::data_contract_is_readonly_error::DataContractIsReadonlyError; use crate::data_contract::config::v0::DataContractConfigGettersV0; -use crate::data_contract::config::DataContractConfig; use crate::validation::SimpleConsensusValidationResult; use platform_value::Identifier; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::multi_identity_events::ActionTaker; -impl DataContractConfig { +impl TokenConfiguration { #[inline(always)] - pub(super) fn validate_config_update_v0( + pub(super) fn validate_token_config_update_v0( &self, - new_config: &DataContractConfig, + new_config: &TokenConfiguration, contract_id: Identifier, + action_taker: ActionTaker, ) -> SimpleConsensusValidationResult { + + + // Validate: Old contract is not read_only if self.readonly() { diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs index 44a9f0a652d..d28c7029410 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs @@ -4,6 +4,7 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfig use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; mod v0; +mod methods; #[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, From)] #[serde(tag = "$format_version")] diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 2dd7be9ba18..f72ff4c1ee1 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -1,25 +1,75 @@ +use std::collections::BTreeSet; use serde::{Deserialize, Serialize}; use platform_value::Identifier; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use crate::multi_identity_events::ActionTaker; pub type RequiredSigners = u8; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] pub enum AuthorizedActionTakers { - None, + NoOne, ContractOwner, MainGroup, - SpecifiedIdentities(Vec, RequiredSigners) + SpecifiedIdentities(BTreeSet, RequiredSigners) +} + +impl AuthorizedActionTakers { + pub fn matches_action_taker(&self, contract_owner_id: &Identifier, main_group: &(BTreeSet, RequiredSigners), action_taker: &ActionTaker) -> bool { + match self { + AuthorizedActionTakers::NoOne => false, + AuthorizedActionTakers::ContractOwner => { + match action_taker { + ActionTaker::SingleIdentity(action_taker) => action_taker == contract_owner_id, + ActionTaker::SpecifiedIdentities(action_takers) => action_takers.contains(contract_owner_id), + } + } + AuthorizedActionTakers::MainGroup => { + match action_taker { + ActionTaker::SingleIdentity(_) => false, + ActionTaker::SpecifiedIdentities(action_takers) => { + let authorized_action_takers_count = main_group.0.intersection(action_takers).count(); + if authorized_action_takers_count > 255 { + return false; + } + authorized_action_takers_count as u8 >= main_group.1 + }, + } + } + AuthorizedActionTakers::SpecifiedIdentities(specified_authorized_identities, required_signers_count) => { + match action_taker { + ActionTaker::SingleIdentity(_) => false, + ActionTaker::SpecifiedIdentities(action_takers) => { + let authorized_action_takers_count = specified_authorized_identities.intersection(action_takers).count(); + if authorized_action_takers_count > 255 { + return false; + } + authorized_action_takers_count as u8 >= *required_signers_count + }, + } + } + } + } +} + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +pub struct ChangeControlRules { + /// This is who is authorized to make such a change + authorized_to_make_change: AuthorizedActionTakers, + /// This is who is authorized to make such a change to the people authorized to make a change + authorized_to_change_to_authorized_action_takers: AuthorizedActionTakers, + /// Are we allowed to change to None in the future + changing_authorized_action_takers_to_no_one_allowed: bool, + /// Are we allowed to change to None in the future + changing_authorized_action_takers_to_contract_owner_allowed: bool, } #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct TokenConfigurationV0 { pub max_supply: u64, - pub max_supply_can_be_increased: AuthorizedActionTakers, - pub main_control_group: Option<(Vec, RequiredSigners)>, - pub main_control_group_can_be_modified: AuthorizedActionTakers, - pub balance_can_be_increased: AuthorizedActionTakers, - pub balance_can_be_destroyed: AuthorizedActionTakers, - pub authorized_action_takers_level_can_be_changed: AuthorizedActionTakers, - pub authorized_action_takers_ + pub max_supply_can_be_increased: ChangeControlRules, + pub main_control_group: Option<(BTreeSet, RequiredSigners)>, + pub main_control_group_can_be_modified: ChangeControlRules, + pub balance_can_be_increased: ChangeControlRules, + pub balance_can_be_destroyed: ChangeControlRules, } \ No newline at end of file diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 9801c2cda13..8891ff4b5a9 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -50,6 +50,7 @@ pub mod signing; pub mod system_data_contracts; pub mod withdrawal; mod tokens; +pub mod multi_identity_events; pub use async_trait; diff --git a/packages/rs-dpp/src/multi_identity_events/mod.rs b/packages/rs-dpp/src/multi_identity_events/mod.rs new file mode 100644 index 00000000000..d67e2687b1c --- /dev/null +++ b/packages/rs-dpp/src/multi_identity_events/mod.rs @@ -0,0 +1,7 @@ +use std::collections::BTreeSet; +use platform_value::Identifier; + +pub enum ActionTaker { + SingleIdentity(Identifier), + SpecifiedIdentities(BTreeSet) +} \ No newline at end of file diff --git a/packages/rs-platform-version/src/version/dpp_versions.rs b/packages/rs-platform-version/src/version/dpp_versions.rs index e2e5778566c..0451987c821 100644 --- a/packages/rs-platform-version/src/version/dpp_versions.rs +++ b/packages/rs-platform-version/src/version/dpp_versions.rs @@ -69,6 +69,7 @@ pub struct DPPValidationVersions { pub struct DataContractValidationVersions { pub validate: FeatureVersion, pub validate_config_update: FeatureVersion, + pub validate_token_config_update: FeatureVersion, pub validate_index_definitions: FeatureVersion, pub validate_index_naming_duplicates: FeatureVersion, pub validate_not_defined_properties: FeatureVersion, From b9ed06370080d9c29b85c2ba7254638961c4846a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 May 2024 18:37:15 +0700 Subject: [PATCH 03/61] more work --- .../mod.rs | 4 +- .../v0/mod.rs | 148 +++--------------- .../token_configuration/mod.rs | 19 ++- .../token_configuration/v0/mod.rs | 87 ++++++---- packages/rs-dpp/src/data_contract/mod.rs | 4 +- packages/rs-dpp/src/lib.rs | 4 +- .../rs-dpp/src/multi_identity_events/mod.rs | 6 +- 7 files changed, 100 insertions(+), 172 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs index 54b7e3873fd..ced7222718b 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs @@ -1,9 +1,9 @@ +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::multi_identity_events::ActionTaker; use crate::validation::SimpleConsensusValidationResult; use crate::ProtocolError; use platform_value::Identifier; use platform_version::version::PlatformVersion; -use crate::data_contract::associated_token::token_configuration::TokenConfiguration; -use crate::multi_identity_events::ActionTaker; mod v0; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index 30198a70084..67456e2f4b6 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -1,10 +1,11 @@ use crate::consensus::state::data_contract::data_contract_config_update_error::DataContractConfigUpdateError; use crate::consensus::state::data_contract::data_contract_is_readonly_error::DataContractIsReadonlyError; +use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::config::v0::DataContractConfigGettersV0; +use crate::multi_identity_events::ActionTaker; use crate::validation::SimpleConsensusValidationResult; use platform_value::Identifier; -use crate::data_contract::associated_token::token_configuration::TokenConfiguration; -use crate::multi_identity_events::ActionTaker; impl TokenConfiguration { #[inline(always)] @@ -14,129 +15,26 @@ impl TokenConfiguration { contract_id: Identifier, action_taker: ActionTaker, ) -> SimpleConsensusValidationResult { - - - - // Validate: Old contract is not read_only - - if self.readonly() { - return SimpleConsensusValidationResult::new_with_error( - DataContractIsReadonlyError::new(contract_id).into(), - ); - } - - // Validate: New contract is not read_only - - if new_config.readonly() { - return SimpleConsensusValidationResult::new_with_error( - DataContractConfigUpdateError::new( - contract_id, - "contract can not be changed to readonly", - ) - .into(), - ); - } - - // Validate: Keeps history did not change - - if new_config.keeps_history() != self.keeps_history() { - return SimpleConsensusValidationResult::new_with_error( - DataContractConfigUpdateError::new( - contract_id, - format!( - "contract can not change whether it keeps history: changing from {} to {}", - self.keeps_history(), - new_config.keeps_history() - ), - ) - .into(), - ); - } - - // Validate: Can be deleted did not change - - if new_config.can_be_deleted() != self.can_be_deleted() { - return SimpleConsensusValidationResult::new_with_error( - DataContractConfigUpdateError::new( - contract_id, - format!( - "contract can not change whether it can be delete: changing from {} to {}", - self.can_be_deleted(), - new_config.can_be_deleted() - ), - ) - .into(), - ); - } - - // Validate: Documents keep history did not change - - if new_config.documents_keep_history_contract_default() - != self.documents_keep_history_contract_default() - { - return SimpleConsensusValidationResult::new_with_error( - DataContractConfigUpdateError::new( - contract_id, - "contract can not change the default of whether documents keeps history", - ) - .into(), - ); - } - - // Validate: Documents mutable contract default did not change - - if new_config.documents_mutable_contract_default() - != self.documents_mutable_contract_default() - { - return SimpleConsensusValidationResult::new_with_error( - DataContractConfigUpdateError::new( - contract_id, - "contract can not change the default of whether documents are mutable", - ) - .into(), - ); - } - - // Validate: Documents can be deleted contract default did not change - - if new_config.documents_can_be_deleted_contract_default() - != self.documents_can_be_deleted_contract_default() - { - return SimpleConsensusValidationResult::new_with_error( - DataContractConfigUpdateError::new( - contract_id, - "contract can not change the default of whether documents can be deleted", - ) - .into(), - ); - } - - // Validate: Requires identity encryption bounded key did not change - - if new_config.requires_identity_encryption_bounded_key() - != self.requires_identity_encryption_bounded_key() - { - return SimpleConsensusValidationResult::new_with_error( - DataContractConfigUpdateError::new( - contract_id, - "contract can not change the requirement of needing a document encryption bounded key", - ) - .into(), - ); - } - - // Validate: Requires identity decryption bounded key did not change - - if new_config.requires_identity_decryption_bounded_key() - != self.requires_identity_decryption_bounded_key() - { - return SimpleConsensusValidationResult::new_with_error( - DataContractConfigUpdateError::new( - contract_id, - "contract can not change the requirement of needing a document decryption bounded key", - ) - .into(), - ); + let TokenConfigurationV0 { + max_supply, + max_supply_can_be_increased, + main_control_group, + main_control_group_can_be_modified, + balance_can_be_increased, + balance_can_be_destroyed, + } = self.as_cow_v0(); + + let TokenConfigurationV0 { + max_supply: new_max_supply, + max_supply_can_be_increased: new_max_supply_can_be_increased, + main_control_group: new_main_control_group, + main_control_group_can_be_modified: new_main_control_group_can_be_modified, + balance_can_be_increased: new_balance_can_be_increased, + balance_can_be_destroyed: new_balance_can_be_destroyed, + } = new_config.as_cow_v0(); + + if max_supply != new_max_supply { + max_supply_can_be_increased. } SimpleConsensusValidationResult::new() diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs index d28c7029410..56f29402364 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs @@ -1,14 +1,23 @@ -use derive_more::From; -use serde::{Deserialize, Serialize}; use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use derive_more::From; +use serde::{Deserialize, Serialize}; +use std::borrow::Cow; -mod v0; mod methods; +mod v0; #[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, From)] #[serde(tag = "$format_version")] pub enum TokenConfiguration { #[serde(rename = "0")] - V0(TokenConfigurationV0) -} \ No newline at end of file + V0(TokenConfigurationV0), +} + +impl TokenConfiguration { + pub fn as_cow_v0(&self) -> Cow { + match self { + TokenConfiguration::V0(v0) => Cow::Borrowed(v0), + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index f72ff4c1ee1..967e445ef74 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -1,8 +1,8 @@ -use std::collections::BTreeSet; -use serde::{Deserialize, Serialize}; -use platform_value::Identifier; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::multi_identity_events::ActionTaker; +use platform_value::Identifier; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeSet; pub type RequiredSigners = u8; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] @@ -10,43 +10,50 @@ pub enum AuthorizedActionTakers { NoOne, ContractOwner, MainGroup, - SpecifiedIdentities(BTreeSet, RequiredSigners) + SpecifiedIdentities(BTreeSet, RequiredSigners), } impl AuthorizedActionTakers { - pub fn matches_action_taker(&self, contract_owner_id: &Identifier, main_group: &(BTreeSet, RequiredSigners), action_taker: &ActionTaker) -> bool { + pub fn allowed_for_action_taker( + &self, + contract_owner_id: &Identifier, + main_group: &(BTreeSet, RequiredSigners), + action_taker: &ActionTaker, + ) -> bool { match self { AuthorizedActionTakers::NoOne => false, - AuthorizedActionTakers::ContractOwner => { - match action_taker { - ActionTaker::SingleIdentity(action_taker) => action_taker == contract_owner_id, - ActionTaker::SpecifiedIdentities(action_takers) => action_takers.contains(contract_owner_id), + AuthorizedActionTakers::ContractOwner => match action_taker { + ActionTaker::SingleIdentity(action_taker) => action_taker == contract_owner_id, + ActionTaker::SpecifiedIdentities(action_takers) => { + action_takers.contains(contract_owner_id) } - } - AuthorizedActionTakers::MainGroup => { - match action_taker { - ActionTaker::SingleIdentity(_) => false, - ActionTaker::SpecifiedIdentities(action_takers) => { - let authorized_action_takers_count = main_group.0.intersection(action_takers).count(); - if authorized_action_takers_count > 255 { - return false; - } - authorized_action_takers_count as u8 >= main_group.1 - }, + }, + AuthorizedActionTakers::MainGroup => match action_taker { + ActionTaker::SingleIdentity(_) => false, + ActionTaker::SpecifiedIdentities(action_takers) => { + let authorized_action_takers_count = + main_group.0.intersection(action_takers).count(); + if authorized_action_takers_count > 255 { + return false; + } + authorized_action_takers_count as u8 >= main_group.1 } - } - AuthorizedActionTakers::SpecifiedIdentities(specified_authorized_identities, required_signers_count) => { - match action_taker { - ActionTaker::SingleIdentity(_) => false, - ActionTaker::SpecifiedIdentities(action_takers) => { - let authorized_action_takers_count = specified_authorized_identities.intersection(action_takers).count(); - if authorized_action_takers_count > 255 { - return false; - } - authorized_action_takers_count as u8 >= *required_signers_count - }, + }, + AuthorizedActionTakers::SpecifiedIdentities( + specified_authorized_identities, + required_signers_count, + ) => match action_taker { + ActionTaker::SingleIdentity(_) => false, + ActionTaker::SpecifiedIdentities(action_takers) => { + let authorized_action_takers_count = specified_authorized_identities + .intersection(action_takers) + .count(); + if authorized_action_takers_count > 255 { + return false; + } + authorized_action_takers_count as u8 >= *required_signers_count } - } + }, } } } @@ -63,6 +70,20 @@ pub struct ChangeControlRules { changing_authorized_action_takers_to_contract_owner_allowed: bool, } +impl ChangeControlRules { + pub fn can_change_to(&self, other: &ChangeControlRules, contract_owner_id: &Identifier, + main_group: &(BTreeSet, RequiredSigners), action_taker: &ActionTaker) { + let ChangeControlRules { + authorized_to_make_change, + authorized_to_change_to_authorized_action_takers, + changing_authorized_action_takers_to_no_one_allowed, + changing_authorized_action_takers_to_contract_owner_allowed + } = self; + + + } +} + #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct TokenConfigurationV0 { @@ -72,4 +93,4 @@ pub struct TokenConfigurationV0 { pub main_control_group_can_be_modified: ChangeControlRules, pub balance_can_be_increased: ChangeControlRules, pub balance_can_be_destroyed: ChangeControlRules, -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index ff20f00360d..58599406264 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -32,14 +32,14 @@ mod methods; pub mod serialized_version; pub use methods::*; pub mod accessors; +mod associated_token; pub mod config; pub mod storage_requirements; -mod associated_token; pub use v0::*; use crate::data_contract::serialized_version::{ - CONTRACT_DESERIALIZATION_LIMIT, DataContractInSerializationFormat, + DataContractInSerializationFormat, CONTRACT_DESERIALIZATION_LIMIT, }; use crate::util::hash::hash_double_to_vec; diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 8891ff4b5a9..d4b75b73a98 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -39,6 +39,7 @@ pub mod asset_lock; pub mod balances; pub mod block; pub mod fee; +pub mod multi_identity_events; pub mod nft; pub mod serialization; #[cfg(any( @@ -48,9 +49,8 @@ pub mod serialization; pub mod signing; #[cfg(feature = "system_contracts")] pub mod system_data_contracts; -pub mod withdrawal; mod tokens; -pub mod multi_identity_events; +pub mod withdrawal; pub use async_trait; diff --git a/packages/rs-dpp/src/multi_identity_events/mod.rs b/packages/rs-dpp/src/multi_identity_events/mod.rs index d67e2687b1c..6c6558cf9fd 100644 --- a/packages/rs-dpp/src/multi_identity_events/mod.rs +++ b/packages/rs-dpp/src/multi_identity_events/mod.rs @@ -1,7 +1,7 @@ -use std::collections::BTreeSet; use platform_value::Identifier; +use std::collections::BTreeSet; pub enum ActionTaker { SingleIdentity(Identifier), - SpecifiedIdentities(BTreeSet) -} \ No newline at end of file + SpecifiedIdentities(BTreeSet), +} From 6be79067e42ed69b0d2a50973e24afad48f8d26f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 15 Nov 2024 12:15:24 +0100 Subject: [PATCH 04/61] temp work --- .../src/data_contract/document_type/v0/mod.rs | 3 + packages/rs-dpp/src/lib.rs | 1 + packages/rs-dpp/src/nft/mod.rs | 4 +- .../document_transition/mod.rs | 3 + .../token_base_transition/fields.rs | 9 ++ .../token_base_transition/from_document.rs | 37 +++++ .../token_base_transition/mod.rs | 107 +++++++++++++ .../token_base_transition/v0/from_document.rs | 20 +++ .../token_base_transition/v0/mod.rs | 130 ++++++++++++++++ .../token_base_transition/v0/v0_methods.rs | 66 ++++++++ .../token_base_transition/v0_methods.rs | 62 ++++++++ .../token_issuance_transition/convertible.rs | 145 ++++++++++++++++++ .../from_document.rs | 43 ++++++ .../token_issuance_transition/mod.rs | 126 +++++++++++++++ .../token_issuance_transition/v0/mod.rs | 60 ++++++++ .../v0/v0_methods.rs | 98 ++++++++++++ .../token_issuance_transition/v0_methods.rs | 80 ++++++++++ .../from_document.rs | 43 ++++++ .../token_transfer_transition/mod.rs | 19 +++ .../v0/from_document.rs | 36 +++++ .../token_transfer_transition/v0/mod.rs | 46 ++++++ .../v0/v0_methods.rs | 66 ++++++++ .../token_transfer_transition/v0_methods.rs | 55 +++++++ .../documents_batch_transition/mod.rs | 4 +- .../rs-dpp/src/tokens/allowed_currency.rs | 7 + packages/rs-dpp/src/tokens/mod.rs | 2 +- .../crypto-card-game-in-game-currency.json | 135 ++++++++++++++++ 27 files changed, 1403 insertions(+), 4 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/from_document.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/from_document.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/from_document.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/from_document.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/from_document.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs create mode 100644 packages/rs-dpp/src/tokens/allowed_currency.rs create mode 100644 packages/rs-drive-abci/tests/supporting_files/contract/crypto-card-game/crypto-card-game-in-game-currency.json diff --git a/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs index 9951c2b638b..c09621233a6 100644 --- a/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs @@ -14,6 +14,7 @@ use crate::document::transfer::Transferable; use crate::identity::SecurityLevel; use crate::nft::TradeMode; use platform_value::{Identifier, Value}; +use crate::tokens::allowed_currency::AllowedCurrency; mod accessors; #[cfg(feature = "random-documents")] @@ -55,6 +56,8 @@ pub struct DocumentTypeV0 { pub(in crate::data_contract) documents_transferable: Transferable, /// How are these documents traded? pub(in crate::data_contract) trade_mode: TradeMode, + /// How are these documents traded? + pub(in crate::data_contract) allowed_trade_currencies: Vec, /// Is document creation restricted? pub(in crate::data_contract) creation_restriction_mode: CreationRestrictionMode, /// The data contract id diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 7ca3f9b8a34..861892702ac 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -61,6 +61,7 @@ pub mod voting; pub mod core_types; pub mod withdrawal; +mod token; pub use async_trait; diff --git a/packages/rs-dpp/src/nft/mod.rs b/packages/rs-dpp/src/nft/mod.rs index 884906fb1e8..a7628abbd2f 100644 --- a/packages/rs-dpp/src/nft/mod.rs +++ b/packages/rs-dpp/src/nft/mod.rs @@ -4,8 +4,8 @@ use crate::consensus::ConsensusError; use crate::ProtocolError; use std::fmt; use std::fmt::{Display, Formatter}; - -#[derive(Debug, PartialEq, Clone, Copy)] +use platform_value::Identifier; +#[derive(Debug, PartialEq, Clone)] pub enum TradeMode { None = 0, DirectPurchase = 1, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs index 448dffcfea4..465b4bbd204 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs @@ -16,6 +16,9 @@ pub mod document_purchase_transition; pub mod document_replace_transition; pub mod document_transfer_transition; pub mod document_update_price_transition; +pub mod token_issuance_transition; +pub mod token_transfer_transition; +pub mod token_base_transition; use crate::prelude::Revision; use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs new file mode 100644 index 00000000000..b7e0135ed04 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs @@ -0,0 +1,9 @@ +pub(in crate::state_transition::state_transitions::document::documents_batch_transition) mod property_names { + pub const ID: &str = "$id"; + pub const DATA_CONTRACT_ID: &str = "$dataContractId"; + pub const DOCUMENT_TYPE: &str = "$type"; + pub const ACTION: &str = "$action"; + pub const IDENTITY_CONTRACT_NONCE: &str = "$identityContractNonce"; +} + +pub const IDENTIFIER_FIELDS: [&str; 2] = [property_names::ID, property_names::DATA_CONTRACT_ID]; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/from_document.rs new file mode 100644 index 00000000000..a84baf514f0 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/from_document.rs @@ -0,0 +1,37 @@ +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::Document; +use crate::prelude::IdentityNonce; +use crate::state_transition::documents_batch_transition::document_base_transition::v0::TokenBaseTransitionV0; +use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; +use crate::ProtocolError; +use platform_version::version::{FeatureVersion, PlatformVersion}; + +impl TokenBaseTransition { + pub fn from_document( + document: &Document, + document_type: DocumentTypeRef, + identity_contract_nonce: IdentityNonce, + platform_version: &PlatformVersion, + feature_version: Option, + ) -> Result { + match feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .document_base_state_transition + .default_current_version, + ) { + 0 => Ok(TokenBaseTransitionV0::from_document( + document, + document_type, + identity_contract_nonce, + ) + .into()), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "TokenBaseTransition::from_document".to_string(), + known_versions: vec![0], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs new file mode 100644 index 00000000000..e7a502aea1f --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs @@ -0,0 +1,107 @@ +mod fields; +mod from_document; +pub mod v0; +mod v0_methods; + +#[cfg(any( + feature = "state-transition-value-conversion", + feature = "state-transition-json-conversion" +))] +use crate::data_contract::DataContract; +use crate::state_transition::documents_batch_transition::document_base_transition::v0::{ + TokenBaseTransitionV0, DocumentTransitionObjectLike, +}; +#[cfg(any( + feature = "state-transition-value-conversion", + feature = "state-transition-json-conversion" +))] +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use derive_more::{Display, From}; +pub use fields::*; +#[cfg(any( + feature = "state-transition-value-conversion", + feature = "state-transition-json-conversion" +))] +use platform_value::Value; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +#[cfg(feature = "state-transition-json-conversion")] +use serde_json::Value as JsonValue; +#[cfg(feature = "state-transition-value-conversion")] +use std::collections::BTreeMap; + +#[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenBaseTransition { + #[display("V0({})", "_0")] + V0(TokenBaseTransitionV0), +} + +impl Default for TokenBaseTransition { + fn default() -> Self { + TokenBaseTransition::V0(TokenBaseTransitionV0::default()) // since only v0 + } +} + +impl DocumentTransitionObjectLike for TokenBaseTransition { + #[cfg(feature = "state-transition-json-conversion")] + fn from_json_object( + json_str: JsonValue, + data_contract: DataContract, + ) -> Result + where + Self: Sized, + { + let value: Value = json_str.into(); + Self::from_object(value, data_contract) + } + #[cfg(feature = "state-transition-value-conversion")] + fn from_object( + raw_transition: Value, + _data_contract: DataContract, + ) -> Result + where + Self: Sized, + { + platform_value::from_value(raw_transition).map_err(ProtocolError::ValueError) + } + #[cfg(feature = "state-transition-value-conversion")] + fn from_value_map( + map: BTreeMap, + _data_contract: DataContract, + ) -> Result + where + Self: Sized, + { + let value: Value = map.into(); + platform_value::from_value(value).map_err(ProtocolError::ValueError) + } + + #[cfg(feature = "state-transition-value-conversion")] + fn to_object(&self) -> Result { + platform_value::to_value(self).map_err(ProtocolError::ValueError) + } + #[cfg(feature = "state-transition-value-conversion")] + fn to_value_map(&self) -> Result, ProtocolError> { + let value = platform_value::to_value(self)?; + value + .into_btree_string_map() + .map_err(ProtocolError::ValueError) + } + + #[cfg(feature = "state-transition-json-conversion")] + fn to_json(&self) -> Result { + self.to_object()? + .try_into() + .map_err(ProtocolError::ValueError) + } + + #[cfg(feature = "state-transition-value-conversion")] + fn to_cleaned_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/from_document.rs new file mode 100644 index 00000000000..087addc457d --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/from_document.rs @@ -0,0 +1,20 @@ +use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::{Document, DocumentV0Getters}; +use crate::prelude::IdentityNonce; +use crate::state_transition::documents_batch_transition::document_base_transition::v0::TokenBaseTransitionV0; + +impl TokenBaseTransitionV0 { + pub(in crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_base_transition) fn from_document( + document: &Document, + document_type: DocumentTypeRef, + identity_contract_nonce: IdentityNonce, + ) -> Self { + TokenBaseTransitionV0 { + id: document.id(), + identity_contract_nonce, + document_type_name: document_type.name().to_string(), + data_contract_id: document_type.data_contract_id(), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs new file mode 100644 index 00000000000..c76302aef86 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs @@ -0,0 +1,130 @@ +pub mod from_document; +pub mod v0_methods; + +#[cfg(feature = "state-transition-value-conversion")] +use std::collections::BTreeMap; + +use bincode::{Decode, Encode}; +use derive_more::Display; + +#[cfg(feature = "state-transition-value-conversion")] +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; +#[cfg(feature = "state-transition-value-conversion")] +use platform_value::Value; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +#[cfg(feature = "state-transition-json-conversion")] +use serde_json::Value as JsonValue; + +#[cfg(feature = "state-transition-value-conversion")] +use crate::data_contract::accessors::v0::DataContractV0Getters; +use crate::identifier::Identifier; +use crate::prelude::IdentityNonce; +#[cfg(feature = "state-transition-value-conversion")] +use crate::state_transition::documents_batch_transition::document_base_transition::property_names; +#[cfg(any( + feature = "state-transition-json-conversion", + feature = "state-transition-value-conversion" +))] +use crate::{data_contract::DataContract, errors::ProtocolError}; + +#[derive(Debug, Clone, Encode, Decode, Default, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[display( + "ID: {}, Type: {}, Contract ID: {}", + "id", + "document_type_name", + "data_contract_id" +)] +pub struct TokenBaseTransitionV0 { + /// The document ID + #[cfg_attr(feature = "state-transition-serde-conversion", serde(rename = "$id"))] + pub id: Identifier, + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "$identity-contract-nonce") + )] + pub identity_contract_nonce: IdentityNonce, + /// Name of document type found int the data contract associated with the `data_contract_id` + #[cfg_attr(feature = "state-transition-serde-conversion", serde(rename = "$type"))] + pub document_type_name: String, + /// Data contract ID generated from the data contract's `owner_id` and `entropy` + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "$dataContractId") + )] + pub data_contract_id: Identifier, +} + +impl TokenBaseTransitionV0 { + #[cfg(feature = "state-transition-value-conversion")] + pub fn from_value_map_consume( + map: &mut BTreeMap, + data_contract: DataContract, + identity_contract_nonce: IdentityNonce, + ) -> Result { + Ok(TokenBaseTransitionV0 { + id: Identifier::from( + map.remove_hash256_bytes(property_names::ID) + .map_err(ProtocolError::ValueError)?, + ), + identity_contract_nonce, + document_type_name: map + .remove_string(property_names::DOCUMENT_TYPE) + .map_err(ProtocolError::ValueError)?, + data_contract_id: Identifier::new( + map.remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID) + .map_err(ProtocolError::ValueError)? + .unwrap_or(data_contract.id().to_buffer()), + ), + }) + } +} + +pub trait DocumentTransitionObjectLike { + #[cfg(feature = "state-transition-json-conversion")] + /// Creates the Document Transition from JSON representation. The JSON representation contains + /// binary data encoded in base64, Identifiers encoded in base58 + fn from_json_object( + json_str: JsonValue, + data_contract: DataContract, + ) -> Result + where + Self: std::marker::Sized; + #[cfg(feature = "state-transition-value-conversion")] + /// Creates the document transition from Raw Object + fn from_object( + raw_transition: Value, + data_contract: DataContract, + ) -> Result + where + Self: std::marker::Sized; + #[cfg(feature = "state-transition-value-conversion")] + fn from_value_map( + map: BTreeMap, + data_contract: DataContract, + ) -> Result + where + Self: std::marker::Sized; + + #[cfg(feature = "state-transition-value-conversion")] + /// Object is an [`platform::Value`] instance that preserves the `Vec` representation + /// for Identifiers and binary data + fn to_object(&self) -> Result; + + #[cfg(feature = "state-transition-value-conversion")] + /// Value Map is a Map of string to [`platform::Value`] that represents the state transition + fn to_value_map(&self) -> Result, ProtocolError>; + + #[cfg(feature = "state-transition-json-conversion")] + /// Object is an [`serde_json::Value`] instance that replaces the binary data with + /// - base58 string for Identifiers + /// - base64 string for other binary data + fn to_json(&self) -> Result; + #[cfg(feature = "state-transition-value-conversion")] + fn to_cleaned_object(&self) -> Result; +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..f226e502c8b --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs @@ -0,0 +1,66 @@ +use crate::state_transition::documents_batch_transition::document_base_transition::v0::TokenBaseTransitionV0; + +use crate::prelude::IdentityNonce; +use platform_value::Identifier; + +/// A trait that contains getter and setter methods for `TokenBaseTransitionV0` +pub trait TokenBaseTransitionV0Methods { + /// Returns the document ID. + fn id(&self) -> Identifier; + + /// Sets the document ID. + fn set_id(&mut self, id: Identifier); + + /// Returns the document type name. + fn document_type_name(&self) -> &String; + + /// Sets the document type name. + fn set_document_type_name(&mut self, document_type_name: String); + + /// Returns the data contract ID. + fn data_contract_id(&self) -> Identifier; + fn data_contract_id_ref(&self) -> &Identifier; + + /// Sets the data contract ID. + fn set_data_contract_id(&mut self, data_contract_id: Identifier); + fn identity_contract_nonce(&self) -> IdentityNonce; + fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce); +} + +impl TokenBaseTransitionV0Methods for TokenBaseTransitionV0 { + fn id(&self) -> Identifier { + self.id + } + + fn set_id(&mut self, id: Identifier) { + self.id = id; + } + + fn document_type_name(&self) -> &String { + &self.document_type_name + } + + fn set_document_type_name(&mut self, document_type_name: String) { + self.document_type_name = document_type_name; + } + + fn data_contract_id(&self) -> Identifier { + self.data_contract_id + } + + fn data_contract_id_ref(&self) -> &Identifier { + &self.data_contract_id + } + + fn set_data_contract_id(&mut self, data_contract_id: Identifier) { + self.data_contract_id = data_contract_id; + } + + fn identity_contract_nonce(&self) -> IdentityNonce { + self.identity_contract_nonce + } + + fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce) { + self.identity_contract_nonce = identity_contract_nonce; + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs new file mode 100644 index 00000000000..5b4b18e091b --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs @@ -0,0 +1,62 @@ +use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; + +use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; + +use crate::prelude::IdentityNonce; +use platform_value::Identifier; + +impl TokenBaseTransitionV0Methods for TokenBaseTransition { + fn id(&self) -> Identifier { + match self { + TokenBaseTransition::V0(v0) => v0.id(), + } + } + + fn set_id(&mut self, id: Identifier) { + match self { + TokenBaseTransition::V0(v0) => v0.set_id(id), + } + } + + fn document_type_name(&self) -> &String { + match self { + TokenBaseTransition::V0(v0) => v0.document_type_name(), + } + } + + fn set_document_type_name(&mut self, document_type_name: String) { + match self { + TokenBaseTransition::V0(v0) => v0.set_document_type_name(document_type_name), + } + } + + fn data_contract_id(&self) -> Identifier { + match self { + TokenBaseTransition::V0(v0) => v0.data_contract_id(), + } + } + + fn data_contract_id_ref(&self) -> &Identifier { + match self { + TokenBaseTransition::V0(v0) => v0.data_contract_id_ref(), + } + } + + fn set_data_contract_id(&mut self, data_contract_id: Identifier) { + match self { + TokenBaseTransition::V0(v0) => v0.set_data_contract_id(data_contract_id), + } + } + + fn identity_contract_nonce(&self) -> IdentityNonce { + match self { + TokenBaseTransition::V0(v0) => v0.identity_contract_nonce, + } + } + + fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce) { + match self { + TokenBaseTransition::V0(v0) => v0.identity_contract_nonce = identity_contract_nonce, + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs new file mode 100644 index 00000000000..ebb0099ded9 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs @@ -0,0 +1,145 @@ +#[cfg(feature = "state-transition-json-conversion")] +use crate::data_contract::accessors::v0::DataContractV0Getters; +#[cfg(feature = "state-transition-json-conversion")] +use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; +#[cfg(any( + feature = "state-transition-json-conversion", + feature = "state-transition-value-conversion" +))] +use crate::prelude::DataContract; +#[cfg(feature = "state-transition-json-conversion")] +use crate::state_transition::data_contract_update_transition::IDENTIFIER_FIELDS; +#[cfg(any( + feature = "state-transition-json-conversion", + feature = "state-transition-value-conversion" +))] +use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; +#[cfg(feature = "state-transition-json-conversion")] +use crate::state_transition::documents_batch_transition::token_issuance_transition::v0::BINARY_FIELDS; +#[cfg(any( + feature = "state-transition-json-conversion", + feature = "state-transition-value-conversion" +))] +use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransition; +#[cfg(feature = "state-transition-value-conversion")] +use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; +#[cfg(feature = "state-transition-value-conversion")] +use crate::state_transition::documents_batch_transition::fields::property_names::STATE_TRANSITION_PROTOCOL_VERSION; +#[cfg(any( + feature = "state-transition-json-conversion", + feature = "state-transition-value-conversion" +))] +use crate::ProtocolError; +#[cfg(any( + feature = "state-transition-json-conversion", + feature = "state-transition-value-conversion" +))] +use platform_value::btreemap_extensions::{ + BTreeValueMapHelper, BTreeValueMapReplacementPathHelper, BTreeValueRemoveFromMapHelper, +}; +#[cfg(feature = "state-transition-json-conversion")] +use platform_value::ReplacementType; +#[cfg(any( + feature = "state-transition-json-conversion", + feature = "state-transition-value-conversion" +))] +use platform_value::Value; +#[cfg(feature = "state-transition-json-conversion")] +use serde_json::Value as JsonValue; +#[cfg(feature = "state-transition-value-conversion")] +use std::collections::BTreeMap; + +#[cfg(any( + feature = "state-transition-json-conversion", + feature = "state-transition-value-conversion" +))] +impl DocumentTransitionObjectLike for TokenIssuanceTransition { + #[cfg(feature = "state-transition-json-conversion")] + fn from_json_object( + json_value: JsonValue, + data_contract: DataContract, + ) -> Result { + let value: Value = json_value.into(); + let mut map = value + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?; + + let document_type = map.get_str("$type")?; + + let document_type = data_contract.document_type_for_name(document_type)?; + + let mut identifiers_paths = document_type.identifier_paths().to_owned(); + + identifiers_paths.extend(IDENTIFIER_FIELDS.iter().map(|s| s.to_string())); + + let mut binary_paths = document_type.binary_paths().to_owned(); + + binary_paths.extend(BINARY_FIELDS.iter().map(|s| s.to_string())); + + map.replace_at_paths(binary_paths.iter(), ReplacementType::BinaryBytes)?; + + map.replace_at_paths(identifiers_paths.iter(), ReplacementType::Identifier)?; + let document = Self::from_value_map(map, data_contract)?; + + Ok(document) + } + + #[cfg(feature = "state-transition-value-conversion")] + fn from_object( + raw_transition: Value, + data_contract: DataContract, + ) -> Result { + let map = raw_transition + .into_btree_string_map() + .map_err(ProtocolError::ValueError)?; + Self::from_value_map(map, data_contract) + } + + #[cfg(feature = "state-transition-value-conversion")] + fn from_value_map( + mut map: BTreeMap, + data_contract: DataContract, + ) -> Result { + let version = map.remove_string(STATE_TRANSITION_PROTOCOL_VERSION)?; + match version.as_str() { + "0" => Ok(TokenIssuanceTransition::V0( + TokenIssuanceTransitionV0::from_value_map(map, data_contract)?, + )), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DocumentMethodV0::hash".to_string(), + known_versions: vec![0], + received: version.parse().map_err(|_| { + ProtocolError::Generic("received non string version".to_string()) + })?, + }), + } + } + + #[cfg(feature = "state-transition-value-conversion")] + fn to_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } + + #[cfg(feature = "state-transition-value-conversion")] + fn to_value_map(&self) -> Result, ProtocolError> { + match self { + TokenIssuanceTransition::V0(v0) => { + let mut value_map = v0.to_value_map()?; + value_map.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_owned(), "0".into()); + Ok(value_map) + } + } + } + + #[cfg(feature = "state-transition-json-conversion")] + fn to_json(&self) -> Result { + self.to_cleaned_object()? + .try_into() + .map_err(ProtocolError::ValueError) + } + + #[cfg(feature = "state-transition-value-conversion")] + fn to_cleaned_object(&self) -> Result { + Ok(self.to_value_map()?.into()) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/from_document.rs new file mode 100644 index 00000000000..f9d141059e5 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/from_document.rs @@ -0,0 +1,43 @@ +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::Document; +use crate::prelude::IdentityNonce; +use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; +use crate::state_transition::documents_batch_transition::document_transition::TokenIssuanceTransition; +use crate::ProtocolError; +use platform_version::version::{FeatureVersion, PlatformVersion}; + +impl TokenIssuanceTransition { + pub fn from_document( + document: Document, + document_type: DocumentTypeRef, + entropy: [u8; 32], + identity_contract_nonce: IdentityNonce, + platform_version: &PlatformVersion, + feature_version: Option, + base_feature_version: Option, + ) -> Result { + match feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .token_issuance_state_transition + .bounds + .default_current_version, + ) { + 0 => Ok(TokenIssuanceTransitionV0::from_document( + document, + document_type, + entropy, + identity_contract_nonce, + platform_version, + base_feature_version, + )? + .into()), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "TokenIssuanceTransition::from_document".to_string(), + known_versions: vec![0], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs new file mode 100644 index 00000000000..223ebec9ced --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs @@ -0,0 +1,126 @@ +mod convertible; +pub mod from_document; +pub mod v0; +mod v0_methods; + +use crate::block::block_info::BlockInfo; +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::Document; +use crate::state_transition::documents_batch_transition::token_issuance_transition::v0::DocumentFromCreateTransitionV0; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use derive_more::{Display, From}; +use platform_value::Identifier; +use platform_version::version::PlatformVersion; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +pub use v0::TokenIssuanceTransitionV0; + +#[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenIssuanceTransition { + #[display("V0({})", "_0")] + V0(TokenIssuanceTransitionV0), +} + +impl Default for TokenIssuanceTransition { + fn default() -> Self { + TokenIssuanceTransition::V0(TokenIssuanceTransitionV0::default()) // since only v0 + } +} + +/// document from create transition +pub trait DocumentFromCreateTransition { + /// Attempts to create a new `Document` from the given `TokenIssuanceTransition` reference, `owner_id`, and additional metadata. + /// + /// # Arguments + /// + /// * `token_issuance_transition` - A reference to the `TokenIssuanceTransition` containing information about the document being created. + /// * `owner_id` - The `Identifier` of the document's owner. + /// * `block_info` - The block info containing information about the current block such as block time, block height and core block height. + /// * `document_type` - A reference to the `DocumentTypeRef` associated with this document, defining its structure and rules. + /// * `platform_version` - A reference to the `PlatformVersion` indicating the version of the platform for compatibility. + /// + /// # Returns + /// + /// * `Result` - A new `Document` object if successful, otherwise a `ProtocolError`. + fn try_from_issuance_transition( + token_issuance_transition: &TokenIssuanceTransition, + owner_id: Identifier, + block_info: &BlockInfo, + document_type: &DocumentTypeRef, + platform_version: &PlatformVersion, + ) -> Result + where + Self: Sized; + + /// Attempts to create a new `Document` from the given `TokenIssuanceTransition` instance, `owner_id`, and additional metadata. + /// + /// # Arguments + /// + /// * `token_issuance_transition` - A `TokenIssuanceTransition` instance containing information about the document being created. + /// * `owner_id` - The `Identifier` of the document's owner. + /// * `block_info` - The block info containing information about the current block such as block time, block height and core block height. + /// * `document_type` - A reference to the `DocumentTypeRef` associated with this document, defining its structure and rules. + /// * `platform_version` - A reference to the `PlatformVersion` indicating the version of the platform for compatibility. + /// + /// # Returns + /// + /// * `Result` - A new `Document` object if successful, otherwise a `ProtocolError`. + fn try_from_owned_create_transition( + token_issuance_transition: TokenIssuanceTransition, + owner_id: Identifier, + block_info: &BlockInfo, + document_type: &DocumentTypeRef, + platform_version: &PlatformVersion, + ) -> Result + where + Self: Sized; +} + +impl DocumentFromCreateTransition for Document { + fn try_from_create_transition( + token_issuance_transition: &TokenIssuanceTransition, + owner_id: Identifier, + block_info: &BlockInfo, + document_type: &DocumentTypeRef, + platform_version: &PlatformVersion, + ) -> Result + where + Self: Sized, + { + match token_issuance_transition { + TokenIssuanceTransition::V0(v0) => Self::try_from_create_transition_v0( + v0, + owner_id, + block_info, + document_type, + platform_version, + ), + } + } + + fn try_from_owned_create_transition( + token_issuance_transition: TokenIssuanceTransition, + owner_id: Identifier, + block_info: &BlockInfo, + document_type: &DocumentTypeRef, + platform_version: &PlatformVersion, + ) -> Result + where + Self: Sized, + { + match token_issuance_transition { + TokenIssuanceTransition::V0(v0) => Self::try_from_owned_create_transition_v0( + v0, + owner_id, + block_info, + document_type, + platform_version, + ), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs new file mode 100644 index 00000000000..94f45149fa3 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs @@ -0,0 +1,60 @@ +pub mod v0_methods; + +use bincode::{Decode, Encode}; + +#[cfg(feature = "state-transition-value-conversion")] +use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; +use platform_value::{Identifier, Value}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +use std::collections::BTreeMap; + +use std::string::ToString; + +#[cfg(feature = "state-transition-value-conversion")] +use crate::data_contract::DataContract; + +use crate::{document, errors::ProtocolError}; + +use crate::block::block_info::BlockInfo; +use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; +use crate::data_contract::document_type::methods::DocumentTypeV0Methods; +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::{Document, DocumentV0}; +use crate::fee::Credits; +use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +#[cfg(feature = "state-transition-value-conversion")] +use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; +use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use derive_more::Display; +#[cfg(feature = "state-transition-value-conversion")] +use platform_value::btreemap_extensions::BTreeValueRemoveTupleFromMapHelper; +use platform_version::version::PlatformVersion; + +#[cfg(feature = "state-transition-value-conversion")] +use crate::state_transition::documents_batch_transition; + +mod property_names { + pub const AMOUNT: &str = "$amount"; + +} +/// The Identifier fields in [`TokenIssuanceTransition`] +pub use super::super::document_base_transition::IDENTIFIER_FIELDS; + +#[derive(Debug, Clone, Default, Encode, Decode, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[display("Base: {base}, Amount: {amount}")] +pub struct TokenIssuanceTransitionV0 { + /// Document Base Transition + #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] + pub base: DocumentBaseTransition, + + /// How much should we issue + #[cfg_attr(feature = "state-transition-serde-conversion")] + pub amount: u64, +} \ No newline at end of file diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..c9bdec184ae --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs @@ -0,0 +1,98 @@ +use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; + +use platform_value::Value; + +use crate::fee::Credits; +use std::collections::BTreeMap; + +pub trait TokenIssuanceTransitionV0Methods { + /// Returns a reference to the `base` field of the `TokenIssuanceTransitionV0`. + fn base(&self) -> &DocumentBaseTransition; + + /// Returns a mut reference to the `base` field of the `TokenIssuanceTransitionV0`. + fn base_mut(&mut self) -> &mut DocumentBaseTransition; + + /// Sets the value of the `base` field in the `TokenIssuanceTransitionV0`. + /// + /// # Arguments + /// + /// * `base` - A value of type `DocumentBaseTransition` to set. + fn set_base(&mut self, base: DocumentBaseTransition); + + /// Returns a reference to the `entropy` field of the `TokenIssuanceTransitionV0`. + fn entropy(&self) -> [u8; 32]; + + /// Sets the value of the `entropy` field in the `TokenIssuanceTransitionV0`. + /// + /// # Arguments + /// + /// * `entropy` - An array of 32 bytes to set. + fn set_entropy(&mut self, entropy: [u8; 32]); + + /// Returns an optional reference to the `data` field of the `TokenIssuanceTransitionV0`. + fn data(&self) -> &BTreeMap; + + /// Returns an optional mutable reference to the `data` field of the `TokenIssuanceTransitionV0`. + fn data_mut(&mut self) -> &mut BTreeMap; + + /// Sets the value of the `data` field in the `TokenIssuanceTransitionV0`. + /// + /// # Arguments + /// + /// * `data` - An `Option` containing a `BTreeMap` to set. + fn set_data(&mut self, data: BTreeMap); + fn prefunded_voting_balance(&self) -> &Option<(String, Credits)>; + fn prefunded_voting_balances_mut(&mut self) -> &mut Option<(String, Credits)>; + fn set_prefunded_voting_balance(&mut self, index_name: String, amount: Credits); + fn clear_prefunded_voting_balance(&mut self); +} + +impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransitionV0 { + fn base(&self) -> &DocumentBaseTransition { + &self.base + } + + fn base_mut(&mut self) -> &mut DocumentBaseTransition { + &mut self.base + } + + fn set_base(&mut self, base: DocumentBaseTransition) { + self.base = base; + } + + fn entropy(&self) -> [u8; 32] { + self.entropy + } + + fn set_entropy(&mut self, entropy: [u8; 32]) { + self.entropy = entropy; + } + + fn data(&self) -> &BTreeMap { + &self.data + } + + fn data_mut(&mut self) -> &mut BTreeMap { + &mut self.data + } + + fn set_data(&mut self, data: BTreeMap) { + self.data = data; + } + + fn prefunded_voting_balance(&self) -> &Option<(String, Credits)> { + &self.prefunded_voting_balance + } + + fn prefunded_voting_balances_mut(&mut self) -> &mut Option<(String, Credits)> { + &mut self.prefunded_voting_balance + } + + fn set_prefunded_voting_balance(&mut self, index_name: String, amount: Credits) { + self.prefunded_voting_balance = Some((index_name, amount)); + } + fn clear_prefunded_voting_balance(&mut self) { + self.prefunded_voting_balance = None; + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs new file mode 100644 index 00000000000..4159c3ace34 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs @@ -0,0 +1,80 @@ +use std::collections::BTreeMap; +use platform_value::{Value}; +use crate::fee::Credits; +use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransition; +use crate::state_transition::documents_batch_transition::token_issuance_transition::v0::v0_methods::TokenIssuanceTransitionV0Methods; + +impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransition { + fn base(&self) -> &DocumentBaseTransition { + match self { + TokenIssuanceTransition::V0(v0) => &v0.base, + } + } + + fn base_mut(&mut self) -> &mut DocumentBaseTransition { + match self { + TokenIssuanceTransition::V0(v0) => &mut v0.base, + } + } + + fn set_base(&mut self, base: DocumentBaseTransition) { + match self { + TokenIssuanceTransition::V0(v0) => v0.base = base, + } + } + + fn entropy(&self) -> [u8; 32] { + match self { + TokenIssuanceTransition::V0(v0) => v0.entropy, + } + } + + fn set_entropy(&mut self, entropy: [u8; 32]) { + match self { + TokenIssuanceTransition::V0(v0) => v0.entropy = entropy, + } + } + + fn data(&self) -> &BTreeMap { + match self { + TokenIssuanceTransition::V0(v0) => &v0.data, + } + } + + fn data_mut(&mut self) -> &mut BTreeMap { + match self { + TokenIssuanceTransition::V0(v0) => &mut v0.data, + } + } + + fn set_data(&mut self, data: BTreeMap) { + match self { + TokenIssuanceTransition::V0(v0) => v0.data = data, + } + } + + fn prefunded_voting_balance(&self) -> &Option<(String, Credits)> { + match self { + TokenIssuanceTransition::V0(v0) => v0.prefunded_voting_balance(), + } + } + + fn prefunded_voting_balances_mut(&mut self) -> &mut Option<(String, Credits)> { + match self { + TokenIssuanceTransition::V0(v0) => v0.prefunded_voting_balances_mut(), + } + } + + fn set_prefunded_voting_balance(&mut self, index_name: String, amount: Credits) { + match self { + TokenIssuanceTransition::V0(v0) => v0.set_prefunded_voting_balance(index_name, amount), + } + } + + fn clear_prefunded_voting_balance(&mut self) { + match self { + TokenIssuanceTransition::V0(v0) => v0.clear_prefunded_voting_balance(), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/from_document.rs new file mode 100644 index 00000000000..de82abeb913 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/from_document.rs @@ -0,0 +1,43 @@ +use platform_value::Identifier; +use platform_version::version::{FeatureVersion, PlatformVersion}; +use crate::data_contract::document_type::{DocumentTypeRef}; +use crate::document::{Document}; +use crate::prelude::IdentityNonce; +use crate::ProtocolError; +use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::{TokenTransferTransition, TokenTransferTransitionV0}; + +impl TokenTransferTransition { + pub fn from_document( + document: Document, + document_type: DocumentTypeRef, + identity_contract_nonce: IdentityNonce, + recipient_owner_id: Identifier, + platform_version: &PlatformVersion, + feature_version: Option, + base_feature_version: Option, + ) -> Result { + match feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .token_transfer_state_transition + .bounds + .default_current_version, + ) { + 0 => Ok(TokenTransferTransitionV0::from_document( + document, + document_type, + identity_contract_nonce, + recipient_owner_id, + platform_version, + base_feature_version, + )? + .into()), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "TokenTransferTransition::from_document".to_string(), + known_versions: vec![0], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs new file mode 100644 index 00000000000..3bce9ea9922 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs @@ -0,0 +1,19 @@ +mod from_document; +pub mod v0; +pub mod v0_methods; + +use bincode::{Decode, Encode}; +use derive_more::{Display, From}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +pub use v0::*; + +#[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenTransferTransition { + #[display("V0({})", "_0")] + V0(TokenTransferTransitionV0), +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/from_document.rs new file mode 100644 index 00000000000..f0f1e597928 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/from_document.rs @@ -0,0 +1,36 @@ +use platform_value::Identifier; +use platform_version::version::{FeatureVersion, PlatformVersion}; +use crate::data_contract::document_type::{DocumentTypeRef}; +use crate::document::{Document, DocumentV0Getters}; +use crate::document::errors::DocumentError; +use crate::prelude::IdentityNonce; +use crate::ProtocolError; +use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; +use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::TokenTransferTransitionV0; + +impl TokenTransferTransitionV0 { + pub(crate) fn from_document( + document: Document, + document_type: DocumentTypeRef, + identity_contract_nonce: IdentityNonce, + recipient_owner_id: Identifier, + platform_version: &PlatformVersion, + base_feature_version: Option, + ) -> Result { + Ok(TokenTransferTransitionV0 { + base: TokenBaseTransition::from_document( + &document, + document_type, + identity_contract_nonce, + platform_version, + base_feature_version, + )?, + revision: document.revision().ok_or_else(|| { + ProtocolError::Document(Box::new(DocumentError::DocumentNoRevisionError { + document: Box::new(document.clone()), + })) + })?, + recipient_owner_id, + }) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs new file mode 100644 index 00000000000..e3c171a6fd5 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs @@ -0,0 +1,46 @@ +mod from_document; +pub mod v0_methods; + +use crate::prelude::Revision; +use bincode::{Decode, Encode}; +use derive_more::Display; + +use platform_value::Identifier; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +pub use super::super::document_base_transition::IDENTIFIER_FIELDS; +use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; + +mod property_names { + pub const REVISION: &str = "$revision"; + + pub const RECIPIENT_OWNER_ID: &str = "recipientOwnerId"; +} + +#[derive(Debug, Clone, Default, Encode, Decode, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[display( + "Base: {}, Revision: {}, Recipient: {:?}", + "base", + "revision", + "recipient_owner_id" +)] +pub struct TokenTransferTransitionV0 { + #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] + pub base: TokenBaseTransition, + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "$revision") + )] + pub revision: Revision, + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "recipientOwnerId") + )] + pub recipient_owner_id: Identifier, +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..acb5ace0bb4 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs @@ -0,0 +1,66 @@ +use platform_value::Identifier; + +use crate::prelude::Revision; + +use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; + +use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::TokenTransferTransitionV0; + +pub trait TokenTransferTransitionV0Methods { + /// Returns a reference to the `base` field of the `DocumentReplaceTransitionV0`. + fn base(&self) -> &TokenBaseTransition; + /// Returns a mut reference to the `base` field of the `DocumentReplaceTransitionV0`. + fn base_mut(&mut self) -> &mut TokenBaseTransition; + + /// Sets the value of the `base` field in the `DocumentReplaceTransitionV0`. + fn set_base(&mut self, base: TokenBaseTransition); + + /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. + fn revision(&self) -> Revision; + + /// Sets the value of the `revision` field in the `DocumentReplaceTransitionV0`. + fn set_revision(&mut self, revision: Revision); + + /// Returns the `recipient_owner_id` field of the `DocumentReplaceTransitionV0`. + fn recipient_owner_id(&self) -> Identifier; + + /// Returns a reference to the `recipient_owner_id` field of the `DocumentReplaceTransitionV0`. + fn recipient_owner_id_ref(&self) -> &Identifier; + + /// Sets the value of the `recipient_owner_id` field in the `DocumentReplaceTransitionV0`. + fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier); +} + +impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { + fn base(&self) -> &TokenBaseTransition { + &self.base + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + &mut self.base + } + + fn set_base(&mut self, base: TokenBaseTransition) { + self.base = base; + } + + fn revision(&self) -> Revision { + self.revision + } + + fn set_revision(&mut self, revision: Revision) { + self.revision = revision; + } + + fn recipient_owner_id(&self) -> Identifier { + self.recipient_owner_id + } + + fn recipient_owner_id_ref(&self) -> &Identifier { + &self.recipient_owner_id + } + + fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier) { + self.recipient_owner_id = recipient_owner_id; + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs new file mode 100644 index 00000000000..61618991166 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs @@ -0,0 +1,55 @@ +use platform_value::Identifier; +use crate::prelude::Revision; +use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; +use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; +use crate::state_transition::documents_batch_transition::document_transition::TokenTransferTransition; + +impl TokenTransferTransitionV0Methods for TokenTransferTransition { + fn base(&self) -> &TokenBaseTransition { + match self { + TokenTransferTransition::V0(v0) => &v0.base, + } + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + match self { + TokenTransferTransition::V0(v0) => &mut v0.base, + } + } + + fn set_base(&mut self, base: TokenBaseTransition) { + match self { + TokenTransferTransition::V0(v0) => v0.base = base, + } + } + + fn revision(&self) -> Revision { + match self { + TokenTransferTransition::V0(v0) => v0.revision, + } + } + + fn set_revision(&mut self, revision: Revision) { + match self { + TokenTransferTransition::V0(v0) => v0.revision = revision, + } + } + + fn recipient_owner_id(&self) -> Identifier { + match self { + TokenTransferTransition::V0(v0) => v0.recipient_owner_id, + } + } + + fn recipient_owner_id_ref(&self) -> &Identifier { + match self { + TokenTransferTransition::V0(v0) => &v0.recipient_owner_id, + } + } + + fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier) { + match self { + TokenTransferTransition::V0(v0) => v0.recipient_owner_id = recipient_owner_id, + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs index f62e971fb7e..f5e7c2193ab 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs @@ -15,7 +15,9 @@ pub use self::document_transition::{ document_base_transition, document_create_transition, document_create_transition::DocumentCreateTransition, document_delete_transition, document_delete_transition::DocumentDeleteTransition, document_replace_transition, - document_replace_transition::DocumentReplaceTransition, + document_replace_transition::DocumentReplaceTransition, token_base_transition, + token_issuance_transition, token_issuance_transition::TokenIssuanceTransition, + token_transfer_transition, token_transfer_transition::TokenTransferTransition, }; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize, PlatformSignable}; diff --git a/packages/rs-dpp/src/tokens/allowed_currency.rs b/packages/rs-dpp/src/tokens/allowed_currency.rs new file mode 100644 index 00000000000..0f048d8dd3a --- /dev/null +++ b/packages/rs-dpp/src/tokens/allowed_currency.rs @@ -0,0 +1,7 @@ +use platform_value::Identifier; + +#[derive(Debug, PartialEq, Clone)] +pub enum AllowedCurrency { + TradingInDash, + OnContract(Identifier, String) +} diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs index 8b137891791..f29df1969b2 100644 --- a/packages/rs-dpp/src/tokens/mod.rs +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -1 +1 @@ - +pub mod allowed_currency; \ No newline at end of file diff --git a/packages/rs-drive-abci/tests/supporting_files/contract/crypto-card-game/crypto-card-game-in-game-currency.json b/packages/rs-drive-abci/tests/supporting_files/contract/crypto-card-game/crypto-card-game-in-game-currency.json new file mode 100644 index 00000000000..3a1c2daeccd --- /dev/null +++ b/packages/rs-drive-abci/tests/supporting_files/contract/crypto-card-game/crypto-card-game-in-game-currency.json @@ -0,0 +1,135 @@ +{ + "$format_version": "0", + "id": "86LHvdC1Tqx5P97LQUSibGFqf2vnKFpB6VkqQ7oso86e", + "ownerId": "2QjL594djCH2NyDsn45vd6yQjEDHupMKo7CEGVTHtQxU", + "version": 1, + "documentSchemas": { + "card": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": true, + "transferable": 1, + "tradeMode": 1, + "creationRestrictionMode": 1, + "properties": { + "name": { + "type": "string", + "description": "Name of the card", + "maxLength": 63, + "position": 0 + }, + "description": { + "type": "string", + "description": "Description of the card", + "maxLength": 256, + "position": 1 + }, + "imageUrl": { + "type": "string", + "description": "URL of the image associated with the card", + "maxLength": 2048, + "format": "uri", + "position": 2 + }, + "imageHash": { + "type": "array", + "description": "SHA256 hash of the bytes of the image specified by imageUrl", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "position": 3 + }, + "imageFingerprint": { + "type": "array", + "description": "dHash of the image specified by imageUrl", + "byteArray": true, + "minItems": 8, + "maxItems": 8, + "position": 4 + }, + "attack": { + "type": "integer", + "description": "Attack power of the card", + "minimum": 0, + "position": 5 + }, + "defense": { + "type": "integer", + "description": "Defense level of the card", + "minimum": 0, + "position": 6 + } + }, + "indices": [ + { + "name": "owner", + "properties": [ + { + "$ownerId": "asc" + } + ] + }, + { + "name": "attack", + "properties": [ + { + "attack": "asc" + } + ] + }, + { + "name": "defense", + "properties": [ + { + "defense": "asc" + } + ] + }, + { + "name": "transferredAt", + "properties": [ + { + "$transferredAt": "asc" + } + ] + }, + { + "name": "ownerTransferredAt", + "properties": [ + { + "$ownerId": "asc" + }, + { + "$transferredAt": "asc" + } + ] + }, + { + "name": "transferredAtBlockHeight", + "properties": [ + { + "$transferredAtBlockHeight": "asc" + } + ] + }, + { + "name": "transferredAtCoreBlockHeight", + "properties": [ + { + "$transferredAtCoreBlockHeight": "asc" + } + ] + } + ], + "required": [ + "name", + "$transferredAt", + "$transferredAtBlockHeight", + "$transferredAtCoreBlockHeight", + "attack", + "defense" + ], + "additionalProperties": false + } + } +} \ No newline at end of file From a34ff06b16b6830ccdd5a18351a6cd4ca9a4f37c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 1 Dec 2024 17:54:10 +0300 Subject: [PATCH 05/61] more work on tokens --- .../protos/platform/v0/platform.proto | 68 ++++++++++++ .../v0/mod.rs | 2 +- .../token_configuration/v0/mod.rs | 21 ++-- .../src/data_contract/document_type/v0/mod.rs | 2 +- packages/rs-dpp/src/lib.rs | 1 - packages/rs-dpp/src/nft/mod.rs | 2 +- .../document_base_transition_trait.rs | 16 +++ .../document_base_transition/mod.rs | 1 + .../v0/v0_methods.rs | 20 +--- .../document_create_transition/v0_methods.rs | 5 +- .../v0/v0_methods.rs | 16 +-- .../document_delete_transition/v0_methods.rs | 4 +- .../v0/v0_methods.rs | 20 ++-- .../v0_methods.rs | 5 +- .../v0/v0_methods.rs | 17 +-- .../document_replace_transition/v0_methods.rs | 5 +- .../v0/v0_methods.rs | 17 +-- .../v0_methods.rs | 5 +- .../v0/v0_methods.rs | 17 +-- .../v0_methods.rs | 5 +- .../document_transition/mod.rs | 2 +- .../token_base_transition/fields.rs | 2 +- .../token_base_transition/from_document.rs | 37 ------- .../token_base_transition/mod.rs | 7 +- .../token_base_transition_accessors.rs | 16 +++ .../token_base_transition/v0/from_document.rs | 20 ---- .../token_base_transition/v0/mod.rs | 64 ++--------- .../token_base_transition/v0/v0_methods.rs | 17 ++- .../token_base_transition/v0_methods.rs | 14 ++- .../token_issuance_transition/convertible.rs | 4 +- .../from_document.rs | 43 -------- .../token_issuance_transition/mod.rs | 101 ------------------ .../token_issuance_transition/v0/mod.rs | 38 +------ .../v0/v0_methods.rs | 97 +++-------------- .../token_issuance_transition/v0_methods.rs | 66 +++--------- .../from_document.rs | 43 -------- .../token_transfer_transition/mod.rs | 1 - .../v0/from_document.rs | 36 ------- .../token_transfer_transition/v0/mod.rs | 5 +- .../v0/v0_methods.rs | 36 +++---- .../token_transfer_transition/v0_methods.rs | 9 +- .../rs-dpp/src/tokens/allowed_currency.rs | 2 +- packages/rs-dpp/src/tokens/mod.rs | 2 +- 43 files changed, 254 insertions(+), 657 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/document_base_transition_trait.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/from_document.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/token_base_transition_accessors.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/from_document.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/from_document.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/from_document.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/from_document.rs diff --git a/packages/dapi-grpc/protos/platform/v0/platform.proto b/packages/dapi-grpc/protos/platform/v0/platform.proto index b46d784ceb7..c949faf5aad 100644 --- a/packages/dapi-grpc/protos/platform/v0/platform.proto +++ b/packages/dapi-grpc/protos/platform/v0/platform.proto @@ -55,6 +55,8 @@ service Platform { rpc getPathElements(GetPathElementsRequest) returns (GetPathElementsResponse); rpc getStatus(GetStatusRequest) returns (GetStatusResponse); rpc getCurrentQuorumsInfo(GetCurrentQuorumsInfoRequest) returns (GetCurrentQuorumsInfoResponse); + rpc getIdentityTokenBalances(GetIdentityTokenBalancesRequest) returns (GetIdentityTokenBalancesResponse); + rpc getIdentitiesTokenBalances(GetIdentitiesTokenBalancesRequest) returns (GetIdentitiesTokenBalancesResponse); } // Proof message includes cryptographic proofs for validating responses @@ -1215,3 +1217,69 @@ message GetCurrentQuorumsInfoResponse { } oneof version { GetCurrentQuorumsInfoResponseV0 v0 = 1; } } + +message GetIdentityTokenBalancesRequest { + message GetIdentityTokenBalancesRequestV0 { + bytes identity_id = 1; // ID of the identity + repeated bytes contract_ids = 2; // List of token contract IDs + bool prove = 3; // Flag to request a proof as the response + } + oneof version { + GetIdentityTokenBalancesRequestV0 v0 = 1; + } +} + +message GetIdentityTokenBalancesResponse { + message GetIdentityTokenBalancesResponseV0 { + message TokenBalanceEntry { + bytes contract_id = 1; // Token contract ID + uint64 balance = 2; // Token balance for the contract + } + + message TokenBalances { + repeated TokenBalanceEntry token_balances = 1; // List of token balances + } + + oneof result { + TokenBalances token_balances = 1; // Actual token balances + Proof proof = 2; // Proof of the token balances, if requested + } + ResponseMetadata metadata = 3; // Metadata about the blockchain state + } + oneof version { + GetIdentityTokenBalancesResponseV0 v0 = 1; + } +} + +message GetIdentitiesTokenBalancesRequest { + message GetIdentitiesTokenBalancesRequestV0 { + bytes contract_id = 1; // Token contract ID + repeated bytes identity_ids = 2; // List of identity IDs + bool prove = 3; // Flag to request a proof as the response + } + oneof version { + GetIdentitiesTokenBalancesRequestV0 v0 = 1; + } +} + +message GetIdentitiesTokenBalancesResponse { + message GetIdentitiesTokenBalancesResponseV0 { + message IdentityTokenBalanceEntry { + bytes identity_id = 1; // Identity ID + uint64 balance = 2; // Token balance for the identity + } + + message IdentityTokenBalances { + repeated IdentityTokenBalanceEntry identity_token_balances = 1; // List of identity token balances + } + + oneof result { + IdentityTokenBalances identity_token_balances = 1; // Actual identity token balances + Proof proof = 2; // Proof of the balances, if requested + } + ResponseMetadata metadata = 3; // Metadata about the blockchain state + } + oneof version { + GetIdentitiesTokenBalancesResponseV0 v0 = 1; + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index 67456e2f4b6..e255a3642b0 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -34,7 +34,7 @@ impl TokenConfiguration { } = new_config.as_cow_v0(); if max_supply != new_max_supply { - max_supply_can_be_increased. + // max_supply_can_be_increased } SimpleConsensusValidationResult::new() diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 967e445ef74..43ae526b6f0 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -71,17 +71,20 @@ pub struct ChangeControlRules { } impl ChangeControlRules { - pub fn can_change_to(&self, other: &ChangeControlRules, contract_owner_id: &Identifier, - main_group: &(BTreeSet, RequiredSigners), action_taker: &ActionTaker) { + pub fn can_change_to( + &self, + other: &ChangeControlRules, + contract_owner_id: &Identifier, + main_group: &(BTreeSet, RequiredSigners), + action_taker: &ActionTaker, + ) { let ChangeControlRules { - authorized_to_make_change, - authorized_to_change_to_authorized_action_takers, - changing_authorized_action_takers_to_no_one_allowed, - changing_authorized_action_takers_to_contract_owner_allowed + authorized_to_make_change, + authorized_to_change_to_authorized_action_takers, + changing_authorized_action_takers_to_no_one_allowed, + changing_authorized_action_takers_to_contract_owner_allowed, } = self; - - - } + } } #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] diff --git a/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs index c09621233a6..048ef06b6e7 100644 --- a/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs @@ -13,8 +13,8 @@ use crate::data_contract::document_type::restricted_creation::CreationRestrictio use crate::document::transfer::Transferable; use crate::identity::SecurityLevel; use crate::nft::TradeMode; -use platform_value::{Identifier, Value}; use crate::tokens::allowed_currency::AllowedCurrency; +use platform_value::{Identifier, Value}; mod accessors; #[cfg(feature = "random-documents")] diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index cad59145c79..31cc2481356 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -61,7 +61,6 @@ pub mod voting; pub mod core_types; pub mod withdrawal; -mod token; pub use async_trait; diff --git a/packages/rs-dpp/src/nft/mod.rs b/packages/rs-dpp/src/nft/mod.rs index a7628abbd2f..b558d676586 100644 --- a/packages/rs-dpp/src/nft/mod.rs +++ b/packages/rs-dpp/src/nft/mod.rs @@ -2,9 +2,9 @@ use crate::consensus::basic::data_contract::UnknownTradeModeError; use crate::consensus::basic::BasicError; use crate::consensus::ConsensusError; use crate::ProtocolError; +use platform_value::Identifier; use std::fmt; use std::fmt::{Display, Formatter}; -use platform_value::Identifier; #[derive(Debug, PartialEq, Clone)] pub enum TradeMode { None = 0, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/document_base_transition_trait.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/document_base_transition_trait.rs new file mode 100644 index 00000000000..efaed10f74d --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/document_base_transition_trait.rs @@ -0,0 +1,16 @@ +use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; + +pub trait DocumentBaseTransitionAccessors { + /// Returns a reference to the `base` field of the `DocumentCreateTransitionV0`. + fn base(&self) -> &DocumentBaseTransition; + + /// Returns a mut reference to the `base` field of the `DocumentCreateTransitionV0`. + fn base_mut(&mut self) -> &mut DocumentBaseTransition; + + /// Sets the value of the `base` field in the `DocumentCreateTransitionV0`. + /// + /// # Arguments + /// + /// * `base` - A value of type `DocumentBaseTransition` to set. + fn set_base(&mut self, base: DocumentBaseTransition); +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/mod.rs index 6d80cc2d872..3ff9b50f21a 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/mod.rs @@ -1,3 +1,4 @@ +pub mod document_base_transition_trait; mod fields; mod from_document; pub mod v0; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/v0_methods.rs index e5e2aa8710b..07850ab77aa 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/v0_methods.rs @@ -5,21 +5,9 @@ use platform_value::Value; use crate::fee::Credits; use std::collections::BTreeMap; +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -pub trait DocumentCreateTransitionV0Methods { - /// Returns a reference to the `base` field of the `DocumentCreateTransitionV0`. - fn base(&self) -> &DocumentBaseTransition; - - /// Returns a mut reference to the `base` field of the `DocumentCreateTransitionV0`. - fn base_mut(&mut self) -> &mut DocumentBaseTransition; - - /// Sets the value of the `base` field in the `DocumentCreateTransitionV0`. - /// - /// # Arguments - /// - /// * `base` - A value of type `DocumentBaseTransition` to set. - fn set_base(&mut self, base: DocumentBaseTransition); - +pub trait DocumentCreateTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `entropy` field of the `DocumentCreateTransitionV0`. fn entropy(&self) -> [u8; 32]; @@ -48,7 +36,7 @@ pub trait DocumentCreateTransitionV0Methods { fn clear_prefunded_voting_balance(&mut self); } -impl DocumentCreateTransitionV0Methods for DocumentCreateTransitionV0 { +impl DocumentBaseTransitionAccessors for DocumentCreateTransitionV0 { fn base(&self) -> &DocumentBaseTransition { &self.base } @@ -60,7 +48,9 @@ impl DocumentCreateTransitionV0Methods for DocumentCreateTransitionV0 { fn set_base(&mut self, base: DocumentBaseTransition) { self.base = base; } +} +impl DocumentCreateTransitionV0Methods for DocumentCreateTransitionV0 { fn entropy(&self) -> [u8; 32] { self.entropy } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0_methods.rs index 11d349f56ca..9c959ffd429 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0_methods.rs @@ -1,11 +1,12 @@ use std::collections::BTreeMap; use platform_value::{Value}; use crate::fee::Credits; +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransition; use crate::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -impl DocumentCreateTransitionV0Methods for DocumentCreateTransition { +impl DocumentBaseTransitionAccessors for DocumentCreateTransition { fn base(&self) -> &DocumentBaseTransition { match self { DocumentCreateTransition::V0(v0) => &v0.base, @@ -23,7 +24,9 @@ impl DocumentCreateTransitionV0Methods for DocumentCreateTransition { DocumentCreateTransition::V0(v0) => v0.base = base, } } +} +impl DocumentCreateTransitionV0Methods for DocumentCreateTransition { fn entropy(&self) -> [u8; 32] { match self { DocumentCreateTransition::V0(v0) => v0.entropy, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/v0_methods.rs index d37685df0d3..82b3fd624d2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/v0_methods.rs @@ -1,20 +1,8 @@ +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition::documents_batch_transition::document_transition::document_delete_transition::DocumentDeleteTransitionV0; -pub trait DocumentDeleteTransitionV0Methods { - /// Returns a reference to the `base` field of the `DocumentCreateTransitionV0`. - fn base(&self) -> &DocumentBaseTransition; - fn base_mut(&mut self) -> &mut DocumentBaseTransition; - - /// Sets the value of the `base` field in the `DocumentCreateTransitionV0`. - /// - /// # Arguments - /// - /// * `base` - A value of type `DocumentBaseTransition` to set. - fn set_base(&mut self, base: DocumentBaseTransition); -} - -impl DocumentDeleteTransitionV0Methods for DocumentDeleteTransitionV0 { +impl DocumentBaseTransitionAccessors for DocumentDeleteTransitionV0 { fn base(&self) -> &DocumentBaseTransition { &self.base } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0_methods.rs index 099c95e8f34..20618a4a6bc 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0_methods.rs @@ -1,8 +1,8 @@ +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_delete_transition::v0::v0_methods::DocumentDeleteTransitionV0Methods; use crate::state_transition::documents_batch_transition::document_transition::DocumentDeleteTransition; -impl DocumentDeleteTransitionV0Methods for DocumentDeleteTransition { +impl DocumentBaseTransitionAccessors for DocumentDeleteTransition { fn base(&self) -> &DocumentBaseTransition { match self { DocumentDeleteTransition::V0(v0) => &v0.base, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/v0_methods.rs index 95333296e41..33df1517da9 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/v0_methods.rs @@ -1,20 +1,10 @@ use crate::fee::Credits; use crate::prelude::Revision; +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::DocumentPurchaseTransitionV0; -pub trait DocumentPurchaseTransitionV0Methods { - /// Returns a reference to the `base` field of the `DocumentCreateTransitionV0`. - fn base(&self) -> &DocumentBaseTransition; - fn base_mut(&mut self) -> &mut DocumentBaseTransition; - - /// Sets the value of the `base` field in the `DocumentCreateTransitionV0`. - /// - /// # Arguments - /// - /// * `base` - A value of type `DocumentBaseTransition` to set. - fn set_base(&mut self, base: DocumentBaseTransition); - +pub trait DocumentPurchaseTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. fn revision(&self) -> Revision; @@ -23,7 +13,7 @@ pub trait DocumentPurchaseTransitionV0Methods { fn price(&self) -> Credits; } -impl DocumentPurchaseTransitionV0Methods for DocumentPurchaseTransitionV0 { +impl DocumentBaseTransitionAccessors for DocumentPurchaseTransitionV0 { fn base(&self) -> &DocumentBaseTransition { &self.base } @@ -33,9 +23,11 @@ impl DocumentPurchaseTransitionV0Methods for DocumentPurchaseTransitionV0 { } fn set_base(&mut self, base: DocumentBaseTransition) { - self.base = base + self.base = base; } +} +impl DocumentPurchaseTransitionV0Methods for DocumentPurchaseTransitionV0 { fn revision(&self) -> Revision { self.revision } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0_methods.rs index 86c2fe8f193..0bb3fc04d16 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0_methods.rs @@ -1,10 +1,11 @@ use crate::fee::Credits; use crate::prelude::Revision; +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use crate::state_transition::documents_batch_transition::document_transition::DocumentPurchaseTransition; -impl DocumentPurchaseTransitionV0Methods for DocumentPurchaseTransition { +impl DocumentBaseTransitionAccessors for DocumentPurchaseTransition { fn base(&self) -> &DocumentBaseTransition { match self { DocumentPurchaseTransition::V0(v0) => &v0.base, @@ -22,7 +23,9 @@ impl DocumentPurchaseTransitionV0Methods for DocumentPurchaseTransition { DocumentPurchaseTransition::V0(v0) => v0.base = base, } } +} +impl DocumentPurchaseTransitionV0Methods for DocumentPurchaseTransition { fn revision(&self) -> Revision { match self { DocumentPurchaseTransition::V0(v0) => v0.revision, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/v0_methods.rs index 9bee325bb1b..034b6c4e275 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/v0_methods.rs @@ -3,20 +3,11 @@ use platform_value::Value; use std::collections::BTreeMap; use crate::prelude::Revision; - +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; - use crate::state_transition::documents_batch_transition::document_transition::document_replace_transition::DocumentReplaceTransitionV0; -pub trait DocumentReplaceTransitionV0Methods { - /// Returns a reference to the `base` field of the `DocumentReplaceTransitionV0`. - fn base(&self) -> &DocumentBaseTransition; - /// Returns a mut reference to the `base` field of the `DocumentReplaceTransitionV0`. - fn base_mut(&mut self) -> &mut DocumentBaseTransition; - - /// Sets the value of the `base` field in the `DocumentReplaceTransitionV0`. - fn set_base(&mut self, base: DocumentBaseTransition); - +pub trait DocumentReplaceTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. fn revision(&self) -> Revision; @@ -33,7 +24,7 @@ pub trait DocumentReplaceTransitionV0Methods { fn set_data(&mut self, data: BTreeMap); } -impl DocumentReplaceTransitionV0Methods for DocumentReplaceTransitionV0 { +impl DocumentBaseTransitionAccessors for DocumentReplaceTransitionV0 { fn base(&self) -> &DocumentBaseTransition { &self.base } @@ -45,7 +36,9 @@ impl DocumentReplaceTransitionV0Methods for DocumentReplaceTransitionV0 { fn set_base(&mut self, base: DocumentBaseTransition) { self.base = base; } +} +impl DocumentReplaceTransitionV0Methods for DocumentReplaceTransitionV0 { fn revision(&self) -> Revision { self.revision } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0_methods.rs index 29f79a05e22..21993559c73 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0_methods.rs @@ -1,11 +1,12 @@ use std::collections::BTreeMap; use platform_value::Value; use crate::prelude::Revision; +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition::documents_batch_transition::document_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; use crate::state_transition::documents_batch_transition::document_transition::DocumentReplaceTransition; -impl DocumentReplaceTransitionV0Methods for DocumentReplaceTransition { +impl DocumentBaseTransitionAccessors for DocumentReplaceTransition { fn base(&self) -> &DocumentBaseTransition { match self { DocumentReplaceTransition::V0(v0) => &v0.base, @@ -23,7 +24,9 @@ impl DocumentReplaceTransitionV0Methods for DocumentReplaceTransition { DocumentReplaceTransition::V0(v0) => v0.base = base, } } +} +impl DocumentReplaceTransitionV0Methods for DocumentReplaceTransition { fn revision(&self) -> Revision { match self { DocumentReplaceTransition::V0(v0) => v0.revision, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/v0_methods.rs index 6e4b8331155..7d490ecbad8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/v0_methods.rs @@ -1,20 +1,11 @@ use platform_value::Identifier; use crate::prelude::Revision; - +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; - use crate::state_transition::documents_batch_transition::document_transition::document_transfer_transition::DocumentTransferTransitionV0; -pub trait DocumentTransferTransitionV0Methods { - /// Returns a reference to the `base` field of the `DocumentReplaceTransitionV0`. - fn base(&self) -> &DocumentBaseTransition; - /// Returns a mut reference to the `base` field of the `DocumentReplaceTransitionV0`. - fn base_mut(&mut self) -> &mut DocumentBaseTransition; - - /// Sets the value of the `base` field in the `DocumentReplaceTransitionV0`. - fn set_base(&mut self, base: DocumentBaseTransition); - +pub trait DocumentTransferTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. fn revision(&self) -> Revision; @@ -31,7 +22,7 @@ pub trait DocumentTransferTransitionV0Methods { fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier); } -impl DocumentTransferTransitionV0Methods for DocumentTransferTransitionV0 { +impl DocumentBaseTransitionAccessors for DocumentTransferTransitionV0 { fn base(&self) -> &DocumentBaseTransition { &self.base } @@ -43,7 +34,9 @@ impl DocumentTransferTransitionV0Methods for DocumentTransferTransitionV0 { fn set_base(&mut self, base: DocumentBaseTransition) { self.base = base; } +} +impl DocumentTransferTransitionV0Methods for DocumentTransferTransitionV0 { fn revision(&self) -> Revision { self.revision } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0_methods.rs index adeff540c05..09f1c74da30 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0_methods.rs @@ -1,10 +1,11 @@ use platform_value::Identifier; use crate::prelude::Revision; +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; use crate::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; -impl DocumentTransferTransitionV0Methods for DocumentTransferTransition { +impl DocumentBaseTransitionAccessors for DocumentTransferTransition { fn base(&self) -> &DocumentBaseTransition { match self { DocumentTransferTransition::V0(v0) => &v0.base, @@ -22,7 +23,9 @@ impl DocumentTransferTransitionV0Methods for DocumentTransferTransition { DocumentTransferTransition::V0(v0) => v0.base = base, } } +} +impl DocumentTransferTransitionV0Methods for DocumentTransferTransition { fn revision(&self) -> Revision { match self { DocumentTransferTransition::V0(v0) => v0.revision, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/v0_methods.rs index 74b27a3589d..32e87609160 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/v0_methods.rs @@ -1,19 +1,10 @@ use crate::fee::Credits; use crate::prelude::Revision; - +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; - use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; -pub trait DocumentUpdatePriceTransitionV0Methods { - /// Returns a reference to the `base` field of the `DocumentUpdatePriceTransitionV0`. - fn base(&self) -> &DocumentBaseTransition; - /// Returns a mut reference to the `base` field of the `DocumentUpdatePriceTransitionV0`. - fn base_mut(&mut self) -> &mut DocumentBaseTransition; - - /// Sets the value of the `base` field in the `DocumentUpdatePriceTransitionV0`. - fn set_base(&mut self, base: DocumentBaseTransition); - +pub trait DocumentUpdatePriceTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentUpdatePriceTransitionV0`. fn revision(&self) -> Revision; @@ -27,7 +18,7 @@ pub trait DocumentUpdatePriceTransitionV0Methods { fn set_price(&mut self, price: Credits); } -impl DocumentUpdatePriceTransitionV0Methods for DocumentUpdatePriceTransitionV0 { +impl DocumentBaseTransitionAccessors for DocumentUpdatePriceTransitionV0 { fn base(&self) -> &DocumentBaseTransition { &self.base } @@ -39,7 +30,9 @@ impl DocumentUpdatePriceTransitionV0Methods for DocumentUpdatePriceTransitionV0 fn set_base(&mut self, base: DocumentBaseTransition) { self.base = base; } +} +impl DocumentUpdatePriceTransitionV0Methods for DocumentUpdatePriceTransitionV0 { fn revision(&self) -> Revision { self.revision } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0_methods.rs index 3b605d7431c..3beeecbbd3e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0_methods.rs @@ -1,10 +1,11 @@ use crate::fee::Credits; use crate::prelude::Revision; +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; use crate::state_transition::documents_batch_transition::document_transition::DocumentUpdatePriceTransition; -impl DocumentUpdatePriceTransitionV0Methods for DocumentUpdatePriceTransition { +impl DocumentBaseTransitionAccessors for DocumentUpdatePriceTransition { fn base(&self) -> &DocumentBaseTransition { match self { DocumentUpdatePriceTransition::V0(v0) => &v0.base, @@ -22,7 +23,9 @@ impl DocumentUpdatePriceTransitionV0Methods for DocumentUpdatePriceTransition { DocumentUpdatePriceTransition::V0(v0) => v0.base = base, } } +} +impl DocumentUpdatePriceTransitionV0Methods for DocumentUpdatePriceTransition { fn revision(&self) -> Revision { match self { DocumentUpdatePriceTransition::V0(v0) => v0.revision, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs index 465b4bbd204..dee8212b18c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs @@ -16,9 +16,9 @@ pub mod document_purchase_transition; pub mod document_replace_transition; pub mod document_transfer_transition; pub mod document_update_price_transition; +pub mod token_base_transition; pub mod token_issuance_transition; pub mod token_transfer_transition; -pub mod token_base_transition; use crate::prelude::Revision; use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs index b7e0135ed04..0ae1c2b9731 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs @@ -1,7 +1,7 @@ pub(in crate::state_transition::state_transitions::document::documents_batch_transition) mod property_names { pub const ID: &str = "$id"; pub const DATA_CONTRACT_ID: &str = "$dataContractId"; - pub const DOCUMENT_TYPE: &str = "$type"; + pub const TOKEN_ID: &str = "$tokenId"; pub const ACTION: &str = "$action"; pub const IDENTITY_CONTRACT_NONCE: &str = "$identityContractNonce"; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/from_document.rs deleted file mode 100644 index a84baf514f0..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/from_document.rs +++ /dev/null @@ -1,37 +0,0 @@ -use crate::data_contract::document_type::DocumentTypeRef; -use crate::document::Document; -use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::TokenBaseTransitionV0; -use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; -use crate::ProtocolError; -use platform_version::version::{FeatureVersion, PlatformVersion}; - -impl TokenBaseTransition { - pub fn from_document( - document: &Document, - document_type: DocumentTypeRef, - identity_contract_nonce: IdentityNonce, - platform_version: &PlatformVersion, - feature_version: Option, - ) -> Result { - match feature_version.unwrap_or( - platform_version - .dpp - .state_transition_serialization_versions - .document_base_state_transition - .default_current_version, - ) { - 0 => Ok(TokenBaseTransitionV0::from_document( - document, - document_type, - identity_contract_nonce, - ) - .into()), - version => Err(ProtocolError::UnknownVersionMismatch { - method: "TokenBaseTransition::from_document".to_string(), - known_versions: vec![0], - received: version, - }), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs index e7a502aea1f..b9d12f51212 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs @@ -1,5 +1,5 @@ mod fields; -mod from_document; +pub mod token_base_transition_accessors; pub mod v0; mod v0_methods; @@ -8,9 +8,8 @@ mod v0_methods; feature = "state-transition-json-conversion" ))] use crate::data_contract::DataContract; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::{ - TokenBaseTransitionV0, DocumentTransitionObjectLike, -}; +use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; +use crate::state_transition::documents_batch_transition::token_base_transition::v0::TokenBaseTransitionV0; #[cfg(any( feature = "state-transition-value-conversion", feature = "state-transition-json-conversion" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/token_base_transition_accessors.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/token_base_transition_accessors.rs new file mode 100644 index 00000000000..5e952d5e1ca --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/token_base_transition_accessors.rs @@ -0,0 +1,16 @@ +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; + +pub trait TokenBaseTransitionAccessors { + /// Returns a reference to the `base` field of the `DocumentCreateTransitionV0`. + fn base(&self) -> &TokenBaseTransition; + + /// Returns a mut reference to the `base` field of the `DocumentCreateTransitionV0`. + fn base_mut(&mut self) -> &mut TokenBaseTransition; + + /// Sets the value of the `base` field in the `DocumentCreateTransitionV0`. + /// + /// # Arguments + /// + /// * `base` - A value of type `DocumentBaseTransition` to set. + fn set_base(&mut self, base: TokenBaseTransition); +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/from_document.rs deleted file mode 100644 index 087addc457d..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/from_document.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; -use crate::data_contract::document_type::DocumentTypeRef; -use crate::document::{Document, DocumentV0Getters}; -use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::TokenBaseTransitionV0; - -impl TokenBaseTransitionV0 { - pub(in crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_base_transition) fn from_document( - document: &Document, - document_type: DocumentTypeRef, - identity_contract_nonce: IdentityNonce, - ) -> Self { - TokenBaseTransitionV0 { - id: document.id(), - identity_contract_nonce, - document_type_name: document_type.name().to_string(), - data_contract_id: document_type.data_contract_id(), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs index c76302aef86..30824d49d50 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs @@ -1,4 +1,3 @@ -pub mod from_document; pub mod v0_methods; #[cfg(feature = "state-transition-value-conversion")] @@ -13,15 +12,13 @@ use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_value::Value; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; -#[cfg(feature = "state-transition-json-conversion")] -use serde_json::Value as JsonValue; #[cfg(feature = "state-transition-value-conversion")] use crate::data_contract::accessors::v0::DataContractV0Getters; use crate::identifier::Identifier; use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::document_base_transition::property_names; +use crate::state_transition::documents_batch_transition::token_base_transition::property_names; #[cfg(any( feature = "state-transition-json-conversion", feature = "state-transition-value-conversion" @@ -37,7 +34,7 @@ use crate::{data_contract::DataContract, errors::ProtocolError}; #[display( "ID: {}, Type: {}, Contract ID: {}", "id", - "document_type_name", + "token_id", "data_contract_id" )] pub struct TokenBaseTransitionV0 { @@ -49,9 +46,12 @@ pub struct TokenBaseTransitionV0 { serde(rename = "$identity-contract-nonce") )] pub identity_contract_nonce: IdentityNonce, - /// Name of document type found int the data contract associated with the `data_contract_id` - #[cfg_attr(feature = "state-transition-serde-conversion", serde(rename = "$type"))] - pub document_type_name: String, + /// ID of the token within the contract + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "$tokenId") + )] + pub token_id: u16, /// Data contract ID generated from the data contract's `owner_id` and `entropy` #[cfg_attr( feature = "state-transition-serde-conversion", @@ -73,8 +73,8 @@ impl TokenBaseTransitionV0 { .map_err(ProtocolError::ValueError)?, ), identity_contract_nonce, - document_type_name: map - .remove_string(property_names::DOCUMENT_TYPE) + token_id: map + .remove_integer(property_names::TOKEN_ID) .map_err(ProtocolError::ValueError)?, data_contract_id: Identifier::new( map.remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID) @@ -84,47 +84,3 @@ impl TokenBaseTransitionV0 { }) } } - -pub trait DocumentTransitionObjectLike { - #[cfg(feature = "state-transition-json-conversion")] - /// Creates the Document Transition from JSON representation. The JSON representation contains - /// binary data encoded in base64, Identifiers encoded in base58 - fn from_json_object( - json_str: JsonValue, - data_contract: DataContract, - ) -> Result - where - Self: std::marker::Sized; - #[cfg(feature = "state-transition-value-conversion")] - /// Creates the document transition from Raw Object - fn from_object( - raw_transition: Value, - data_contract: DataContract, - ) -> Result - where - Self: std::marker::Sized; - #[cfg(feature = "state-transition-value-conversion")] - fn from_value_map( - map: BTreeMap, - data_contract: DataContract, - ) -> Result - where - Self: std::marker::Sized; - - #[cfg(feature = "state-transition-value-conversion")] - /// Object is an [`platform::Value`] instance that preserves the `Vec` representation - /// for Identifiers and binary data - fn to_object(&self) -> Result; - - #[cfg(feature = "state-transition-value-conversion")] - /// Value Map is a Map of string to [`platform::Value`] that represents the state transition - fn to_value_map(&self) -> Result, ProtocolError>; - - #[cfg(feature = "state-transition-json-conversion")] - /// Object is an [`serde_json::Value`] instance that replaces the binary data with - /// - base58 string for Identifiers - /// - base64 string for other binary data - fn to_json(&self) -> Result; - #[cfg(feature = "state-transition-value-conversion")] - fn to_cleaned_object(&self) -> Result; -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs index f226e502c8b..563b8fa7252 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs @@ -1,6 +1,5 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::v0::TokenBaseTransitionV0; - use crate::prelude::IdentityNonce; +use crate::state_transition::documents_batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use platform_value::Identifier; /// A trait that contains getter and setter methods for `TokenBaseTransitionV0` @@ -12,10 +11,10 @@ pub trait TokenBaseTransitionV0Methods { fn set_id(&mut self, id: Identifier); /// Returns the document type name. - fn document_type_name(&self) -> &String; + fn token_id(&self) -> u16; - /// Sets the document type name. - fn set_document_type_name(&mut self, document_type_name: String); + /// Sets the token id. + fn set_token_id(&mut self, token_id: u16); /// Returns the data contract ID. fn data_contract_id(&self) -> Identifier; @@ -36,12 +35,12 @@ impl TokenBaseTransitionV0Methods for TokenBaseTransitionV0 { self.id = id; } - fn document_type_name(&self) -> &String { - &self.document_type_name + fn token_id(&self) -> u16 { + self.token_id } - fn set_document_type_name(&mut self, document_type_name: String) { - self.document_type_name = document_type_name; + fn set_token_id(&mut self, token_id: u16) { + self.token_id = token_id; } fn data_contract_id(&self) -> Identifier { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs index 5b4b18e091b..29848b71700 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs @@ -1,8 +1,6 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; - -use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; - use crate::prelude::IdentityNonce; +use crate::state_transition::documents_batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; use platform_value::Identifier; impl TokenBaseTransitionV0Methods for TokenBaseTransition { @@ -18,15 +16,15 @@ impl TokenBaseTransitionV0Methods for TokenBaseTransition { } } - fn document_type_name(&self) -> &String { + fn token_id(&self) -> u16 { match self { - TokenBaseTransition::V0(v0) => v0.document_type_name(), + TokenBaseTransition::V0(v0) => v0.token_id(), } } - fn set_document_type_name(&mut self, document_type_name: String) { + fn set_token_id(&mut self, token_id: u16) { match self { - TokenBaseTransition::V0(v0) => v0.set_document_type_name(document_type_name), + TokenBaseTransition::V0(v0) => v0.set_token_id(token_id), } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs index ebb0099ded9..5cedcd97f15 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs @@ -14,6 +14,8 @@ use crate::state_transition::data_contract_update_transition::IDENTIFIER_FIELDS; feature = "state-transition-value-conversion" ))] use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; +#[cfg(feature = "state-transition-value-conversion")] +use crate::state_transition::documents_batch_transition::fields::property_names::STATE_TRANSITION_PROTOCOL_VERSION; #[cfg(feature = "state-transition-json-conversion")] use crate::state_transition::documents_batch_transition::token_issuance_transition::v0::BINARY_FIELDS; #[cfg(any( @@ -23,8 +25,6 @@ use crate::state_transition::documents_batch_transition::token_issuance_transiti use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransition; #[cfg(feature = "state-transition-value-conversion")] use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; -#[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::fields::property_names::STATE_TRANSITION_PROTOCOL_VERSION; #[cfg(any( feature = "state-transition-json-conversion", feature = "state-transition-value-conversion" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/from_document.rs deleted file mode 100644 index f9d141059e5..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/from_document.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::data_contract::document_type::DocumentTypeRef; -use crate::document::Document; -use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; -use crate::state_transition::documents_batch_transition::document_transition::TokenIssuanceTransition; -use crate::ProtocolError; -use platform_version::version::{FeatureVersion, PlatformVersion}; - -impl TokenIssuanceTransition { - pub fn from_document( - document: Document, - document_type: DocumentTypeRef, - entropy: [u8; 32], - identity_contract_nonce: IdentityNonce, - platform_version: &PlatformVersion, - feature_version: Option, - base_feature_version: Option, - ) -> Result { - match feature_version.unwrap_or( - platform_version - .dpp - .state_transition_serialization_versions - .token_issuance_state_transition - .bounds - .default_current_version, - ) { - 0 => Ok(TokenIssuanceTransitionV0::from_document( - document, - document_type, - entropy, - identity_contract_nonce, - platform_version, - base_feature_version, - )? - .into()), - version => Err(ProtocolError::UnknownVersionMismatch { - method: "TokenIssuanceTransition::from_document".to_string(), - known_versions: vec![0], - received: version, - }), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs index 223ebec9ced..6a88124d820 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs @@ -1,17 +1,9 @@ mod convertible; -pub mod from_document; pub mod v0; mod v0_methods; -use crate::block::block_info::BlockInfo; -use crate::data_contract::document_type::DocumentTypeRef; -use crate::document::Document; -use crate::state_transition::documents_batch_transition::token_issuance_transition::v0::DocumentFromCreateTransitionV0; -use crate::ProtocolError; use bincode::{Decode, Encode}; use derive_more::{Display, From}; -use platform_value::Identifier; -use platform_version::version::PlatformVersion; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; pub use v0::TokenIssuanceTransitionV0; @@ -31,96 +23,3 @@ impl Default for TokenIssuanceTransition { TokenIssuanceTransition::V0(TokenIssuanceTransitionV0::default()) // since only v0 } } - -/// document from create transition -pub trait DocumentFromCreateTransition { - /// Attempts to create a new `Document` from the given `TokenIssuanceTransition` reference, `owner_id`, and additional metadata. - /// - /// # Arguments - /// - /// * `token_issuance_transition` - A reference to the `TokenIssuanceTransition` containing information about the document being created. - /// * `owner_id` - The `Identifier` of the document's owner. - /// * `block_info` - The block info containing information about the current block such as block time, block height and core block height. - /// * `document_type` - A reference to the `DocumentTypeRef` associated with this document, defining its structure and rules. - /// * `platform_version` - A reference to the `PlatformVersion` indicating the version of the platform for compatibility. - /// - /// # Returns - /// - /// * `Result` - A new `Document` object if successful, otherwise a `ProtocolError`. - fn try_from_issuance_transition( - token_issuance_transition: &TokenIssuanceTransition, - owner_id: Identifier, - block_info: &BlockInfo, - document_type: &DocumentTypeRef, - platform_version: &PlatformVersion, - ) -> Result - where - Self: Sized; - - /// Attempts to create a new `Document` from the given `TokenIssuanceTransition` instance, `owner_id`, and additional metadata. - /// - /// # Arguments - /// - /// * `token_issuance_transition` - A `TokenIssuanceTransition` instance containing information about the document being created. - /// * `owner_id` - The `Identifier` of the document's owner. - /// * `block_info` - The block info containing information about the current block such as block time, block height and core block height. - /// * `document_type` - A reference to the `DocumentTypeRef` associated with this document, defining its structure and rules. - /// * `platform_version` - A reference to the `PlatformVersion` indicating the version of the platform for compatibility. - /// - /// # Returns - /// - /// * `Result` - A new `Document` object if successful, otherwise a `ProtocolError`. - fn try_from_owned_create_transition( - token_issuance_transition: TokenIssuanceTransition, - owner_id: Identifier, - block_info: &BlockInfo, - document_type: &DocumentTypeRef, - platform_version: &PlatformVersion, - ) -> Result - where - Self: Sized; -} - -impl DocumentFromCreateTransition for Document { - fn try_from_create_transition( - token_issuance_transition: &TokenIssuanceTransition, - owner_id: Identifier, - block_info: &BlockInfo, - document_type: &DocumentTypeRef, - platform_version: &PlatformVersion, - ) -> Result - where - Self: Sized, - { - match token_issuance_transition { - TokenIssuanceTransition::V0(v0) => Self::try_from_create_transition_v0( - v0, - owner_id, - block_info, - document_type, - platform_version, - ), - } - } - - fn try_from_owned_create_transition( - token_issuance_transition: TokenIssuanceTransition, - owner_id: Identifier, - block_info: &BlockInfo, - document_type: &DocumentTypeRef, - platform_version: &PlatformVersion, - ) -> Result - where - Self: Sized, - { - match token_issuance_transition { - TokenIssuanceTransition::V0(v0) => Self::try_from_owned_create_transition_v0( - v0, - owner_id, - block_info, - document_type, - platform_version, - ), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs index 94f45149fa3..c8c2de608b2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs @@ -1,43 +1,13 @@ pub mod v0_methods; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; use bincode::{Decode, Encode}; - -#[cfg(feature = "state-transition-value-conversion")] -use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; -use platform_value::{Identifier, Value}; +use derive_more::Display; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; -use std::collections::BTreeMap; - -use std::string::ToString; - -#[cfg(feature = "state-transition-value-conversion")] -use crate::data_contract::DataContract; - -use crate::{document, errors::ProtocolError}; - -use crate::block::block_info::BlockInfo; -use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; -use crate::data_contract::document_type::methods::DocumentTypeV0Methods; -use crate::data_contract::document_type::DocumentTypeRef; -use crate::document::{Document, DocumentV0}; -use crate::fee::Credits; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; -#[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use derive_more::Display; -#[cfg(feature = "state-transition-value-conversion")] -use platform_value::btreemap_extensions::BTreeValueRemoveTupleFromMapHelper; -use platform_version::version::PlatformVersion; - -#[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition; - mod property_names { pub const AMOUNT: &str = "$amount"; - } /// The Identifier fields in [`TokenIssuanceTransition`] pub use super::super::document_base_transition::IDENTIFIER_FIELDS; @@ -52,9 +22,9 @@ pub use super::super::document_base_transition::IDENTIFIER_FIELDS; pub struct TokenIssuanceTransitionV0 { /// Document Base Transition #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] - pub base: DocumentBaseTransition, + pub base: TokenBaseTransition, /// How much should we issue #[cfg_attr(feature = "state-transition-serde-conversion")] pub amount: u64, -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs index c9bdec184ae..8b643593ac6 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs @@ -1,98 +1,33 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; -use platform_value::Value; - -use crate::fee::Credits; -use std::collections::BTreeMap; - -pub trait TokenIssuanceTransitionV0Methods { - /// Returns a reference to the `base` field of the `TokenIssuanceTransitionV0`. - fn base(&self) -> &DocumentBaseTransition; - - /// Returns a mut reference to the `base` field of the `TokenIssuanceTransitionV0`. - fn base_mut(&mut self) -> &mut DocumentBaseTransition; - - /// Sets the value of the `base` field in the `TokenIssuanceTransitionV0`. - /// - /// # Arguments - /// - /// * `base` - A value of type `DocumentBaseTransition` to set. - fn set_base(&mut self, base: DocumentBaseTransition); - - /// Returns a reference to the `entropy` field of the `TokenIssuanceTransitionV0`. - fn entropy(&self) -> [u8; 32]; - - /// Sets the value of the `entropy` field in the `TokenIssuanceTransitionV0`. - /// - /// # Arguments - /// - /// * `entropy` - An array of 32 bytes to set. - fn set_entropy(&mut self, entropy: [u8; 32]); - - /// Returns an optional reference to the `data` field of the `TokenIssuanceTransitionV0`. - fn data(&self) -> &BTreeMap; - - /// Returns an optional mutable reference to the `data` field of the `TokenIssuanceTransitionV0`. - fn data_mut(&mut self) -> &mut BTreeMap; - - /// Sets the value of the `data` field in the `TokenIssuanceTransitionV0`. - /// - /// # Arguments - /// - /// * `data` - An `Option` containing a `BTreeMap` to set. - fn set_data(&mut self, data: BTreeMap); - fn prefunded_voting_balance(&self) -> &Option<(String, Credits)>; - fn prefunded_voting_balances_mut(&mut self) -> &mut Option<(String, Credits)>; - fn set_prefunded_voting_balance(&mut self, index_name: String, amount: Credits); - fn clear_prefunded_voting_balance(&mut self); -} - -impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransitionV0 { - fn base(&self) -> &DocumentBaseTransition { +impl TokenBaseTransitionAccessors for TokenIssuanceTransitionV0 { + fn base(&self) -> &TokenBaseTransition { &self.base } - fn base_mut(&mut self) -> &mut DocumentBaseTransition { + fn base_mut(&mut self) -> &mut TokenBaseTransition { &mut self.base } - fn set_base(&mut self, base: DocumentBaseTransition) { + fn set_base(&mut self, base: TokenBaseTransition) { self.base = base; } +} - fn entropy(&self) -> [u8; 32] { - self.entropy - } - - fn set_entropy(&mut self, entropy: [u8; 32]) { - self.entropy = entropy; - } - - fn data(&self) -> &BTreeMap { - &self.data - } - - fn data_mut(&mut self) -> &mut BTreeMap { - &mut self.data - } - - fn set_data(&mut self, data: BTreeMap) { - self.data = data; - } +pub trait TokenIssuanceTransitionV0Methods: TokenBaseTransitionAccessors { + fn amount(&self) -> u64; - fn prefunded_voting_balance(&self) -> &Option<(String, Credits)> { - &self.prefunded_voting_balance - } + fn set_amount(&mut self, amount: u64); +} - fn prefunded_voting_balances_mut(&mut self) -> &mut Option<(String, Credits)> { - &mut self.prefunded_voting_balance +impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransitionV0 { + fn amount(&self) -> u64 { + self.amount } - fn set_prefunded_voting_balance(&mut self, index_name: String, amount: Credits) { - self.prefunded_voting_balance = Some((index_name, amount)); - } - fn clear_prefunded_voting_balance(&mut self) { - self.prefunded_voting_balance = None; + fn set_amount(&mut self, amount: u64) { + self.amount = amount; } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs index 4159c3ace34..b4bdc520bc1 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs @@ -1,80 +1,38 @@ -use std::collections::BTreeMap; -use platform_value::{Value}; -use crate::fee::Credits; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransition; use crate::state_transition::documents_batch_transition::token_issuance_transition::v0::v0_methods::TokenIssuanceTransitionV0Methods; -impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransition { - fn base(&self) -> &DocumentBaseTransition { +impl TokenBaseTransitionAccessors for TokenIssuanceTransition { + fn base(&self) -> &TokenBaseTransition { match self { TokenIssuanceTransition::V0(v0) => &v0.base, } } - fn base_mut(&mut self) -> &mut DocumentBaseTransition { + fn base_mut(&mut self) -> &mut TokenBaseTransition { match self { TokenIssuanceTransition::V0(v0) => &mut v0.base, } } - fn set_base(&mut self, base: DocumentBaseTransition) { + fn set_base(&mut self, base: TokenBaseTransition) { match self { TokenIssuanceTransition::V0(v0) => v0.base = base, } } +} - fn entropy(&self) -> [u8; 32] { - match self { - TokenIssuanceTransition::V0(v0) => v0.entropy, - } - } - - fn set_entropy(&mut self, entropy: [u8; 32]) { - match self { - TokenIssuanceTransition::V0(v0) => v0.entropy = entropy, - } - } - - fn data(&self) -> &BTreeMap { - match self { - TokenIssuanceTransition::V0(v0) => &v0.data, - } - } - - fn data_mut(&mut self) -> &mut BTreeMap { - match self { - TokenIssuanceTransition::V0(v0) => &mut v0.data, - } - } - - fn set_data(&mut self, data: BTreeMap) { - match self { - TokenIssuanceTransition::V0(v0) => v0.data = data, - } - } - - fn prefunded_voting_balance(&self) -> &Option<(String, Credits)> { - match self { - TokenIssuanceTransition::V0(v0) => v0.prefunded_voting_balance(), - } - } - - fn prefunded_voting_balances_mut(&mut self) -> &mut Option<(String, Credits)> { - match self { - TokenIssuanceTransition::V0(v0) => v0.prefunded_voting_balances_mut(), - } - } - - fn set_prefunded_voting_balance(&mut self, index_name: String, amount: Credits) { +impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransition { + fn amount(&self) -> u64 { match self { - TokenIssuanceTransition::V0(v0) => v0.set_prefunded_voting_balance(index_name, amount), + TokenIssuanceTransition::V0(v0) => v0.amount(), } } - fn clear_prefunded_voting_balance(&mut self) { + fn set_amount(&mut self, amount: u64) { match self { - TokenIssuanceTransition::V0(v0) => v0.clear_prefunded_voting_balance(), + TokenIssuanceTransition::V0(v0) => v0.set_amount(amount), } } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/from_document.rs deleted file mode 100644 index de82abeb913..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/from_document.rs +++ /dev/null @@ -1,43 +0,0 @@ -use platform_value::Identifier; -use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::data_contract::document_type::{DocumentTypeRef}; -use crate::document::{Document}; -use crate::prelude::IdentityNonce; -use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::{TokenTransferTransition, TokenTransferTransitionV0}; - -impl TokenTransferTransition { - pub fn from_document( - document: Document, - document_type: DocumentTypeRef, - identity_contract_nonce: IdentityNonce, - recipient_owner_id: Identifier, - platform_version: &PlatformVersion, - feature_version: Option, - base_feature_version: Option, - ) -> Result { - match feature_version.unwrap_or( - platform_version - .dpp - .state_transition_serialization_versions - .token_transfer_state_transition - .bounds - .default_current_version, - ) { - 0 => Ok(TokenTransferTransitionV0::from_document( - document, - document_type, - identity_contract_nonce, - recipient_owner_id, - platform_version, - base_feature_version, - )? - .into()), - version => Err(ProtocolError::UnknownVersionMismatch { - method: "TokenTransferTransition::from_document".to_string(), - known_versions: vec![0], - received: version, - }), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs index 3bce9ea9922..39c8a54695f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs @@ -1,4 +1,3 @@ -mod from_document; pub mod v0; pub mod v0_methods; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/from_document.rs deleted file mode 100644 index f0f1e597928..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/from_document.rs +++ /dev/null @@ -1,36 +0,0 @@ -use platform_value::Identifier; -use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::data_contract::document_type::{DocumentTypeRef}; -use crate::document::{Document, DocumentV0Getters}; -use crate::document::errors::DocumentError; -use crate::prelude::IdentityNonce; -use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::TokenTransferTransitionV0; - -impl TokenTransferTransitionV0 { - pub(crate) fn from_document( - document: Document, - document_type: DocumentTypeRef, - identity_contract_nonce: IdentityNonce, - recipient_owner_id: Identifier, - platform_version: &PlatformVersion, - base_feature_version: Option, - ) -> Result { - Ok(TokenTransferTransitionV0 { - base: TokenBaseTransition::from_document( - &document, - document_type, - identity_contract_nonce, - platform_version, - base_feature_version, - )?, - revision: document.revision().ok_or_else(|| { - ProtocolError::Document(Box::new(DocumentError::DocumentNoRevisionError { - document: Box::new(document.clone()), - })) - })?, - recipient_owner_id, - }) - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs index e3c171a6fd5..98c36109ceb 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs @@ -1,4 +1,3 @@ -mod from_document; pub mod v0_methods; use crate::prelude::Revision; @@ -9,8 +8,8 @@ use platform_value::Identifier; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; -pub use super::super::document_base_transition::IDENTIFIER_FIELDS; -use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; +pub use super::super::token_base_transition::IDENTIFIER_FIELDS; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; mod property_names { pub const REVISION: &str = "$revision"; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs index acb5ace0bb4..7ab7a1c75c3 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs @@ -2,19 +2,25 @@ use platform_value::Identifier; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; - use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::TokenTransferTransitionV0; +use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; + +impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { + fn base(&self) -> &TokenBaseTransition { + &self.base + } -pub trait TokenTransferTransitionV0Methods { - /// Returns a reference to the `base` field of the `DocumentReplaceTransitionV0`. - fn base(&self) -> &TokenBaseTransition; - /// Returns a mut reference to the `base` field of the `DocumentReplaceTransitionV0`. - fn base_mut(&mut self) -> &mut TokenBaseTransition; + fn base_mut(&mut self) -> &mut TokenBaseTransition { + &mut self.base + } - /// Sets the value of the `base` field in the `DocumentReplaceTransitionV0`. - fn set_base(&mut self, base: TokenBaseTransition); + fn set_base(&mut self, base: TokenBaseTransition) { + self.base = base; + } +} +pub trait TokenTransferTransitionV0Methods: TokenBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. fn revision(&self) -> Revision; @@ -32,18 +38,6 @@ pub trait TokenTransferTransitionV0Methods { } impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { - fn base(&self) -> &TokenBaseTransition { - &self.base - } - - fn base_mut(&mut self) -> &mut TokenBaseTransition { - &mut self.base - } - - fn set_base(&mut self, base: TokenBaseTransition) { - self.base = base; - } - fn revision(&self) -> Revision { self.revision } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs index 61618991166..bdb827b76de 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs @@ -1,10 +1,11 @@ use platform_value::Identifier; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::TokenBaseTransition; use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::TokenTransferTransition; +use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::documents_batch_transition::TokenTransferTransition; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; -impl TokenTransferTransitionV0Methods for TokenTransferTransition { +impl TokenBaseTransitionAccessors for TokenTransferTransition { fn base(&self) -> &TokenBaseTransition { match self { TokenTransferTransition::V0(v0) => &v0.base, @@ -22,7 +23,9 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransition { TokenTransferTransition::V0(v0) => v0.base = base, } } +} +impl TokenTransferTransitionV0Methods for TokenTransferTransition { fn revision(&self) -> Revision { match self { TokenTransferTransition::V0(v0) => v0.revision, diff --git a/packages/rs-dpp/src/tokens/allowed_currency.rs b/packages/rs-dpp/src/tokens/allowed_currency.rs index 0f048d8dd3a..f6c5b4da938 100644 --- a/packages/rs-dpp/src/tokens/allowed_currency.rs +++ b/packages/rs-dpp/src/tokens/allowed_currency.rs @@ -3,5 +3,5 @@ use platform_value::Identifier; #[derive(Debug, PartialEq, Clone)] pub enum AllowedCurrency { TradingInDash, - OnContract(Identifier, String) + OnContract(Identifier, String), } diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs index f29df1969b2..8219bad9d2d 100644 --- a/packages/rs-dpp/src/tokens/mod.rs +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -1 +1 @@ -pub mod allowed_currency; \ No newline at end of file +pub mod allowed_currency; From 279d16f0fadff097ea67fbd79ec5aacf066c9156 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 1 Dec 2024 19:36:57 +0300 Subject: [PATCH 06/61] added burn transition --- .../document_transition/mod.rs | 3 +- .../token_burn_transition/mod.rs | 24 +++ .../token_burn_transition/v0/mod.rs | 29 ++++ .../token_burn_transition/v0/v0_methods.rs | 33 ++++ .../token_burn_transition/v0_methods.rs | 38 +++++ .../token_issuance_transition/convertible.rs | 145 ------------------ .../token_issuance_transition/mod.rs | 1 - .../token_issuance_transition/v0/mod.rs | 1 - .../token_transfer_transition/v0/mod.rs | 11 +- .../v0/v0_methods.rs | 14 +- .../token_transfer_transition/v0_methods.rs | 8 +- .../documents_batch_transition/mod.rs | 1 + 12 files changed, 142 insertions(+), 166 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0_methods.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs index dee8212b18c..24f4b2d5204 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs @@ -19,6 +19,7 @@ pub mod document_update_price_transition; pub mod token_base_transition; pub mod token_issuance_transition; pub mod token_transfer_transition; +pub mod token_burn_transition; use crate::prelude::Revision; use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; @@ -30,12 +31,12 @@ pub use document_transfer_transition::DocumentTransferTransition; pub use document_purchase_transition::DocumentPurchaseTransition; pub use document_update_price_transition::DocumentUpdatePriceTransition; use platform_value::Value; +use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; -use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_delete_transition::v0::v0_methods::DocumentDeleteTransitionV0Methods; use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; pub const PROPERTY_ACTION: &str = "$action"; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/mod.rs new file mode 100644 index 00000000000..5c07e9a97de --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/mod.rs @@ -0,0 +1,24 @@ +pub mod v0; +mod v0_methods; + +use bincode::{Decode, Encode}; +use derive_more::{Display, From}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +pub use v0::TokenBurnTransitionV0; + +#[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenBurnTransition { + #[display("V0({})", "_0")] + V0(TokenBurnTransitionV0), +} + +impl Default for TokenBurnTransition { + fn default() -> Self { + TokenBurnTransition::V0(TokenBurnTransitionV0::default()) // since only v0 + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/mod.rs new file mode 100644 index 00000000000..dac79ad9e2e --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/mod.rs @@ -0,0 +1,29 @@ +pub mod v0_methods; + +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use bincode::{Decode, Encode}; +use derive_more::Display; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +mod property_names { + pub const AMOUNT: &str = "$amount"; +} +/// The Identifier fields in [`TokenBurnTransition`] +pub use super::super::document_base_transition::IDENTIFIER_FIELDS; + +#[derive(Debug, Clone, Default, Encode, Decode, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[display("Base: {base}, Amount: {burn_amount}")] +pub struct TokenBurnTransitionV0 { + /// Document Base Transition + #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] + pub base: TokenBaseTransition, + + /// How much should we burn + pub burn_amount: u64, +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..07029b9f14d --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/v0_methods.rs @@ -0,0 +1,33 @@ +use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::documents_batch_transition::token_burn_transition::TokenBurnTransitionV0; + +impl TokenBaseTransitionAccessors for TokenBurnTransitionV0 { + fn base(&self) -> &TokenBaseTransition { + &self.base + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + &mut self.base + } + + fn set_base(&mut self, base: TokenBaseTransition) { + self.base = base; + } +} + +pub trait TokenBurnTransitionV0Methods: TokenBaseTransitionAccessors { + fn burn_amount(&self) -> u64; + + fn set_burn_amount(&mut self, amount: u64); +} + +impl TokenBurnTransitionV0Methods for TokenBurnTransitionV0 { + fn burn_amount(&self) -> u64 { + self.burn_amount + } + + fn set_burn_amount(&mut self, amount: u64) { + self.burn_amount = amount; + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0_methods.rs new file mode 100644 index 00000000000..b2f46acc438 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0_methods.rs @@ -0,0 +1,38 @@ +use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::documents_batch_transition::token_burn_transition::TokenBurnTransition; +use crate::state_transition::documents_batch_transition::token_burn_transition::v0::v0_methods::TokenBurnTransitionV0Methods; + +impl TokenBaseTransitionAccessors for TokenBurnTransition { + fn base(&self) -> &TokenBaseTransition { + match self { + TokenBurnTransition::V0(v0) => &v0.base, + } + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + match self { + TokenBurnTransition::V0(v0) => &mut v0.base, + } + } + + fn set_base(&mut self, base: TokenBaseTransition) { + match self { + TokenBurnTransition::V0(v0) => v0.base = base, + } + } +} + +impl TokenBurnTransitionV0Methods for TokenBurnTransition { + fn burn_amount(&self) -> u64 { + match self { + TokenBurnTransition::V0(v0) => v0.burn_amount(), + } + } + + fn set_burn_amount(&mut self, burn_amount: u64) { + match self { + TokenBurnTransition::V0(v0) => v0.set_burn_amount(burn_amount), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs deleted file mode 100644 index 5cedcd97f15..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/convertible.rs +++ /dev/null @@ -1,145 +0,0 @@ -#[cfg(feature = "state-transition-json-conversion")] -use crate::data_contract::accessors::v0::DataContractV0Getters; -#[cfg(feature = "state-transition-json-conversion")] -use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; -#[cfg(any( - feature = "state-transition-json-conversion", - feature = "state-transition-value-conversion" -))] -use crate::prelude::DataContract; -#[cfg(feature = "state-transition-json-conversion")] -use crate::state_transition::data_contract_update_transition::IDENTIFIER_FIELDS; -#[cfg(any( - feature = "state-transition-json-conversion", - feature = "state-transition-value-conversion" -))] -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; -#[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::fields::property_names::STATE_TRANSITION_PROTOCOL_VERSION; -#[cfg(feature = "state-transition-json-conversion")] -use crate::state_transition::documents_batch_transition::token_issuance_transition::v0::BINARY_FIELDS; -#[cfg(any( - feature = "state-transition-json-conversion", - feature = "state-transition-value-conversion" -))] -use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransition; -#[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; -#[cfg(any( - feature = "state-transition-json-conversion", - feature = "state-transition-value-conversion" -))] -use crate::ProtocolError; -#[cfg(any( - feature = "state-transition-json-conversion", - feature = "state-transition-value-conversion" -))] -use platform_value::btreemap_extensions::{ - BTreeValueMapHelper, BTreeValueMapReplacementPathHelper, BTreeValueRemoveFromMapHelper, -}; -#[cfg(feature = "state-transition-json-conversion")] -use platform_value::ReplacementType; -#[cfg(any( - feature = "state-transition-json-conversion", - feature = "state-transition-value-conversion" -))] -use platform_value::Value; -#[cfg(feature = "state-transition-json-conversion")] -use serde_json::Value as JsonValue; -#[cfg(feature = "state-transition-value-conversion")] -use std::collections::BTreeMap; - -#[cfg(any( - feature = "state-transition-json-conversion", - feature = "state-transition-value-conversion" -))] -impl DocumentTransitionObjectLike for TokenIssuanceTransition { - #[cfg(feature = "state-transition-json-conversion")] - fn from_json_object( - json_value: JsonValue, - data_contract: DataContract, - ) -> Result { - let value: Value = json_value.into(); - let mut map = value - .into_btree_string_map() - .map_err(ProtocolError::ValueError)?; - - let document_type = map.get_str("$type")?; - - let document_type = data_contract.document_type_for_name(document_type)?; - - let mut identifiers_paths = document_type.identifier_paths().to_owned(); - - identifiers_paths.extend(IDENTIFIER_FIELDS.iter().map(|s| s.to_string())); - - let mut binary_paths = document_type.binary_paths().to_owned(); - - binary_paths.extend(BINARY_FIELDS.iter().map(|s| s.to_string())); - - map.replace_at_paths(binary_paths.iter(), ReplacementType::BinaryBytes)?; - - map.replace_at_paths(identifiers_paths.iter(), ReplacementType::Identifier)?; - let document = Self::from_value_map(map, data_contract)?; - - Ok(document) - } - - #[cfg(feature = "state-transition-value-conversion")] - fn from_object( - raw_transition: Value, - data_contract: DataContract, - ) -> Result { - let map = raw_transition - .into_btree_string_map() - .map_err(ProtocolError::ValueError)?; - Self::from_value_map(map, data_contract) - } - - #[cfg(feature = "state-transition-value-conversion")] - fn from_value_map( - mut map: BTreeMap, - data_contract: DataContract, - ) -> Result { - let version = map.remove_string(STATE_TRANSITION_PROTOCOL_VERSION)?; - match version.as_str() { - "0" => Ok(TokenIssuanceTransition::V0( - TokenIssuanceTransitionV0::from_value_map(map, data_contract)?, - )), - version => Err(ProtocolError::UnknownVersionMismatch { - method: "DocumentMethodV0::hash".to_string(), - known_versions: vec![0], - received: version.parse().map_err(|_| { - ProtocolError::Generic("received non string version".to_string()) - })?, - }), - } - } - - #[cfg(feature = "state-transition-value-conversion")] - fn to_object(&self) -> Result { - Ok(self.to_value_map()?.into()) - } - - #[cfg(feature = "state-transition-value-conversion")] - fn to_value_map(&self) -> Result, ProtocolError> { - match self { - TokenIssuanceTransition::V0(v0) => { - let mut value_map = v0.to_value_map()?; - value_map.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_owned(), "0".into()); - Ok(value_map) - } - } - } - - #[cfg(feature = "state-transition-json-conversion")] - fn to_json(&self) -> Result { - self.to_cleaned_object()? - .try_into() - .map_err(ProtocolError::ValueError) - } - - #[cfg(feature = "state-transition-value-conversion")] - fn to_cleaned_object(&self) -> Result { - Ok(self.to_value_map()?.into()) - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs index 6a88124d820..a82e5a3a6fe 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs @@ -1,4 +1,3 @@ -mod convertible; pub mod v0; mod v0_methods; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs index c8c2de608b2..11ab6dc928e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs @@ -25,6 +25,5 @@ pub struct TokenIssuanceTransitionV0 { pub base: TokenBaseTransition, /// How much should we issue - #[cfg_attr(feature = "state-transition-serde-conversion")] pub amount: u64, } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs index 98c36109ceb..755a7b2d876 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs @@ -12,8 +12,7 @@ pub use super::super::token_base_transition::IDENTIFIER_FIELDS; use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; mod property_names { - pub const REVISION: &str = "$revision"; - + pub const AMOUNT: &str = "$amount"; pub const RECIPIENT_OWNER_ID: &str = "recipientOwnerId"; } @@ -24,9 +23,9 @@ mod property_names { serde(rename_all = "camelCase") )] #[display( - "Base: {}, Revision: {}, Recipient: {:?}", + "Base: {}, Amount: {}, Recipient: {:?}", "base", - "revision", + "amount", "recipient_owner_id" )] pub struct TokenTransferTransitionV0 { @@ -34,9 +33,9 @@ pub struct TokenTransferTransitionV0 { pub base: TokenBaseTransition, #[cfg_attr( feature = "state-transition-serde-conversion", - serde(rename = "$revision") + serde(rename = "$amount") )] - pub revision: Revision, + pub amount: u64, #[cfg_attr( feature = "state-transition-serde-conversion", serde(rename = "recipientOwnerId") diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs index 7ab7a1c75c3..32d2a4eae06 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs @@ -1,7 +1,5 @@ use platform_value::Identifier; -use crate::prelude::Revision; - use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::TokenTransferTransitionV0; use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; @@ -22,10 +20,10 @@ impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { pub trait TokenTransferTransitionV0Methods: TokenBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. - fn revision(&self) -> Revision; + fn amount(&self) -> u64; /// Sets the value of the `revision` field in the `DocumentReplaceTransitionV0`. - fn set_revision(&mut self, revision: Revision); + fn set_amount(&mut self, amount: u64); /// Returns the `recipient_owner_id` field of the `DocumentReplaceTransitionV0`. fn recipient_owner_id(&self) -> Identifier; @@ -38,12 +36,12 @@ pub trait TokenTransferTransitionV0Methods: TokenBaseTransitionAccessors { } impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { - fn revision(&self) -> Revision { - self.revision + fn amount(&self) -> u64 { + self.amount } - fn set_revision(&mut self, revision: Revision) { - self.revision = revision; + fn set_amount(&mut self, amount: u64) { + self.amount = amount; } fn recipient_owner_id(&self) -> Identifier { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs index bdb827b76de..eb720839121 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs @@ -26,15 +26,15 @@ impl TokenBaseTransitionAccessors for TokenTransferTransition { } impl TokenTransferTransitionV0Methods for TokenTransferTransition { - fn revision(&self) -> Revision { + fn amount(&self) -> u64 { match self { - TokenTransferTransition::V0(v0) => v0.revision, + TokenTransferTransition::V0(v0) => v0.amount, } } - fn set_revision(&mut self, revision: Revision) { + fn set_amount(&mut self, amount: u64) { match self { - TokenTransferTransition::V0(v0) => v0.revision = revision, + TokenTransferTransition::V0(v0) => v0.amount = amount, } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs index f5e7c2193ab..119e2df6b25 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs @@ -17,6 +17,7 @@ pub use self::document_transition::{ document_delete_transition::DocumentDeleteTransition, document_replace_transition, document_replace_transition::DocumentReplaceTransition, token_base_transition, token_issuance_transition, token_issuance_transition::TokenIssuanceTransition, + token_burn_transition, token_burn_transition::TokenBurnTransition, token_transfer_transition, token_transfer_transition::TokenTransferTransition, }; From cf32dd538667a3dee4c96a230e8fcd74d06339d9 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 5 Dec 2024 11:40:08 +0300 Subject: [PATCH 07/61] more work on tokens --- .../meta_schemas/token/v0/token-meta.json | 0 .../schema/enrich_with_base_schema/v0/mod.rs | 3 + .../document_transition/mod.rs | 2 +- .../documents_batch_transition/mod.rs | 6 +- packages/rs-drive/src/drive/mod.rs | 1 + .../rs-drive/src/drive/tokens/balance/mod.rs | 5 + .../src/drive/tokens/balance/prove.rs | 150 +++ .../src/drive/tokens/balance/queries.rs | 73 ++ .../src/drive/tokens/balance/update.rs | 896 ++++++++++++++++++ packages/rs-drive/src/drive/tokens/mod.rs | 30 + .../tokens/token-example-contract.json | 23 + 11 files changed, 1185 insertions(+), 4 deletions(-) create mode 100644 packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json create mode 100644 packages/rs-drive/src/drive/tokens/balance/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/prove.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/queries.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/update.rs create mode 100644 packages/rs-drive/src/drive/tokens/mod.rs create mode 100644 packages/rs-drive/tests/supporting_files/contract/tokens/token-example-contract.json diff --git a/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json b/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs index 3560e2b9308..80ccb05111f 100644 --- a/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs @@ -6,6 +6,9 @@ use platform_value::{Value, ValueMapHelper}; pub const DATA_CONTRACT_SCHEMA_URI_V0: &str = "https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json"; +pub const TOKEN_SCHEMA_URI_V0: &str = + "https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/token-meta.json"; + pub const PROPERTY_SCHEMA: &str = "$schema"; const SYSTEM_GENERATED_FIELDS: [&str; 9] = [ diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs index 24f4b2d5204..39bcbc1da4c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs @@ -17,9 +17,9 @@ pub mod document_replace_transition; pub mod document_transfer_transition; pub mod document_update_price_transition; pub mod token_base_transition; +pub mod token_burn_transition; pub mod token_issuance_transition; pub mod token_transfer_transition; -pub mod token_burn_transition; use crate::prelude::Revision; use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs index 119e2df6b25..8c7a1891458 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs @@ -16,9 +16,9 @@ pub use self::document_transition::{ document_create_transition::DocumentCreateTransition, document_delete_transition, document_delete_transition::DocumentDeleteTransition, document_replace_transition, document_replace_transition::DocumentReplaceTransition, token_base_transition, - token_issuance_transition, token_issuance_transition::TokenIssuanceTransition, - token_burn_transition, token_burn_transition::TokenBurnTransition, - token_transfer_transition, token_transfer_transition::TokenTransferTransition, + token_burn_transition, token_burn_transition::TokenBurnTransition, token_issuance_transition, + token_issuance_transition::TokenIssuanceTransition, token_transfer_transition, + token_transfer_transition::TokenTransferTransition, }; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize, PlatformSignable}; diff --git a/packages/rs-drive/src/drive/mod.rs b/packages/rs-drive/src/drive/mod.rs index fc28c49647a..5b28351f547 100644 --- a/packages/rs-drive/src/drive/mod.rs +++ b/packages/rs-drive/src/drive/mod.rs @@ -50,6 +50,7 @@ pub mod votes; #[cfg(feature = "server")] mod shared; +mod tokens; #[cfg(feature = "server")] use crate::cache::DriveCache; diff --git a/packages/rs-drive/src/drive/tokens/balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/mod.rs new file mode 100644 index 00000000000..d76e8051c89 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/mod.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "server")] +mod prove; +mod queries; +#[cfg(feature = "server")] +mod update; diff --git a/packages/rs-drive/src/drive/tokens/balance/prove.rs b/packages/rs-drive/src/drive/tokens/balance/prove.rs new file mode 100644 index 00000000000..68c386465bb --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/prove.rs @@ -0,0 +1,150 @@ +use crate::drive::Drive; +use crate::error::Error; + +use dpp::version::drive_versions::DriveVersion; + +use grovedb::TransactionArg; + +impl Drive { + /// Proves an Identity's token balance from the backing store + pub fn prove_identity_token_balance( + &self, + identity_id: [u8; 32], + token_id: [u8; 32], + transaction: TransactionArg, + drive_version: &DriveVersion, + ) -> Result, Error> { + let balance_query = Self::token_balance_for_identity_id_query(token_id, identity_id); + self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) + } + + /// Proves multiple Identity token balances from the backing store + pub fn prove_many_identity_token_balances( + &self, + identity_ids: &[[u8; 32]], + token_id: [u8; 32], + transaction: TransactionArg, + drive_version: &DriveVersion, + ) -> Result, Error> { + let balance_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids); + self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) + } + + /// Proves multiple Identity balances from the backing store by range + pub fn prove_many_identity_token_balances_by_range( + &self, + start_at: Option<([u8; 32], bool)>, + ascending: bool, + limit: u16, + transaction: TransactionArg, + drive_version: &DriveVersion, + ) -> Result, Error> { + let balance_query = Self::balances_for_range_query(start_at, ascending, limit); + self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; + use dpp::block::block_info::BlockInfo; + use dpp::identity::Identity; + + mod prove_identity_balance { + use super::*; + use dpp::identity::accessors::IdentityGettersV0; + use dpp::version::PlatformVersion; + + #[test] + fn should_prove_a_single_identity_balance() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::first(); + + let identity = Identity::random_identity(3, Some(14), platform_version) + .expect("expected a platform identity"); + + let identity_id = identity.id().to_buffer(); + drive + .add_new_identity( + identity.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + let proof = drive + .prove_identity_balance(identity.id().to_buffer(), None, &platform_version.drive) + .expect("should not error when proving an identity"); + + let (_, proved_identity_balance) = Drive::verify_identity_balance_for_identity_id( + proof.as_slice(), + identity_id, + false, + platform_version, + ) + .expect("expect that this be verified"); + + assert_eq!(proved_identity_balance, Some(identity.balance())); + } + } + + mod prove_many_identity_balances { + use super::*; + use dpp::fee::Credits; + use dpp::identity::accessors::IdentityGettersV0; + use platform_version::version::PlatformVersion; + use std::collections::BTreeMap; + + #[test] + fn should_prove_multiple_identity_balances() { + let drive = setup_drive_with_initial_state_structure(None); + let platform_version = PlatformVersion::latest(); + let identities: BTreeMap<[u8; 32], Identity> = + Identity::random_identities(10, 3, Some(14), platform_version) + .expect("expected to get random identities") + .into_iter() + .map(|identity| (identity.id().to_buffer(), identity)) + .collect(); + + for identity in identities.values() { + drive + .add_new_identity( + identity.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + } + let identity_ids = identities.keys().copied().collect::>(); + let identity_balances = identities + .into_iter() + .map(|(id, identity)| (id, Some(identity.balance()))) + .collect::>>(); + let proof = drive + .prove_many_identity_balances( + identity_ids.as_slice(), + None, + &platform_version.drive, + ) + .expect("should not error when proving an identity"); + + let (_, proved_identity_balances): ([u8; 32], BTreeMap<[u8; 32], Option>) = + Drive::verify_identity_balances_for_identity_ids( + proof.as_slice(), + false, + identity_ids.as_slice(), + platform_version, + ) + .expect("expect that this be verified"); + + assert_eq!(proved_identity_balances, identity_balances); + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/queries.rs b/packages/rs-drive/src/drive/tokens/balance/queries.rs new file mode 100644 index 00000000000..d800225ad94 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/queries.rs @@ -0,0 +1,73 @@ +use crate::drive::balances::balance_path_vec; +use crate::drive::tokens::token_balances_path_vec; +use crate::drive::Drive; +use crate::query::{Query, QueryItem}; +use grovedb::{PathQuery, SizedQuery}; +use std::ops::RangeFull; + +impl Drive { + /// The query for proving the identities balance of a token from an identity id. + pub fn token_balance_for_identity_id_query( + token_id: [u8; 32], + identity_id: [u8; 32], + ) -> PathQuery { + let balance_path = token_balances_path_vec(token_id); + PathQuery::new_single_key(balance_path, identity_id.to_vec()) + } + + /// The query getting a token balance for many identities + pub fn token_balances_for_identity_ids_query( + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + ) -> PathQuery { + let balance_path = token_balances_path_vec(token_id); + let mut query = Query::new(); + query.insert_keys(identity_ids.iter().map(|key| key.to_vec()).collect()); + PathQuery { + path: balance_path, + query: SizedQuery { + query, + limit: None, + offset: None, + }, + } + } + + /// The query getting token balances for identities in a range + pub fn token_balances_for_range_query( + token_id: [u8; 32], + start_at: Option<([u8; 32], bool)>, + ascending: bool, + limit: u16, + ) -> PathQuery { + let balance_path = token_balances_path_vec(token_id); + let mut query = Query::new_with_direction(ascending); + if ascending { + if let Some((start_at, start_at_included)) = start_at { + if start_at_included { + query.insert_item(QueryItem::RangeFrom(start_at.to_vec()..)) + } else { + query.insert_item(QueryItem::RangeAfter(start_at.to_vec()..)) + } + } else { + query.insert_item(QueryItem::RangeFull(RangeFull)) + } + } else if let Some((start_at, start_at_included)) = start_at { + if start_at_included { + query.insert_item(QueryItem::RangeToInclusive(..=start_at.to_vec())) + } else { + query.insert_item(QueryItem::RangeTo(..start_at.to_vec())) + } + } else { + query.insert_item(QueryItem::RangeFull(RangeFull)) + } + PathQuery { + path: balance_path, + query: SizedQuery { + query, + limit: Some(limit), + offset: None, + }, + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/update.rs b/packages/rs-drive/src/drive/tokens/balance/update.rs new file mode 100644 index 00000000000..dc7c94e3e76 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/update.rs @@ -0,0 +1,896 @@ +#[cfg(test)] +mod tests { + + use dpp::prelude::*; + + use crate::error::drive::DriveError; + use crate::error::Error; + use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; + use crate::util::test_helpers::test_utils::identities::create_test_identity; + use dpp::block::epoch::Epoch; + use dpp::identity::accessors::IdentityGettersV0; + + mod add_to_identity_balance { + use dpp::block::block_info::BlockInfo; + use dpp::fee::fee_result::FeeResult; + use dpp::identity::accessors::IdentityGettersV0; + use dpp::version::PlatformVersion; + + use crate::fees::op::LowLevelDriveOperation; + + use super::*; + + #[test] + fn should_add_to_balance() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = Identity::random_identity(5, Some(12345), platform_version) + .expect("expected a random identity"); + + let old_balance = identity.balance(); + + let block_info = BlockInfo::default_with_epoch(Epoch::new(0).unwrap()); + + drive + .add_new_identity( + identity.clone(), + false, + &block_info, + true, + None, + platform_version, + ) + .expect("expected to insert identity"); + + let db_transaction = drive.grove.start_transaction(); + + let amount = 300; + + let fee_result = drive + .add_to_identity_balance( + identity.id().to_buffer(), + amount, + &block_info, + true, + Some(&db_transaction), + platform_version, + ) + .expect("expected to add to identity balance"); + + assert_eq!( + fee_result, + FeeResult { + processing_fee: 174660, + removed_bytes_from_system: 0, + ..Default::default() + } + ); + + drive + .grove + .commit_transaction(db_transaction) + .unwrap() + .expect("expected to be able to commit a transaction"); + + let (balance, _fee_cost) = drive + .fetch_identity_balance_with_costs( + identity.id().to_buffer(), + &block_info, + true, + None, + platform_version, + ) + .expect("expected to get balance"); + + assert_eq!(balance.unwrap(), old_balance + amount); + } + + #[test] + fn should_fail_if_balance_is_not_persisted() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let block_info = BlockInfo::default_with_epoch(Epoch::new(0).unwrap()); + + let result = drive.add_to_identity_balance( + [0; 32], + 300, + &block_info, + true, + None, + platform_version, + ); + + assert!( + matches!(result, Err(Error::Drive(DriveError::CorruptedCodeExecution(m))) if m == "there should always be a balance") + ); + } + + #[test] + fn should_deduct_from_debt_if_balance_is_nil() { + let drive = setup_drive_with_initial_state_structure(None); + let platform_version = PlatformVersion::latest(); + + let identity = create_test_identity(&drive, [0; 32], Some(1), None, platform_version) + .expect("expected an identity"); + + let added_balance = 300; + let negative_amount = 100; + + // Persist negative balance + let batch = vec![drive + .update_identity_negative_credit_operation( + identity.id().to_buffer(), + negative_amount, + platform_version, + ) + .expect("expected to get an update_identity_negative_credit_operation")]; + + let mut drive_operations: Vec = vec![]; + drive + .apply_batch_low_level_drive_operations( + None, + None, + batch, + &mut drive_operations, + &platform_version.drive, + ) + .expect("should apply batch"); + + let block_info = BlockInfo::default(); + + let fee_result = drive + .add_to_identity_balance( + identity.id().to_buffer(), + added_balance, + &block_info, + true, + None, + platform_version, + ) + .expect("expected to add to identity balance"); + + assert_eq!( + fee_result, + FeeResult { + storage_fee: 0, + processing_fee: 385160, + removed_bytes_from_system: 0, + ..Default::default() + } + ); + + let (updated_balance, _fee_cost) = drive + .fetch_identity_balance_with_costs( + identity.id().to_buffer(), + &block_info, + true, + None, + platform_version, + ) + .expect("expected to get balance"); + + assert_eq!( + updated_balance.expect("balance should present"), + added_balance - negative_amount + ); + + let updated_negative_balance = drive + .fetch_identity_negative_balance_operations( + identity.id().to_buffer(), + true, + None, + &mut drive_operations, + platform_version, + ) + .expect("expected to get balance") + .expect("balance should present"); + + assert_eq!(updated_negative_balance, 0) + } + + #[test] + fn should_keep_nil_balance_and_reduce_debt_if_added_balance_is_lower() { + let drive = setup_drive_with_initial_state_structure(None); + let platform_version = PlatformVersion::latest(); + let identity = create_test_identity(&drive, [0; 32], Some(1), None, platform_version) + .expect("expected an identity"); + + let added_balance = 50; + let negative_amount = 100; + + // Persist negative balance + let batch = vec![drive + .update_identity_negative_credit_operation( + identity.id().to_buffer(), + negative_amount, + platform_version, + ) + .expect("expected to get an update_identity_negative_credit_operation")]; + + let mut drive_operations: Vec = vec![]; + drive + .apply_batch_low_level_drive_operations( + None, + None, + batch, + &mut drive_operations, + &platform_version.drive, + ) + .expect("should apply batch"); + + let block_info = BlockInfo::default(); + + let fee_result = drive + .add_to_identity_balance( + identity.id().to_buffer(), + added_balance, + &block_info, + true, + None, + platform_version, + ) + .expect("expected to add to identity balance"); + + assert_eq!( + fee_result, + FeeResult { + storage_fee: 0, + processing_fee: 260540, + removed_bytes_from_system: 0, + ..Default::default() + } + ); + + let (updated_balance, _fee_cost) = drive + .fetch_identity_balance_with_costs( + identity.id().to_buffer(), + &block_info, + true, + None, + platform_version, + ) + .expect("expected to get balance"); + + assert_eq!(updated_balance.expect("balance should present"), 0); + + let updated_negative_balance = drive + .fetch_identity_negative_balance_operations( + identity.id().to_buffer(), + true, + None, + &mut drive_operations, + platform_version, + ) + .expect("expected to get balance") + .expect("balance should present"); + + assert_eq!(updated_negative_balance, negative_amount - added_balance) + } + + #[test] + fn should_estimate_costs_without_state() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = Identity::random_identity(5, Some(12345), platform_version) + .expect("expected a random identity"); + + let block = BlockInfo::default_with_epoch(Epoch::new(0).unwrap()); + + let app_hash_before = drive + .grove + .root_hash(None, &platform_version.drive.grove_version) + .unwrap() + .expect("should return app hash"); + + let fee_result = drive + .add_to_identity_balance( + identity.id().to_buffer(), + 300, + &block, + false, + None, + platform_version, + ) + .expect("expected to get estimated costs to update an identity balance"); + + assert_eq!( + fee_result, + FeeResult { + processing_fee: 4278840, + ..Default::default() + } + ); + + let app_hash_after = drive + .grove + .root_hash(None, &platform_version.drive.grove_version) + .unwrap() + .expect("should return app hash"); + + assert_eq!(app_hash_after, app_hash_before); + + let (balance, _fee_cost) = drive + .fetch_identity_balance_with_costs( + identity.id().to_buffer(), + &block, + true, + None, + platform_version, + ) + .expect("expected to get balance"); + + assert!(balance.is_none()); //shouldn't have changed + } + } + + mod remove_from_identity_balance { + use super::*; + use dpp::block::block_info::BlockInfo; + use dpp::fee::fee_result::FeeResult; + use dpp::version::PlatformVersion; + + #[test] + fn should_remove_from_balance() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = Identity::random_identity(5, Some(12345), platform_version) + .expect("expected a random identity"); + + let old_balance = identity.balance(); + + let block = BlockInfo::default_with_epoch(Epoch::new(0).unwrap()); + + drive + .add_new_identity( + identity.clone(), + false, + &block, + true, + None, + platform_version, + ) + .expect("expected to insert identity"); + + let db_transaction = drive.grove.start_transaction(); + + let amount = 10; + + let fee_result = drive + .remove_from_identity_balance( + identity.id().to_buffer(), + amount, + &block, + true, + Some(&db_transaction), + platform_version, + None, + ) + .expect("expected to add to identity balance"); + + assert_eq!( + fee_result, + FeeResult { + processing_fee: 174660, + removed_bytes_from_system: 0, + ..Default::default() + } + ); + + drive + .grove + .commit_transaction(db_transaction) + .unwrap() + .expect("expected to be able to commit a transaction"); + + let (balance, _fee_cost) = drive + .fetch_identity_balance_with_costs( + identity.id().to_buffer(), + &block, + true, + None, + platform_version, + ) + .expect("expected to get balance"); + + assert_eq!(balance.unwrap(), old_balance - amount); + } + + #[test] + fn should_estimated_costs_without_state() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = Identity::random_identity(5, Some(12345), platform_version) + .expect("expected a random identity"); + + let block = BlockInfo::default_with_epoch(Epoch::new(0).unwrap()); + + let app_hash_before = drive + .grove + .root_hash(None, &platform_version.drive.grove_version) + .unwrap() + .expect("should return app hash"); + + let amount = 10; + + let fee_result = drive + .remove_from_identity_balance( + identity.id().to_buffer(), + amount, + &block, + false, + None, + platform_version, + None, + ) + .expect("expected to add to identity balance"); + + let app_hash_after = drive + .grove + .root_hash(None, &platform_version.drive.grove_version) + .unwrap() + .expect("should return app hash"); + + assert_eq!(app_hash_after, app_hash_before); + + assert_eq!( + fee_result, + FeeResult { + processing_fee: 2476860, + ..Default::default() + } + ); + + let (balance, _fee_cost) = drive + .fetch_identity_balance_with_costs( + identity.id().to_buffer(), + &block, + true, + None, + platform_version, + ) + .expect("expected to get balance"); + + assert!(balance.is_none()); //shouldn't have changed + } + } + + mod apply_balance_change_from_fee_to_identity_operations { + use super::*; + use crate::error::identity::IdentityError; + use crate::fees::op::LowLevelDriveOperation; + use dpp::block::block_info::BlockInfo; + use dpp::fee::epoch::{CreditsPerEpoch, GENESIS_EPOCH_INDEX}; + use dpp::fee::fee_result::refunds::{CreditsPerEpochByIdentifier, FeeRefunds}; + use dpp::fee::fee_result::FeeResult; + use dpp::fee::{Credits, SignedCredits}; + use dpp::version::PlatformVersion; + use grovedb::batch::GroveOp; + use grovedb::Element; + use nohash_hasher::IntMap; + use std::collections::BTreeMap; + + #[test] + fn should_do_nothing_if_there_is_no_balance_change() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = create_test_identity(&drive, [0; 32], Some(15), None, platform_version) + .expect("expected to create an identity"); + + let fee_result = FeeResult::default_with_fees(0, 0); + let fee_change = fee_result.clone().into_balance_change(identity.id()); + + let (drive_operations, fee_result_outcome) = drive + .apply_balance_change_from_fee_to_identity_operations( + fee_change, + None, + platform_version, + ) + .expect("should apply fee change"); + + assert_eq!(drive_operations.len(), 0); + assert_eq!(fee_result_outcome, fee_result); + } + + #[test] + fn should_add_to_balance() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = create_test_identity(&drive, [0; 32], Some(15), None, platform_version) + .expect("expected to create an identity"); + let other_identity = + create_test_identity(&drive, [1; 32], Some(16), None, platform_version) + .expect("expected to create an identity"); + + let removed_credits = 100000; + let other_removed_credits = 200000; + + let credits_per_epoch: CreditsPerEpoch = + IntMap::from_iter([(GENESIS_EPOCH_INDEX, removed_credits)]); + + let other_credits_per_epoch: CreditsPerEpoch = + IntMap::from_iter([(GENESIS_EPOCH_INDEX, other_removed_credits)]); + + let refunds_per_epoch_by_identifier: CreditsPerEpochByIdentifier = + BTreeMap::from_iter([ + (identity.id().to_buffer(), credits_per_epoch), + (other_identity.id().to_buffer(), other_credits_per_epoch), + ]); + + let fee_result = FeeResult { + fee_refunds: FeeRefunds(refunds_per_epoch_by_identifier), + ..Default::default() + }; + let fee_change = fee_result.clone().into_balance_change(identity.id()); + + let (drive_operations, fee_result_outcome) = drive + .apply_balance_change_from_fee_to_identity_operations( + fee_change, + None, + platform_version, + ) + .expect("should apply fee change"); + + assert!(matches!( + drive_operations[..], + [ + _, + _, + LowLevelDriveOperation::GroveOperation(grovedb::batch::QualifiedGroveDbOp { + op: GroveOp::Replace { + element: Element::SumItem(refund_amount, None), + }, + .. + }), + .., + LowLevelDriveOperation::GroveOperation(grovedb::batch::QualifiedGroveDbOp { + op: GroveOp::Replace { + element: Element::SumItem(other_refund_amount, None), + }, + .. + }) + ] if refund_amount as Credits == removed_credits && other_refund_amount as Credits == other_removed_credits + )); + + assert_eq!(fee_result_outcome, fee_result); + } + + #[test] + fn should_fail_if_balance_is_not_persisted() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let fee_result = FeeResult::default_with_fees(100000, 100); + let fee_change = fee_result.into_balance_change([0; 32].into()); + + let result = drive.apply_balance_change_from_fee_to_identity_operations( + fee_change, + None, + platform_version, + ); + + assert!( + matches!(result, Err(Error::Drive(DriveError::CorruptedCodeExecution(m))) if m == "there should always be a balance if apply is set to true") + ); + } + + #[test] + fn should_deduct_from_debt_if_balance_is_nil() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let removed_credits = 10000; + let negative_amount = 1000; + + let identity = create_test_identity(&drive, [0; 32], Some(15), None, platform_version) + .expect("expected to create an identity"); + + // Persist negative balance + let batch = vec![drive + .update_identity_negative_credit_operation( + identity.id().to_buffer(), + negative_amount, + platform_version, + ) + .expect("expected to get an update_identity_negative_credit_operation")]; + + let mut drive_operations: Vec = vec![]; + drive + .apply_batch_low_level_drive_operations( + None, + None, + batch, + &mut drive_operations, + &platform_version.drive, + ) + .expect("should apply batch"); + + let credits_per_epoch: CreditsPerEpoch = + IntMap::from_iter([(GENESIS_EPOCH_INDEX, removed_credits)]); + + let refunds_per_epoch_by_identifier: CreditsPerEpochByIdentifier = + BTreeMap::from_iter([(identity.id().to_buffer(), credits_per_epoch)]); + + let fee_result = FeeResult { + fee_refunds: FeeRefunds(refunds_per_epoch_by_identifier), + ..Default::default() + }; + let fee_change = fee_result.clone().into_balance_change(identity.id()); + + let (drive_operations, fee_result_outcome) = drive + .apply_balance_change_from_fee_to_identity_operations( + fee_change, + None, + platform_version, + ) + .expect("should apply fee change"); + + assert!(matches!( + &drive_operations[..], + [ + _, + _, + LowLevelDriveOperation::GroveOperation(grovedb::batch::QualifiedGroveDbOp { + op: GroveOp::Replace { + element: Element::SumItem(refund_amount, None), + }, + .. + }), + LowLevelDriveOperation::GroveOperation(grovedb::batch::QualifiedGroveDbOp { + op: GroveOp::Replace { + element: Element::Item(debt_bytes, None), + }, + .. + }) + ] if *refund_amount as Credits == removed_credits - negative_amount && debt_bytes == &0u64.to_be_bytes() + )); + + assert_eq!(fee_result_outcome, fee_result); + } + + #[test] + fn should_keep_nil_balance_and_reduce_debt_if_added_balance_is_lower() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let removed_credits = 1000; + let negative_amount = 3000; + + let identity = create_test_identity(&drive, [0; 32], Some(15), None, platform_version) + .expect("expected to create an identity"); + + // Persist negative balance + let batch = vec![drive + .update_identity_negative_credit_operation( + identity.id().to_buffer(), + negative_amount, + platform_version, + ) + .expect("expected to get an update_identity_negative_credit_operation")]; + + let mut drive_operations: Vec = vec![]; + drive + .apply_batch_low_level_drive_operations( + None, + None, + batch, + &mut drive_operations, + &platform_version.drive, + ) + .expect("should apply batch"); + + let credits_per_epoch: CreditsPerEpoch = + IntMap::from_iter([(GENESIS_EPOCH_INDEX, removed_credits)]); + + let refunds_per_epoch_by_identifier: CreditsPerEpochByIdentifier = + BTreeMap::from_iter([(identity.id().to_buffer(), credits_per_epoch)]); + + let fee_result = FeeResult { + fee_refunds: FeeRefunds(refunds_per_epoch_by_identifier), + ..Default::default() + }; + let fee_change = fee_result.clone().into_balance_change(identity.id()); + + let (drive_operations, fee_result_outcome) = drive + .apply_balance_change_from_fee_to_identity_operations( + fee_change, + None, + platform_version, + ) + .expect("should apply fee change"); + + assert!(matches!( + &drive_operations[..], + [ + _, + _, + LowLevelDriveOperation::GroveOperation(grovedb::batch::QualifiedGroveDbOp { + op: GroveOp::Replace { + element: Element::Item(debt_bytes, None), + }, + .. + }) + ] if debt_bytes == &2000u64.to_be_bytes() + )); + + assert_eq!(fee_result_outcome, fee_result); + } + + #[test] + fn should_remove_from_balance_less_amount() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = create_test_identity(&drive, [0; 32], Some(15), None, platform_version) + .expect("expected to create an identity"); + + let initial_balance = 100; + + drive + .add_to_identity_balance( + identity.id().to_buffer(), + initial_balance, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("should set initial balance"); + + let processing_fee = 20; + let storage_fee = 10; + + let fee_result = FeeResult { + processing_fee, + storage_fee, + ..Default::default() + }; + + let fee_change = fee_result.clone().into_balance_change(identity.id()); + + let (drive_operations, fee_result_outcome) = drive + .apply_balance_change_from_fee_to_identity_operations( + fee_change, + None, + platform_version, + ) + .expect("should apply fee change"); + + assert!(matches!( + drive_operations[..], + [_, LowLevelDriveOperation::GroveOperation(grovedb::batch::QualifiedGroveDbOp { + op: GroveOp::Replace { + element: Element::SumItem(balance, None), + }, + .. + })] if balance == (initial_balance - storage_fee - processing_fee) as SignedCredits + )); + + assert_eq!(fee_result_outcome, fee_result); + } + + #[test] + fn should_remove_from_balance_bigger_amount_and_get_into_debt() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = create_test_identity(&drive, [0; 32], Some(15), None, platform_version) + .expect("expected to create an identity"); + + let initial_balance = 100; + + drive + .add_to_identity_balance( + identity.id().to_buffer(), + initial_balance, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("should set initial balance"); + + let processing_fee = 110; + let storage_fee = 80; + + let fee_result = FeeResult { + processing_fee, + storage_fee, + ..Default::default() + }; + + let fee_change = fee_result.into_balance_change(identity.id()); + + let (drive_operations, fee_result_outcome) = drive + .apply_balance_change_from_fee_to_identity_operations( + fee_change, + None, + platform_version, + ) + .expect("should apply fee change"); + + let expected_debt_bytes = + (storage_fee + processing_fee - initial_balance).to_be_bytes(); + + assert!(matches!( + &drive_operations[..], + [ + _, + LowLevelDriveOperation::GroveOperation(grovedb::batch::QualifiedGroveDbOp { + op: GroveOp::Replace { + element: Element::SumItem(balance, None), + }, + .. + }), + LowLevelDriveOperation::GroveOperation(grovedb::batch::QualifiedGroveDbOp { + op: GroveOp::Replace { + element: Element::Item(debt_bytes, None), + }, + .. + }) + ] if balance == &(0 as SignedCredits) && debt_bytes == &expected_debt_bytes + )); + + assert_eq!( + fee_result_outcome, + FeeResult { + storage_fee, + processing_fee: initial_balance - storage_fee, + ..Default::default() + } + ); + } + + #[test] + fn should_return_error_if_required_amount_bigger_than_balance() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = create_test_identity(&drive, [0; 32], Some(15), None, platform_version) + .expect("expected to create an identity"); + + let processing_fee = 110; + let storage_fee = 80; + + let fee_result = FeeResult { + processing_fee, + storage_fee, + ..Default::default() + }; + + let fee_change = fee_result.into_balance_change(identity.id()); + + let result = drive.apply_balance_change_from_fee_to_identity_operations( + fee_change, + None, + platform_version, + ); + + assert!(matches!( + result, + Err(Error::Identity(IdentityError::IdentityInsufficientBalance( + _ + ))) + )); + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs new file mode 100644 index 00000000000..d2c81784557 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -0,0 +1,30 @@ +use crate::drive::RootTree; + +mod balance; + +/// The path for the balances tree +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn token_balances_root_path() -> [&'static [u8]; 1] { + [Into::<&[u8; 1]>::into(RootTree::TokenBalances)] +} + +/// The path for the balances tree +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn token_balances_root_path_vec() -> Vec> { + vec![Into::<&[u8; 1]>::into(RootTree::TokenBalances).to_vec()] +} + +/// The path for the balances tree +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn token_balances_path(token_id: &[u8; 32]) -> [&[u8]; 2] { + [ + Into::<&[u8; 1]>::into(RootTree::DataContractDocuments), + token_id, + ] +} + +/// The path for the balances tree +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn token_balances_path_vec(token_id: [u8; 32]) -> Vec> { + vec![vec![RootTree::TokenBalances as u8], token_id.to_vec()] +} diff --git a/packages/rs-drive/tests/supporting_files/contract/tokens/token-example-contract.json b/packages/rs-drive/tests/supporting_files/contract/tokens/token-example-contract.json new file mode 100644 index 00000000000..2a47ff22bc3 --- /dev/null +++ b/packages/rs-drive/tests/supporting_files/contract/tokens/token-example-contract.json @@ -0,0 +1,23 @@ +{ + "$format_version": "0", + "id": "AcYUCSvAmUwryNsQqkqqD1o3BnFuzepGtR3Mhh2swLk6", + "ownerId": "HLfavpy1B2mVHnpYYDKDVM76eWJRqvPfuuASy7cyJBXC", + "version": 1, + "tokens": { + "flurgon": { + "shouldCapitalize": true, + "pluralForm": "flurgons", + "maintainer": "GQcEb4CaXEXtPUpnJyHUt78jDij6etgEXUKyect7ZRSm", + "initialSupply": 100000000000, + "decimals": 8, + "transferable": true, + "maxSupply": 100000000000, + "roles": { + "maintainer": { + "canMint": true, + "canBurn": true + } + } + } + } +} From 71218a44627387d96049141dc49a2fed761438f3 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 10 Dec 2024 00:20:07 +0300 Subject: [PATCH 08/61] more work --- .../src/document/document_factory/mod.rs | 2 +- .../src/document/document_factory/v0/mod.rs | 2 +- .../specialized_document_factory/mod.rs | 2 +- .../specialized_document_factory/v0/mod.rs | 2 +- .../src/state_transition/serialization.rs | 2 +- ....rs => document_transition_action_type.rs} | 2 +- .../document_transition_methods/mod.rs | 0 .../document_transition/mod.rs | 179 ++++++++++++++---- .../token_transition_action_type.rs | 39 ++++ .../get_document_transitions_fixture.rs | 2 +- .../documents_batch/data_triggers/executor.rs | 2 +- .../data_triggers/triggers/dashpay/v0/mod.rs | 6 +- .../data_triggers/triggers/dpns/v0/mod.rs | 4 +- .../documents_batch/transformer/v0/mod.rs | 4 +- .../src/drive/tokens/balance/prove.rs | 29 ++- .../create_token_root_tree/mod.rs | 114 +++++++++++ .../create_token_root_tree/v0/mod.rs | 136 +++++++++++++ .../src/drive/tokens/initialization/mod.rs | 1 + packages/rs-drive/src/drive/tokens/mod.rs | 1 + .../transformer.rs | 4 +- .../transformer.rs | 4 +- .../v0/transformer.rs | 4 +- .../transformer.rs | 4 +- .../v0/transformer.rs | 4 +- .../v0/transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../document_transition_action_type.rs | 22 +++ .../v0/transformer.rs | 2 +- .../document_transition/mod.rs | 49 ++++- .../token_base_transition_action/mod.rs | 60 ++++++ .../transformer.rs | 35 ++++ .../token_base_transition_action/v0/mod.rs | 68 +++++++ .../v0/transformer.rs | 50 +++++ .../token_burn_transition_action/mod.rs | 76 ++++++++ .../transformer.rs | 64 +++++++ .../token_burn_transition_action/v0/mod.rs | 44 +++++ .../v0/transformer.rs | 65 +++++++ .../token_issuance_transition_action/mod.rs | 76 ++++++++ .../transformer.rs | 64 +++++++ .../v0/mod.rs | 44 +++++ .../v0/transformer.rs | 65 +++++++ .../token_transfer_transition_action/mod.rs | 95 ++++++++++ .../transformer.rs | 62 ++++++ .../v0/mod.rs | 78 ++++++++ .../v0/transformer.rs | 52 +++++ ...ype.rs => token_transition_action_type.rs} | 0 .../drive_identity_method_versions/mod.rs | 22 +++ .../src/version/drive_versions/mod.rs | 2 + .../errors/invalid_document_action_error.rs | 2 +- packages/wasm-dpp/src/document/factory.rs | 2 +- .../document_transition/mod.rs | 2 +- 52 files changed, 1577 insertions(+), 79 deletions(-) rename packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/{action_type.rs => document_transition_action_type.rs} (94%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_methods/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs create mode 100644 packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/initialization/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs rename packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/{action_type.rs => token_transition_action_type.rs} (100%) diff --git a/packages/rs-dpp/src/document/document_factory/mod.rs b/packages/rs-dpp/src/document/document_factory/mod.rs index 75db720fd59..ab09444cbe1 100644 --- a/packages/rs-dpp/src/document/document_factory/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/mod.rs @@ -14,7 +14,7 @@ use crate::document::Document; use crate::document::ExtendedDocument; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ - document_transition::action_type::DocumentTransitionActionType, DocumentsBatchTransition, + document_transition::document_transition_action_type::DocumentTransitionActionType, DocumentsBatchTransition, }; use crate::util::entropy_generator::EntropyGenerator; pub use v0::DocumentFactoryV0; diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index 58fc96de91a..c16547b1990 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -26,7 +26,7 @@ use crate::prelude::{BlockHeight, CoreBlockHeight, TimestampMillis}; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ document_transition::{ - action_type::DocumentTransitionActionType, DocumentCreateTransition, + document_transition_action_type::DocumentTransitionActionType, DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransition, }, DocumentsBatchTransition, DocumentsBatchTransitionV0, diff --git a/packages/rs-dpp/src/document/specialized_document_factory/mod.rs b/packages/rs-dpp/src/document/specialized_document_factory/mod.rs index 8a9c438804a..dbd21b3e6f3 100644 --- a/packages/rs-dpp/src/document/specialized_document_factory/mod.rs +++ b/packages/rs-dpp/src/document/specialized_document_factory/mod.rs @@ -14,7 +14,7 @@ use crate::document::Document; use crate::document::ExtendedDocument; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ - document_transition::action_type::DocumentTransitionActionType, DocumentsBatchTransition, + document_transition::document_transition_action_type::DocumentTransitionActionType, DocumentsBatchTransition, }; use crate::util::entropy_generator::EntropyGenerator; pub use v0::SpecializedDocumentFactoryV0; diff --git a/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs b/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs index e482d3822a7..99982449130 100644 --- a/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs @@ -25,7 +25,7 @@ use crate::prelude::{BlockHeight, CoreBlockHeight, TimestampMillis}; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ document_transition::{ - action_type::DocumentTransitionActionType, DocumentCreateTransition, + document_transition_action_type::DocumentTransitionActionType, DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransition, }, DocumentsBatchTransition, DocumentsBatchTransitionV0, diff --git a/packages/rs-dpp/src/state_transition/serialization.rs b/packages/rs-dpp/src/state_transition/serialization.rs index c36ae53db4f..a8ed69101c5 100644 --- a/packages/rs-dpp/src/state_transition/serialization.rs +++ b/packages/rs-dpp/src/state_transition/serialization.rs @@ -27,7 +27,7 @@ mod tests { use crate::state_transition::data_contract_update_transition::{ DataContractUpdateTransition, DataContractUpdateTransitionV0, }; - use crate::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; + use crate::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; use crate::state_transition::documents_batch_transition::{ DocumentsBatchTransition, DocumentsBatchTransitionV0, }; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs similarity index 94% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs index fd7c376f7b9..02564237d1f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs @@ -1,4 +1,4 @@ -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use crate::state_transition::documents_batch_transition::document_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentTransition}; use crate::ProtocolError; // @append-only diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_methods/mod.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs index 39bcbc1da4c..9697e82c1d3 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::prelude::{Identifier, IdentityNonce}; use document_base_transition::DocumentBaseTransition; -pub mod action_type; +pub mod document_transition_action_type; pub mod document_base_transition; pub mod document_create_transition; pub mod document_delete_transition; @@ -20,6 +20,7 @@ pub mod token_base_transition; pub mod token_burn_transition; pub mod token_issuance_transition; pub mod token_transfer_transition; +pub mod token_transition_action_type; use crate::prelude::Revision; use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; @@ -34,46 +35,16 @@ use platform_value::Value; use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; - +use crate::state_transition::documents_batch_transition::{TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition}; +use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::documents_batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; pub const PROPERTY_ACTION: &str = "$action"; -pub trait DocumentTransitionV0Methods { - fn base(&self) -> &DocumentBaseTransition; - /// returns the value of dynamic property. The dynamic property is a property that is not specified in protocol - /// the `path` supports dot-syntax: i.e: property.internal_property - fn get_dynamic_property(&self, path: &str) -> Option<&Value>; - /// get the id - fn get_id(&self) -> Identifier; - /// get the document type - fn document_type_name(&self) -> &String; - /// get the data contract id - fn data_contract_id(&self) -> Identifier; - /// get the data of the transition if exits - fn data(&self) -> Option<&BTreeMap>; - /// get the revision of transition if exits - fn revision(&self) -> Option; - - /// get the identity contract nonce - fn identity_contract_nonce(&self) -> IdentityNonce; - #[cfg(test)] - /// Inserts the dynamic property into the document - fn insert_dynamic_property(&mut self, property_name: String, value: Value); - /// set data contract's ID - fn set_data_contract_id(&mut self, id: Identifier); - fn base_mut(&mut self) -> &mut DocumentBaseTransition; - fn data_mut(&mut self) -> Option<&mut BTreeMap>; - - // sets revision of the transition - fn set_revision(&mut self, revision: Revision); - - // sets identity contract nonce - fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce); -} - #[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] #[cfg_attr( feature = "state-transition-serde-conversion", @@ -140,6 +111,39 @@ impl DocumentTransition { } } +pub trait DocumentTransitionV0Methods { + fn base(&self) -> &DocumentBaseTransition; + /// returns the value of dynamic property. The dynamic property is a property that is not specified in protocol + /// the `path` supports dot-syntax: i.e: property.internal_property + fn get_dynamic_property(&self, path: &str) -> Option<&Value>; + /// get the id + fn get_id(&self) -> Identifier; + /// get the document type + fn document_type_name(&self) -> &String; + /// get the data contract id + fn data_contract_id(&self) -> Identifier; + /// get the data of the transition if exits + fn data(&self) -> Option<&BTreeMap>; + /// get the revision of transition if exits + fn revision(&self) -> Option; + + /// get the identity contract nonce + fn identity_contract_nonce(&self) -> IdentityNonce; + #[cfg(test)] + /// Inserts the dynamic property into the document + fn insert_dynamic_property(&mut self, property_name: String, value: Value); + /// set data contract's ID + fn set_data_contract_id(&mut self, id: Identifier); + fn base_mut(&mut self) -> &mut DocumentBaseTransition; + fn data_mut(&mut self) -> Option<&mut BTreeMap>; + + // sets revision of the transition + fn set_revision(&mut self, revision: Revision); + + // sets identity contract nonce + fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce); +} + impl DocumentTransitionV0Methods for DocumentTransition { fn base(&self) -> &DocumentBaseTransition { match self { @@ -276,3 +280,108 @@ impl DocumentTransitionV0Methods for DocumentTransition { } } } + + + +#[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenTransition { + #[display("TokenBurnTransition({})", "_0")] + Burn(TokenBurnTransition), + + #[display("TokenIssuanceTransition({})", "_0")] + Issuance(TokenIssuanceTransition), + + #[display("TokenTransferTransition({})", "_0")] + Transfer(TokenTransferTransition), +} + +impl TokenTransition { + pub fn as_transition_burn(&self) -> Option<&TokenBurnTransition> { + if let Self::Burn(ref t) = self { + Some(t) + } else { + None + } + } + pub fn as_transition_issuance(&self) -> Option<&TokenIssuanceTransition> { + if let Self::Issuance(ref t) = self { + Some(t) + } else { + None + } + } + + pub fn as_transition_transfer(&self) -> Option<&TokenTransferTransition> { + if let Self::Transfer(ref t) = self { + Some(t) + } else { + None + } + } +} + +pub trait TokenTransitionV0Methods { + fn base(&self) -> &TokenBaseTransition; + fn base_mut(&mut self) -> &mut TokenBaseTransition; + /// get the data contract id + fn data_contract_id(&self) -> Identifier; + /// set data contract's ID + fn set_data_contract_id(&mut self, id: Identifier); + + /// get the identity contract nonce + fn identity_contract_nonce(&self) -> IdentityNonce; + /// sets identity contract nonce + fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce); +} + +impl TokenTransitionV0Methods for TokenTransition { + fn base(&self) -> &TokenBaseTransition { + match self { + TokenTransition::Burn(t) => t.base(), + TokenTransition::Issuance(t) => t.base(), + TokenTransition::Transfer(t) => t.base(), + } + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + match self { + TokenTransition::Burn(t) => t.base_mut(), + TokenTransition::Issuance(t) => t.base_mut(), + TokenTransition::Transfer(t) => t.base_mut(), + } + } + + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + fn set_data_contract_id(&mut self, id: Identifier) { + self.base_mut().set_data_contract_id(id); + } + + fn identity_contract_nonce(&self) -> IdentityNonce { + self.base().identity_contract_nonce() + } + + fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce) { + self.base_mut().set_identity_contract_nonce(nonce); + } +} + +#[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum BatchedTransition { + #[display("DocumentTransition({})", "_0")] + Document(DocumentTransition), + #[display("TokenTransition({})", "_0")] + Token(TokenTransition), +} + + diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs new file mode 100644 index 00000000000..30d61be4077 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs @@ -0,0 +1,39 @@ +use crate::ProtocolError; +use crate::state_transition::documents_batch_transition::document_transition::TokenTransition; + +// @append-only +#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)] +pub enum TokenTransitionActionType { + Burn, + Issuance, + Transfer, +} + +pub trait TransitionActionTypeGetter { + fn action_type(&self) -> TokenTransitionActionType; +} + +impl TransitionActionTypeGetter for TokenTransition { + fn action_type(&self) -> TokenTransitionActionType { + match self { + TokenTransition::Burn(_) => TokenTransitionActionType::Burn, + TokenTransition::Issuance(_) => TokenTransitionActionType::Issuance, + TokenTransition::Transfer(_) => TokenTransitionActionType::Transfer, + } + } +} + +impl TryFrom<&str> for TokenTransitionActionType { + type Error = ProtocolError; + + fn try_from(value: &str) -> Result { + match value { + "burn" => Ok(TokenTransitionActionType::Burn), + "issuance" => Ok(TokenTransitionActionType::Issuance), + "transfer" => Ok(TokenTransitionActionType::Transfer), + action_type => Err(ProtocolError::Generic(format!( + "unknown token transition action type {action_type}" + ))), + } + } +} \ No newline at end of file diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index dfb531b5546..23126df2baf 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -5,7 +5,7 @@ use platform_version::version::PlatformVersion; use std::collections::BTreeMap; use crate::document::Document; -use crate::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; +use crate::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; use crate::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs index ac229976a55..1606d5a06c1 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs @@ -3,7 +3,7 @@ use crate::execution::validation::state_transition::documents_batch::data_trigge }; use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use dpp::state_transition::documents_batch_transition::document_transition::action_type::TransitionActionTypeGetter; +use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::TransitionActionTypeGetter; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use dpp::version::PlatformVersion; use crate::execution::validation::state_transition::documents_batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs index b1b183ef24d..1b1e8bec303 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs @@ -194,7 +194,7 @@ mod test { }; let result = create_contact_request_data_trigger( - &DocumentCreateTransitionAction::from_document_borrowed_create_transition_with_contract_lookup(&platform.drive, None, document_create_transition, &BlockInfo::default(), |_identifier| { + &DocumentCreateTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup(&platform.drive, None, document_create_transition, &BlockInfo::default(), |_identifier| { Ok(Arc::new(DataContractFetchInfo::dashpay_contract_fixture(protocol_version))) }, platform_version).expect("expected to create action").0.into(), &data_trigger_context, @@ -312,7 +312,7 @@ mod test { let _dashpay_identity_id = data_trigger_context.owner_id.to_owned(); let result = create_contact_request_data_trigger( - &DocumentCreateTransitionAction::from_document_borrowed_create_transition_with_contract_lookup(&platform.drive, None, document_create_transition, &BlockInfo::default(), |_identifier| { + &DocumentCreateTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup(&platform.drive, None, document_create_transition, &BlockInfo::default(), |_identifier| { Ok(Arc::new(DataContractFetchInfo::dashpay_contract_fixture(protocol_version))) }, platform_version).expect("expected to create action").0.into(), &data_trigger_context, @@ -425,7 +425,7 @@ mod test { let _dashpay_identity_id = data_trigger_context.owner_id.to_owned(); let result = create_contact_request_data_trigger( - &DocumentCreateTransitionAction::from_document_borrowed_create_transition_with_contract_lookup(&platform.drive, None, document_create_transition, &BlockInfo::default(), |_identifier| { + &DocumentCreateTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup(&platform.drive, None, document_create_transition, &BlockInfo::default(), |_identifier| { Ok(Arc::new(DataContractFetchInfo::dashpay_contract_fixture(protocol_version))) }, platform_version).expect("expected to create action").0.into(), &data_trigger_context, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs index a790d727bd8..349d858ef98 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs @@ -504,8 +504,8 @@ mod test { }; let result = create_domain_data_trigger_v0( - &DocumentCreateTransitionAction::from_document_borrowed_create_transition_with_contract_lookup(&platform.drive, None, - document_create_transition, &BlockInfo::default(), |_identifier| { + &DocumentCreateTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup(&platform.drive, None, + document_create_transition, &BlockInfo::default(), |_identifier| { Ok(Arc::new(DataContractFetchInfo::dpns_contract_fixture(platform_version.protocol_version))) }, platform_version).expect("expected to create action").0.into(), &data_trigger_context, 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 68ec4de478e..c8797a4c4e6 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 @@ -371,7 +371,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition DocumentTransition::Create(document_create_transition) => { let result = ConsensusValidationResult::::new(); - let (document_create_action, fee_result) = DocumentCreateTransitionAction::from_document_borrowed_create_transition_with_contract_lookup( + let (document_create_action, fee_result) = DocumentCreateTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup( drive, transaction, document_create_transition, block_info, |_identifier| { Ok(data_contract_fetch_info.clone()) @@ -474,7 +474,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition } } DocumentTransition::Delete(document_delete_transition) => { - let action = DocumentDeleteTransitionAction::from_document_borrowed_create_transition_with_contract_lookup(document_delete_transition, |_identifier| { + let action = DocumentDeleteTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup(document_delete_transition, |_identifier| { Ok(data_contract_fetch_info.clone()) })?; Ok(DocumentTransitionAction::DeleteAction(action).into()) diff --git a/packages/rs-drive/src/drive/tokens/balance/prove.rs b/packages/rs-drive/src/drive/tokens/balance/prove.rs index 68c386465bb..968b1588489 100644 --- a/packages/rs-drive/src/drive/tokens/balance/prove.rs +++ b/packages/rs-drive/src/drive/tokens/balance/prove.rs @@ -9,8 +9,8 @@ impl Drive { /// Proves an Identity's token balance from the backing store pub fn prove_identity_token_balance( &self, - identity_id: [u8; 32], token_id: [u8; 32], + identity_id: [u8; 32], transaction: TransactionArg, drive_version: &DriveVersion, ) -> Result, Error> { @@ -21,8 +21,8 @@ impl Drive { /// Proves multiple Identity token balances from the backing store pub fn prove_many_identity_token_balances( &self, - identity_ids: &[[u8; 32]], token_id: [u8; 32], + identity_ids: &[[u8; 32]], transaction: TransactionArg, drive_version: &DriveVersion, ) -> Result, Error> { @@ -33,13 +33,14 @@ impl Drive { /// Proves multiple Identity balances from the backing store by range pub fn prove_many_identity_token_balances_by_range( &self, + token_id: [u8; 32], start_at: Option<([u8; 32], bool)>, ascending: bool, limit: u16, transaction: TransactionArg, drive_version: &DriveVersion, ) -> Result, Error> { - let balance_query = Self::balances_for_range_query(start_at, ascending, limit); + let balance_query = Self::token_balances_for_range_query(token_id, start_at, ascending, limit); self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) } } @@ -51,13 +52,13 @@ mod tests { use dpp::block::block_info::BlockInfo; use dpp::identity::Identity; - mod prove_identity_balance { + mod prove_identity_token_balance { use super::*; use dpp::identity::accessors::IdentityGettersV0; use dpp::version::PlatformVersion; #[test] - fn should_prove_a_single_identity_balance() { + fn should_prove_a_single_identity_token_balance() { let drive = setup_drive_with_initial_state_structure(None); let platform_version = PlatformVersion::first(); @@ -77,10 +78,10 @@ mod tests { ) .expect("expected to add an identity"); let proof = drive - .prove_identity_balance(identity.id().to_buffer(), None, &platform_version.drive) + .prove_identity_token_balance(identity.id().to_buffer(), None, &platform_version.drive) .expect("should not error when proving an identity"); - let (_, proved_identity_balance) = Drive::verify_identity_balance_for_identity_id( + let (_, proved_identity_balance) = Drive::verify_identity_token_balance_for_identity_id( proof.as_slice(), identity_id, false, @@ -92,15 +93,17 @@ mod tests { } } - mod prove_many_identity_balances { + mod prove_many_identity_token_balances { use super::*; use dpp::fee::Credits; use dpp::identity::accessors::IdentityGettersV0; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; + use rand::rngs::StdRng; + use rand::{Rng, SeedableRng}; #[test] - fn should_prove_multiple_identity_balances() { + fn should_prove_multiple_identity_single_token_balances() { let drive = setup_drive_with_initial_state_structure(None); let platform_version = PlatformVersion::latest(); let identities: BTreeMap<[u8; 32], Identity> = @@ -109,6 +112,12 @@ mod tests { .into_iter() .map(|identity| (identity.id().to_buffer(), identity)) .collect(); + + let mut rng = StdRng::seed_from_u64(293); + + let token_id: [u8;32] = rng.gen(); + + drive.add_new_token(token_id); for identity in identities.values() { drive @@ -128,7 +137,7 @@ mod tests { .map(|(id, identity)| (id, Some(identity.balance()))) .collect::>>(); let proof = drive - .prove_many_identity_balances( + .prove_many_identity_token_balances( identity_ids.as_slice(), None, &platform_version.drive, diff --git a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs b/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs new file mode 100644 index 00000000000..3350c403a86 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs @@ -0,0 +1,114 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::identity::Identity; +use dpp::version::PlatformVersion; + +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + + +impl Drive { + /// Adds a identity by inserting a new identity subtree structure to the `Identities` subtree. + pub fn create_token_root_tree( + &self, + token_id: [u8;32], + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive + .methods + .token + .insert + .create_token_root_tree + { + 0 => self.create_token_root_tree_v0( + token_id, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "create_token_root_tree".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds identity creation operations to drive operations + pub fn create_token_root_tree_add_to_operations( + &self, + token_id: [u8;32], + apply: bool, + previous_batch_operations: &mut Option<&mut Vec>, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version + .drive + .methods + .token + .insert + .create_token_root_tree + { + 0 => self.create_token_root_tree_add_to_operations_v0( + token_id, + apply, + previous_batch_operations, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "create_token_root_tree_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// The operations needed to create an identity + pub fn create_token_root_tree_operations( + &self, + token_id: [u8;32], + previous_batch_operations: &mut Option<&mut Vec>, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .insert + .create_token_root_tree + { + 0 => self.create_token_root_tree_operations_v0( + token_id, + previous_batch_operations, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "create_token_root_tree_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs b/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs new file mode 100644 index 00000000000..f39fa2f708c --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs @@ -0,0 +1,136 @@ +use crate::drive::{ + Drive +}; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::BatchInsertTreeApplyType; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; +use platform_version::version::PlatformVersion; +use crate::drive::tokens::token_balances_root_path; +use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKey; + +impl Drive { + /// Creates a new token root subtree at `TokenBalances` keyed by `token_id`. + /// This function applies the operations directly, calculates fees, and returns the fee result. + pub(super) fn create_token_root_tree_v0( + &self, + token_id: [u8; 32], + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations: Vec = vec![]; + + // Add operations to create the token root tree + self.create_token_root_tree_add_to_operations_v0( + token_id, + apply, + &mut None, + transaction, + &mut drive_operations, + platform_version, + )?; + + // If applying, calculate fees + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + /// Adds the token root creation operations to the provided `drive_operations` vector without + /// calculating or returning fees. If `apply` is false, it will only estimate costs. + pub(super) fn create_token_root_tree_add_to_operations_v0( + &self, + token_id: [u8; 32], + apply: bool, + previous_batch_operations: &mut Option<&mut Vec>, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = if apply { + None::> + } else { + Some(HashMap::new()) + }; + + // Get the operations required to create the token tree + let batch_operations = self.create_token_root_tree_operations_v0( + token_id, + previous_batch_operations, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + // Apply or estimate the operations + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + /// Gathers the operations needed to create the token root subtree. If `apply` is false, it + /// populates `estimated_costs_only_with_layer_info` instead of applying. + pub(super) fn create_token_root_tree_operations_v0( + &self, + token_id: [u8; 32], + previous_batch_operations: &mut Option<&mut Vec>, + estimated_costs_only_with_layer_info: &mut Option>, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut batch_operations: Vec = vec![]; + + // Decide if we're doing a stateful or stateless insert for cost estimation + let apply_type = if estimated_costs_only_with_layer_info.is_none() { + BatchInsertTreeApplyType::StatefulBatchInsertTree + } else { + BatchInsertTreeApplyType::StatelessBatchInsertTree { + in_tree_using_sums: false, + is_sum_tree: true, + flags_len: 0, // No additional storage flags here + } + }; + + // Insert an empty tree for this token if it doesn't exist + let inserted = self.batch_insert_empty_tree_if_not_exists( + PathFixedSizeKey(( + token_balances_root_path(), + token_id.to_vec(), + )), + true, + None, // No storage flags + apply_type, + transaction, + previous_batch_operations, + &mut batch_operations, + &platform_version.drive, + )?; + + if !inserted { + // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. + return Err(Error::Drive(DriveError::CorruptedDriveState( + "token root tree already exists".to_string(), + ))); + } + + Ok(batch_operations) + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/drive/tokens/initialization/mod.rs b/packages/rs-drive/src/drive/tokens/initialization/mod.rs new file mode 100644 index 00000000000..fc9a17c4b21 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/initialization/mod.rs @@ -0,0 +1 @@ +mod create_token_root_tree; \ No newline at end of file diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index d2c81784557..68d46e6dbe1 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -1,6 +1,7 @@ use crate::drive::RootTree; mod balance; +pub mod initialization; /// The path for the balances tree #[cfg(any(feature = "server", feature = "verify"))] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs index 35a79fc023f..4b86b6efe72 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs @@ -8,7 +8,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti impl DocumentBaseTransitionAction { /// from base transition with contract lookup - pub fn from_base_transition_with_contract_lookup( + pub fn try_from_base_transition_with_contract_lookup( value: DocumentBaseTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -24,7 +24,7 @@ impl DocumentBaseTransitionAction { } /// from borrowed base transition with contract lookup - pub fn from_borrowed_base_transition_with_contract_lookup( + pub fn try_from_borrowed_base_transition_with_contract_lookup( value: &DocumentBaseTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs index 50d8b830afa..96b76d29065 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs @@ -14,7 +14,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti impl DocumentCreateTransitionAction { /// from_document_create_transition_with_contract_lookup - pub fn from_document_create_transition_with_contract_lookup( + pub fn try_from_document_create_transition_with_contract_lookup( drive: &Drive, transaction: TransactionArg, value: DocumentCreateTransition, @@ -31,7 +31,7 @@ impl DocumentCreateTransitionAction { } /// from_document_borrowed_create_transition_with_contract_lookup - pub fn from_document_borrowed_create_transition_with_contract_lookup( + pub fn try_from_document_borrowed_create_transition_with_contract_lookup( drive: &Drive, transaction: TransactionArg, value: &DocumentCreateTransition, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs index 2c2aea87bec..1cd3025e4d4 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs @@ -34,7 +34,7 @@ impl DocumentCreateTransitionActionV0 { prefunded_voting_balance, .. } = value; - let base = DocumentBaseTransitionAction::from_base_transition_with_contract_lookup( + let base = DocumentBaseTransitionAction::try_from_base_transition_with_contract_lookup( base, get_data_contract, )?; @@ -130,7 +130,7 @@ impl DocumentCreateTransitionActionV0 { .. } = value; let base = - DocumentBaseTransitionAction::from_borrowed_base_transition_with_contract_lookup( + DocumentBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( base, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs index da6cd644cc4..e32d5cc1d08 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs @@ -8,7 +8,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti impl DocumentDeleteTransitionAction { /// from - pub fn from_document_create_transition_with_contract_lookup( + pub fn try_from_document_create_transition_with_contract_lookup( value: DocumentDeleteTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -18,7 +18,7 @@ impl DocumentDeleteTransitionAction { } /// from borrowed - pub fn from_document_borrowed_create_transition_with_contract_lookup( + pub fn try_from_document_borrowed_create_transition_with_contract_lookup( value: &DocumentDeleteTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs index ff183289440..bdfd2bf8f6b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs @@ -15,7 +15,7 @@ impl DocumentDeleteTransitionActionV0 { ) -> Result { let DocumentDeleteTransitionV0 { base, .. } = value; Ok(DocumentDeleteTransitionActionV0 { - base: DocumentBaseTransitionAction::from_base_transition_with_contract_lookup( + base: DocumentBaseTransitionAction::try_from_base_transition_with_contract_lookup( base, get_data_contract, )?, @@ -29,7 +29,7 @@ impl DocumentDeleteTransitionActionV0 { ) -> Result { let DocumentDeleteTransitionV0 { base, .. } = value; Ok(DocumentDeleteTransitionActionV0 { - base: DocumentBaseTransitionAction::from_borrowed_base_transition_with_contract_lookup( + base: DocumentBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( base, get_data_contract, )?, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs index e888f20d33e..0625690bda3 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs @@ -21,7 +21,7 @@ impl DocumentPurchaseTransitionActionV0 { ) -> Result { let DocumentPurchaseTransitionV0 { base, price, .. } = document_purchase_transition; let base = - DocumentBaseTransitionAction::from_borrowed_base_transition_with_contract_lookup( + DocumentBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( base, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs index 8127c39532a..dad93afed20 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs @@ -31,7 +31,7 @@ impl DocumentReplaceTransitionActionV0 { .. } = document_replace_transition; let base = - DocumentBaseTransitionAction::from_borrowed_base_transition_with_contract_lookup( + DocumentBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( base, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs index 88f6d0776ab..92c0c768d54 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs @@ -24,7 +24,7 @@ impl DocumentTransferTransitionActionV0 { .. } = document_transfer_transition; let base = - DocumentBaseTransitionAction::from_borrowed_base_transition_with_contract_lookup( + DocumentBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( base, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs new file mode 100644 index 00000000000..d8765d18a01 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs @@ -0,0 +1,22 @@ +use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::{ + DocumentTransitionActionType, TransitionActionTypeGetter, +}; + +impl TransitionActionTypeGetter for DocumentTransitionAction { + fn action_type(&self) -> DocumentTransitionActionType { + match self { + DocumentTransitionAction::CreateAction(_) => DocumentTransitionActionType::Create, + DocumentTransitionAction::DeleteAction(_) => DocumentTransitionActionType::Delete, + DocumentTransitionAction::ReplaceAction(_) => DocumentTransitionActionType::Replace, + DocumentTransitionAction::TransferAction(_) => DocumentTransitionActionType::Transfer, + DocumentTransitionAction::PurchaseAction(_) => DocumentTransitionActionType::Purchase, + DocumentTransitionAction::UpdatePriceAction(_) => { + DocumentTransitionActionType::UpdatePrice + } + DocumentTransitionAction::BumpIdentityDataContractNonce(_) => { + DocumentTransitionActionType::IgnoreWhileBumpingRevision + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs index 6054d09f9b8..c32bb5bc166 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs @@ -20,7 +20,7 @@ impl DocumentUpdatePriceTransitionActionV0 { ) -> Result { let DocumentUpdatePriceTransitionV0 { base, price, .. } = document_update_price_transition; let base = - DocumentBaseTransitionAction::from_borrowed_base_transition_with_contract_lookup( + DocumentBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( base, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index 51c7f19d2d0..d869f4bd56c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -1,4 +1,4 @@ -mod action_type; +mod document_transition_action_type; /// document_base_transition_action pub mod document_base_transition_action; /// document_create_transition_action @@ -13,8 +13,16 @@ pub mod document_replace_transition_action; pub mod document_transfer_transition_action; /// document_update_price_transition_action pub mod document_update_price_transition_action; +/// token_base_transition_action +pub mod token_base_transition_action; +/// token_burn_transition_action +pub mod token_burn_transition_action; +/// token_issuance_transition_action +pub mod token_issuance_transition_action; +/// token_transfer_transition_action +pub mod token_transfer_transition_action; -pub use dpp::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; +pub use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; use derive_more::From; @@ -77,3 +85,40 @@ impl DocumentTransitionAction { } } } + + +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors, TokenTransferTransitionActionAccessorsV0}; + +/// token action +#[derive(Debug, Clone, From)] +pub enum TokenTransitionAction { + /// burn + BurnAction(TokenBurnTransitionAction), + /// issuance + IssuanceAction(TokenIssuanceTransitionAction), + /// transfer + TransferAction(TokenTransferTransitionAction), +} + +impl TokenTransitionAction { + /// Returns a reference to the base token transition action if available + pub fn base(&self) -> Option<&TokenBaseTransitionAction> { + match self { + TokenTransitionAction::BurnAction(action) => Some(action.base()), + TokenTransitionAction::IssuanceAction(action) => Some(action.base()), + TokenTransitionAction::TransferAction(action) => Some(action.base()), + } + } + + /// Consumes self and returns the base token transition action if available + pub fn base_owned(self) -> Option { + match self { + TokenTransitionAction::BurnAction(action) => Some(action.base_owned()), + TokenTransitionAction::IssuanceAction(action) => Some(action.base_owned()), + TokenTransitionAction::TransferAction(action) => Some(action.base_owned()), + } + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs new file mode 100644 index 00000000000..9735a345829 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs @@ -0,0 +1,60 @@ +use derive_more::From; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::platform_value::Identifier; + +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::prelude::IdentityNonce; +use std::sync::Arc; + +/// transformer module +pub mod transformer; +mod v0; + +use crate::drive::contract::DataContractFetchInfo; + +pub use v0::*; + +/// document base transition action +#[derive(Debug, Clone, From)] +pub enum TokenBaseTransitionAction { + /// v0 + V0(TokenBaseTransitionActionV0), +} + +impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionAction { + fn id(&self) -> Identifier { + match self { + TokenBaseTransitionAction::V0(v0) => v0.id, + } + } + + fn token_id(&self) -> u16 { + match self { + TokenBaseTransitionAction::V0(v0) => v0.token_id, + } + } + + fn data_contract_id(&self) -> Identifier { + match self { + TokenBaseTransitionAction::V0(v0) => v0.data_contract_id(), + } + } + + fn data_contract_fetch_info_ref(&self) -> &Arc { + match self { + TokenBaseTransitionAction::V0(v0) => v0.data_contract_fetch_info_ref(), + } + } + + fn data_contract_fetch_info(&self) -> Arc { + match self { + TokenBaseTransitionAction::V0(v0) => v0.data_contract_fetch_info(), + } + } + + fn identity_contract_nonce(&self) -> IdentityNonce { + match self { + TokenBaseTransitionAction::V0(v0) => v0.identity_contract_nonce(), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs new file mode 100644 index 00000000000..0cd8d3f4517 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs @@ -0,0 +1,35 @@ +use dpp::platform_value::Identifier; +use std::sync::Arc; + +use dpp::ProtocolError; +use dpp::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; + +impl TokenBaseTransitionAction { + /// from base transition with contract lookup + pub fn try_from_base_transition_with_contract_lookup( + value: TokenBaseTransition, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + match value { + TokenBaseTransition::V0(v0) => Ok( + TokenBaseTransitionActionV0::try_from_base_transition_with_contract_lookup( + v0, + get_data_contract, + )? + .into(), + ), + } + } + + /// from borrowed base transition with contract lookup + pub fn try_from_borrowed_base_transition_with_contract_lookup( + value: &TokenBaseTransition, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + match value { + TokenBaseTransition::V0(v0) => Ok(TokenBaseTransitionActionV0::try_from_borrowed_base_transition_with_contract_lookup(v0, get_data_contract)?.into()), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs new file mode 100644 index 00000000000..7399a447c99 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs @@ -0,0 +1,68 @@ +use std::sync::Arc; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; +use crate::drive::contract::DataContractFetchInfo; + +/// transformer +pub mod transformer; + +/// Token base transition action v0 +#[derive(Debug, Clone)] +pub struct TokenBaseTransitionActionV0 { + /// The token transition ID + pub id: Identifier, + /// The identity contract nonce, used to prevent replay attacks + pub identity_contract_nonce: IdentityNonce, + /// The token ID within the data contract + pub token_id: u16, + /// A potential data contract + pub data_contract: Arc, +} + +/// Token base transition action accessors v0 +pub trait TokenBaseTransitionActionAccessorsV0 { + /// Returns the token transition ID + fn id(&self) -> Identifier; + + /// The token ID within the data contract + fn token_id(&self) -> u16; + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier; + + /// Returns a reference to the data contract fetch info, without cloning + fn data_contract_fetch_info_ref(&self) -> &Arc; + + /// Returns the data contract fetch info (cloned Arc) + fn data_contract_fetch_info(&self) -> Arc; + + /// Returns the identity contract nonce + fn identity_contract_nonce(&self) -> IdentityNonce; +} + +impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { + fn id(&self) -> Identifier { + self.id + } + + fn token_id(&self) -> u16 { + self.token_id + } + + fn data_contract_id(&self) -> Identifier { + self.data_contract.contract.id() + } + + fn data_contract_fetch_info_ref(&self) -> &Arc { + &self.data_contract + } + + fn data_contract_fetch_info(&self) -> Arc { + self.data_contract.clone() + } + + fn identity_contract_nonce(&self) -> IdentityNonce { + self.identity_contract_nonce + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs new file mode 100644 index 00000000000..cd31ad0eca7 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -0,0 +1,50 @@ +use std::sync::Arc; + +use dpp::platform_value::Identifier; + +use dpp::ProtocolError; +use dpp::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use dpp::state_transition::documents_batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; + +impl TokenBaseTransitionActionV0 { + /// try from base transition with contract lookup + pub fn try_from_base_transition_with_contract_lookup( + value: TokenBaseTransitionV0, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + let TokenBaseTransitionV0 { + id, + token_id, + data_contract_id, + identity_contract_nonce, + } = value; + Ok(TokenBaseTransitionActionV0 { + id, + identity_contract_nonce, + token_id, + data_contract: get_data_contract(data_contract_id)?, + }) + } + + /// try from borrowed base transition with contract lookup + pub fn try_from_borrowed_base_transition_with_contract_lookup( + value: &TokenBaseTransitionV0, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + let TokenBaseTransitionV0 { + id, + token_id, + data_contract_id, + identity_contract_nonce, + } = value; + Ok(TokenBaseTransitionActionV0 { + id: *id, + identity_contract_nonce: *identity_contract_nonce, + token_id: *token_id, + data_contract: get_data_contract(*data_contract_id)?, + }) + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs new file mode 100644 index 00000000000..ad67240e662 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs @@ -0,0 +1,76 @@ +use derive_more::From; +use std::sync::Arc; + +use crate::drive::contract::DataContractFetchInfo; +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; + +/// transformer module for token burn transition action +pub mod transformer; +mod v0; + +pub use v0::*; // re-export the v0 module items (including TokenBurnTransitionActionV0) + +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{ + TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0, +}; + +/// Token burn transition action +#[derive(Debug, Clone, From)] +pub enum TokenBurnTransitionAction { + /// v0 + V0(TokenBurnTransitionActionV0), +} + +/// Accessors trait for TokenBurnTransitionAction for version 0 fields +pub trait TokenBurnTransitionActionAccessorsV0 { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Returns the burn amount + fn burn_amount(&self) -> u64; + + /// Returns the token ID + fn token_id(&self) -> u16 { + self.base().token_id() + } + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + /// Returns the identity contract nonce + fn identity_contract_nonce(&self) -> IdentityNonce { + self.base().identity_contract_nonce() + } + + /// Returns the ID of the token burn transition + fn id(&self) -> Identifier { + self.base().id() + } +} + +impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenBurnTransitionAction::V0(v0) => &v0.base, + } + } + + fn burn_amount(&self) -> u64 { + match self { + TokenBurnTransitionAction::V0(v0) => v0.burn_amount, + } + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs new file mode 100644 index 00000000000..c7fbab433ff --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs @@ -0,0 +1,64 @@ +use std::sync::Arc; + +use dpp::platform_value::Identifier; +use dpp::ProtocolError; + +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{ + TokenBurnTransitionAction, TokenBurnTransitionActionV0, +}; +use dpp::state_transition::documents_batch_transition::token_burn_transition::TokenBurnTransition; + +/// Implement methods to transform a `TokenBurnTransition` into a `TokenBurnTransitionAction`. +impl TokenBurnTransitionAction { + /// Transform a `TokenBurnTransition` into a `TokenBurnTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `value` - A `TokenBurnTransition` instance. + /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// + /// # Returns + /// + /// * `Result` - A `TokenBurnTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_token_burn_transition_with_contract_lookup( + value: TokenBurnTransition, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + match value { + TokenBurnTransition::V0(v0) => { + let v0_action = + TokenBurnTransitionActionV0::try_from_token_burn_transition_with_contract_lookup( + v0, + get_data_contract, + )?; + Ok(v0_action.into()) + } + } + } + + /// Transform a borrowed `TokenBurnTransition` into a `TokenBurnTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `value` - A reference to a `TokenBurnTransition`. + /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// + /// # Returns + /// + /// * `Result` - A `TokenBurnTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_borrowed_token_burn_transition_with_contract_lookup( + value: &TokenBurnTransition, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + match value { + TokenBurnTransition::V0(v0) => { + let v0_action = TokenBurnTransitionActionV0::try_from_borrowed_token_burn_transition_with_contract_lookup( + v0, + get_data_contract, + )?; + Ok(v0_action.into()) + } + } + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs new file mode 100644 index 00000000000..43361d713bb --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs @@ -0,0 +1,44 @@ +mod transformer; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessors}; + +/// Token burn transition action v0 +#[derive(Debug, Clone)] +pub struct TokenBurnTransitionActionV0 { + /// Base token transition action + pub base: TokenBaseTransitionAction, + /// The amount of tokens to burn + pub burn_amount: u64, +} + +/// Accessors for `TokenBurnTransitionActionV0` +pub trait TokenBurnTransitionActionAccessorsV0 { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Consumes self and returns the base token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + + /// Returns the amount of tokens to burn + fn burn_amount(&self) -> u64; + + /// Sets the amount of tokens to burn + fn set_burn_amount(&mut self, amount: u64); +} + +impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionActionV0 { + fn base(&self) -> &TokenBaseTransitionAction { + &self.base + } + + fn base_owned(self) -> TokenBaseTransitionAction { + self.base + } + + fn burn_amount(&self) -> u64 { + self.burn_amount + } + + fn set_burn_amount(&mut self, amount: u64) { + self.burn_amount = amount; + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs new file mode 100644 index 00000000000..a32a792fa3f --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -0,0 +1,65 @@ +use std::sync::Arc; + +use dpp::identifier::Identifier; +use dpp::ProtocolError; +use dpp::state_transition::documents_batch_transition::token_burn_transition::v0::TokenBurnTransitionV0; + +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; + +impl TokenBurnTransitionActionV0 { + /// Attempt to convert a `TokenBurnTransitionV0` into a `TokenBurnTransitionActionV0` using a data contract lookup function. + /// + /// # Arguments + /// + /// * `value` - A `TokenBurnTransitionV0` from which to derive the action + /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` + /// + /// # Returns + /// + /// * `Result` - A `TokenBurnTransitionActionV0` if successful, else `ProtocolError`. + pub fn try_from_token_burn_transition_with_contract_lookup( + value: TokenBurnTransitionV0, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + let TokenBurnTransitionV0 { + base, + burn_amount, + } = value; + + let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup(base, get_data_contract)?; + + Ok(TokenBurnTransitionActionV0 { + base: base_action, + burn_amount, + }) + } + + /// Attempt to convert a borrowed `TokenBurnTransitionV0` into a `TokenBurnTransitionActionV0` using a data contract lookup function. + /// + /// # Arguments + /// + /// * `value` - A reference to a `TokenBurnTransitionV0` from which to derive the action + /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` + /// + /// # Returns + /// + /// * `Result` - A `TokenBurnTransitionActionV0` if successful, else `ProtocolError`. + pub fn try_from_borrowed_token_burn_transition_with_contract_lookup( + value: &TokenBurnTransitionV0, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + let TokenBurnTransitionV0 { + base, + burn_amount, + } = value; + + let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup(base, get_data_contract)?; + + Ok(TokenBurnTransitionActionV0 { + base: base_action, + burn_amount: *burn_amount, + }) + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs new file mode 100644 index 00000000000..2945960906b --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs @@ -0,0 +1,76 @@ +use derive_more::From; +use std::sync::Arc; + +use crate::drive::contract::DataContractFetchInfo; +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; + +/// transformer module for token issuance transition action +pub mod transformer; +mod v0; + +pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) + +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{ + TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0, +}; + +/// Token issuance transition action +#[derive(Debug, Clone, From)] +pub enum TokenIssuanceTransitionAction { + /// v0 + V0(TokenIssuanceTransitionActionV0), +} + +/// Accessors trait for TokenIssuanceTransitionAction for version 0 fields +pub trait TokenIssuanceTransitionActionAccessorsV0 { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Returns the issuance amount + fn issuance_amount(&self) -> u64; + + /// Returns the token ID + fn token_id(&self) -> u16 { + self.base().token_id() + } + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + /// Returns the identity contract nonce + fn identity_contract_nonce(&self) -> IdentityNonce { + self.base().identity_contract_nonce() + } + + /// Returns the ID of the token issuance transition + fn id(&self) -> Identifier { + self.base().id() + } +} + +impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenIssuanceTransitionAction::V0(v0) => &v0.base, + } + } + + fn issuance_amount(&self) -> u64 { + match self { + TokenIssuanceTransitionAction::V0(v0) => v0.issuance_amount, + } + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs new file mode 100644 index 00000000000..9c48ded7ecc --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs @@ -0,0 +1,64 @@ +use std::sync::Arc; + +use dpp::platform_value::Identifier; +use dpp::ProtocolError; + +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{ + TokenIssuanceTransitionAction, TokenIssuanceTransitionActionV0, +}; +use dpp::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransition; + +/// Implement methods to transform a `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction`. +impl TokenIssuanceTransitionAction { + /// Transform a `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `value` - A `TokenIssuanceTransition` instance. + /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// + /// # Returns + /// + /// * `Result` - A `TokenIssuanceTransitionAction` if successful, otherwise `ProtocolError`. + pub fn from_token_issuance_transition_with_contract_lookup( + value: TokenIssuanceTransition, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + match value { + TokenIssuanceTransition::V0(v0) => { + let v0_action = + TokenIssuanceTransitionActionV0::try_from_token_issuance_transition_with_contract_lookup( + v0, + get_data_contract, + )?; + Ok(v0_action.into()) + } + } + } + + /// Transform a borrowed `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `value` - A reference to a `TokenIssuanceTransition`. + /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// + /// # Returns + /// + /// * `Result` - A `TokenIssuanceTransitionAction` if successful, otherwise `ProtocolError`. + pub fn from_borrowed_token_issuance_transition_with_contract_lookup( + value: &TokenIssuanceTransition, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + match value { + TokenIssuanceTransition::V0(v0) => { + let v0_action = TokenIssuanceTransitionActionV0::try_from_borrowed_token_issuance_transition_with_contract_lookup( + v0, + get_data_contract, + )?; + Ok(v0_action.into()) + } + } + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs new file mode 100644 index 00000000000..848bab85c9a --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs @@ -0,0 +1,44 @@ +mod transformer; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessors}; + +/// Token issuance transition action v0 +#[derive(Debug, Clone)] +pub struct TokenIssuanceTransitionActionV0 { + /// Base token transition action + pub base: TokenBaseTransitionAction, + /// The amount of tokens to create + pub issuance_amount: u64, +} + +/// Accessors for `TokenIssuanceTransitionActionV0` +pub trait TokenIssuanceTransitionActionAccessorsV0 { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Consumes self and returns the base token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + + /// Returns the amount of tokens to issuance + fn issuance_amount(&self) -> u64; + + /// Sets the amount of tokens to issuance + fn set_issuance_amount(&mut self, amount: u64); +} + +impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV0 { + fn base(&self) -> &TokenBaseTransitionAction { + &self.base + } + + fn base_owned(self) -> TokenBaseTransitionAction { + self.base + } + + fn issuance_amount(&self) -> u64 { + self.issuance_amount + } + + fn set_issuance_amount(&mut self, amount: u64) { + self.issuance_amount = amount; + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs new file mode 100644 index 00000000000..7db1c9eb90a --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs @@ -0,0 +1,65 @@ +use std::sync::Arc; + +use dpp::identifier::Identifier; +use dpp::ProtocolError; +use dpp::state_transition::documents_batch_transition::token_issuance_transition::v0::TokenIssuanceTransitionV0; + +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::v0::TokenIssuanceTransitionActionV0; + +impl TokenIssuanceTransitionActionV0 { + /// Attempt to convert a `TokenIssuanceTransitionV0` into a `TokenIssuanceTransitionActionV0` using a data contract lookup function. + /// + /// # Arguments + /// + /// * `value` - A `TokenIssuanceTransitionV0` from which to derive the action + /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` + /// + /// # Returns + /// + /// * `Result` - A `TokenIssuanceTransitionActionV0` if successful, else `ProtocolError`. + pub fn try_from_token_issuance_transition_with_contract_lookup( + value: TokenIssuanceTransitionV0, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + let TokenIssuanceTransitionV0 { + base, + amount, + } = value; + + let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup(base, get_data_contract)?; + + Ok(TokenIssuanceTransitionActionV0 { + base: base_action, + issuance_amount: amount, + }) + } + + /// Attempt to convert a borrowed `TokenIssuanceTransitionV0` into a `TokenIssuanceTransitionActionV0` using a data contract lookup function. + /// + /// # Arguments + /// + /// * `value` - A reference to a `TokenIssuanceTransitionV0` from which to derive the action + /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` + /// + /// # Returns + /// + /// * `Result` - A `TokenIssuanceTransitionActionV0` if successful, else `ProtocolError`. + pub fn try_from_borrowed_token_issuance_transition_with_contract_lookup( + value: &TokenIssuanceTransitionV0, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + let TokenIssuanceTransitionV0 { + base, + amount, + } = value; + + let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup(base, get_data_contract)?; + + Ok(TokenIssuanceTransitionActionV0 { + base: base_action, + issuance_amount: *amount, + }) + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs new file mode 100644 index 00000000000..1b096ed4559 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs @@ -0,0 +1,95 @@ +use derive_more::From; + +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::{ + TokenTransferTransitionActionV0, TokenTransferTransitionActionAccessorsV0, +}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; +use std::sync::Arc; + +use crate::drive::contract::DataContractFetchInfo; + +/// transformer module +pub mod transformer; +pub mod v0; + +#[derive(Debug, Clone, From)] +pub enum TokenTransferTransitionAction { + /// v0 + V0(TokenTransferTransitionActionV0), +} + +/// Accessors trait for TokenTransferTransitionAction +pub trait TokenTransferTransitionActionAccessors { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Returns the amount of tokens to transfer + fn amount(&self) -> u64; + + /// Returns the recipient owner ID + fn recipient_owner_id(&self) -> Identifier; + + /// Returns the token ID + fn token_id(&self) -> u16; + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier; + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc; + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc; + + /// Returns the identity contract nonce + fn identity_contract_nonce(&self) -> IdentityNonce; + + /// Returns the ID of the token transfer transition + fn id(&self) -> Identifier; +} + +impl TokenTransferTransitionActionAccessors for TokenTransferTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenTransferTransitionAction::V0(v0) => v0.base(), + } + } + + fn amount(&self) -> u64 { + match self { + TokenTransferTransitionAction::V0(v0) => v0.amount(), + } + } + + fn recipient_owner_id(&self) -> Identifier { + match self { + TokenTransferTransitionAction::V0(v0) => v0.recipient_owner_id(), + } + } + + fn token_id(&self) -> u16 { + self.base().token_id() + } + + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + fn identity_contract_nonce(&self) -> IdentityNonce { + self.base().identity_contract_nonce() + } + + fn id(&self) -> Identifier { + self.base().id() + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs new file mode 100644 index 00000000000..a98da47162f --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs @@ -0,0 +1,62 @@ +use std::sync::Arc; + +use dpp::platform_value::Identifier; +use dpp::ProtocolError; +use dpp::state_transition::documents_batch_transition::TokenTransferTransition; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionV0; + +/// Implement methods to transform a `TokenTransferTransition` into a `TokenTransferTransitionAction`. +impl TokenTransferTransitionAction { + /// Transform a `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `value` - A `TokenTransferTransition` instance. + /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// + /// # Returns + /// + /// * `Result` - A `TokenTransferTransitionAction` if successful, otherwise `ProtocolError`. + pub fn from_token_transfer_transition_with_contract_lookup( + value: TokenTransferTransition, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + match value { + TokenTransferTransition::V0(v0) => { + let v0_action = + TokenTransferTransitionActionV0::try_from_token_transfer_transition_with_contract_lookup( + v0, + get_data_contract, + )?; + Ok(v0_action.into()) + } + } + } + + /// Transform a borrowed `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `value` - A reference to a `TokenTransferTransition`. + /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// + /// # Returns + /// + /// * `Result` - A `TokenTransferTransitionAction` if successful, otherwise `ProtocolError`. + pub fn from_borrowed_token_transfer_transition_with_contract_lookup( + value: &TokenTransferTransition, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + match value { + TokenTransferTransition::V0(v0) => { + let v0_action = TokenTransferTransitionActionV0::try_from_borrowed_token_transfer_transition_with_contract_lookup( + v0, + get_data_contract, + )?; + Ok(v0_action.into()) + } + } + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs new file mode 100644 index 00000000000..398e95a45a5 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs @@ -0,0 +1,78 @@ +mod transformer; + +use std::sync::Arc; + +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; + +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{ + TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0, +}; + +/// Token transfer transition action v0 +#[derive(Debug, Clone)] +pub struct TokenTransferTransitionActionV0 { + /// Base token transition action + pub base: TokenBaseTransitionAction, + /// The amount to transfer + pub amount: u64, + /// The recipient owner ID + pub recipient_owner_id: Identifier, +} + +/// Accessors for `TokenTransferTransitionActionV0` +pub trait TokenTransferTransitionActionAccessorsV0 { + /// Returns the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Returns the amount of tokens to transfer + fn amount(&self) -> u64; + + /// Returns the recipient owner ID + fn recipient_owner_id(&self) -> Identifier; + + /// Returns the token ID from the base action + fn token_id(&self) -> u16 { + self.base().token_id() + } + + /// Returns the data contract ID from the base action + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info from the base action + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + /// Returns the identity contract nonce from the base action + fn identity_contract_nonce(&self) -> IdentityNonce { + self.base().identity_contract_nonce() + } + + /// Returns the transition ID from the base action + fn id(&self) -> Identifier { + self.base().id() + } +} + +impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionActionV0 { + fn base(&self) -> &TokenBaseTransitionAction { + &self.base + } + + fn amount(&self) -> u64 { + self.amount + } + + fn recipient_owner_id(&self) -> Identifier { + self.recipient_owner_id + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs new file mode 100644 index 00000000000..ec1cabe8a00 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -0,0 +1,52 @@ +use std::sync::Arc; + +use dpp::identifier::Identifier; +use dpp::ProtocolError; +use dpp::state_transition::documents_batch_transition::token_transfer_transition::v0::TokenTransferTransitionV0; + +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionActionV0; + +impl TokenTransferTransitionActionV0 { + /// Convert a `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using contract lookup + pub fn try_from_token_transfer_transition_with_contract_lookup( + value: TokenTransferTransitionV0, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + let TokenTransferTransitionV0 { + base, + amount, + recipient_owner_id, + } = value; + + let base_action = + TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup(base, get_data_contract)?; + + Ok(TokenTransferTransitionActionV0 { + base: base_action, + amount, + recipient_owner_id, + }) + } + + /// Convert a borrowed `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using contract lookup + pub fn try_from_borrowed_token_transfer_transition_with_contract_lookup( + value: &TokenTransferTransitionV0, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + ) -> Result { + let TokenTransferTransitionV0 { + base, + amount, + recipient_owner_id, + } = value; + + let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup(&base, get_data_contract)?; + + Ok(TokenTransferTransitionActionV0 { + base: base_action.into(), + amount: *amount, + recipient_owner_id: *recipient_owner_id, + }) + } +} \ No newline at end of file diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/action_type.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transition_action_type.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/action_type.rs rename to packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transition_action_type.rs diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs index c44788e4c36..38489383995 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs @@ -2,6 +2,28 @@ use versioned_feature_core::{FeatureVersion, OptionalFeatureVersion}; pub mod v1; +#[derive(Clone, Debug, Default)] +pub struct DriveTokenMethodVersions { + pub fetch: DriveTokenFetchMethodVersions, + pub prove: DriveTokenProveMethodVersions, + pub insert: DriveTokenInsertMethodVersions, +} + +#[derive(Clone, Debug, Default)] +pub struct DriveTokenFetchMethodVersions { + +} + +#[derive(Clone, Debug, Default)] +pub struct DriveTokenProveMethodVersions { + +} + +#[derive(Clone, Debug, Default)] +pub struct DriveTokenInsertMethodVersions { + pub create_token_root_tree: FeatureVersion, +} + #[derive(Clone, Debug, Default)] pub struct DriveIdentityMethodVersions { pub fetch: DriveIdentityFetchMethodVersions, diff --git a/packages/rs-platform-version/src/version/drive_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/mod.rs index b8c3fae487d..2ef8e57c128 100644 --- a/packages/rs-platform-version/src/version/drive_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/mod.rs @@ -9,6 +9,7 @@ use drive_structure_version::DriveStructureVersion; use drive_verify_method_versions::DriveVerifyMethodVersions; use drive_vote_method_versions::DriveVoteMethodVersions; use grovedb_version::version::GroveVersion; +use crate::version::drive_versions::drive_identity_method_versions::DriveTokenMethodVersions; pub mod drive_contract_method_versions; pub mod drive_credit_pool_method_versions; @@ -45,6 +46,7 @@ pub struct DriveMethodVersions { pub asset_lock: DriveAssetLockMethodVersions, pub verify: DriveVerifyMethodVersions, pub identity: DriveIdentityMethodVersions, + pub token: DriveTokenMethodVersions, pub platform_system: DrivePlatformSystemMethodVersions, pub operations: DriveOperationsMethodVersion, pub batch_operations: DriveBatchOperationsMethodVersion, diff --git a/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs b/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs index 0496d71c07b..00c3628694d 100644 --- a/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs +++ b/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs @@ -3,7 +3,7 @@ use dpp::state_transition::documents_batch_transition::document_transition::Docu use thiserror::Error; use super::*; -use dpp::state_transition::documents_batch_transition::document_transition::action_type::TransitionActionTypeGetter; +use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::TransitionActionTypeGetter; #[wasm_bindgen] #[derive(Error, Debug)] diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 0b927a60803..e7aa93c253a 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -14,7 +14,7 @@ use dpp::document::Document; use dpp::prelude::ExtendedDocument; use dpp::identifier::Identifier; -use dpp::state_transition::documents_batch_transition::document_transition::action_type::DocumentTransitionActionType; +use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; use dpp::version::PlatformVersion; use std::convert::TryFrom; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index a26d579d7de..d952f2ed3d7 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -8,7 +8,7 @@ mod document_create_transition; use dpp::platform_value::Value; use dpp::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::action_type::TransitionActionTypeGetter; +use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::TransitionActionTypeGetter; use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransitionV0Methods; use dpp::{ state_transition::documents_batch_transition::document_transition::DocumentTransition, From 531aab2592417a62f1cc09d4a8041125e4b9ee54 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 10 Dec 2024 09:58:29 +0300 Subject: [PATCH 09/61] more work --- packages/rs-dpp/src/balances/credits.rs | 3 + .../v0/mod.rs | 3 - .../src/document/document_factory/mod.rs | 3 +- .../specialized_document_factory/mod.rs | 3 +- packages/rs-dpp/src/nft/mod.rs | 2 +- .../document_transition_action_type.rs | 4 +- .../document_transition/mod.rs | 6 +- .../token_transition_action_type.rs | 4 +- .../src/drive/tokens/balance/prove.rs | 34 ++++++---- .../create_token_root_tree/mod.rs | 7 +- .../create_token_root_tree/v0/mod.rs | 21 +++--- .../src/drive/tokens/initialization/mod.rs | 2 +- .../document/mod.rs | 4 ++ .../document/token_burn_transition.rs | 60 +++++++++++++++++ .../document/token_issuance_transition.rs | 60 +++++++++++++++++ .../document/token_transfer_transition.rs | 61 ++++++++++++++++++ .../document/token_transition.rs | 35 ++++++++++ .../document_transition/mod.rs | 24 ++++--- .../token_base_transition_action/mod.rs | 4 +- .../token_base_transition_action/v0/mod.rs | 29 ++++++--- .../v0/transformer.rs | 6 +- .../token_burn_transition_action/mod.rs | 9 ++- .../transformer.rs | 2 +- .../token_burn_transition_action/v0/mod.rs | 2 +- .../v0/transformer.rs | 27 ++++---- .../token_issuance_transition_action/mod.rs | 10 ++- .../transformer.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 27 ++++---- .../token_transfer_transition_action/mod.rs | 64 ++++++++----------- .../transformer.rs | 2 +- .../v0/mod.rs | 12 ++-- .../v0/transformer.rs | 22 ++++--- .../document/documents_batch/mod.rs | 4 +- .../document/documents_batch/v0/mod.rs | 4 +- .../src/util/batch/drive_op_batch/mod.rs | 12 ++++ .../src/util/batch/drive_op_batch/token.rs | 43 +++++++++++++ .../drive_identity_method_versions/mod.rs | 22 ------- .../mod.rs | 3 + .../v1.rs | 3 + .../drive_token_method_versions/mod.rs | 21 ++++++ .../drive_token_method_versions/v1.rs | 12 ++++ .../src/version/drive_versions/mod.rs | 3 +- .../src/version/drive_versions/v1.rs | 2 + .../src/version/drive_versions/v2.rs | 2 + .../src/version/mocks/v2_test.rs | 2 + 46 files changed, 509 insertions(+), 180 deletions(-) create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs create mode 100644 packages/rs-drive/src/util/batch/drive_op_batch/token.rs create mode 100644 packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs create mode 100644 packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs diff --git a/packages/rs-dpp/src/balances/credits.rs b/packages/rs-dpp/src/balances/credits.rs index d0f9e2805b9..678159d24a3 100644 --- a/packages/rs-dpp/src/balances/credits.rs +++ b/packages/rs-dpp/src/balances/credits.rs @@ -19,6 +19,9 @@ pub type Duffs = u64; pub type Credits = u64; +/// Token Amount type +pub type TokenAmount = u64; + /// Signed Credits type is used for internal computations and total credits /// balance verification diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index e255a3642b0..b33965da2dc 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -1,8 +1,5 @@ -use crate::consensus::state::data_contract::data_contract_config_update_error::DataContractConfigUpdateError; -use crate::consensus::state::data_contract::data_contract_is_readonly_error::DataContractIsReadonlyError; use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; -use crate::data_contract::config::v0::DataContractConfigGettersV0; use crate::multi_identity_events::ActionTaker; use crate::validation::SimpleConsensusValidationResult; use platform_value::Identifier; diff --git a/packages/rs-dpp/src/document/document_factory/mod.rs b/packages/rs-dpp/src/document/document_factory/mod.rs index ab09444cbe1..ec445012e6e 100644 --- a/packages/rs-dpp/src/document/document_factory/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/mod.rs @@ -14,7 +14,8 @@ use crate::document::Document; use crate::document::ExtendedDocument; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ - document_transition::document_transition_action_type::DocumentTransitionActionType, DocumentsBatchTransition, + document_transition::document_transition_action_type::DocumentTransitionActionType, + DocumentsBatchTransition, }; use crate::util::entropy_generator::EntropyGenerator; pub use v0::DocumentFactoryV0; diff --git a/packages/rs-dpp/src/document/specialized_document_factory/mod.rs b/packages/rs-dpp/src/document/specialized_document_factory/mod.rs index dbd21b3e6f3..80f0bf09994 100644 --- a/packages/rs-dpp/src/document/specialized_document_factory/mod.rs +++ b/packages/rs-dpp/src/document/specialized_document_factory/mod.rs @@ -14,7 +14,8 @@ use crate::document::Document; use crate::document::ExtendedDocument; #[cfg(feature = "state-transitions")] use crate::state_transition::documents_batch_transition::{ - document_transition::document_transition_action_type::DocumentTransitionActionType, DocumentsBatchTransition, + document_transition::document_transition_action_type::DocumentTransitionActionType, + DocumentsBatchTransition, }; use crate::util::entropy_generator::EntropyGenerator; pub use v0::SpecializedDocumentFactoryV0; diff --git a/packages/rs-dpp/src/nft/mod.rs b/packages/rs-dpp/src/nft/mod.rs index b558d676586..f81092f0790 100644 --- a/packages/rs-dpp/src/nft/mod.rs +++ b/packages/rs-dpp/src/nft/mod.rs @@ -5,7 +5,7 @@ use crate::ProtocolError; use platform_value::Identifier; use std::fmt; use std::fmt::{Display, Formatter}; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum TradeMode { None = 0, DirectPurchase = 1, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs index 02564237d1f..7eb27a84a6e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs @@ -1,4 +1,6 @@ -use crate::state_transition::documents_batch_transition::document_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentTransition}; +use crate::state_transition::documents_batch_transition::document_transition::{ + DocumentPurchaseTransition, DocumentTransferTransition, DocumentTransition, +}; use crate::ProtocolError; // @append-only diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs index 9697e82c1d3..92ee2015e97 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs @@ -8,13 +8,13 @@ use serde::{Deserialize, Serialize}; use crate::prelude::{Identifier, IdentityNonce}; use document_base_transition::DocumentBaseTransition; -pub mod document_transition_action_type; pub mod document_base_transition; pub mod document_create_transition; pub mod document_delete_transition; pub mod document_purchase_transition; pub mod document_replace_transition; pub mod document_transfer_transition; +pub mod document_transition_action_type; pub mod document_update_price_transition; pub mod token_base_transition; pub mod token_burn_transition; @@ -281,8 +281,6 @@ impl DocumentTransitionV0Methods for DocumentTransition { } } - - #[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] #[cfg_attr( feature = "state-transition-serde-conversion", @@ -383,5 +381,3 @@ pub enum BatchedTransition { #[display("TokenTransition({})", "_0")] Token(TokenTransition), } - - diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs index 30d61be4077..5d33edb1164 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs @@ -1,5 +1,5 @@ -use crate::ProtocolError; use crate::state_transition::documents_batch_transition::document_transition::TokenTransition; +use crate::ProtocolError; // @append-only #[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)] @@ -36,4 +36,4 @@ impl TryFrom<&str> for TokenTransitionActionType { ))), } } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/drive/tokens/balance/prove.rs b/packages/rs-drive/src/drive/tokens/balance/prove.rs index 968b1588489..f2ce692e6a7 100644 --- a/packages/rs-drive/src/drive/tokens/balance/prove.rs +++ b/packages/rs-drive/src/drive/tokens/balance/prove.rs @@ -40,7 +40,8 @@ impl Drive { transaction: TransactionArg, drive_version: &DriveVersion, ) -> Result, Error> { - let balance_query = Self::token_balances_for_range_query(token_id, start_at, ascending, limit); + let balance_query = + Self::token_balances_for_range_query(token_id, start_at, ascending, limit); self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) } } @@ -78,16 +79,21 @@ mod tests { ) .expect("expected to add an identity"); let proof = drive - .prove_identity_token_balance(identity.id().to_buffer(), None, &platform_version.drive) + .prove_identity_token_balance( + identity.id().to_buffer(), + None, + &platform_version.drive, + ) .expect("should not error when proving an identity"); - let (_, proved_identity_balance) = Drive::verify_identity_token_balance_for_identity_id( - proof.as_slice(), - identity_id, - false, - platform_version, - ) - .expect("expect that this be verified"); + let (_, proved_identity_balance) = + Drive::verify_identity_token_balance_for_identity_id( + proof.as_slice(), + identity_id, + false, + platform_version, + ) + .expect("expect that this be verified"); assert_eq!(proved_identity_balance, Some(identity.balance())); } @@ -98,9 +104,9 @@ mod tests { use dpp::fee::Credits; use dpp::identity::accessors::IdentityGettersV0; use platform_version::version::PlatformVersion; - use std::collections::BTreeMap; use rand::rngs::StdRng; use rand::{Rng, SeedableRng}; + use std::collections::BTreeMap; #[test] fn should_prove_multiple_identity_single_token_balances() { @@ -112,11 +118,11 @@ mod tests { .into_iter() .map(|identity| (identity.id().to_buffer(), identity)) .collect(); - + let mut rng = StdRng::seed_from_u64(293); - - let token_id: [u8;32] = rng.gen(); - + + let token_id: [u8; 32] = rng.gen(); + drive.add_new_token(token_id); for identity in identities.values() { diff --git a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs b/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs index 3350c403a86..c7936fa707a 100644 --- a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs +++ b/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs @@ -13,12 +13,11 @@ use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; use std::collections::HashMap; - impl Drive { /// Adds a identity by inserting a new identity subtree structure to the `Identities` subtree. pub fn create_token_root_tree( &self, - token_id: [u8;32], + token_id: [u8; 32], block_info: &BlockInfo, apply: bool, transaction: TransactionArg, @@ -49,7 +48,7 @@ impl Drive { /// Adds identity creation operations to drive operations pub fn create_token_root_tree_add_to_operations( &self, - token_id: [u8;32], + token_id: [u8; 32], apply: bool, previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, @@ -82,7 +81,7 @@ impl Drive { /// The operations needed to create an identity pub fn create_token_root_tree_operations( &self, - token_id: [u8;32], + token_id: [u8; 32], previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, diff --git a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs b/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs index f39fa2f708c..a20e5c8e8f5 100644 --- a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs @@ -1,18 +1,16 @@ -use crate::drive::{ - Drive -}; +use crate::drive::tokens::token_balances_root_path; +use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use crate::util::grove_operations::BatchInsertTreeApplyType; +use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKey; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; -use std::collections::HashMap; use platform_version::version::PlatformVersion; -use crate::drive::tokens::token_balances_root_path; -use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKey; +use std::collections::HashMap; impl Drive { /// Creates a new token root subtree at `TokenBalances` keyed by `token_id`. @@ -92,7 +90,9 @@ impl Drive { &self, token_id: [u8; 32], previous_batch_operations: &mut Option<&mut Vec>, - estimated_costs_only_with_layer_info: &mut Option>, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { @@ -111,10 +111,7 @@ impl Drive { // Insert an empty tree for this token if it doesn't exist let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey(( - token_balances_root_path(), - token_id.to_vec(), - )), + PathFixedSizeKey((token_balances_root_path(), token_id.to_vec())), true, None, // No storage flags apply_type, @@ -133,4 +130,4 @@ impl Drive { Ok(batch_operations) } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/drive/tokens/initialization/mod.rs b/packages/rs-drive/src/drive/tokens/initialization/mod.rs index fc9a17c4b21..8ee69e35926 100644 --- a/packages/rs-drive/src/drive/tokens/initialization/mod.rs +++ b/packages/rs-drive/src/drive/tokens/initialization/mod.rs @@ -1 +1 @@ -mod create_token_root_tree; \ No newline at end of file +mod create_token_root_tree; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs index d473c995af1..8df3a3906e7 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs @@ -12,6 +12,10 @@ mod document_transfer_transition; mod document_transition; mod document_update_price_transition; mod documents_batch_transition; +mod token_burn_transition; +mod token_issuance_transition; +mod token_transfer_transition; +mod token_transition; /// A converter that will get High Level Drive Operations from State transitions pub trait DriveHighLevelDocumentOperationConverter { diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs new file mode 100644 index 00000000000..9bed296313b --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs @@ -0,0 +1,60 @@ +use dpp::block::epoch::Epoch; +use dpp::identifier::Identifier; +use platform_version::version::PlatformVersion; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use crate::util::batch::{DriveOperation, IdentityOperationType}; +use crate::util::batch::drive_op_batch::TokenOperationType; +use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; +use crate::util::object_size_info::DataContractInfo::DataContractFetchInfo; + +impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { + fn into_high_level_document_drive_operations<'b>( + mut self, + _epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .state_transitions + .convert_to_high_level_operations + .token_burn_transition + { + 0 => { + let data_contract_id = self.base().data_contract_id(); + + let contract_fetch_info = self.base().data_contract_fetch_info(); + + let identity_contract_nonce = self.base().identity_contract_nonce(); + + let mut ops = vec![IdentityOperation( + IdentityOperationType::UpdateIdentityContractNonce { + identity_id: owner_id.into_buffer(), + contract_id: data_contract_id.into_buffer(), + nonce: identity_contract_nonce, + }, + )]; + + ops.push(TokenOperation(TokenOperationType::TokenBurn { + contract_info: DataContractFetchInfo(contract_fetch_info), + token_position: self.token_position(), + token_id: self.token_id(), + burn_amount: self.burn_amount(), + })); + + Ok(ops) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "TokenBurnTransitionAction::into_high_level_document_drive_operations" + .to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs new file mode 100644 index 00000000000..85080d7ff28 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs @@ -0,0 +1,60 @@ +use dpp::block::epoch::Epoch; +use dpp::identifier::Identifier; +use platform_version::version::PlatformVersion; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use crate::util::batch::{DriveOperation, IdentityOperationType}; +use crate::util::batch::drive_op_batch::TokenOperationType; +use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; +use crate::util::object_size_info::DataContractInfo::DataContractFetchInfo; + +impl DriveHighLevelDocumentOperationConverter for TokenIssuanceTransitionAction { + fn into_high_level_document_drive_operations<'b>( + mut self, + _epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .state_transitions + .convert_to_high_level_operations + .token_issuance_transition + { + 0 => { + let data_contract_id = self.base().data_contract_id(); + + let contract_fetch_info = self.base().data_contract_fetch_info(); + + let identity_contract_nonce = self.base().identity_contract_nonce(); + + let mut ops = vec![IdentityOperation( + IdentityOperationType::UpdateIdentityContractNonce { + identity_id: owner_id.into_buffer(), + contract_id: data_contract_id.into_buffer(), + nonce: identity_contract_nonce, + }, + )]; + + ops.push(TokenOperation(TokenOperationType::TokenIssuance { + contract_info: DataContractFetchInfo(contract_fetch_info), + token_position: self.token_position(), + token_id: self.token_id(), + issuance_amount: self.issuance_amount(), + })); + + Ok(ops) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "TokenIssuanceTransitionAction::into_high_level_document_drive_operations" + .to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs new file mode 100644 index 00000000000..b02870222b7 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs @@ -0,0 +1,61 @@ +use dpp::block::epoch::Epoch; +use dpp::identifier::Identifier; +use platform_version::version::PlatformVersion; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; +use crate::util::batch::{DriveOperation, IdentityOperationType}; +use crate::util::batch::drive_op_batch::TokenOperationType; +use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; +use crate::util::object_size_info::DataContractInfo::DataContractFetchInfo; + +impl DriveHighLevelDocumentOperationConverter for TokenTransferTransitionAction { + fn into_high_level_document_drive_operations<'b>( + mut self, + _epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .state_transitions + .convert_to_high_level_operations + .token_transfer_transition + { + 0 => { + let data_contract_id = self.base().data_contract_id(); + + let contract_fetch_info = self.base().data_contract_fetch_info(); + + let identity_contract_nonce = self.base().identity_contract_nonce(); + + let mut ops = vec![IdentityOperation( + IdentityOperationType::UpdateIdentityContractNonce { + identity_id: owner_id.into_buffer(), + contract_id: data_contract_id.into_buffer(), + nonce: identity_contract_nonce, + }, + )]; + + ops.push(TokenOperation(TokenOperationType::TokenTransfer { + contract_info: DataContractFetchInfo(contract_fetch_info), + token_position: self.token_position(), + token_id: self.token_id(), + recipient_id: self.recipient_id(), + amount: self.amount(), + })); + + Ok(ops) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "TokenTransferTransitionAction::into_high_level_document_drive_operations" + .to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs new file mode 100644 index 00000000000..e577bf9c9d5 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs @@ -0,0 +1,35 @@ +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::TokenTransitionAction; +use crate::util::batch::DriveOperation; +use dpp::block::epoch::Epoch; +use dpp::prelude::Identifier; +use dpp::version::PlatformVersion; + +impl DriveHighLevelDocumentOperationConverter for TokenTransitionAction { + fn into_high_level_document_drive_operations<'b>( + self, + epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match self { + TokenTransitionAction::BurnAction(token_burn_transition) => token_burn_transition + .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + TokenTransitionAction::IssuanceAction(token_issuance_transition) => { + token_issuance_transition.into_high_level_document_drive_operations( + epoch, + owner_id, + platform_version, + ) + } + TokenTransitionAction::TransferAction(token_transfer_transition) => { + token_transfer_transition.into_high_level_document_drive_operations( + epoch, + owner_id, + platform_version, + ) + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index d869f4bd56c..9d642fb7c57 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -1,4 +1,3 @@ -mod document_transition_action_type; /// document_base_transition_action pub mod document_base_transition_action; /// document_create_transition_action @@ -11,6 +10,7 @@ pub mod document_purchase_transition_action; pub mod document_replace_transition_action; /// document_transfer_transition_action pub mod document_transfer_transition_action; +mod document_transition_action_type; /// document_update_price_transition_action pub mod document_update_price_transition_action; /// token_base_transition_action @@ -25,7 +25,6 @@ pub mod token_transfer_transition_action; pub use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; use derive_more::From; - use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; @@ -35,6 +34,10 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors, TokenTransferTransitionActionAccessorsV0}; /// version pub const DOCUMENT_TRANSITION_ACTION_VERSION: u32 = 0; @@ -86,12 +89,6 @@ impl DocumentTransitionAction { } } - -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors, TokenTransferTransitionActionAccessorsV0}; - /// token action #[derive(Debug, Clone, From)] pub enum TokenTransitionAction { @@ -121,4 +118,13 @@ impl TokenTransitionAction { TokenTransitionAction::TransferAction(action) => Some(action.base_owned()), } } -} \ No newline at end of file +} + +/// token action +#[derive(Debug, Clone, From)] +pub enum BatchTransitionAction { + /// document + DocumentAction(DocumentTransitionAction), + /// token + TokenAction(TokenTransitionAction), +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs index 9735a345829..c20c622ede0 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs @@ -28,9 +28,9 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionAction { } } - fn token_id(&self) -> u16 { + fn token_position(&self) -> u16 { match self { - TokenBaseTransitionAction::V0(v0) => v0.token_id, + TokenBaseTransitionAction::V0(v0) => v0.token_position, } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs index 7399a447c99..54a49ff5ae8 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs @@ -1,8 +1,10 @@ -use std::sync::Arc; +use crate::drive::contract::DataContractFetchInfo; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; -use crate::drive::contract::DataContractFetchInfo; +use dpp::util::hash::{hash_double, hash_single}; +use platform_version::version::PlatformVersion; +use std::sync::Arc; /// transformer pub mod transformer; @@ -14,8 +16,8 @@ pub struct TokenBaseTransitionActionV0 { pub id: Identifier, /// The identity contract nonce, used to prevent replay attacks pub identity_contract_nonce: IdentityNonce, - /// The token ID within the data contract - pub token_id: u16, + /// The token position within the data contract + pub token_position: u16, /// A potential data contract pub data_contract: Arc, } @@ -25,8 +27,17 @@ pub trait TokenBaseTransitionActionAccessorsV0 { /// Returns the token transition ID fn id(&self) -> Identifier; - /// The token ID within the data contract - fn token_id(&self) -> u16; + /// The token position within the data contract + fn token_position(&self) -> u16; + + /// The token id + fn token_id(&self) -> Identifier { + // Prepare the data for hashing + let mut bytes = b"token".to_vec(); + bytes.extend_from_slice(self.data_contract_id().as_bytes()); + bytes.extend_from_slice(&self.token_position().to_be_bytes()); + hash_double(bytes).into() + } /// Returns the data contract ID fn data_contract_id(&self) -> Identifier; @@ -46,8 +57,8 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { self.id } - fn token_id(&self) -> u16 { - self.token_id + fn token_position(&self) -> u16 { + self.token_position } fn data_contract_id(&self) -> Identifier { @@ -65,4 +76,4 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { fn identity_contract_nonce(&self) -> IdentityNonce { self.identity_contract_nonce } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index cd31ad0eca7..5271a915b71 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -17,14 +17,14 @@ impl TokenBaseTransitionActionV0 { ) -> Result { let TokenBaseTransitionV0 { id, - token_id, + token_id, data_contract_id, identity_contract_nonce, } = value; Ok(TokenBaseTransitionActionV0 { id, identity_contract_nonce, - token_id, + token_position: token_id, data_contract: get_data_contract(data_contract_id)?, }) } @@ -43,7 +43,7 @@ impl TokenBaseTransitionActionV0 { Ok(TokenBaseTransitionActionV0 { id: *id, identity_contract_nonce: *identity_contract_nonce, - token_id: *token_id, + token_position: *token_id, data_contract: get_data_contract(*data_contract_id)?, }) } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs index ad67240e662..5bd20100683 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs @@ -30,8 +30,13 @@ pub trait TokenBurnTransitionActionAccessorsV0 { /// Returns the burn amount fn burn_amount(&self) -> u64; + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } + /// Returns the token ID - fn token_id(&self) -> u16 { + fn token_id(&self) -> Identifier { self.base().token_id() } @@ -73,4 +78,4 @@ impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionAction { TokenBurnTransitionAction::V0(v0) => v0.burn_amount, } } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs index c7fbab433ff..0c30139ef25 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs @@ -61,4 +61,4 @@ impl TokenBurnTransitionAction { } } } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs index 43361d713bb..ac2d734442a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs @@ -41,4 +41,4 @@ impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionActionV0 { fn set_burn_amount(&mut self, amount: u64) { self.burn_amount = amount; } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index a32a792fa3f..fd19381a0e4 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use dpp::identifier::Identifier; -use dpp::ProtocolError; use dpp::state_transition::documents_batch_transition::token_burn_transition::v0::TokenBurnTransitionV0; +use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; @@ -23,12 +23,12 @@ impl TokenBurnTransitionActionV0 { value: TokenBurnTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenBurnTransitionV0 { - base, - burn_amount, - } = value; + let TokenBurnTransitionV0 { base, burn_amount } = value; - let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup(base, get_data_contract)?; + let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( + base, + get_data_contract, + )?; Ok(TokenBurnTransitionActionV0 { base: base_action, @@ -50,16 +50,17 @@ impl TokenBurnTransitionActionV0 { value: &TokenBurnTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenBurnTransitionV0 { - base, - burn_amount, - } = value; - - let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup(base, get_data_contract)?; + let TokenBurnTransitionV0 { base, burn_amount } = value; + + let base_action = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + base, + get_data_contract, + )?; Ok(TokenBurnTransitionActionV0 { base: base_action, burn_amount: *burn_amount, }) } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs index 2945960906b..ca088bd3211 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use crate::drive::contract::DataContractFetchInfo; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; +use dpp::util::hash::hash_double; /// transformer module for token issuance transition action pub mod transformer; @@ -30,8 +31,13 @@ pub trait TokenIssuanceTransitionActionAccessorsV0 { /// Returns the issuance amount fn issuance_amount(&self) -> u64; + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } + /// Returns the token ID - fn token_id(&self) -> u16 { + fn token_id(&self) -> Identifier { self.base().token_id() } @@ -73,4 +79,4 @@ impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionAction TokenIssuanceTransitionAction::V0(v0) => v0.issuance_amount, } } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs index 9c48ded7ecc..b8d58504ae7 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs @@ -61,4 +61,4 @@ impl TokenIssuanceTransitionAction { } } } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs index 848bab85c9a..c8f73a9a960 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs @@ -41,4 +41,4 @@ impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV fn set_issuance_amount(&mut self, amount: u64) { self.issuance_amount = amount; } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs index 7db1c9eb90a..fd678a81d73 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use dpp::identifier::Identifier; -use dpp::ProtocolError; use dpp::state_transition::documents_batch_transition::token_issuance_transition::v0::TokenIssuanceTransitionV0; +use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; @@ -23,12 +23,12 @@ impl TokenIssuanceTransitionActionV0 { value: TokenIssuanceTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenIssuanceTransitionV0 { - base, - amount, - } = value; + let TokenIssuanceTransitionV0 { base, amount } = value; - let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup(base, get_data_contract)?; + let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( + base, + get_data_contract, + )?; Ok(TokenIssuanceTransitionActionV0 { base: base_action, @@ -50,16 +50,17 @@ impl TokenIssuanceTransitionActionV0 { value: &TokenIssuanceTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenIssuanceTransitionV0 { - base, - amount, - } = value; - - let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup(base, get_data_contract)?; + let TokenIssuanceTransitionV0 { base, amount } = value; + + let base_action = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + base, + get_data_contract, + )?; Ok(TokenIssuanceTransitionActionV0 { base: base_action, issuance_amount: *amount, }) } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs index 1b096ed4559..c46b4a9209a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs @@ -7,7 +7,6 @@ use crate::state_transition_action::document::documents_batch::document_transiti use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; use std::sync::Arc; - use crate::drive::contract::DataContractFetchInfo; /// transformer module @@ -28,26 +27,43 @@ pub trait TokenTransferTransitionActionAccessors { /// Returns the amount of tokens to transfer fn amount(&self) -> u64; - /// Returns the recipient owner ID - fn recipient_owner_id(&self) -> Identifier; + /// Returns the recipient ID + fn recipient_id(&self) -> Identifier; + + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } /// Returns the token ID - fn token_id(&self) -> u16; + fn token_id(&self) -> Identifier { + self.base().token_id() + } /// Returns the data contract ID - fn data_contract_id(&self) -> Identifier; + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } /// Returns a reference to the data contract fetch info - fn data_contract_fetch_info_ref(&self) -> &Arc; + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } /// Returns the data contract fetch info - fn data_contract_fetch_info(&self) -> Arc; + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } /// Returns the identity contract nonce - fn identity_contract_nonce(&self) -> IdentityNonce; + fn identity_contract_nonce(&self) -> IdentityNonce { + self.base().identity_contract_nonce() + } /// Returns the ID of the token transfer transition - fn id(&self) -> Identifier; + fn id(&self) -> Identifier { + self.base().id() + } } impl TokenTransferTransitionActionAccessors for TokenTransferTransitionAction { @@ -63,33 +79,9 @@ impl TokenTransferTransitionActionAccessors for TokenTransferTransitionAction { } } - fn recipient_owner_id(&self) -> Identifier { + fn recipient_id(&self) -> Identifier { match self { - TokenTransferTransitionAction::V0(v0) => v0.recipient_owner_id(), + TokenTransferTransitionAction::V0(v0) => v0.recipient_id(), } } - - fn token_id(&self) -> u16 { - self.base().token_id() - } - - fn data_contract_id(&self) -> Identifier { - self.base().data_contract_id() - } - - fn data_contract_fetch_info_ref(&self) -> &Arc { - self.base().data_contract_fetch_info_ref() - } - - fn data_contract_fetch_info(&self) -> Arc { - self.base().data_contract_fetch_info() - } - - fn identity_contract_nonce(&self) -> IdentityNonce { - self.base().identity_contract_nonce() - } - - fn id(&self) -> Identifier { - self.base().id() - } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs index a98da47162f..4fa1726b9af 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs @@ -59,4 +59,4 @@ impl TokenTransferTransitionAction { } } } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs index 398e95a45a5..538ef76f120 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs @@ -18,7 +18,7 @@ pub struct TokenTransferTransitionActionV0 { /// The amount to transfer pub amount: u64, /// The recipient owner ID - pub recipient_owner_id: Identifier, + pub recipient_id: Identifier, } /// Accessors for `TokenTransferTransitionActionV0` @@ -30,11 +30,11 @@ pub trait TokenTransferTransitionActionAccessorsV0 { fn amount(&self) -> u64; /// Returns the recipient owner ID - fn recipient_owner_id(&self) -> Identifier; + fn recipient_id(&self) -> Identifier; /// Returns the token ID from the base action fn token_id(&self) -> u16 { - self.base().token_id() + self.base().token_position() } /// Returns the data contract ID from the base action @@ -72,7 +72,7 @@ impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionActionV self.amount } - fn recipient_owner_id(&self) -> Identifier { - self.recipient_owner_id + fn recipient_id(&self) -> Identifier { + self.recipient_id } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index ec1cabe8a00..e1b1bc7d05e 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use dpp::identifier::Identifier; -use dpp::ProtocolError; use dpp::state_transition::documents_batch_transition::token_transfer_transition::v0::TokenTransferTransitionV0; +use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; @@ -20,13 +20,15 @@ impl TokenTransferTransitionActionV0 { recipient_owner_id, } = value; - let base_action = - TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup(base, get_data_contract)?; + let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( + base, + get_data_contract, + )?; Ok(TokenTransferTransitionActionV0 { base: base_action, amount, - recipient_owner_id, + recipient_id: recipient_owner_id, }) } @@ -40,13 +42,17 @@ impl TokenTransferTransitionActionV0 { amount, recipient_owner_id, } = value; - - let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup(&base, get_data_contract)?; + + let base_action = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + &base, + get_data_contract, + )?; Ok(TokenTransferTransitionActionV0 { base: base_action.into(), amount: *amount, - recipient_owner_id: *recipient_owner_id, + recipient_id: *recipient_owner_id, }) } -} \ No newline at end of file +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs index 9d5891f0d1f..665baa8f14c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs @@ -1,4 +1,4 @@ -use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::{BatchTransitionAction, DocumentTransitionAction}; use crate::state_transition_action::document::documents_batch::v0::DocumentsBatchTransitionActionV0; use derive_more::From; use dpp::data_contract::accessors::v0::DataContractV0Getters; @@ -52,7 +52,7 @@ impl DocumentsBatchTransitionAction { } /// transitions owned - pub fn transitions_owned(self) -> Vec { + pub fn transitions_owned(self) -> Vec { match self { DocumentsBatchTransitionAction::V0(v0) => v0.transitions, } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs index 295f0c45b4a..d385fc4b388 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs @@ -1,5 +1,5 @@ use dpp::fee::Credits; -use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::{BatchTransitionAction, DocumentTransitionAction}; use dpp::identifier::Identifier; use dpp::prelude::UserFeeIncrease; use dpp::ProtocolError; @@ -12,7 +12,7 @@ pub struct DocumentsBatchTransitionActionV0 { /// The owner making the transitions pub owner_id: Identifier, /// The inner transitions - pub transitions: Vec, + pub transitions: Vec, /// fee multiplier pub user_fee_increase: UserFeeIncrease, } diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs index abdd9f4cc6d..bf351d6ac1d 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs @@ -5,6 +5,7 @@ mod finalize_task; mod identity; mod prefunded_specialized_balance; mod system; +mod token; mod withdrawals; use crate::util::batch::GroveDbOpBatch; @@ -22,6 +23,7 @@ pub use document::UpdateOperationInfo; pub use identity::IdentityOperationType; pub use prefunded_specialized_balance::PrefundedSpecializedBalanceOperationType; pub use system::SystemOperationType; +pub use token::TokenOperationType; pub use withdrawals::WithdrawalOperationType; use grovedb::{EstimatedLayerInformation, TransactionArg}; @@ -69,6 +71,8 @@ pub enum DriveOperation<'a> { DataContractOperation(DataContractOperationType<'a>), /// A document operation DocumentOperation(DocumentOperationType<'a>), + /// A token operation + TokenOperation(TokenOperationType<'a>), /// Withdrawal operation WithdrawalOperation(WithdrawalOperationType), /// An identity operation @@ -152,6 +156,14 @@ impl DriveLowLevelOperationConverter for DriveOperation<'_> { .into_iter() .map(GroveOperation) .collect()), + DriveOperation::TokenOperation(token_operation_type) => token_operation_type + .into_low_level_drive_operations( + drive, + estimated_costs_only_with_layer_info, + block_info, + transaction, + platform_version, + ), } } } diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs new file mode 100644 index 00000000000..4836b377c93 --- /dev/null +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -0,0 +1,43 @@ +use crate::util::object_size_info::DataContractInfo; +use dpp::balances::credits::TokenAmount; +use dpp::identifier::Identifier; + +/// Operations on Documents +#[derive(Clone, Debug)] +pub enum TokenOperationType<'a> { + /// Adds a document to a contract matching the desired info. + TokenBurn { + /// Data Contract info to potentially be resolved if needed + contract_info: DataContractInfo<'a>, + /// Token position in the contract, is 0 if there is only one token + token_position: u16, + /// The token id + token_id: Identifier, + /// The amount to burn + burn_amount: TokenAmount, + }, + /// Adds a document to a contract matching the desired info. + TokenIssuance { + /// Data Contract info to potentially be resolved if needed + contract_info: DataContractInfo<'a>, + /// Token position in the contract, is 0 if there is only one token + token_position: u16, + /// The token id + token_id: Identifier, + /// The amount to issue + issuance_amount: TokenAmount, + }, + /// Adds a document to a contract matching the desired info. + TokenTransfer { + /// Data Contract info to potentially be resolved if needed + contract_info: DataContractInfo<'a>, + /// Token position in the contract, is 0 if there is only one token + token_position: u16, + /// The token id + token_id: Identifier, + /// The recipient of the transfer + recipient_id: Identifier, + /// The amount to transfer + amount: TokenAmount, + }, +} diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs index 38489383995..c44788e4c36 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs @@ -2,28 +2,6 @@ use versioned_feature_core::{FeatureVersion, OptionalFeatureVersion}; pub mod v1; -#[derive(Clone, Debug, Default)] -pub struct DriveTokenMethodVersions { - pub fetch: DriveTokenFetchMethodVersions, - pub prove: DriveTokenProveMethodVersions, - pub insert: DriveTokenInsertMethodVersions, -} - -#[derive(Clone, Debug, Default)] -pub struct DriveTokenFetchMethodVersions { - -} - -#[derive(Clone, Debug, Default)] -pub struct DriveTokenProveMethodVersions { - -} - -#[derive(Clone, Debug, Default)] -pub struct DriveTokenInsertMethodVersions { - pub create_token_root_tree: FeatureVersion, -} - #[derive(Clone, Debug, Default)] pub struct DriveIdentityMethodVersions { pub fetch: DriveIdentityFetchMethodVersions, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs index c4825489080..72cc00bf3ff 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs @@ -20,6 +20,9 @@ pub struct DriveStateTransitionActionConvertToHighLevelOperationsMethodVersions pub document_replace_transition: FeatureVersion, pub document_transfer_transition: FeatureVersion, pub document_update_price_transition: FeatureVersion, + pub token_burn_transition: FeatureVersion, + pub token_issuance_transition: FeatureVersion, + pub token_transfer_transition: FeatureVersion, pub documents_batch_transition: FeatureVersion, pub identity_create_transition: FeatureVersion, pub identity_credit_transfer_transition: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs index 45e732c99c4..3b694dbfb4e 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs @@ -22,6 +22,9 @@ pub const DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1: DriveStateTransitionMethodV document_replace_transition: 0, document_transfer_transition: 0, document_update_price_transition: 0, + token_burn_transition: 0, + token_issuance_transition: 0, + token_transfer_transition: 0, documents_batch_transition: 0, identity_create_transition: 0, identity_credit_transfer_transition: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs new file mode 100644 index 00000000000..f80cf8108ca --- /dev/null +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -0,0 +1,21 @@ +use versioned_feature_core::FeatureVersion; + +pub mod v1; + +#[derive(Clone, Debug, Default)] +pub struct DriveTokenMethodVersions { + pub fetch: DriveTokenFetchMethodVersions, + pub prove: DriveTokenProveMethodVersions, + pub insert: DriveTokenInsertMethodVersions, +} + +#[derive(Clone, Debug, Default)] +pub struct DriveTokenFetchMethodVersions {} + +#[derive(Clone, Debug, Default)] +pub struct DriveTokenProveMethodVersions {} + +#[derive(Clone, Debug, Default)] +pub struct DriveTokenInsertMethodVersions { + pub create_token_root_tree: FeatureVersion, +} diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs new file mode 100644 index 00000000000..d4a2a602394 --- /dev/null +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -0,0 +1,12 @@ +use crate::version::drive_versions::drive_token_method_versions::{ + DriveTokenFetchMethodVersions, DriveTokenInsertMethodVersions, DriveTokenMethodVersions, + DriveTokenProveMethodVersions, +}; + +pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenMethodVersions { + fetch: DriveTokenFetchMethodVersions {}, + prove: DriveTokenProveMethodVersions {}, + insert: DriveTokenInsertMethodVersions { + create_token_root_tree: 0, + }, +}; diff --git a/packages/rs-platform-version/src/version/drive_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/mod.rs index 2ef8e57c128..2cadffa64f5 100644 --- a/packages/rs-platform-version/src/version/drive_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/mod.rs @@ -1,3 +1,4 @@ +use crate::version::drive_versions::drive_token_method_versions::DriveTokenMethodVersions; use crate::version::FeatureVersion; use drive_contract_method_versions::DriveContractMethodVersions; use drive_credit_pool_method_versions::DriveCreditPoolMethodVersions; @@ -9,7 +10,6 @@ use drive_structure_version::DriveStructureVersion; use drive_verify_method_versions::DriveVerifyMethodVersions; use drive_vote_method_versions::DriveVoteMethodVersions; use grovedb_version::version::GroveVersion; -use crate::version::drive_versions::drive_identity_method_versions::DriveTokenMethodVersions; pub mod drive_contract_method_versions; pub mod drive_credit_pool_method_versions; @@ -18,6 +18,7 @@ pub mod drive_grove_method_versions; pub mod drive_identity_method_versions; pub mod drive_state_transition_method_versions; pub mod drive_structure_version; +pub mod drive_token_method_versions; pub mod drive_verify_method_versions; pub mod drive_vote_method_versions; pub mod v1; diff --git a/packages/rs-platform-version/src/version/drive_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/v1.rs index bbe1a12746f..b058e036701 100644 --- a/packages/rs-platform-version/src/version/drive_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/v1.rs @@ -5,6 +5,7 @@ use crate::version::drive_versions::drive_grove_method_versions::v1::DRIVE_GROVE use crate::version::drive_versions::drive_identity_method_versions::v1::DRIVE_IDENTITY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_state_transition_method_versions::v1::DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_structure_version::v1::DRIVE_STRUCTURE_V1; +use crate::version::drive_versions::drive_token_method_versions::v1::DRIVE_TOKEN_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_verify_method_versions::v1::DRIVE_VERIFY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_vote_method_versions::v1::DRIVE_VOTE_METHOD_VERSIONS_V1; use crate::version::drive_versions::{ @@ -61,6 +62,7 @@ pub const DRIVE_VERSION_V1: DriveVersion = DriveVersion { }, verify: DRIVE_VERIFY_METHOD_VERSIONS_V1, identity: DRIVE_IDENTITY_METHOD_VERSIONS_V1, + token: DRIVE_TOKEN_METHOD_VERSIONS_V1, platform_system: DrivePlatformSystemMethodVersions { estimation_costs: DriveSystemEstimationCostsMethodVersions { for_total_system_credits_update: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/v2.rs b/packages/rs-platform-version/src/version/drive_versions/v2.rs index 5747bc732be..9ffd2082845 100644 --- a/packages/rs-platform-version/src/version/drive_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_versions/v2.rs @@ -5,6 +5,7 @@ use crate::version::drive_versions::drive_grove_method_versions::v1::DRIVE_GROVE use crate::version::drive_versions::drive_identity_method_versions::v1::DRIVE_IDENTITY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_state_transition_method_versions::v1::DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_structure_version::v1::DRIVE_STRUCTURE_V1; +use crate::version::drive_versions::drive_token_method_versions::v1::DRIVE_TOKEN_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_verify_method_versions::v1::DRIVE_VERIFY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_vote_method_versions::v2::DRIVE_VOTE_METHOD_VERSIONS_V2; use crate::version::drive_versions::{ @@ -61,6 +62,7 @@ pub const DRIVE_VERSION_V2: DriveVersion = DriveVersion { }, verify: DRIVE_VERIFY_METHOD_VERSIONS_V1, identity: DRIVE_IDENTITY_METHOD_VERSIONS_V1, + token: DRIVE_TOKEN_METHOD_VERSIONS_V1, platform_system: DrivePlatformSystemMethodVersions { estimation_costs: DriveSystemEstimationCostsMethodVersions { for_total_system_credits_update: 0, 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 931ef19b974..6d0fe5e47a1 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -30,6 +30,7 @@ use crate::version::drive_versions::drive_grove_method_versions::v1::DRIVE_GROVE use crate::version::drive_versions::drive_identity_method_versions::v1::DRIVE_IDENTITY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_state_transition_method_versions::v1::DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_structure_version::v1::DRIVE_STRUCTURE_V1; +use crate::version::drive_versions::drive_token_method_versions::v1::DRIVE_TOKEN_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_verify_method_versions::v1::DRIVE_VERIFY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_vote_method_versions::v1::DRIVE_VOTE_METHOD_VERSIONS_V1; use crate::version::drive_versions::{ @@ -95,6 +96,7 @@ pub const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { }, verify: DRIVE_VERIFY_METHOD_VERSIONS_V1, identity: DRIVE_IDENTITY_METHOD_VERSIONS_V1, + token: DRIVE_TOKEN_METHOD_VERSIONS_V1, platform_system: DrivePlatformSystemMethodVersions { estimation_costs: DriveSystemEstimationCostsMethodVersions { for_total_system_credits_update: 0, From b9235d2570be7b5446d8e0339115fb77308c24df Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Tue, 10 Dec 2024 14:05:53 +0700 Subject: [PATCH 10/61] feat(dpp): token meta schema (#2378) --- .../meta_schemas/token/v0/token-meta.json | 106 ++++++++++++++++++ .../src/validation/meta_validators/mod.rs | 65 ++++++++++- 2 files changed, 167 insertions(+), 4 deletions(-) diff --git a/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json b/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json index e69de29bb2d..225e89a5f2b 100644 --- a/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json +++ b/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json @@ -0,0 +1,106 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/dashpay/platform/blob/master/packages/rs-dpp/schema/meta_schemas/document/v0/document-meta.json", + "type": "object", + "$defs": { + "localization": { + "type": "string", + "pattern": "^[\\p{L}\\p{N}]*$", + "minLength": 1, + "maxLength": 64, + "$comment": "Allow only alphanumeric characters" + } + }, + "properties": { + "shouldCapitalize": { + "type": "boolean", + "description": "TODO" + }, + "localizations": { + "type": "object", + "description": "TODO", + "additionalProperties": { + "type": "object", + "properties": { + "singular": { + "$ref": "#/$defs/localization" + }, + "plural": { + "$ref": "#/$defs/localization" + } + }, + "required": ["singular", "plural"], + "additionalProperties": false + }, + "maxProperties": 255, + "minProperties": 1 + }, + "maintainer": { + "type": "array", + "contentMediaType": "application/x.dash.dpp.identifier", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "TODO" + }, + "initialSupply": { + "type": "integer", + "minimum": 0, + "description": "TODO" + }, + "decimals": { + "type": "integer", + "minimum": 0, + "description": "TODO" + }, + "maxSupply": { + "type": "integer", + "minimum": 1, + "description": "TODO" + }, + "permissions": { + "type": "object", + "properties": { + "maintainer": { + "type": "object", + "properties": { + "canMint": { + "type": "boolean" + }, + "canBurn": { + "type": "boolean" + } + }, + "additionalProperties": false, + "required": ["canBurn", "canMint"] + } + }, + "additionalProperties": false, + "minProperties": 1, + "description": "TODO" + }, + "description": { + "type": "string", + "maxLength": 1024, + "description": "Token description" + }, + "metadata": { + "type": "object", + "propertyNames": { + "type": "string", + "maxLength": 255 + }, + "additionalProperties": { + "type": "string", + "maxLength": 1024 + }, + "minProperties": 1, + "maxProperties": 255, + "description": "Token arbitrary metadata" + } + }, + "required": [ + "initialSupply", + "decimals" + ] +} diff --git a/packages/rs-dpp/src/validation/meta_validators/mod.rs b/packages/rs-dpp/src/validation/meta_validators/mod.rs index 8d1ce93b7e3..05e1024a526 100644 --- a/packages/rs-dpp/src/validation/meta_validators/mod.rs +++ b/packages/rs-dpp/src/validation/meta_validators/mod.rs @@ -36,10 +36,14 @@ lazy_static! { "../../../schema/meta_schemas/draft2020-12/meta/content.json" )) .expect("Valid schema!"); - static ref DATA_CONTRACT_V0: Value = serde_json::from_str::(include_str!( + static ref DOCUMENT_META_JSON_V0: Value = serde_json::from_str::(include_str!( "../../../schema/meta_schemas/document/v0/document-meta.json" )) .unwrap(); + static ref TOKEN_META_JSON_V0: Value = serde_json::from_str::(include_str!( + "../../../schema/meta_schemas/token/v0/token-meta.json" + )) + .unwrap(); pub static ref DRAFT_202012_META_SCHEMA: JSONSchema = JSONSchema::options() .with_draft(Draft::Draft202012) @@ -85,8 +89,7 @@ lazy_static! { .compile(&DRAFT202012) .expect("Invalid data contract schema"); - - // Compiled version of data contract meta schema + // Compiled version of document meta schema pub static ref DOCUMENT_META_SCHEMA_V0: JSONSchema = JSONSchema::options() .with_keyword( "byteArray", @@ -137,6 +140,60 @@ lazy_static! { DRAFT202012.clone(), ) .to_owned() - .compile(&DATA_CONTRACT_V0) + .compile(&DOCUMENT_META_JSON_V0) + .expect("Invalid data contract schema"); + + // Compiled version of token meta schema + pub static ref TOKEN_META_SCHEMA_V0: JSONSchema = JSONSchema::options() + .with_keyword( + "byteArray", + |_, _, _| Ok(Box::new(ByteArrayKeyword)), + ) + .with_patterns_regex_engine(RegexEngine::Regex(RegexOptions { + size_limit: Some(5 * (1 << 20)), + ..Default::default() + })) + .should_ignore_unknown_formats(false) + .should_validate_formats(true) + .with_patterns_regex_engine(RegexEngine::Regex(Default::default())) + .with_draft(Draft::Draft202012) + .with_document( + "https://json-schema.org/draft/2020-12/meta/applicator".to_string(), + DRAFT202012_APPLICATOR.clone(), + ) + .with_document( + "https://json-schema.org/draft/2020-12/meta/core".to_string(), + DRAFT202012_CORE.clone(), + ) + .with_document( + "https://json-schema.org/draft/2020-12/meta/applicator".to_string(), + DRAFT202012_APPLICATOR.clone(), + ) + .with_document( + "https://json-schema.org/draft/2020-12/meta/unevaluated".to_string(), + DRAFT202012_UNEVALUATED.clone(), + ) + .with_document( + "https://json-schema.org/draft/2020-12/meta/validation".to_string(), + DRAFT202012_VALIDATION.clone(), + ) + .with_document( + "https://json-schema.org/draft/2020-12/meta/meta-data".to_string(), + DRAFT202012_META_DATA.clone(), + ) + .with_document( + "https://json-schema.org/draft/2020-12/meta/format-annotation".to_string(), + DRAFT202012_FORMAT_ANNOTATION.clone(), + ) + .with_document( + "https://json-schema.org/draft/2020-12/meta/content".to_string(), + DRAFT202012_CONTENT.clone(), + ) + .with_document( + "https://json-schema.org/draft/2020-12/schema".to_string(), + DRAFT202012.clone(), + ) + .to_owned() + .compile(&TOKEN_META_JSON_V0) .expect("Invalid data contract schema"); } From 154a0b20092b90ec742f84a4fb3f830649dfaee4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 10 Dec 2024 14:15:54 +0300 Subject: [PATCH 11/61] more config --- .../v0/mod.rs | 12 +- .../token_configuration/v0/mod.rs | 114 +++++++++++++++--- .../document_transition_action_type.rs | 6 +- .../rs-drive/src/drive/tokens/burn/mod.rs | 1 + .../rs-drive/src/drive/tokens/issuance/mod.rs | 1 + packages/rs-drive/src/drive/tokens/mod.rs | 3 + .../rs-drive/src/drive/tokens/transfer/mod.rs | 1 + .../src/util/batch/drive_op_batch/token.rs | 45 +++++++ 8 files changed, 160 insertions(+), 23 deletions(-) create mode 100644 packages/rs-drive/src/drive/tokens/burn/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/issuance/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/transfer/mod.rs diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index b33965da2dc..33babb41f72 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -13,8 +13,8 @@ impl TokenConfiguration { action_taker: ActionTaker, ) -> SimpleConsensusValidationResult { let TokenConfigurationV0 { - max_supply, - max_supply_can_be_increased, + base_supply: max_supply, + manual_minting_rules: manual_supply_increase_rules, main_control_group, main_control_group_can_be_modified, balance_can_be_increased, @@ -22,10 +22,10 @@ impl TokenConfiguration { } = self.as_cow_v0(); let TokenConfigurationV0 { - max_supply: new_max_supply, - max_supply_can_be_increased: new_max_supply_can_be_increased, - main_control_group: new_main_control_group, - main_control_group_can_be_modified: new_main_control_group_can_be_modified, + base_supply: new_max_supply, + manual_minting_rules: manual_supply_increase_rules, + main_control_group, + main_control_group_can_be_modified, balance_can_be_increased: new_balance_can_be_increased, balance_can_be_destroyed: new_balance_can_be_destroyed, } = new_config.as_cow_v0(); diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 43ae526b6f0..d53e13f29f6 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -2,7 +2,8 @@ use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::multi_identity_events::ActionTaker; use platform_value::Identifier; use serde::{Deserialize, Serialize}; -use std::collections::BTreeSet; +use serde_json::map::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; pub type RequiredSigners = u8; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] @@ -63,7 +64,7 @@ pub struct ChangeControlRules { /// This is who is authorized to make such a change authorized_to_make_change: AuthorizedActionTakers, /// This is who is authorized to make such a change to the people authorized to make a change - authorized_to_change_to_authorized_action_takers: AuthorizedActionTakers, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers, /// Are we allowed to change to None in the future changing_authorized_action_takers_to_no_one_allowed: bool, /// Are we allowed to change to None in the future @@ -77,23 +78,108 @@ impl ChangeControlRules { contract_owner_id: &Identifier, main_group: &(BTreeSet, RequiredSigners), action_taker: &ActionTaker, - ) { - let ChangeControlRules { - authorized_to_make_change, - authorized_to_change_to_authorized_action_takers, - changing_authorized_action_takers_to_no_one_allowed, - changing_authorized_action_takers_to_contract_owner_allowed, - } = self; + ) -> bool { + // First, check if the action taker is allowed to make any changes at all + if !self.authorized_to_make_change.allowed_for_action_taker( + contract_owner_id, + main_group, + action_taker, + ) { + return false; + } + + // Check if authorized_to_make_change is being modified + if self.authorized_to_make_change != other.authorized_to_make_change { + // Changing the authorized action takers requires the action_taker to be allowed by + // authorized_to_change_authorized_action_takers in the current rules + if !self + .authorized_to_change_authorized_action_takers + .allowed_for_action_taker(contract_owner_id, main_group, action_taker) + { + return false; + } + + // If we are changing to NoOne, ensure it's allowed + if let AuthorizedActionTakers::NoOne = other.authorized_to_make_change { + if !self.changing_authorized_action_takers_to_no_one_allowed { + return false; + } + } + + // If we are changing to ContractOwner, ensure it's allowed + if let AuthorizedActionTakers::ContractOwner = other.authorized_to_make_change { + if !self.changing_authorized_action_takers_to_contract_owner_allowed { + return false; + } + } + } + + // Check if authorized_to_change_authorized_action_takers is being modified + if self.authorized_to_change_authorized_action_takers + != other.authorized_to_change_authorized_action_takers + { + // Must be allowed by the current authorized_to_change_authorized_action_takers + if !self + .authorized_to_change_authorized_action_takers + .allowed_for_action_taker(contract_owner_id, main_group, action_taker) + { + return false; + } + + // If we are changing to NoOne, ensure it's allowed + if let AuthorizedActionTakers::NoOne = + other.authorized_to_change_authorized_action_takers + { + if !self.changing_authorized_action_takers_to_no_one_allowed { + return false; + } + } + + // If we are changing to ContractOwner, ensure it's allowed + if let AuthorizedActionTakers::ContractOwner = + other.authorized_to_change_authorized_action_takers + { + if !self.changing_authorized_action_takers_to_contract_owner_allowed { + return false; + } + } + } + + // If we reach here, the changes are allowed + true } } +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct TokenConfigurationLocalizationsV0 { + pub singular_form: String, + pub plural_form: String, +} + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct TokenConfigurationConventionV0 { + pub should_capitalize: bool, + pub localizations: BTreeMap, + pub decimals: u16, +} + #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct TokenConfigurationV0 { - pub max_supply: u64, - pub max_supply_can_be_increased: ChangeControlRules, + pub conventions: TokenConfigurationConventionV0, + /// The supply at the creation of the token + pub base_supply: u64, + /// The maximum supply the token can ever have + pub max_supply: Option, + /// Who can change the max supply + /// Even if set no one can ever change this under the base supply + pub max_supply_change_rules: ChangeControlRules, + pub new_tokens_destination_identity: Option, + pub new_tokens_destination_identity_rules: ChangeControlRules, + pub manual_minting_rules: ChangeControlRules, + pub manual_burning_rules: ChangeControlRules, pub main_control_group: Option<(BTreeSet, RequiredSigners)>, - pub main_control_group_can_be_modified: ChangeControlRules, - pub balance_can_be_increased: ChangeControlRules, - pub balance_can_be_destroyed: ChangeControlRules, + pub main_control_group_can_be_modified: AuthorizedActionTakers, } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs index 7eb27a84a6e..7a2c30b237e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs @@ -1,6 +1,4 @@ -use crate::state_transition::documents_batch_transition::document_transition::{ - DocumentPurchaseTransition, DocumentTransferTransition, DocumentTransition, -}; +use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; use crate::ProtocolError; // @append-only @@ -41,6 +39,8 @@ impl TryFrom<&str> for DocumentTransitionActionType { "replace" => Ok(DocumentTransitionActionType::Replace), "delete" => Ok(DocumentTransitionActionType::Delete), "transfer" => Ok(DocumentTransitionActionType::Transfer), + "updatePrice" | "update_price" => Ok(DocumentTransitionActionType::UpdatePrice), + "purchase" => Ok(DocumentTransitionActionType::Purchase), action_type => Err(ProtocolError::Generic(format!( "unknown action type {action_type}" ))), diff --git a/packages/rs-drive/src/drive/tokens/burn/mod.rs b/packages/rs-drive/src/drive/tokens/burn/mod.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/burn/mod.rs @@ -0,0 +1 @@ + diff --git a/packages/rs-drive/src/drive/tokens/issuance/mod.rs b/packages/rs-drive/src/drive/tokens/issuance/mod.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/issuance/mod.rs @@ -0,0 +1 @@ + diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index 68d46e6dbe1..bf32de69eb2 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -1,7 +1,10 @@ use crate::drive::RootTree; mod balance; +mod burn; pub mod initialization; +mod issuance; +mod transfer; /// The path for the balances tree #[cfg(any(feature = "server", feature = "verify"))] diff --git a/packages/rs-drive/src/drive/tokens/transfer/mod.rs b/packages/rs-drive/src/drive/tokens/transfer/mod.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/transfer/mod.rs @@ -0,0 +1 @@ + diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index 4836b377c93..b083a898f1a 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -1,6 +1,16 @@ +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::batch::drive_op_batch::DriveLowLevelOperationConverter; +use crate::util::batch::IdentityOperationType; use crate::util::object_size_info::DataContractInfo; use dpp::balances::credits::TokenAmount; +use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::HashMap; /// Operations on Documents #[derive(Clone, Debug)] @@ -41,3 +51,38 @@ pub enum TokenOperationType<'a> { amount: TokenAmount, }, } + +impl DriveLowLevelOperationConverter for TokenOperationType { + fn into_low_level_drive_operations( + self, + drive: &Drive, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match self { + TokenOperationType::TokenBurn { + contract_info, + token_position, + token_id, + burn_amount, + } => {} + TokenOperationType::TokenIssuance { + contract_info, + token_position, + token_id, + issuance_amount, + } => {} + TokenOperationType::TokenTransfer { + contract_info, + token_position, + token_id, + recipient_id, + amount, + } => {} + } + } +} From 0537aa6d77b5c7e19cd7cb2cbb3c4e05a68b188e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 10 Dec 2024 17:29:26 +0300 Subject: [PATCH 12/61] more work --- .../src/drive/tokens/balance/fetch/mod.rs | 125 ++++++++++++++ .../src/drive/tokens/balance/fetch/v0/mod.rs | 84 +++++++++ .../rs-drive/src/drive/tokens/balance/mod.rs | 2 + .../rs-drive/src/drive/tokens/burn/mod.rs | 103 +++++++++++ .../rs-drive/src/drive/tokens/burn/v0/mod.rs | 152 +++++++++++++++++ .../src/drive/tokens/initialization/mod.rs | 1 - .../rs-drive/src/drive/tokens/issuance/mod.rs | 1 - .../rs-drive/src/drive/tokens/mint/mod.rs | 100 +++++++++++ .../rs-drive/src/drive/tokens/mint/v0/mod.rs | 131 ++++++++++++++ packages/rs-drive/src/drive/tokens/mod.rs | 10 +- .../system/add_to_token_total_supply/mod.rs | 113 ++++++++++++ .../add_to_token_total_supply/v0/mod.rs | 120 +++++++++++++ .../create_token_root_tree/mod.rs | 6 +- .../create_token_root_tree/v0/mod.rs | 0 .../rs-drive/src/drive/tokens/system/mod.rs | 3 + .../remove_from_token_total_supply/mod.rs | 116 +++++++++++++ .../remove_from_token_total_supply/v0/mod.rs | 125 ++++++++++++++ .../rs-drive/src/drive/tokens/transfer/mod.rs | 109 ++++++++++++ .../src/drive/tokens/transfer/v0/mod.rs | 161 ++++++++++++++++++ .../document/token_issuance_transition.rs | 4 +- .../src/util/batch/drive_op_batch/token.rs | 87 +++++++--- .../drive_token_method_versions/mod.rs | 13 +- .../drive_token_method_versions/v1.rs | 6 +- 23 files changed, 1527 insertions(+), 45 deletions(-) create mode 100644 packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/burn/v0/mod.rs delete mode 100644 packages/rs-drive/src/drive/tokens/initialization/mod.rs delete mode 100644 packages/rs-drive/src/drive/tokens/issuance/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/mint/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/mint/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs rename packages/rs-drive/src/drive/tokens/{initialization => system}/create_token_root_tree/mod.rs (98%) rename packages/rs-drive/src/drive/tokens/{initialization => system}/create_token_root_tree/v0/mod.rs (100%) create mode 100644 packages/rs-drive/src/drive/tokens/system/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs new file mode 100644 index 00000000000..b229848387b --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs @@ -0,0 +1,125 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::balances::credits::TokenAmount; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::fee::Credits; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Fetches the Identity's token balance from the backing store. + /// Passing `apply = false` will return estimated costs (0 or Some(0) in place of actual values). + /// + /// # Arguments + /// + /// * `token_id` - The ID of the token. + /// * `identity_id` - The ID of the Identity whose token balance is to be fetched. + /// * `apply` - Whether to actually fetch from state (true) or estimate costs (false). + /// * `transaction` - The current transaction. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - The token balance of the Identity if successful, or an error. + pub fn fetch_identity_token_balance( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.fetch.balance { + 0 => self.fetch_identity_token_balance_v0( + token_id, + identity_id, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_balance".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the Identity's token balance with costs (if `apply = true`) and returns associated fee result. + pub fn fetch_identity_token_balance_with_costs( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(Option, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_identity_token_balance_operations( + token_id, + identity_id, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the operations to get Identity's token balance from the backing store. + /// If `apply` is false, the operations are stateless and only used for cost estimation. + /// + /// # Arguments + /// + /// * `token_id` - The ID of the token. + /// * `identity_id` - The ID of the Identity whose token balance is to be fetched. + /// * `apply` - Whether to fetch actual stateful data (true) or just estimate costs (false). + /// * `transaction` - The current transaction. + /// * `drive_operations` - The drive operations vector to populate. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - The token balance of the Identity if successful, or an error. + pub fn fetch_identity_token_balance_operations( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.fetch.balance { + 0 => self.fetch_identity_token_balance_operations_v0( + token_id, + identity_id, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_balance_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs new file mode 100644 index 00000000000..ba713f72a20 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs @@ -0,0 +1,84 @@ +use crate::drive::tokens::token_balances_path_vec; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::balances::credits::TokenAmount; +use dpp::version::PlatformVersion; +use grovedb::Element::SumItem; +use grovedb::TransactionArg; + +impl Drive { + pub(super) fn fetch_identity_token_balance_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.fetch_identity_token_balance_operations_v0( + token_id, + identity_id, + apply, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_identity_token_balance_operations_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let direct_query_type = if apply { + DirectQueryType::StatefulDirectQuery + } else { + // 8 is the size of an i64 used in sum trees + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums: true, + query_target: QueryTargetValue(8), + } + }; + + let balance_path = token_balances_path_vec(token_id); + + match self.grove_get_raw_optional( + (&balance_path).into(), + identity_id.as_slice(), + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + ) { + Ok(Some(SumItem(balance, _))) if balance >= 0 => Ok(Some(balance as TokenAmount)), + + Ok(None) | Err(Error::GroveDB(grovedb::Error::PathKeyNotFound(_))) => { + // If we are applying (stateful), no balance means None. + // If we are estimating (stateless), return Some(0) to indicate no cost or minimal cost scenario. + if apply { + Ok(None) + } else { + Ok(Some(0)) + } + } + + Ok(Some(SumItem(..))) => Err(Error::Drive(DriveError::CorruptedElementType( + "identity token balance was present but was negative", + ))), + + Ok(Some(_)) => Err(Error::Drive(DriveError::CorruptedElementType( + "identity token balance was present but was not a sum item", + ))), + + Err(e) => Err(e), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/mod.rs index d76e8051c89..403f48d6ab2 100644 --- a/packages/rs-drive/src/drive/tokens/balance/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/mod.rs @@ -1,4 +1,6 @@ #[cfg(feature = "server")] +mod fetch; +#[cfg(feature = "server")] mod prove; mod queries; #[cfg(feature = "server")] diff --git a/packages/rs-drive/src/drive/tokens/burn/mod.rs b/packages/rs-drive/src/drive/tokens/burn/mod.rs index 8b137891791..a7301ea8711 100644 --- a/packages/rs-drive/src/drive/tokens/burn/mod.rs +++ b/packages/rs-drive/src/drive/tokens/burn/mod.rs @@ -1 +1,104 @@ +mod v0; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Burns tokens by reducing the total supply and removing them from an identity's balance. + pub fn token_burn( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + burn_amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version.drive.methods.token.update.burn { + 0 => self.token_burn_v0( + token_id, + identity_id, + burn_amount, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_burn".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds the operations to burn tokens without calculating fees and optionally applying. + pub fn token_burn_add_to_operations( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + burn_amount: u64, + apply: bool, + previous_batch_operations: &mut Option<&mut Vec>, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version.drive.methods.token.update.burn { + 0 => self.token_burn_add_to_operations_v0( + token_id, + identity_id, + burn_amount, + apply, + previous_batch_operations, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_burn_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Gathers the operations needed to burn tokens. + pub fn token_burn_operations( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + burn_amount: u64, + previous_batch_operations: &mut Option<&mut Vec>, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.update.burn { + 0 => self.token_burn_operations_v0( + token_id, + identity_id, + burn_amount, + previous_batch_operations, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_burn_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs b/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs new file mode 100644 index 00000000000..e6b2b223f08 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs @@ -0,0 +1,152 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + pub(super) fn token_burn_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + burn_amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations = vec![]; + + self.token_burn_add_to_operations_v0( + token_id, + identity_id, + burn_amount, + apply, + &mut None, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + pub(super) fn token_burn_add_to_operations_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + burn_amount: u64, + apply: bool, + previous_batch_operations: &mut Option<&mut Vec>, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + if apply { None } else { Some(HashMap::new()) }; + + let batch_operations = self.token_burn_operations_v0( + token_id, + identity_id, + burn_amount, + previous_batch_operations, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + pub(super) fn token_burn_operations_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + burn_amount: u64, + _previous_batch_operations: &mut Option<&mut Vec>, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + + // Add estimation info if needed + if let Some(esti) = estimated_costs_only_with_layer_info { + Self::add_estimation_costs_for_balances(esti, &platform_version.drive)?; + Self::add_estimation_costs_for_negative_credit( + identity_id, + esti, + &platform_version.drive, + )?; + } + + // Fetch current balance + let current_balance = self + .fetch_identity_balance_operations( + identity_id, + estimated_costs_only_with_layer_info.is_none(), + transaction, + &mut drive_operations, + platform_version, + )? + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "there should be a balance when burning tokens".to_string(), + )))?; + + if current_balance < burn_amount { + return Err(Error::Drive(DriveError::CorruptedDriveState( + "cannot burn more tokens than currently owned".to_string(), + ))); + } + + let new_balance = current_balance - burn_amount; + + // Update identity balance + drive_operations.push(self.update_identity_balance_operation_v0(identity_id, new_balance)?); + + // Update total supply for the token (subtract burn_amount) + let current_supply = self + .fetch_token_total_supply_operations( + token_id, + estimated_costs_only_with_layer_info.is_none(), + transaction, + &mut drive_operations, + platform_version, + )? + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "token should have a total supply".to_string(), + )))?; + + if current_supply < burn_amount { + return Err(Error::Drive(DriveError::CorruptedDriveState( + "cannot burn more tokens than total supply".to_string(), + ))); + } + + let new_supply = current_supply - burn_amount; + drive_operations.push(self.update_token_total_supply_operation_v0(token_id, new_supply)?); + + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/drive/tokens/initialization/mod.rs b/packages/rs-drive/src/drive/tokens/initialization/mod.rs deleted file mode 100644 index 8ee69e35926..00000000000 --- a/packages/rs-drive/src/drive/tokens/initialization/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod create_token_root_tree; diff --git a/packages/rs-drive/src/drive/tokens/issuance/mod.rs b/packages/rs-drive/src/drive/tokens/issuance/mod.rs deleted file mode 100644 index 8b137891791..00000000000 --- a/packages/rs-drive/src/drive/tokens/issuance/mod.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/rs-drive/src/drive/tokens/mint/mod.rs b/packages/rs-drive/src/drive/tokens/mint/mod.rs new file mode 100644 index 00000000000..a28686838d8 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/mint/mod.rs @@ -0,0 +1,100 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Mints (issues) new tokens by increasing the total supply and adding them to an identity's balance. + pub fn token_mint( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + issuance_amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version.drive.methods.token.update.mint { + 0 => self.token_mint_v0( + token_id, + identity_id, + issuance_amount, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_mint".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds the operations to mint tokens without calculating fees and optionally applying. + pub fn token_mint_add_to_operations( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + issuance_amount: u64, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version.drive.methods.token.update.mint { + 0 => self.token_mint_add_to_operations_v0( + token_id, + identity_id, + issuance_amount, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_mint_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Gathers the operations needed to mint tokens. + pub fn token_mint_operations( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + issuance_amount: u64, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.update.mint { + 0 => self.token_mint_operations_v0( + token_id, + identity_id, + issuance_amount, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_mint_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs b/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs new file mode 100644 index 00000000000..b789ad0e414 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs @@ -0,0 +1,131 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + pub(super) fn token_mint_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + issuance_amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations = vec![]; + + self.token_mint_add_to_operations_v0( + token_id, + identity_id, + issuance_amount, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + pub(super) fn token_mint_add_to_operations_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + issuance_amount: u64, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + if apply { None } else { Some(HashMap::new()) }; + + let batch_operations = self.token_mint_operations_v0( + token_id, + identity_id, + issuance_amount, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + pub(super) fn token_mint_operations_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + issuance_amount: u64, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + + // Estimation + if let Some(esti) = estimated_costs_only_with_layer_info { + Self::add_estimation_costs_for_balances(esti, &platform_version.drive)?; + Self::add_estimation_costs_for_negative_credit( + identity_id, + esti, + &platform_version.drive, + )?; + } + + // Fetch current balance + let current_balance = self + .fetch_identity_token_balance_operations( + token_id, + identity_id, + estimated_costs_only_with_layer_info.is_none(), + transaction, + &mut drive_operations, + platform_version, + )? + .unwrap_or(0); + + let new_balance = current_balance + .checked_add(issuance_amount) + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "overflow when adding issuance_amount".to_string(), + )))?; + + // Update identity balance + drive_operations.push(self.update_identity_balance_operation_v0(identity_id, new_balance)?); + + drive_operations.push(self.add_to_token_total_supply_operations( + token_id, + issuance_amount, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); + + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index bf32de69eb2..26bb174acb5 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -1,10 +1,10 @@ use crate::drive::RootTree; -mod balance; -mod burn; -pub mod initialization; -mod issuance; -mod transfer; +pub mod balance; +pub mod burn; +pub mod mint; +pub mod system; +pub mod transfer; /// The path for the balances tree #[cfg(any(feature = "server", feature = "verify"))] diff --git a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/mod.rs b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/mod.rs new file mode 100644 index 00000000000..c4315b91d0e --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/mod.rs @@ -0,0 +1,113 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Adds to the token's total supply + pub fn add_to_token_total_supply( + &self, + token_id: [u8; 32], + amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive + .methods + .token + .update + .add_to_token_total_supply + { + 0 => self.add_to_token_total_supply_v0( + token_id, + amount, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_to_token_total_supply".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds the operations of adding to the token total supply + pub fn add_to_token_total_supply_add_to_operations( + &self, + token_id: [u8; 32], + amount: u64, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version + .drive + .methods + .token + .update + .add_to_token_total_supply + { + 0 => self.add_to_token_total_supply_add_to_operations_v0( + token_id, + amount, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_to_token_total_supply_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// The operations needed to add to the token total supply + pub fn add_to_token_total_supply_operations( + &self, + token_id: [u8; 32], + amount: u64, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .update + .add_to_token_total_supply + { + 0 => self.add_to_token_total_supply_operations_v0( + token_id, + amount, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_to_token_total_supply_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs new file mode 100644 index 00000000000..8058a7ec16f --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs @@ -0,0 +1,120 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + pub(super) fn add_to_token_total_supply_v0( + &self, + token_id: [u8; 32], + amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations = vec![]; + + self.add_to_token_total_supply_add_to_operations_v0( + token_id, + amount, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + pub(super) fn add_to_token_total_supply_add_to_operations_v0( + &self, + token_id: [u8; 32], + amount: u64, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + if apply { None } else { Some(HashMap::new()) }; + + let batch_operations = self.add_to_token_total_supply_operations_v0( + token_id, + amount, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + pub(super) fn add_to_token_total_supply_operations_v0( + &self, + token_id: [u8; 32], + amount: u64, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + + // If we only estimate, add estimation costs + if let Some(esti) = estimated_costs_only_with_layer_info { + // Add your estimation logic similar to add_to_system_credits_operations_v0 + // For example: + Self::add_estimation_costs_for_token_total_supply_update( + esti, + &platform_version.drive, + )?; + } + + // Fetch current total supply + let current_supply = self + .fetch_token_total_supply_operations( + token_id, + estimated_costs_only_with_layer_info.is_none(), + transaction, + &mut drive_operations, + platform_version, + )? + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "token should have a total supply before adding".to_string(), + )))?; + + let new_supply = current_supply.checked_add(amount).ok_or(Error::Drive( + DriveError::CorruptedDriveState( + "overflow when adding to token total supply".to_string(), + ), + ))?; + + // Update token total supply + drive_operations.push(self.update_token_total_supply_operation_v0(token_id, new_supply)?); + + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs similarity index 98% rename from packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs rename to packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs index c7936fa707a..5e8f2c660ac 100644 --- a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs @@ -27,7 +27,7 @@ impl Drive { .drive .methods .token - .insert + .update .create_token_root_tree { 0 => self.create_token_root_tree_v0( @@ -59,7 +59,7 @@ impl Drive { .drive .methods .token - .insert + .update .create_token_root_tree { 0 => self.create_token_root_tree_add_to_operations_v0( @@ -93,7 +93,7 @@ impl Drive { .drive .methods .token - .insert + .update .create_token_root_tree { 0 => self.create_token_root_tree_operations_v0( diff --git a/packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs similarity index 100% rename from packages/rs-drive/src/drive/tokens/initialization/create_token_root_tree/v0/mod.rs rename to packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs diff --git a/packages/rs-drive/src/drive/tokens/system/mod.rs b/packages/rs-drive/src/drive/tokens/system/mod.rs new file mode 100644 index 00000000000..7f760fc3cf3 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/system/mod.rs @@ -0,0 +1,3 @@ +mod add_to_token_total_supply; +mod create_token_root_tree; +mod remove_from_token_total_supply; diff --git a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/mod.rs b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/mod.rs new file mode 100644 index 00000000000..9219e8dcefb --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/mod.rs @@ -0,0 +1,116 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Removes from the token's total supply + pub fn remove_from_token_total_supply( + &self, + token_id: [u8; 32], + amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive + .methods + .token + .update + .remove_from_token_total_supply + { + 0 => self.remove_from_token_total_supply_v0( + token_id, + amount, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "remove_from_token_total_supply".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds the operations of removing from the token total supply + pub fn remove_from_token_total_supply_add_to_operations( + &self, + token_id: [u8; 32], + amount: u64, + apply: bool, + previous_batch_operations: &mut Option<&mut Vec>, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version + .drive + .methods + .token + .update + .remove_from_token_total_supply + { + 0 => self.remove_from_token_total_supply_add_to_operations_v0( + token_id, + amount, + apply, + previous_batch_operations, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "remove_from_token_total_supply_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// The operations needed to remove from the token total supply + pub fn remove_from_token_total_supply_operations( + &self, + token_id: [u8; 32], + amount: u64, + previous_batch_operations: &mut Option<&mut Vec>, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .update + .remove_from_token_total_supply + { + 0 => self.remove_from_token_total_supply_operations_v0( + token_id, + amount, + previous_batch_operations, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "remove_from_token_total_supply_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs new file mode 100644 index 00000000000..11a618803e1 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs @@ -0,0 +1,125 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + pub(super) fn remove_from_token_total_supply_v0( + &self, + token_id: [u8; 32], + amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations = vec![]; + + self.remove_from_token_total_supply_add_to_operations_v0( + token_id, + amount, + apply, + &mut None, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + pub(super) fn remove_from_token_total_supply_add_to_operations_v0( + &self, + token_id: [u8; 32], + amount: u64, + apply: bool, + previous_batch_operations: &mut Option<&mut Vec>, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + if apply { None } else { Some(HashMap::new()) }; + + let batch_operations = self.remove_from_token_total_supply_operations_v0( + token_id, + amount, + previous_batch_operations, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + pub(super) fn remove_from_token_total_supply_operations_v0( + &self, + token_id: [u8; 32], + amount: u64, + _previous_batch_operations: &mut Option<&mut Vec>, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + + // If we only estimate, add estimation costs + if let Some(esti) = estimated_costs_only_with_layer_info { + // Add your estimation logic similar to add_to_token_total_supply if needed + // For example (this is a placeholder method, you must implement similarly as others): + Self::add_estimation_costs_for_token_total_supply_update( + esti, + &platform_version.drive, + )?; + } + + // Fetch current total supply + let current_supply = self + .fetch_token_total_supply_operations( + token_id, + estimated_costs_only_with_layer_info.is_none(), + transaction, + &mut drive_operations, + platform_version, + )? + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "token should have a total supply before removing".to_string(), + )))?; + + if current_supply < amount { + return Err(Error::Drive(DriveError::CorruptedDriveState( + "cannot remove more from total supply than currently exists".to_string(), + ))); + } + + let new_supply = current_supply - amount; + + // Update token total supply + drive_operations.push(self.update_token_total_supply_operation_v0(token_id, new_supply)?); + + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/drive/tokens/transfer/mod.rs b/packages/rs-drive/src/drive/tokens/transfer/mod.rs index 8b137891791..10bef172b7e 100644 --- a/packages/rs-drive/src/drive/tokens/transfer/mod.rs +++ b/packages/rs-drive/src/drive/tokens/transfer/mod.rs @@ -1 +1,110 @@ +mod v0; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Transfers tokens from one identity to another without changing total supply. + pub fn token_transfer( + &self, + token_id: [u8; 32], + from_identity_id: [u8; 32], + to_identity_id: [u8; 32], + amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version.drive.methods.token.update.transfer { + 0 => self.token_transfer_v0( + token_id, + from_identity_id, + to_identity_id, + amount, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_transfer".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds operations to transfer tokens without calculating fees. + pub fn token_transfer_add_to_operations( + &self, + token_id: [u8; 32], + from_identity_id: [u8; 32], + to_identity_id: [u8; 32], + amount: u64, + apply: bool, + previous_batch_operations: &mut Option<&mut Vec>, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version.drive.methods.token.update.transfer { + 0 => self.token_transfer_add_to_operations_v0( + token_id, + from_identity_id, + to_identity_id, + amount, + apply, + previous_batch_operations, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_transfer_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Gathers the operations needed to transfer tokens. + pub fn token_transfer_operations( + &self, + token_id: [u8; 32], + from_identity_id: [u8; 32], + to_identity_id: [u8; 32], + amount: u64, + previous_batch_operations: &mut Option<&mut Vec>, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.update.transfer { + 0 => self.token_transfer_operations_v0( + token_id, + from_identity_id, + to_identity_id, + amount, + previous_batch_operations, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_transfer_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs b/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs new file mode 100644 index 00000000000..04a74dfaaea --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs @@ -0,0 +1,161 @@ +// token_transfer/v0.rs +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + pub(super) fn token_transfer_v0( + &self, + token_id: [u8; 32], + from_identity_id: [u8; 32], + to_identity_id: [u8; 32], + amount: u64, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations = vec![]; + + self.token_transfer_add_to_operations_v0( + token_id, + from_identity_id, + to_identity_id, + amount, + apply, + &mut None, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + pub(super) fn token_transfer_add_to_operations_v0( + &self, + token_id: [u8; 32], + from_identity_id: [u8; 32], + to_identity_id: [u8; 32], + amount: u64, + apply: bool, + previous_batch_operations: &mut Option<&mut Vec>, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + if apply { None } else { Some(HashMap::new()) }; + + let batch_operations = self.token_transfer_operations_v0( + token_id, + from_identity_id, + to_identity_id, + amount, + previous_batch_operations, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + pub(super) fn token_transfer_operations_v0( + &self, + _token_id: [u8; 32], + from_identity_id: [u8; 32], + to_identity_id: [u8; 32], + amount: u64, + _previous_batch_operations: &mut Option<&mut Vec>, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + + // Estimation + if let Some(esti) = estimated_costs_only_with_layer_info { + Self::add_estimation_costs_for_balances(esti, &platform_version.drive)?; + Self::add_estimation_costs_for_negative_credit( + from_identity_id, + esti, + &platform_version.drive, + )?; + Self::add_estimation_costs_for_negative_credit( + to_identity_id, + esti, + &platform_version.drive, + )?; + } + + // Fetch sender balance + let from_balance = self + .fetch_identity_balance_operations( + from_identity_id, + estimated_costs_only_with_layer_info.is_none(), + transaction, + &mut drive_operations, + platform_version, + )? + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "sender identity must have a balance".to_string(), + )))?; + + if from_balance < amount { + return Err(Error::Drive(DriveError::CorruptedDriveState( + "sender does not have enough balance to transfer".to_string(), + ))); + } + + let new_from_balance = from_balance - amount; + drive_operations + .push(self.update_identity_balance_operation_v0(from_identity_id, new_from_balance)?); + + // Fetch recipient balance + let to_balance = self + .fetch_identity_balance_operations( + to_identity_id, + estimated_costs_only_with_layer_info.is_none(), + transaction, + &mut drive_operations, + platform_version, + )? + .unwrap_or(0); + + let new_to_balance = + to_balance + .checked_add(amount) + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "overflow on recipient balance".to_string(), + )))?; + drive_operations + .push(self.update_identity_balance_operation_v0(to_identity_id, new_to_balance)?); + + // Total supply remains the same. + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs index 85080d7ff28..21541aedd98 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs @@ -40,11 +40,11 @@ impl DriveHighLevelDocumentOperationConverter for TokenIssuanceTransitionAction }, )]; - ops.push(TokenOperation(TokenOperationType::TokenIssuance { + ops.push(TokenOperation(TokenOperationType::TokenMint { contract_info: DataContractFetchInfo(contract_fetch_info), token_position: self.token_position(), token_id: self.token_id(), - issuance_amount: self.issuance_amount(), + mint_amount: self.issuance_amount(), })); Ok(ops) diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index b083a898f1a..3fb3fd4acea 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -15,36 +15,30 @@ use std::collections::HashMap; /// Operations on Documents #[derive(Clone, Debug)] pub enum TokenOperationType<'a> { - /// Adds a document to a contract matching the desired info. + /// Burns token from the account issuing the . TokenBurn { - /// Data Contract info to potentially be resolved if needed - contract_info: DataContractInfo<'a>, - /// Token position in the contract, is 0 if there is only one token - token_position: u16, /// The token id token_id: Identifier, + /// The identity to burn from + identity_balance_holder_id: Identifier, /// The amount to burn burn_amount: TokenAmount, }, /// Adds a document to a contract matching the desired info. - TokenIssuance { - /// Data Contract info to potentially be resolved if needed - contract_info: DataContractInfo<'a>, - /// Token position in the contract, is 0 if there is only one token - token_position: u16, + TokenMint { /// The token id token_id: Identifier, + /// The identity to burn from + identity_balance_holder_id: Identifier, /// The amount to issue - issuance_amount: TokenAmount, + mint_amount: TokenAmount, }, /// Adds a document to a contract matching the desired info. TokenTransfer { - /// Data Contract info to potentially be resolved if needed - contract_info: DataContractInfo<'a>, - /// Token position in the contract, is 0 if there is only one token - token_position: u16, /// The token id token_id: Identifier, + /// The token id + sender_id: Identifier, /// The recipient of the transfer recipient_id: Identifier, /// The amount to transfer @@ -52,7 +46,7 @@ pub enum TokenOperationType<'a> { }, } -impl DriveLowLevelOperationConverter for TokenOperationType { +impl DriveLowLevelOperationConverter for TokenOperationType<'_> { fn into_low_level_drive_operations( self, drive: &Drive, @@ -65,24 +59,63 @@ impl DriveLowLevelOperationConverter for TokenOperationType { ) -> Result, Error> { match self { TokenOperationType::TokenBurn { - contract_info, - token_position, token_id, + identity_balance_holder_id, burn_amount, - } => {} - TokenOperationType::TokenIssuance { - contract_info, - token_position, + } => { + let token_id_bytes: [u8; 32] = token_id.to_buffer(); + let identity_id_bytes: [u8; 32] = identity_balance_holder_id.to_buffer(); + let batch_operations = drive.token_burn_operations( + token_id_bytes, + identity_id_bytes, + burn_amount, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + Ok(batch_operations) + } + TokenOperationType::TokenMint { token_id, - issuance_amount, - } => {} + identity_balance_holder_id, + mint_amount, + } => { + let token_id_bytes: [u8; 32] = token_id.to_buffer(); + let identity_id_bytes: [u8; 32] = identity_balance_holder_id.to_buffer(); + let batch_operations = drive.token_mint_operations( + token_id_bytes, + identity_id_bytes, + mint_amount, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + Ok(batch_operations) + } TokenOperationType::TokenTransfer { - contract_info, - token_position, token_id, + sender_id, recipient_id, amount, - } => {} + } => { + let token_id_bytes: [u8; 32] = token_id.to_buffer(); + let sender_id_bytes: [u8; 32] = sender_id.to_buffer(); + let recipient_id_bytes: [u8; 32] = recipient_id.to_buffer(); + + let batch_operations = drive.token_transfer_operations( + token_id_bytes, + sender_id_bytes, + recipient_id_bytes, + amount, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + Ok(batch_operations) + } } } } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index f80cf8108ca..5ab0a46da49 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -6,16 +6,23 @@ pub mod v1; pub struct DriveTokenMethodVersions { pub fetch: DriveTokenFetchMethodVersions, pub prove: DriveTokenProveMethodVersions, - pub insert: DriveTokenInsertMethodVersions, + pub update: DriveTokenUpdateMethodVersions, } #[derive(Clone, Debug, Default)] -pub struct DriveTokenFetchMethodVersions {} +pub struct DriveTokenFetchMethodVersions { + pub balance: FeatureVersion, +} #[derive(Clone, Debug, Default)] pub struct DriveTokenProveMethodVersions {} #[derive(Clone, Debug, Default)] -pub struct DriveTokenInsertMethodVersions { +pub struct DriveTokenUpdateMethodVersions { pub create_token_root_tree: FeatureVersion, + pub burn: FeatureVersion, + pub mint: FeatureVersion, + pub transfer: FeatureVersion, + pub add_to_token_total_supply: FeatureVersion, + pub remove_from_token_total_supply: FeatureVersion, } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index d4a2a602394..a173f38ac94 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -1,12 +1,12 @@ use crate::version::drive_versions::drive_token_method_versions::{ - DriveTokenFetchMethodVersions, DriveTokenInsertMethodVersions, DriveTokenMethodVersions, - DriveTokenProveMethodVersions, + DriveTokenFetchMethodVersions, DriveTokenMethodVersions, DriveTokenProveMethodVersions, + DriveTokenUpdateMethodVersions, }; pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenMethodVersions { fetch: DriveTokenFetchMethodVersions {}, prove: DriveTokenProveMethodVersions {}, - insert: DriveTokenInsertMethodVersions { + update: DriveTokenUpdateMethodVersions { create_token_root_tree: 0, }, }; From 148767da917bdc65845057bcfbd538ebbb0d3b6a Mon Sep 17 00:00:00 2001 From: Ivan Shumkov Date: Tue, 10 Dec 2024 22:05:50 +0700 Subject: [PATCH 13/61] chore: update tokens metaschema --- .../meta_schemas/token/v0/token-meta.json | 251 ++++++++++++++---- 1 file changed, 195 insertions(+), 56 deletions(-) diff --git a/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json b/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json index 225e89a5f2b..7e5d833fc8b 100644 --- a/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json +++ b/packages/rs-dpp/schema/meta_schemas/token/v0/token-meta.json @@ -9,80 +9,218 @@ "minLength": 1, "maxLength": 64, "$comment": "Allow only alphanumeric characters" + }, + "identifier": { + "type": "string", + "contentMediaType": "application/x.dash.dpp.identifier", + "byteArray": true, + "minLength": 32, + "maxLength": 32, + "description": "A 32-byte identifier" + }, + "optionalIdentifier": { + "type": ["string", "null"], + "contentMediaType": "application/x.dash.dpp.identifier", + "byteArray": true, + "minLength": 32, + "maxLength": 32, + "description": "A 32-byte identifier" + }, + "authorizedActionTakers": { + "description": "Specifies who is authorized to take certain actions", + "oneOf": [ + { + "type": "object", + "properties": { + "type": { "const": "noOne" } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { "const": "contractOwner" } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { "const": "mainGroup" } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { "const": "specifiedIdentities" }, + "identifiers": { + "type": "array", + "description": "An array of authorized identifiers", + "items": { + "$ref": "#/$defs/identifier" + }, + "uniqueItems": true + }, + "requiredSignersCount": { + "$ref": "#/$defs/requiredSignersCount", + "description": "Rules for required signers within these specified identities" + } + }, + "required": ["type", "identifiers", "requiredSignersCount"], + "additionalProperties": false + } + ] + }, + "changeControlRules": { + "type": "object", + "description": "Defines who can make changes to certain parameters and who can change that ability", + "properties": { + "authorizedToMakeChange": { + "$ref": "#/$defs/authorizedActionTakers", + "description": "Who is authorized to make the relevant change" + }, + "authorizedToChangeAuthorizedActionTakers": { + "$ref": "#/$defs/authorizedActionTakers", + "description": "Who is authorized to modify the list of people who can make the change" + }, + "changingAuthorizedActionTakersToNoOneAllowed": { + "type": "boolean", + "description": "Whether it is allowed to change the authorized action takers to no one in the future" + }, + "changingAuthorizedActionTakersToContractOwnerAllowed": { + "type": "boolean", + "description": "Whether it is allowed to change the authorized action takers to contract owner in the future" + } + }, + "required": [ + "authorizedToMakeChange", + "authorizedToChangeAuthorizedActionTakers", + "changingAuthorizedActionTakersToNoOneAllowed", + "changingAuthorizedActionTakersToContractOwnerAllowed" + ], + "additionalProperties": false + }, + "requiredSignersCount": { + "type": "integer", + "description": "How many signers are required to authorize actions", + "minimum": 1, + "maximum": 255 } }, "properties": { - "shouldCapitalize": { - "type": "boolean", - "description": "TODO" + "description": { + "type": "string", + "maxLength": 1024, + "description": "Token description" }, - "localizations": { + "displayConventions": { "type": "object", - "description": "TODO", - "additionalProperties": { - "type": "object", - "properties": { - "singular": { - "$ref": "#/$defs/localization" + "description": "Token display conventions including capitalization and localization", + "properties": { + "capitalize": { + "type": "boolean", + "description": "Indicates whether token names should be capitalized" + }, + "localizations": { + "type": "object", + "description": "A map of locale keys to their corresponding singular/plural forms", + "additionalProperties": { + "type": "object", + "description": "Localization forms for a given locale key", + "properties": { + "singularForm": { + "$ref": "#/$defs/localization" + }, + "pluralForm": { + "$ref": "#/$defs/localization" + } + }, + "required": [ + "singularForm", + "pluralForm" + ], + "additionalProperties": false }, - "plural": { - "$ref": "#/$defs/localization" + "maxProperties": 255, + "minProperties": 1, + "propertyNames": { + "type": "string", + "minLength": 1, + "maxLength": 255 } }, - "required": ["singular", "plural"], - "additionalProperties": false + "decimals": { + "type": "integer", + "minimum": 0, + "description": "The number of decimal places the token supports" + } }, - "maxProperties": 255, - "minProperties": 1 - }, - "maintainer": { - "type": "array", - "contentMediaType": "application/x.dash.dpp.identifier", - "byteArray": true, - "minItems": 32, - "maxItems": 32, - "description": "TODO" + "required": ["capitalize", "localizations", "decimals"], + "additionalProperties": false }, "initialSupply": { "type": "integer", "minimum": 0, - "description": "TODO" + "description": "The initial (base) supply of the token at creation time" }, - "decimals": { - "type": "integer", - "minimum": 0, - "description": "TODO" + "initialSupplyDestinationIdentityId": { + "$ref": "#/$defs/optionalIdentifier", + "description": "Optional identity where initial supply tokens are sent. If not set, the data contract owner identity is used" }, "maxSupply": { - "type": "integer", + "type": ["integer", "null"], "minimum": 1, - "description": "TODO" + "description": "The maximum supply the token can ever have, or null if there is no maximum" }, - "permissions": { - "type": "object", - "properties": { - "maintainer": { - "type": "object", - "properties": { - "canMint": { - "type": "boolean" + "maxSupplyChangeRules": { + "$ref": "#/$defs/changeControlRules", + "description": "Rules governing who can change the max supply and under what conditions" + }, + "mintedTokensDestinationIdentityId": { + "$ref": "#/$defs/optionalIdentifier", + "description": "Optional identity where newly minted tokens are sent. If set then minted tokens can be sent only to this identity" + }, + "mintedTokensDestinationIdentityRules": { + "$ref": "#/$defs/changeControlRules", + "description": "Rules for changing the new tokens destination identity" + }, + "mintingRules": { + "$ref": "#/$defs/changeControlRules", + "description": "Rules governing who and how new tokens can be minted manually" + }, + "burningRules": { + "$ref": "#/$defs/changeControlRules", + "description": "Rules governing who and how tokens can be burned manually" + }, + "mainControlGroup": { + "type": "array", + "description": "The main control group, if present", + "items": { + "type": "object", + "properties": { + "identifiers": { + "type": "array", + "description": "A set of identities representing members of the control group", + "items": { + "$ref": "#/$defs/identifier" }, - "canBurn": { - "type": "boolean" - } + "uniqueItems": true }, - "additionalProperties": false, - "required": ["canBurn", "canMint"] - } - }, - "additionalProperties": false, - "minProperties": 1, - "description": "TODO" + "requiredSignersCount": { + "$ref": "#/$defs/requiredSignersCount" + } + }, + "required": ["identifiers", "requiredSignersCount"], + "additionalProperties": false + } }, - "description": { - "type": "string", - "maxLength": 1024, - "description": "Token description" + "mainControlGroupCanBeModified": { + "$ref": "#/$defs/authorizedActionTakers", + "description": "Specifies which entities are authorized to modify the main control group" }, "metadata": { "type": "object", @@ -100,7 +238,8 @@ } }, "required": [ - "initialSupply", - "decimals" - ] + "displayConventions", + "initialSupply" + ], + "additionalProperties": false } From 3049b9e02ca6227875f79b09e9fec4906d57b507 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 12 Dec 2024 07:41:17 +0300 Subject: [PATCH 14/61] more work --- .../rs-dpp/src/data_contract/accessors/mod.rs | 24 +++ .../src/data_contract/accessors/v1/mod.rs | 33 +++ .../src/data_contract/associated_token/mod.rs | 2 +- .../token_configuration/v0/mod.rs | 68 +++--- .../src/data_contract/conversion/json/mod.rs | 11 +- .../src/data_contract/group/accessors/mod.rs | 1 + .../data_contract/group/accessors/v0/mod.rs | 29 +++ .../rs-dpp/src/data_contract/group/mod.rs | 65 ++++++ .../rs-dpp/src/data_contract/group/v0/mod.rs | 44 ++++ packages/rs-dpp/src/data_contract/mod.rs | 31 ++- .../data_contract/serialized_version/mod.rs | 163 ++++++++++++--- .../serialized_version/v0/mod.rs | 7 - .../serialized_version/v1/mod.rs | 63 ++++++ .../data_contract/v0/serialization/bincode.rs | 31 --- .../src/data_contract/v0/serialization/mod.rs | 74 ++++++- .../src/data_contract/v1/accessors/mod.rs | 179 ++++++++++++++++ .../src/data_contract/v1/conversion/cbor.rs | 99 +++++++++ .../src/data_contract/v1/conversion/json.rs | 38 ++++ .../src/data_contract/v1/conversion/mod.rs | 8 + .../src/data_contract/v1/conversion/value.rs | 68 ++++++ .../src/data_contract/v1/data_contract.rs | 73 +++++++ .../src/data_contract/v1/methods/mod.rs | 1 + .../src/data_contract/v1/methods/schema.rs | 197 ++++++++++++++++++ packages/rs-dpp/src/data_contract/v1/mod.rs | 7 + .../src/data_contract/v1/serialization/mod.rs | 189 +++++++++++++++++ 25 files changed, 1403 insertions(+), 102 deletions(-) create mode 100644 packages/rs-dpp/src/data_contract/accessors/v1/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/group/accessors/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/group/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/group/v0/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs delete mode 100644 packages/rs-dpp/src/data_contract/v0/serialization/bincode.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/accessors/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/conversion/cbor.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/conversion/json.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/conversion/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/conversion/value.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/data_contract.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/methods/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/methods/schema.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/v1/serialization/mod.rs diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index fc5dc0789b7..bbdd413de6b 100644 --- a/packages/rs-dpp/src/data_contract/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/mod.rs @@ -11,35 +11,41 @@ use crate::data_contract::errors::DataContractError; use std::collections::BTreeMap; pub mod v0; +pub mod v1; impl DataContractV0Getters for DataContract { fn id(&self) -> Identifier { match self { DataContract::V0(v0) => v0.id(), + DataContract::V1(v1) => v1.id(), } } fn id_ref(&self) -> &Identifier { match self { DataContract::V0(v0) => v0.id_ref(), + DataContract::V1(v1) => v1.id_ref(), } } fn version(&self) -> u32 { match self { DataContract::V0(v0) => v0.version(), + DataContract::V1(v1) => v1.version(), } } fn owner_id(&self) -> Identifier { match self { DataContract::V0(v0) => v0.owner_id(), + DataContract::V1(v1) => v1.owner_id(), } } fn document_type_cloned_for_name(&self, name: &str) -> Result { match self { DataContract::V0(v0) => v0.document_type_cloned_for_name(name), + DataContract::V1(v1) => v1.document_type_cloned_for_name(name), } } @@ -49,72 +55,84 @@ impl DataContractV0Getters for DataContract { ) -> Result<&DocumentType, DataContractError> { match self { DataContract::V0(v0) => v0.document_type_borrowed_for_name(name), + DataContract::V1(v1) => v1.document_type_borrowed_for_name(name), } } fn document_type_for_name(&self, name: &str) -> Result { match self { DataContract::V0(v0) => v0.document_type_for_name(name), + DataContract::V1(v1) => v1.document_type_for_name(name), } } fn document_type_optional_for_name(&self, name: &str) -> Option { match self { DataContract::V0(v0) => v0.document_type_optional_for_name(name), + DataContract::V1(v1) => v1.document_type_optional_for_name(name), } } fn document_type_cloned_optional_for_name(&self, name: &str) -> Option { match self { DataContract::V0(v0) => v0.document_type_cloned_optional_for_name(name), + DataContract::V1(v1) => v1.document_type_cloned_optional_for_name(name), } } fn has_document_type_for_name(&self, name: &str) -> bool { match self { DataContract::V0(v0) => v0.has_document_type_for_name(name), + DataContract::V1(v1) => v1.has_document_type_for_name(name), } } fn document_types_with_contested_indexes(&self) -> BTreeMap<&DocumentName, &DocumentType> { match self { DataContract::V0(v0) => v0.document_types_with_contested_indexes(), + DataContract::V1(v1) => v1.document_types_with_contested_indexes(), } } fn document_types(&self) -> &BTreeMap { match self { DataContract::V0(v0) => v0.document_types(), + DataContract::V1(v1) => v1.document_types(), } } fn document_types_mut(&mut self) -> &mut BTreeMap { match self { DataContract::V0(v0) => v0.document_types_mut(), + DataContract::V1(v1) => v1.document_types_mut(), } } fn metadata(&self) -> Option<&Metadata> { match self { DataContract::V0(v0) => v0.metadata(), + DataContract::V1(v1) => v1.metadata(), } } fn metadata_mut(&mut self) -> Option<&mut Metadata> { match self { DataContract::V0(v0) => v0.metadata_mut(), + DataContract::V1(v1) => v1.metadata_mut(), } } fn config(&self) -> &DataContractConfig { match self { DataContract::V0(v0) => v0.config(), + DataContract::V1(v1) => v1.config(), } } fn config_mut(&mut self) -> &mut DataContractConfig { match self { DataContract::V0(v0) => v0.config_mut(), + DataContract::V1(v1) => v1.config_mut(), } } } @@ -123,36 +141,42 @@ impl DataContractV0Setters for DataContract { fn set_id(&mut self, id: Identifier) { match self { DataContract::V0(v0) => v0.set_id(id), + DataContract::V1(v1) => v1.set_id(id), } } fn set_version(&mut self, version: u32) { match self { DataContract::V0(v0) => v0.set_version(version), + DataContract::V1(v1) => v1.set_version(version), } } fn increment_version(&mut self) { match self { DataContract::V0(v0) => v0.increment_version(), + DataContract::V1(v1) => v1.increment_version(), } } fn set_owner_id(&mut self, owner_id: Identifier) { match self { DataContract::V0(v0) => v0.set_owner_id(owner_id), + DataContract::V1(v1) => v1.set_owner_id(owner_id), } } fn set_metadata(&mut self, metadata: Option) { match self { DataContract::V0(v0) => v0.set_metadata(metadata), + DataContract::V1(v1) => v1.set_metadata(metadata), } } fn set_config(&mut self, config: DataContractConfig) { match self { DataContract::V0(v0) => v0.set_config(config), + DataContract::V1(v1) => v1.set_config(config), } } } diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs new file mode 100644 index 00000000000..b53d89a2eeb --- /dev/null +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -0,0 +1,33 @@ +use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::group::{Group, GroupName}; +use crate::data_contract::TokenName; +use std::collections::BTreeMap; + +pub trait DataContractV1Getters: DataContractV0Getters { + /// Returns a reference to the groups map. + fn groups(&self) -> &BTreeMap; + + /// Returns a mutable reference to the groups map. + fn groups_mut(&mut self) -> &mut BTreeMap; + + /// Returns a reference to the tokens map. + fn tokens(&self) -> &BTreeMap; + + /// Returns a mutable reference to the tokens map. + fn tokens_mut(&mut self) -> &mut BTreeMap; +} + +pub trait DataContractV1Setters: DataContractV0Setters { + /// Sets the groups map for the data contract. + fn set_groups(&mut self, groups: BTreeMap); + + /// Sets the tokens map for the data contract. + fn set_tokens(&mut self, tokens: BTreeMap); + + /// Adds or updates a single group in the groups map. + fn add_group(&mut self, name: GroupName, group: Group); + + /// Adds or updates a single token configuration in the tokens map. + fn add_token(&mut self, name: TokenName, token: TokenConfiguration); +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/mod.rs index f09c33dc596..ad9156e391c 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/mod.rs @@ -1 +1 @@ -mod token_configuration; +pub mod token_configuration; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index d53e13f29f6..0ff77a10161 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -1,60 +1,66 @@ +use crate::data_contract::group::accessors::v0::GroupV0Getters; +use crate::data_contract::group::{Group, GroupMemberPower, RequiredSigners}; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::multi_identity_events::ActionTaker; use platform_value::Identifier; use serde::{Deserialize, Serialize}; -use serde_json::map::BTreeMap; use std::collections::{BTreeMap, BTreeSet}; -pub type RequiredSigners = u8; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] pub enum AuthorizedActionTakers { NoOne, ContractOwner, MainGroup, - SpecifiedIdentities(BTreeSet, RequiredSigners), + Group(Group), } impl AuthorizedActionTakers { pub fn allowed_for_action_taker( &self, contract_owner_id: &Identifier, - main_group: &(BTreeSet, RequiredSigners), + main_group: &Group, action_taker: &ActionTaker, ) -> bool { match self { + // No one is allowed AuthorizedActionTakers::NoOne => false, + + // Only the contract owner is allowed AuthorizedActionTakers::ContractOwner => match action_taker { ActionTaker::SingleIdentity(action_taker) => action_taker == contract_owner_id, ActionTaker::SpecifiedIdentities(action_takers) => { action_takers.contains(contract_owner_id) } }, - AuthorizedActionTakers::MainGroup => match action_taker { - ActionTaker::SingleIdentity(_) => false, - ActionTaker::SpecifiedIdentities(action_takers) => { - let authorized_action_takers_count = - main_group.0.intersection(action_takers).count(); - if authorized_action_takers_count > 255 { - return false; - } - authorized_action_takers_count as u8 >= main_group.1 - } - }, - AuthorizedActionTakers::SpecifiedIdentities( - specified_authorized_identities, - required_signers_count, - ) => match action_taker { - ActionTaker::SingleIdentity(_) => false, - ActionTaker::SpecifiedIdentities(action_takers) => { - let authorized_action_takers_count = specified_authorized_identities - .intersection(action_takers) - .count(); - if authorized_action_takers_count > 255 { - return false; - } - authorized_action_takers_count as u8 >= *required_signers_count - } - }, + + // MainGroup allows multiparty actions with specific power requirements + AuthorizedActionTakers::MainGroup => { + Self::is_action_taker_authorized(main_group, action_taker) + } + + // Group-specific permissions with power aggregation logic + AuthorizedActionTakers::Group(group) => { + Self::is_action_taker_authorized(group, action_taker) + } + } + } + + /// Helper method to check if action takers meet the group's required power threshold. + fn is_action_taker_authorized(group: &Group, action_taker: &ActionTaker) -> bool { + match action_taker { + ActionTaker::SingleIdentity(_) => false, + ActionTaker::SpecifiedIdentities(action_takers) => { + // Calculate the total power of action takers who are members of the group + let total_power: GroupMemberPower = group + .members() + .iter() + .filter(|(member_id, _)| action_takers.contains(*member_id)) + .map(|(_, power)| *power) + .sum(); + + // Compare total power to the group's required power + total_power >= group.required_power() as GroupMemberPower + } } } } @@ -76,7 +82,7 @@ impl ChangeControlRules { &self, other: &ChangeControlRules, contract_owner_id: &Identifier, - main_group: &(BTreeSet, RequiredSigners), + main_group: &Group, action_taker: &ActionTaker, ) -> bool { // First, check if the action taker is allowed to make any changes at all diff --git a/packages/rs-dpp/src/data_contract/conversion/json/mod.rs b/packages/rs-dpp/src/data_contract/conversion/json/mod.rs index b06f6ff2ff9..2e4147653cc 100644 --- a/packages/rs-dpp/src/data_contract/conversion/json/mod.rs +++ b/packages/rs-dpp/src/data_contract/conversion/json/mod.rs @@ -2,7 +2,7 @@ mod v0; pub use v0::*; use crate::data_contract::v0::DataContractV0; -use crate::data_contract::DataContract; +use crate::data_contract::{DataContract, DataContractV1}; use crate::version::PlatformVersion; use crate::ProtocolError; use serde_json::Value as JsonValue; @@ -24,9 +24,12 @@ impl DataContractJsonConversionMethodsV0 for DataContract { 0 => Ok( DataContractV0::from_json(json_value, full_validation, platform_version)?.into(), ), + 1 => Ok( + DataContractV1::from_json(json_value, full_validation, platform_version)?.into(), + ), version => Err(ProtocolError::UnknownVersionMismatch { - method: "DataContract::from_json_object".to_string(), - known_versions: vec![0], + method: "DataContract::from_json".to_string(), + known_versions: vec![0, 1], received: version, }), } @@ -35,6 +38,7 @@ impl DataContractJsonConversionMethodsV0 for DataContract { fn to_json(&self, platform_version: &PlatformVersion) -> Result { match self { DataContract::V0(v0) => v0.to_json(platform_version), + DataContract::V1(v1) => v1.to_json(platform_version), } } @@ -44,6 +48,7 @@ impl DataContractJsonConversionMethodsV0 for DataContract { ) -> Result { match self { DataContract::V0(v0) => v0.to_validating_json(platform_version), + DataContract::V1(v1) => v1.to_validating_json(platform_version), } } } diff --git a/packages/rs-dpp/src/data_contract/group/accessors/mod.rs b/packages/rs-dpp/src/data_contract/group/accessors/mod.rs new file mode 100644 index 00000000000..2d24cd45f58 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/group/accessors/mod.rs @@ -0,0 +1 @@ +pub mod v0; diff --git a/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs new file mode 100644 index 00000000000..b6d6d39df81 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs @@ -0,0 +1,29 @@ +use platform_value::Identifier; +use std::collections::BTreeMap; + +/// Getters for GroupV0 +pub trait GroupV0Getters { + /// Returns the members map of the group + fn members(&self) -> &BTreeMap; + + /// Returns a mutable reference to the members map of the group + fn members_mut(&mut self) -> &mut BTreeMap; + + /// Returns the required power of the group + fn required_power(&self) -> u8; +} + +/// Setters for GroupV0 +pub trait GroupV0Setters { + /// Sets the members of the group + fn set_members(&mut self, members: BTreeMap); + + /// Inserts or updates a member with a specific power + fn set_member_power(&mut self, member_id: Identifier, power: u32); + + /// Removes a member from the group + fn remove_member(&mut self, member_id: &Identifier) -> bool; + + /// Sets the required power of the group + fn set_required_power(&mut self, required_power: u8); +} diff --git a/packages/rs-dpp/src/data_contract/group/mod.rs b/packages/rs-dpp/src/data_contract/group/mod.rs new file mode 100644 index 00000000000..c1762fad525 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/group/mod.rs @@ -0,0 +1,65 @@ +use crate::data_contract::group::accessors::v0::{GroupV0Getters, GroupV0Setters}; +use crate::data_contract::group::v0::GroupV0; +use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use platform_value::Identifier; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +pub mod accessors; +mod v0; + +pub type GroupName = String; +pub type RequiredSigners = u8; + +pub type GroupMemberPower = u32; +pub type GroupRequiredPower = u32; +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +pub enum Group { + V0(GroupV0), +} + +impl GroupV0Getters for Group { + fn members(&self) -> &BTreeMap { + match self { + Group::V0(group_v0) => group_v0.members(), + } + } + + fn members_mut(&mut self) -> &mut BTreeMap { + match self { + Group::V0(group_v0) => group_v0.members_mut(), + } + } + + fn required_power(&self) -> GroupRequiredPower { + match self { + Group::V0(group_v0) => group_v0.required_power(), + } + } +} + +impl GroupV0Setters for Group { + fn set_members(&mut self, members: BTreeMap) { + match self { + Group::V0(group_v0) => group_v0.set_members(members), + } + } + + fn set_member_power(&mut self, member_id: Identifier, power: u32) { + match self { + Group::V0(group_v0) => group_v0.set_member_power(member_id, power), + } + } + + fn remove_member(&mut self, member_id: &Identifier) -> bool { + match self { + Group::V0(group_v0) => group_v0.remove_member(member_id), + } + } + + fn set_required_power(&mut self, required_power: GroupRequiredPower) { + match self { + Group::V0(group_v0) => group_v0.set_required_power(required_power), + } + } +} diff --git a/packages/rs-dpp/src/data_contract/group/v0/mod.rs b/packages/rs-dpp/src/data_contract/group/v0/mod.rs new file mode 100644 index 00000000000..ae8b64532a0 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/group/v0/mod.rs @@ -0,0 +1,44 @@ +use crate::data_contract::group::accessors::v0::{GroupV0Getters, GroupV0Setters}; +use crate::data_contract::group::{GroupMemberPower, GroupRequiredPower}; +use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use platform_value::Identifier; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +pub struct GroupV0 { + pub members: BTreeMap, + pub required_power: GroupRequiredPower, +} + +impl GroupV0Getters for GroupV0 { + fn members(&self) -> &BTreeMap { + &self.members + } + + fn members_mut(&mut self) -> &mut BTreeMap { + &mut self.members + } + + fn required_power(&self) -> GroupRequiredPower { + self.required_power + } +} + +impl GroupV0Setters for GroupV0 { + fn set_members(&mut self, members: BTreeMap) { + self.members = members; + } + + fn set_member_power(&mut self, member_id: Identifier, power: u32) { + self.members.insert(member_id, power); + } + + fn remove_member(&mut self, member_id: &Identifier) -> bool { + self.members.remove(member_id).is_some() + } + + fn set_required_power(&mut self, required_power: GroupRequiredPower) { + self.required_power = required_power; + } +} diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index 0283f429bc9..f8fdc07b787 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -18,6 +18,7 @@ pub mod created_data_contract; pub mod document_type; mod v0; +mod v1; #[cfg(feature = "factories")] pub mod factory; @@ -32,11 +33,13 @@ mod methods; pub mod serialized_version; pub use methods::*; pub mod accessors; -mod associated_token; +pub mod associated_token; pub mod config; +mod group; pub mod storage_requirements; pub use v0::*; +pub use v1::*; use crate::data_contract::serialized_version::{ DataContractInSerializationFormat, CONTRACT_DESERIALIZATION_LIMIT, @@ -54,6 +57,7 @@ pub use serde_json::Value as JsonValue; type JsonSchema = JsonValue; type DefinitionName = String; pub type DocumentName = String; +pub type TokenName = String; type PropertyPath = String; pub const INITIAL_DATA_CONTRACT_VERSION: u32 = 1; @@ -86,6 +90,7 @@ pub const INITIAL_DATA_CONTRACT_VERSION: u32 = 1; #[derive(Debug, Clone, PartialEq, From, PlatformVersioned)] pub enum DataContract { V0(DataContractV0), + V1(DataContractV1), } impl PlatformSerializableWithPlatformVersion for DataContract { @@ -215,18 +220,42 @@ impl DataContract { pub fn as_v0(&self) -> Option<&DataContractV0> { match self { DataContract::V0(v0) => Some(v0), + _ => None, } } pub fn as_v0_mut(&mut self) -> Option<&mut DataContractV0> { match self { DataContract::V0(v0) => Some(v0), + _ => None, } } pub fn into_v0(self) -> Option { match self { DataContract::V0(v0) => Some(v0), + _ => None, + } + } + + pub fn as_v1(&self) -> Option<&DataContractV1> { + match self { + DataContract::V1(v1) => Some(v1), + _ => None, + } + } + + pub fn as_v1_mut(&mut self) -> Option<&mut DataContractV1> { + match self { + DataContract::V1(v1) => Some(v1), + _ => None, + } + } + + pub fn into_v1(self) -> Option { + match self { + DataContract::V1(v1) => Some(v1), + _ => None, } } diff --git a/packages/rs-dpp/src/data_contract/serialized_version/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/mod.rs index 150bc6a28bf..e59b10a1868 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/mod.rs @@ -1,7 +1,7 @@ use crate::data_contract::data_contract::DataContractV0; use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; use crate::data_contract::{DataContract, DefinitionName, DocumentName}; -use crate::version::PlatformVersion; +use crate::version::{FeatureVersion, PlatformVersion}; use std::collections::BTreeMap; use crate::validation::operations::ProtocolValidationOperation; @@ -15,6 +15,14 @@ use platform_versioning::PlatformVersioned; use serde::{Deserialize, Serialize}; pub(in crate::data_contract) mod v0; +pub(in crate::data_contract) mod v1; + +pub mod property_names { + pub const ID: &str = "id"; + pub const OWNER_ID: &str = "ownerId"; + pub const VERSION: &str = "version"; + pub const DEFINITIONS: &str = "$defs"; +} pub const CONTRACT_DESERIALIZATION_LIMIT: usize = 15000; @@ -27,6 +35,8 @@ pub const CONTRACT_DESERIALIZATION_LIMIT: usize = 15000; pub enum DataContractInSerializationFormat { #[cfg_attr(feature = "data-contract-serde-conversion", serde(rename = "0"))] V0(DataContractInSerializationFormatV0), + #[cfg_attr(feature = "data-contract-serde-conversion", serde(rename = "1"))] + V1(DataContractInSerializationFormatV1), } impl DataContractInSerializationFormat { @@ -34,6 +44,7 @@ impl DataContractInSerializationFormat { pub fn id(&self) -> Identifier { match self { DataContractInSerializationFormat::V0(v0) => v0.id, + DataContractInSerializationFormat::V1(v1) => v1.id, } } @@ -41,24 +52,28 @@ impl DataContractInSerializationFormat { pub fn owner_id(&self) -> Identifier { match self { DataContractInSerializationFormat::V0(v0) => v0.owner_id, + DataContractInSerializationFormat::V1(v1) => v1.owner_id, } } pub fn document_schemas(&self) -> &BTreeMap { match self { DataContractInSerializationFormat::V0(v0) => &v0.document_schemas, + DataContractInSerializationFormat::V1(v1) => &v1.document_schemas, } } pub fn schema_defs(&self) -> Option<&BTreeMap> { match self { DataContractInSerializationFormat::V0(v0) => v0.schema_defs.as_ref(), + DataContractInSerializationFormat::V1(v1) => &v1.schema_defs.as_ref(), } } pub fn version(&self) -> u32 { match self { DataContractInSerializationFormat::V0(v0) => v0.version, + DataContractInSerializationFormat::V1(v1) => v1.version, } } } @@ -80,9 +95,13 @@ impl TryFromPlatformVersioned for DataContractInSerializationFor let v0_format: DataContractInSerializationFormatV0 = DataContract::V0(value).into(); Ok(v0_format.into()) } + 1 => { + let v1_format: DataContractInSerializationFormatV1 = DataContract::V0(value).into(); + Ok(v1_format.into()) + } version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContract::serialize_to_default_current_version".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -107,9 +126,14 @@ impl TryFromPlatformVersioned<&DataContractV0> for DataContractInSerializationFo DataContract::V0(value.to_owned()).into(); Ok(v0_format.into()) } + 1 => { + let v1_format: DataContractInSerializationFormatV1 = + DataContract::V0(value.to_owned()).into(); + Ok(v1_format.into()) + } version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContract::serialize_to_default_current_version".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -133,9 +157,13 @@ impl TryFromPlatformVersioned<&DataContract> for DataContractInSerializationForm let v0_format: DataContractInSerializationFormatV0 = value.clone().into(); Ok(v0_format.into()) } + 1 => { + let v1_format: DataContractInSerializationFormatV1 = value.clone().into(); + Ok(v1_format.into()) + } version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContract::serialize_to_default_current_version".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -159,9 +187,13 @@ impl TryFromPlatformVersioned for DataContractInSerializationForma let v0_format: DataContractInSerializationFormatV0 = value.into(); Ok(v0_format.into()) } + 1 => { + let v1_format: DataContractInSerializationFormatV1 = value.into(); + Ok(v1_format.into()) + } version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContract::serialize_consume_to_default_current_version".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -175,29 +207,108 @@ impl DataContract { validation_operations: &mut Vec, platform_version: &PlatformVersion, ) -> Result { - match value { - DataContractInSerializationFormat::V0(serialization_format_v0) => { - match platform_version - .dpp - .contract_versions - .contract_structure_version - { - 0 => { - let data_contract = DataContractV0::try_from_platform_versioned_v0( - serialization_format_v0, - full_validation, - validation_operations, - platform_version, - )?; - Ok(data_contract.into()) + match platform_version + .dpp + .contract_versions + .contract_structure_version + { + 0 => match value { + DataContractInSerializationFormat::V0(serialization_format_v0) => { + match platform_version + .dpp + .contract_versions + .contract_structure_version + { + 0 => { + let data_contract = DataContractV0::try_from_platform_versioned_v0( + serialization_format_v0, + full_validation, + validation_operations, + platform_version, + )?; + Ok(data_contract.into()) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::try_from_platform_versioned".to_string(), + known_versions: vec![0], + received: version, + }), } - version => Err(ProtocolError::UnknownVersionMismatch { - method: "DataContract::from_serialization_format".to_string(), - known_versions: vec![0], - received: version, - }), } - } + DataContractInSerializationFormat::V1(serialization_format_v1) => { + match platform_version + .dpp + .contract_versions + .contract_structure_version + { + 0 => { + let data_contract = DataContractV0::try_from_platform_versioned_v1( + serialization_format_v1, + full_validation, + validation_operations, + platform_version, + )?; + Ok(data_contract.into()) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::try_from_platform_versioned".to_string(), + known_versions: vec![0], + received: version, + }), + } + } + }, + 1 => match value { + DataContractInSerializationFormat::V0(serialization_format_v0) => { + match platform_version + .dpp + .contract_versions + .contract_structure_version + { + 0 => { + let data_contract = DataContractV0::try_from_platform_versioned_v0( + serialization_format_v0, + full_validation, + validation_operations, + platform_version, + )?; + Ok(data_contract.into()) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::from_serialization_format".to_string(), + known_versions: vec![0], + received: version, + }), + } + } + DataContractInSerializationFormat::V1(serialization_format_v1) => { + match platform_version + .dpp + .contract_versions + .contract_structure_version + { + 0 => { + let data_contract = DataContractV0::try_from_platform_versioned_v1( + serialization_format_v1, + full_validation, + validation_operations, + platform_version, + )?; + Ok(data_contract.into()) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::from_serialization_format".to_string(), + known_versions: vec![0], + received: version, + }), + } + } + }, + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::try_from_platform_versioned".to_string(), + known_versions: vec![0, 1], + received: version, + }), } } } diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs index 085b1d2a829..5be1f7be854 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs @@ -9,13 +9,6 @@ use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; -pub mod property_names { - pub const ID: &str = "id"; - pub const OWNER_ID: &str = "ownerId"; - pub const VERSION: &str = "version"; - pub const DEFINITIONS: &str = "$defs"; -} - #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode)] #[serde(rename_all = "camelCase")] pub struct DataContractInSerializationFormatV0 { diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs new file mode 100644 index 00000000000..7eda5daaad7 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -0,0 +1,63 @@ +use crate::data_contract::config::v0::DataContractConfigV0; +use crate::data_contract::config::DataContractConfig; +use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; + +use crate::data_contract::v0::DataContractV0; +use crate::data_contract::{DataContract, DefinitionName, DocumentName}; +use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use platform_value::{Identifier, Value}; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode)] +#[serde(rename_all = "camelCase")] +pub struct DataContractInSerializationFormatV1 { + /// A unique identifier for the data contract. + pub id: Identifier, + + /// Internal configuration for the contract. + #[serde(default = "DataContractConfigV0::default_with_version")] + pub config: DataContractConfig, + + /// The version of this data contract. + pub version: u32, + + /// The identifier of the contract owner. + pub owner_id: Identifier, + + /// Shared subschemas to reuse across documents as $defs object + pub schema_defs: Option>, + + /// Document JSON Schemas per type + pub document_schemas: BTreeMap, +} + +impl From for DataContractInSerializationFormatV0 { + fn from(value: DataContract) -> Self { + match value { + DataContract::V0(v0) => { + let DataContractV0 { + id, + config, + version, + owner_id, + schema_defs, + document_types, + .. + } = v0; + + DataContractInSerializationFormatV0 { + id, + config, + version, + owner_id, + document_schemas: document_types + .into_iter() + .map(|(key, document_type)| (key, document_type.schema_owned())) + .collect(), + schema_defs, + } + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/v0/serialization/bincode.rs b/packages/rs-dpp/src/data_contract/v0/serialization/bincode.rs deleted file mode 100644 index 65d78beaa1a..00000000000 --- a/packages/rs-dpp/src/data_contract/v0/serialization/bincode.rs +++ /dev/null @@ -1,31 +0,0 @@ -#[cfg(test)] -mod tests { - use crate::data_contract::DataContract; - use crate::identity::accessors::IdentityGettersV0; - use crate::identity::Identity; - use crate::serialization::{ - PlatformDeserializableWithPotentialValidationFromVersionedStructure, - PlatformSerializableWithPlatformVersion, - }; - use crate::tests::fixtures::get_data_contract_fixture; - use crate::version::PlatformVersion; - use platform_version::version::LATEST_PLATFORM_VERSION; - - #[test] - #[cfg(feature = "random-identities")] - fn data_contract_ser_de() { - let platform_version = PlatformVersion::latest(); - let identity = Identity::random_identity(5, Some(5), platform_version) - .expect("expected a random identity"); - let contract = - get_data_contract_fixture(Some(identity.id()), 0, platform_version.protocol_version) - .data_contract_owned(); - let bytes = contract - .serialize_to_bytes_with_platform_version(LATEST_PLATFORM_VERSION) - .expect("expected to serialize"); - let recovered_contract = - DataContract::versioned_deserialize(&bytes, false, platform_version) - .expect("expected to deserialize state transition"); - assert_eq!(contract, recovered_contract); - } -} diff --git a/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs b/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs index 104ede8844f..eb5e6a57266 100644 --- a/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs +++ b/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs @@ -10,8 +10,6 @@ use crate::ProtocolError; use crate::validation::operations::ProtocolValidationOperation; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -pub mod bincode; - impl Serialize for DataContractV0 { fn serialize(&self, serializer: S) -> Result where @@ -115,4 +113,76 @@ impl DataContractV0 { Ok(data_contract) } + + pub(in crate::data_contract) fn try_from_platform_versioned_v1( + data_contract_data: DataContractInSerializationFormatV1, + full_validation: bool, + validation_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + let DataContractInSerializationFormatV0 { + id, + config, + version, + owner_id, + document_schemas, + schema_defs, + } = data_contract_data; + + let document_types = DocumentType::create_document_types_from_document_schemas( + id, + document_schemas, + schema_defs.as_ref(), + config.documents_keep_history_contract_default(), + config.documents_mutable_contract_default(), + config.documents_can_be_deleted_contract_default(), + full_validation, + validation_operations, + platform_version, + )?; + + let data_contract = DataContractV0 { + id, + version, + owner_id, + document_types, + metadata: None, + config, + schema_defs, + }; + + Ok(data_contract) + } +} + +#[cfg(test)] +mod tests { + use crate::data_contract::DataContract; + use crate::identity::accessors::IdentityGettersV0; + use crate::identity::Identity; + use crate::serialization::{ + PlatformDeserializableWithPotentialValidationFromVersionedStructure, + PlatformSerializableWithPlatformVersion, + }; + use crate::tests::fixtures::get_data_contract_fixture; + use crate::version::PlatformVersion; + use platform_version::version::LATEST_PLATFORM_VERSION; + + #[test] + #[cfg(feature = "random-identities")] + fn data_contract_ser_de() { + let platform_version = PlatformVersion::first(); + let identity = Identity::random_identity(5, Some(5), platform_version) + .expect("expected a random identity"); + let contract = + get_data_contract_fixture(Some(identity.id()), 0, platform_version.protocol_version) + .data_contract_owned(); + let bytes = contract + .serialize_to_bytes_with_platform_version(LATEST_PLATFORM_VERSION) + .expect("expected to serialize"); + let recovered_contract = + DataContract::versioned_deserialize(&bytes, false, platform_version) + .expect("expected to deserialize state transition"); + assert_eq!(contract, recovered_contract); + } } diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs new file mode 100644 index 00000000000..667b11da30e --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -0,0 +1,179 @@ +use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; +use crate::data_contract::config::DataContractConfig; +use crate::data_contract::document_type::{DocumentType, DocumentTypeRef}; +use crate::data_contract::errors::DataContractError; + +use crate::data_contract::v1::DataContractV1; +use crate::data_contract::{DocumentName, TokenName}; +use crate::metadata::Metadata; + +use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1Setters}; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; +use crate::data_contract::group::{Group, GroupName}; +use platform_value::Identifier; +use std::collections::BTreeMap; + +impl DataContractV0Getters for DataContractV1 { + fn id(&self) -> Identifier { + self.id + } + + fn id_ref(&self) -> &Identifier { + &self.id + } + + fn version(&self) -> u32 { + self.version + } + + fn owner_id(&self) -> Identifier { + self.owner_id + } + + fn document_type_cloned_for_name(&self, name: &str) -> Result { + self.document_type_cloned_optional_for_name(name) + .ok_or_else(|| { + DataContractError::DocumentTypeNotFound( + "can not get document type from contract".to_string(), + ) + }) + } + + fn document_type_borrowed_for_name( + &self, + name: &str, + ) -> Result<&DocumentType, DataContractError> { + self.document_types.get(name).ok_or_else(|| { + DataContractError::DocumentTypeNotFound( + "can not get document type from contract".to_string(), + ) + }) + } + + fn document_type_for_name(&self, name: &str) -> Result { + self.document_type_optional_for_name(name).ok_or_else(|| { + DataContractError::DocumentTypeNotFound( + "can not get document type from contract".to_string(), + ) + }) + } + + fn document_type_optional_for_name(&self, name: &str) -> Option { + self.document_types + .get(name) + .map(|document_type| document_type.as_ref()) + } + + fn document_type_cloned_optional_for_name(&self, name: &str) -> Option { + self.document_types.get(name).cloned() + } + + fn has_document_type_for_name(&self, name: &str) -> bool { + self.document_types.get(name).is_some() + } + + fn document_types_with_contested_indexes(&self) -> BTreeMap<&DocumentName, &DocumentType> { + self.document_types + .iter() + .filter(|(_, document_type)| { + document_type + .indexes() + .iter() + .any(|(_, index)| index.contested_index.is_some()) + }) + .collect() + } + + fn document_types(&self) -> &BTreeMap { + &self.document_types + } + + fn document_types_mut(&mut self) -> &mut BTreeMap { + &mut self.document_types + } + + fn metadata(&self) -> Option<&Metadata> { + self.metadata.as_ref() + } + + fn metadata_mut(&mut self) -> Option<&mut Metadata> { + self.metadata.as_mut() + } + + fn config(&self) -> &DataContractConfig { + &self.config + } + + fn config_mut(&mut self) -> &mut DataContractConfig { + &mut self.config + } +} + +impl DataContractV0Setters for DataContractV1 { + fn set_id(&mut self, id: Identifier) { + self.id = id; + + self.document_types + .iter_mut() + .for_each(|(_, document_type)| match document_type { + DocumentType::V0(v0) => v0.data_contract_id = id, + }) + } + + fn set_version(&mut self, version: u32) { + self.version = version; + } + + fn increment_version(&mut self) { + self.version += 1; + } + + fn set_owner_id(&mut self, owner_id: Identifier) { + self.owner_id = owner_id; + } + + fn set_metadata(&mut self, metadata: Option) { + self.metadata = metadata; + } + + fn set_config(&mut self, config: DataContractConfig) { + self.config = config; + } +} + +impl DataContractV1Getters for DataContractV1 { + fn groups(&self) -> &BTreeMap { + &self.groups + } + + fn groups_mut(&mut self) -> &mut BTreeMap { + &mut self.groups + } + + fn tokens(&self) -> &BTreeMap { + &self.tokens + } + + fn tokens_mut(&mut self) -> &mut BTreeMap { + &mut self.tokens + } +} + +impl DataContractV1Setters for DataContractV1 { + fn set_groups(&mut self, groups: BTreeMap) { + self.groups = groups; + } + + fn set_tokens(&mut self, tokens: BTreeMap) { + self.tokens = tokens; + } + + fn add_group(&mut self, name: GroupName, group: Group) { + self.groups.insert(name, group); + } + + fn add_token(&mut self, name: TokenName, token: TokenConfiguration) { + self.tokens.insert(name, token); + } +} diff --git a/packages/rs-dpp/src/data_contract/v1/conversion/cbor.rs b/packages/rs-dpp/src/data_contract/v1/conversion/cbor.rs new file mode 100644 index 00000000000..ba47910fe18 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/conversion/cbor.rs @@ -0,0 +1,99 @@ +use crate::data_contract::conversion::cbor::DataContractCborConversionMethodsV0; +use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; +use crate::data_contract::data_contract::DataContractV1; +use crate::util::cbor_value::CborCanonicalMap; + +use crate::data_contract::DataContractV1; +use crate::version::PlatformVersion; +use crate::ProtocolError; +use ciborium::Value as CborValue; +use platform_value::{Identifier, Value}; +use std::convert::TryFrom; + +impl DataContractCborConversionMethodsV0 for DataContractV1 { + // TODO: Do we need to use this? + fn from_cbor_with_id( + cbor_bytes: impl AsRef<[u8]>, + contract_id: Option, + full_validation: bool, + platform_version: &PlatformVersion, + ) -> Result { + let mut data_contract = Self::from_cbor(cbor_bytes, full_validation, platform_version)?; + if let Some(id) = contract_id { + data_contract.id = id; + } + Ok(data_contract) + } + + fn from_cbor( + cbor_bytes: impl AsRef<[u8]>, + full_validation: bool, + platform_version: &PlatformVersion, + ) -> Result { + let data_contract_cbor_value: CborValue = ciborium::de::from_reader(cbor_bytes.as_ref()) + .map_err(|_| { + ProtocolError::DecodingError("unable to decode contract from cbor".to_string()) + })?; + + let data_contract_value: Value = + Value::try_from(data_contract_cbor_value).map_err(ProtocolError::ValueError)?; + + Self::from_value(data_contract_value, full_validation, platform_version) + } + + fn to_cbor(&self, platform_version: &PlatformVersion) -> Result, ProtocolError> { + let value = self.to_value(platform_version)?; + + let mut buf: Vec = Vec::new(); + + ciborium::ser::into_writer(&value, &mut buf) + .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; + + Ok(buf) + } + + // /// Returns Data Contract as a Buffer + // fn to_cbor_buffer(&self) -> Result, ProtocolError> { + // let mut object = self.to_object()?; + // if self.defs.is_none() { + // object.remove(property_names::DEFINITIONS)?; + // } + // object + // .to_map_mut() + // .unwrap() + // .sort_by_lexicographical_byte_ordering_keys_and_inner_maps(); + // + // // we are on version 0 here + // cbor_serializer::serializable_value_to_cbor(&object, Some(0)) + // } + + // TODO: Revisit + fn to_cbor_canonical_map( + &self, + _platform_version: &PlatformVersion, + ) -> Result { + unimplemented!(); + + // let mut contract_cbor_map = CborCanonicalMap::new(); + // + // contract_cbor_map.insert(property_names::ID, self.id.to_buffer().to_vec()); + // contract_cbor_map.insert(property_names::SCHEMA, self.schema.as_str()); + // contract_cbor_map.insert(property_names::VERSION, self.version); + // contract_cbor_map.insert(property_names::OWNER_ID, self.owner_id.to_buffer().to_vec()); + // + // let docs = CborValue::serialized(&self.documents) + // .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; + // + // contract_cbor_map.insert(property_names::DOCUMENTS, docs); + // + // if let Some(_defs) = &self.defs { + // contract_cbor_map.insert( + // property_names::DEFINITIONS, + // CborValue::serialized(&self.defs) + // .map_err(|e| ProtocolError::EncodingError(e.to_string()))?, + // ); + // }; + // + // Ok(contract_cbor_map) + } +} diff --git a/packages/rs-dpp/src/data_contract/v1/conversion/json.rs b/packages/rs-dpp/src/data_contract/v1/conversion/json.rs new file mode 100644 index 00000000000..56478ddb8ff --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/conversion/json.rs @@ -0,0 +1,38 @@ +use crate::data_contract::conversion::json::DataContractJsonConversionMethodsV0; +use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; + +use crate::version::PlatformVersion; +use crate::ProtocolError; + +use crate::data_contract::DataContractV1; +use serde_json::Value as JsonValue; +use std::convert::TryInto; + +impl DataContractJsonConversionMethodsV0 for DataContractV1 { + fn from_json( + json_value: JsonValue, + full_validation: bool, + platform_version: &PlatformVersion, + ) -> Result { + Self::from_value(json_value.into(), full_validation, platform_version) + } + + /// Returns Data Contract as a JSON Value + fn to_json(&self, platform_version: &PlatformVersion) -> Result { + self.to_value(platform_version)? + .try_into() + .map_err(ProtocolError::ValueError) + + // TODO: I guess we should convert the binary fields back to base64/base58? + } + + /// Returns Data Contract as a JSON Value that can be used for validation + fn to_validating_json( + &self, + platform_version: &PlatformVersion, + ) -> Result { + self.to_value(platform_version)? + .try_into_validating_json() + .map_err(ProtocolError::ValueError) + } +} diff --git a/packages/rs-dpp/src/data_contract/v1/conversion/mod.rs b/packages/rs-dpp/src/data_contract/v1/conversion/mod.rs new file mode 100644 index 00000000000..eb58a91c438 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/conversion/mod.rs @@ -0,0 +1,8 @@ +#[cfg(feature = "data-contract-cbor-conversion")] +mod cbor; +#[cfg(feature = "data-contract-json-conversion")] +mod json; +#[cfg(feature = "data-contract-value-conversion")] +mod value; + +// TODO: We need from_* / from_*_value / to_* / to_*_value methods for all types: cbor, json, platform_value (value?) diff --git a/packages/rs-dpp/src/data_contract/v1/conversion/value.rs b/packages/rs-dpp/src/data_contract/v1/conversion/value.rs new file mode 100644 index 00000000000..b521b7d4b75 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/conversion/value.rs @@ -0,0 +1,68 @@ +use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; +use crate::data_contract::data_contract::DataContractV1; +use crate::data_contract::serialized_version::v0::{ + property_names, DataContractInSerializationFormatV0, +}; +use crate::data_contract::serialized_version::DataContractInSerializationFormat; +use crate::data_contract::DataContractV1; +use crate::version::PlatformVersion; +use crate::ProtocolError; +use platform_value::{ReplacementType, Value}; +use platform_version::TryFromPlatformVersioned; + +pub const DATA_CONTRACT_IDENTIFIER_FIELDS_V0: [&str; 2] = + [property_names::ID, property_names::OWNER_ID]; + +impl DataContractValueConversionMethodsV0 for DataContractV1 { + fn from_value( + mut value: Value, + full_validation: bool, + platform_version: &PlatformVersion, + ) -> Result { + value.replace_at_paths( + DATA_CONTRACT_IDENTIFIER_FIELDS_V0, + ReplacementType::Identifier, + )?; + let format_version = value.get_str("$format_version")?; + match format_version { + "0" => { + let data_contract_data: DataContractInSerializationFormatV0 = + platform_value::from_value(value).map_err(ProtocolError::ValueError)?; + + DataContractV1::try_from_platform_versioned( + data_contract_data.into(), + full_validation, + &mut vec![], // this is not used in consensus code + platform_version, + ) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContractV1::from_value".to_string(), + known_versions: vec![0], + received: version + .parse() + .map_err(|_| ProtocolError::Generic("Conversion error".to_string()))?, + }), + } + } + + fn to_value(&self, platform_version: &PlatformVersion) -> Result { + let data_contract_data = + DataContractInSerializationFormat::try_from_platform_versioned(self, platform_version)?; + + let value = + platform_value::to_value(data_contract_data).map_err(ProtocolError::ValueError)?; + + Ok(value) + } + + fn into_value(self, platform_version: &PlatformVersion) -> Result { + let data_contract_data = + DataContractInSerializationFormat::try_from_platform_versioned(self, platform_version)?; + + let value = + platform_value::to_value(data_contract_data).map_err(ProtocolError::ValueError)?; + + Ok(value) + } +} diff --git a/packages/rs-dpp/src/data_contract/v1/data_contract.rs b/packages/rs-dpp/src/data_contract/v1/data_contract.rs new file mode 100644 index 00000000000..e555f61f237 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/data_contract.rs @@ -0,0 +1,73 @@ +use std::collections::BTreeMap; + +use platform_value::Identifier; +use platform_value::Value; + +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::config::DataContractConfig; +use crate::data_contract::document_type::DocumentType; +use crate::data_contract::group::{Group, GroupName}; +use crate::data_contract::{DefinitionName, DocumentName, TokenName}; +use crate::metadata::Metadata; + +/// `DataContractV1` represents a data contract in a decentralized platform. +/// +/// It contains information about the contract, such as its protocol version, unique identifier, +/// schema, version, and owner identifier. The struct also includes details about the document +/// types, metadata, configuration, and document schemas associated with the contract. +/// +/// Additionally, `DataContractV1` holds definitions for JSON schemas, entropy, and binary properties +/// of the documents. +/// +/// # Changes from `DataContractV0` to `DataContractV1` +/// +/// In `DataContractV1`, two significant features were introduced to enhance contract governance +/// and support token-related operations: +/// +/// 1. **Groups** (`groups: BTreeMap`) +/// - Groups allow for specific multiparty actions on the contract. Each group is defined with a +/// set of members (`Identifier`) and their corresponding member power (`u32`). +/// - Groups facilitate fine-grained access control and decision-making processes by enabling +/// required power thresholds for group actions. +/// - This is particularly useful for contracts where multiple parties are involved in controlling +/// or managing contract-specific features. +/// +/// 2. **Tokens** (`tokens: BTreeMap`) +/// - Tokens introduce configurable token-related functionality within the contract, such as +/// base supply, maximum supply, and manual minting/burning rules. +/// - Token configurations include change control rules, ensuring proper governance for +/// modifying supply limits and token-related settings. +/// - This addition enables contracts to define and manage tokens while ensuring compliance +/// with governance rules (e.g., who can mint or burn tokens). +/// +#[derive(Debug, Clone, PartialEq)] +pub struct DataContractV1 { + /// A unique identifier for the data contract. + /// This field must always present in all versions. + pub id: Identifier, + + /// The version of this data contract. + pub version: u32, + + /// The identifier of the contract owner. + pub owner_id: Identifier, + + /// A mapping of document names to their corresponding document types. + pub document_types: BTreeMap, + + // TODO: Move metadata from here + /// Optional metadata associated with the contract. + pub metadata: Option, + + /// Internal configuration for the contract. + pub config: DataContractConfig, + + /// Shared subschemas to reuse across documents (see $defs) + pub schema_defs: Option>, + + /// Groups that allow for specific multiparty actions on the contract + pub groups: BTreeMap, + + /// The tokens on the contract. + pub tokens: BTreeMap, +} diff --git a/packages/rs-dpp/src/data_contract/v1/methods/mod.rs b/packages/rs-dpp/src/data_contract/v1/methods/mod.rs new file mode 100644 index 00000000000..6bde67a2b14 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/methods/mod.rs @@ -0,0 +1 @@ +mod schema; diff --git a/packages/rs-dpp/src/data_contract/v1/methods/schema.rs b/packages/rs-dpp/src/data_contract/v1/methods/schema.rs new file mode 100644 index 00000000000..8173352e8fa --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/methods/schema.rs @@ -0,0 +1,197 @@ +use crate::data_contract::config::v0::DataContractConfigGettersV0; +use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; +use crate::data_contract::document_type::DocumentType; +use crate::data_contract::schema::DataContractSchemaMethodsV0; +use crate::data_contract::{DataContractV1, DefinitionName, DocumentName}; +use crate::validation::operations::ProtocolValidationOperation; +use crate::ProtocolError; +use platform_value::Value; +use platform_version::version::PlatformVersion; +use std::collections::BTreeMap; + +impl DataContractSchemaMethodsV0 for DataContractV1 { + fn set_document_schemas( + &mut self, + schemas: BTreeMap, + defs: Option>, + full_validation: bool, + validation_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), ProtocolError> { + self.document_types = DocumentType::create_document_types_from_document_schemas( + self.id, + schemas, + defs.as_ref(), + self.config.documents_keep_history_contract_default(), + self.config.documents_mutable_contract_default(), + self.config.documents_can_be_deleted_contract_default(), + full_validation, + validation_operations, + platform_version, + )?; + + Ok(()) + } + + fn set_document_schema( + &mut self, + name: &str, + schema: Value, + full_validation: bool, + validation_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), ProtocolError> { + let document_type = DocumentType::try_from_schema( + self.id, + name, + schema, + self.schema_defs.as_ref(), + self.config.documents_keep_history_contract_default(), + self.config.documents_mutable_contract_default(), + self.config.documents_mutable_contract_default(), + full_validation, + validation_operations, + platform_version, + )?; + + self.document_types + .insert(document_type.name().clone(), document_type); + + Ok(()) + } + + fn document_schemas(&self) -> BTreeMap { + self.document_types + .iter() + .map(|(name, document_type)| (name.to_owned(), document_type.schema())) + .collect() + } + + fn schema_defs(&self) -> Option<&BTreeMap> { + self.schema_defs.as_ref() + } + + fn set_schema_defs( + &mut self, + defs: Option>, + full_validation: bool, + validation_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), ProtocolError> { + let document_schemas = self + .document_types + .iter() + .map(|(name, document_type)| (name.to_owned(), document_type.schema().to_owned())) + .collect(); + + self.set_document_schemas( + document_schemas, + defs.clone(), + full_validation, + validation_operations, + platform_version, + )?; + + self.schema_defs = defs; + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use super::*; + use crate::data_contract::config::DataContractConfig; + use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; + use crate::data_contract::v0::DataContractV1; + use platform_value::{platform_value, Identifier}; + + #[test] + fn should_set_a_new_schema_defs() { + let platform_version = PlatformVersion::latest(); + + let config = DataContractConfig::default_for_version(platform_version) + .expect("should create a default config"); + + let schema = platform_value!({ + "type": "object", + "properties": { + "a": { + "type": "string", + "maxLength": 10, + "position": 0 + } + }, + "additionalProperties": false, + }); + + let serialization_format = DataContractInSerializationFormatV0 { + id: Identifier::random(), + config, + version: 0, + owner_id: Default::default(), + schema_defs: None, + document_schemas: BTreeMap::from([("document_type_name".to_string(), schema.clone())]), + }; + + let mut data_contract = DataContractV1::try_from_platform_versioned( + serialization_format.into(), + true, + &mut vec![], + platform_version, + ) + .expect("should create a contract from serialization format"); + + let defs = platform_value!({ + "test": { + "type": "string", + }, + }); + + let defs_map = Some(defs.into_btree_string_map().expect("should convert to map")); + + data_contract + .set_schema_defs(defs_map.clone(), true, &mut vec![], platform_version) + .expect("should set defs"); + + assert_eq!(defs_map.as_ref(), data_contract.schema_defs()) + } + + fn should_set_empty_schema_defs() { + let platform_version = PlatformVersion::latest(); + + let config = DataContractConfig::default_for_version(platform_version) + .expect("should create a default config"); + + let defs = platform_value!({ + "test": { + "type": "string", + }, + }); + + let defs_map = Some(defs.into_btree_string_map().expect("should convert to map")); + + let serialization_format = DataContractInSerializationFormatV0 { + id: Identifier::random(), + config, + version: 0, + owner_id: Default::default(), + schema_defs: defs_map, + document_schemas: Default::default(), + }; + + let mut data_contract = DataContractV1::try_from_platform_versioned( + serialization_format.into(), + true, + &mut vec![], + platform_version, + ) + .expect("should create a contract from serialization format"); + + data_contract + .set_schema_defs(None, true, &mut vec![], platform_version) + .expect("should set defs"); + + assert_eq!(None, data_contract.schema_defs()) + } +} diff --git a/packages/rs-dpp/src/data_contract/v1/mod.rs b/packages/rs-dpp/src/data_contract/v1/mod.rs new file mode 100644 index 00000000000..c814a35c4bf --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/mod.rs @@ -0,0 +1,7 @@ +mod accessors; +mod conversion; +pub mod data_contract; +mod methods; +pub mod serialization; + +pub use data_contract::*; diff --git a/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs b/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs new file mode 100644 index 00000000000..63ad37f0f47 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs @@ -0,0 +1,189 @@ +use crate::data_contract::config::v0::DataContractConfigGettersV0; +use crate::data_contract::document_type::DocumentType; +use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; +use crate::data_contract::serialized_version::DataContractInSerializationFormat; +use crate::data_contract::{DataContract, DataContractV1}; +use crate::version::{PlatformVersion, PlatformVersionCurrentVersion}; +use crate::ProtocolError; + +use crate::data_contract::serialized_version::v1::DataContractInSerializationFormatV1; +use crate::validation::operations::ProtocolValidationOperation; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +impl Serialize for DataContractV1 { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let data_contract: DataContract = self.clone().into(); + let serialization_format = DataContractInSerializationFormatV1::from(data_contract); + serialization_format.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for DataContractV1 { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let serialization_format = DataContractInSerializationFormat::deserialize(deserializer)?; + let current_version = + PlatformVersion::get_current().map_err(|e| serde::de::Error::custom(e.to_string()))?; + // when deserializing from json/platform_value/cbor we always want to validate (as this is not coming from the state) + DataContractV1::try_from_platform_versioned_v0( + serialization_format, + true, + &mut vec![], + current_version, + ) + .map_err(serde::de::Error::custom) + } +} + +impl DataContractV1 { + pub(in crate::data_contract) fn try_from_platform_versioned( + value: DataContractInSerializationFormat, + full_validation: bool, + validation_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + match value { + DataContractInSerializationFormat::V0(serialization_format_v0) => { + match platform_version + .dpp + .contract_versions + .contract_structure_version + { + 0 => { + let data_contract = DataContractV1::try_from_platform_versioned_v0( + serialization_format_v0, + full_validation, + validation_operations, + platform_version, + )?; + + Ok(data_contract) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContractV1::from_serialization_format".to_string(), + known_versions: vec![0], + received: version, + }), + } + } + } + } + + pub(in crate::data_contract) fn try_from_platform_versioned_v0( + data_contract_data: DataContractInSerializationFormatV0, + full_validation: bool, + validation_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + let DataContractInSerializationFormatV0 { + id, + config, + version, + owner_id, + document_schemas, + schema_defs, + } = data_contract_data; + + let document_types = DocumentType::create_document_types_from_document_schemas( + id, + document_schemas, + schema_defs.as_ref(), + config.documents_keep_history_contract_default(), + config.documents_mutable_contract_default(), + config.documents_can_be_deleted_contract_default(), + full_validation, + validation_operations, + platform_version, + )?; + + let data_contract = DataContractV1 { + id, + version, + owner_id, + document_types, + metadata: None, + config, + schema_defs, + }; + + Ok(data_contract) + } + + pub(in crate::data_contract) fn try_from_platform_versioned_v1( + data_contract_data: DataContractInSerializationFormatV1, + full_validation: bool, + validation_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + let DataContractInSerializationFormatV0 { + id, + config, + version, + owner_id, + document_schemas, + schema_defs, + } = data_contract_data; + + let document_types = DocumentType::create_document_types_from_document_schemas( + id, + document_schemas, + schema_defs.as_ref(), + config.documents_keep_history_contract_default(), + config.documents_mutable_contract_default(), + config.documents_can_be_deleted_contract_default(), + full_validation, + validation_operations, + platform_version, + )?; + + let data_contract = DataContractV1 { + id, + version, + owner_id, + document_types, + metadata: None, + config, + schema_defs, + }; + + Ok(data_contract) + } +} + +#[cfg(test)] +mod tests { + use crate::data_contract::DataContract; + use crate::identity::accessors::IdentityGettersV0; + use crate::identity::Identity; + use crate::serialization::{ + PlatformDeserializableWithPotentialValidationFromVersionedStructure, + PlatformSerializableWithPlatformVersion, + }; + use crate::tests::fixtures::get_data_contract_fixture; + use crate::version::PlatformVersion; + use platform_version::version::LATEST_PLATFORM_VERSION; + + #[test] + #[cfg(feature = "random-identities")] + fn data_contract_ser_de() { + // V1 of the contract is first present in protocol version 7 + let platform_version = PlatformVersion::get(7).expect("expected protocol version 7"); + let identity = Identity::random_identity(5, Some(5), platform_version) + .expect("expected a random identity"); + let contract = + get_data_contract_fixture(Some(identity.id()), 0, platform_version.protocol_version) + .data_contract_owned(); + let bytes = contract + .serialize_to_bytes_with_platform_version(LATEST_PLATFORM_VERSION) + .expect("expected to serialize"); + let recovered_contract = + DataContract::versioned_deserialize(&bytes, false, platform_version) + .expect("expected to deserialize state transition"); + assert_eq!(contract, recovered_contract); + } +} From e2a512964d0923832100f529b2651dac846ccb73 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 13 Dec 2024 12:58:24 +0300 Subject: [PATCH 15/61] compiled dpp --- .../mod.rs | 15 +- .../v0/mod.rs | 174 ++++++++++++++--- .../token_configuration/mod.rs | 9 + .../token_configuration/v0/mod.rs | 183 +++--------------- .../authorized_action_takers.rs | 65 +++++++ .../data_contract/change_control_rules/mod.rs | 30 +++ .../change_control_rules/v0/mod.rs | 97 ++++++++++ .../src/data_contract/conversion/value/mod.rs | 2 + .../schema/enrich_with_base_schema/v0/mod.rs | 2 +- .../src/data_contract/document_type/v0/mod.rs | 3 - .../src/data_contract/factory/v0/mod.rs | 4 +- .../data_contract/group/accessors/v0/mod.rs | 5 +- .../src/data_contract/methods/schema/mod.rs | 22 +++ packages/rs-dpp/src/data_contract/mod.rs | 10 +- .../data_contract/serialized_version/mod.rs | 176 ++++++++--------- .../serialized_version/v0/mod.rs | 24 +++ .../serialized_version/v1/mod.rs | 44 ++++- .../src/data_contract/v0/conversion/cbor.rs | 2 +- .../src/data_contract/v0/conversion/value.rs | 7 +- .../src/data_contract/v0/serialization/mod.rs | 43 ++-- .../src/data_contract/v1/conversion/value.rs | 8 +- .../src/data_contract/v1/serialization/mod.rs | 49 ++--- .../src/errors/consensus/basic/basic_error.rs | 12 +- ...ntract_token_configuration_update_error.rs | 63 ++++++ .../consensus/basic/data_contract/mod.rs | 2 + packages/rs-dpp/src/errors/consensus/codes.rs | 1 + packages/rs-dpp/src/nft/mod.rs | 1 - .../document_create_transition/v0/mod.rs | 2 +- .../token_transfer_transition/v0/mod.rs | 1 - .../token_transfer_transition/v0_methods.rs | 1 - .../methods/v0/mod.rs | 1 + .../v0/v0_methods.rs | 2 + .../dpp_validation_versions/mod.rs | 1 + .../dpp_validation_versions/v1.rs | 1 + .../dpp_validation_versions/v2.rs | 1 + .../drive_token_method_versions/v1.rs | 7 +- 36 files changed, 714 insertions(+), 356 deletions(-) create mode 100644 packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs create mode 100644 packages/rs-dpp/src/data_contract/change_control_rules/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/data_contract/data_contract_token_configuration_update_error.rs diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs index ced7222718b..dd6b1348904 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs @@ -1,4 +1,5 @@ use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::group::Group; use crate::multi_identity_events::ActionTaker; use crate::validation::SimpleConsensusValidationResult; use crate::ProtocolError; @@ -11,17 +12,23 @@ impl TokenConfiguration { pub fn validate_token_config_update( &self, new_config: &TokenConfiguration, - contract_id: Identifier, - action_taker: ActionTaker, + contract_owner_id: &Identifier, + main_group: &Group, + action_taker: &ActionTaker, platform_version: &PlatformVersion, ) -> Result { match platform_version .dpp .validation .data_contract - .validate_config_update + .validate_token_config_update { - 0 => Ok(self.validate_token_config_update_v0(new_config, contract_id, action_taker)), + 0 => Ok(self.validate_token_config_update_v0( + new_config, + contract_owner_id, + main_group, + action_taker, + )), version => Err(ProtocolError::UnknownVersionMismatch { method: "validate_token_config_update".to_string(), known_versions: vec![0], diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index 33babb41f72..4a78953ce8a 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -1,5 +1,6 @@ -use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; +use crate::consensus::basic::data_contract::DataContractTokenConfigurationUpdateError; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::group::Group; use crate::multi_identity_events::ActionTaker; use crate::validation::SimpleConsensusValidationResult; use platform_value::Identifier; @@ -9,31 +10,158 @@ impl TokenConfiguration { pub(super) fn validate_token_config_update_v0( &self, new_config: &TokenConfiguration, - contract_id: Identifier, - action_taker: ActionTaker, + contract_owner_id: &Identifier, + main_group: &Group, + action_taker: &ActionTaker, ) -> SimpleConsensusValidationResult { - let TokenConfigurationV0 { - base_supply: max_supply, - manual_minting_rules: manual_supply_increase_rules, - main_control_group, - main_control_group_can_be_modified, - balance_can_be_increased, - balance_can_be_destroyed, - } = self.as_cow_v0(); - - let TokenConfigurationV0 { - base_supply: new_max_supply, - manual_minting_rules: manual_supply_increase_rules, - main_control_group, - main_control_group_can_be_modified, - balance_can_be_increased: new_balance_can_be_increased, - balance_can_be_destroyed: new_balance_can_be_destroyed, - } = new_config.as_cow_v0(); - - if max_supply != new_max_supply { - // max_supply_can_be_increased + let old = self.as_cow_v0(); + let new = new_config.as_cow_v0(); + + // Check immutable fields: conventions + if old.conventions != new.conventions { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "conventions".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + + // Check immutable fields: base_supply + if old.base_supply != new.base_supply { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "baseSupply".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + + // Check changes to max_supply and max_supply_change_rules + if old.max_supply != new.max_supply + || old.max_supply_change_rules != new.max_supply_change_rules + { + if !old.max_supply_change_rules.can_change_to( + &new.max_supply_change_rules, + contract_owner_id, + main_group, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "maxSupply or maxSupplyChangeRules".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + + // Check changes to new_tokens_destination_identity and rules + if old.new_tokens_destination_identity != new.new_tokens_destination_identity + || old.new_tokens_destination_identity_rules + != new.new_tokens_destination_identity_rules + { + if !old.new_tokens_destination_identity_rules.can_change_to( + &new.new_tokens_destination_identity_rules, + contract_owner_id, + main_group, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "newTokensDestinationIdentity or newTokensDestinationIdentityRules" + .to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + + // Check changes to manual_minting_rules + if old.manual_minting_rules != new.manual_minting_rules { + if !old.manual_minting_rules.can_change_to( + &new.manual_minting_rules, + contract_owner_id, + main_group, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "manualMintingRules".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + + // Check changes to manual_burning_rules + if old.manual_burning_rules != new.manual_burning_rules { + if !old.manual_burning_rules.can_change_to( + &new.manual_burning_rules, + contract_owner_id, + main_group, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "manualBurningRules".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + + // Check changes to main_control_group + if old.main_control_group != new.main_control_group { + if !old + .main_control_group_can_be_modified + .allowed_for_action_taker(contract_owner_id, main_group, action_taker) + { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "mainControlGroup".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + + // Check changes to main_control_group_can_be_modified + if old.main_control_group_can_be_modified != new.main_control_group_can_be_modified { + // Assuming this is immutable + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "mainControlGroupCanBeModified".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); } + // If we reach here with no errors, return an empty result SimpleConsensusValidationResult::new() } } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs index 56f29402364..5cfe1f5541c 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs @@ -3,6 +3,7 @@ use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use derive_more::From; use serde::{Deserialize, Serialize}; use std::borrow::Cow; +use std::fmt; mod methods; mod v0; @@ -21,3 +22,11 @@ impl TokenConfiguration { } } } + +impl fmt::Display for TokenConfiguration { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TokenConfiguration::V0(v0) => write!(f, "{}", v0), + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 0ff77a10161..457eb0a730d 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -1,164 +1,16 @@ -use crate::data_contract::group::accessors::v0::GroupV0Getters; -use crate::data_contract::group::{Group, GroupMemberPower, RequiredSigners}; +use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; +use crate::data_contract::change_control_rules::ChangeControlRules; +use crate::data_contract::group::RequiredSigners; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; -use crate::multi_identity_events::ActionTaker; use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet}; - -#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] -pub enum AuthorizedActionTakers { - NoOne, - ContractOwner, - MainGroup, - Group(Group), -} - -impl AuthorizedActionTakers { - pub fn allowed_for_action_taker( - &self, - contract_owner_id: &Identifier, - main_group: &Group, - action_taker: &ActionTaker, - ) -> bool { - match self { - // No one is allowed - AuthorizedActionTakers::NoOne => false, - - // Only the contract owner is allowed - AuthorizedActionTakers::ContractOwner => match action_taker { - ActionTaker::SingleIdentity(action_taker) => action_taker == contract_owner_id, - ActionTaker::SpecifiedIdentities(action_takers) => { - action_takers.contains(contract_owner_id) - } - }, - - // MainGroup allows multiparty actions with specific power requirements - AuthorizedActionTakers::MainGroup => { - Self::is_action_taker_authorized(main_group, action_taker) - } - - // Group-specific permissions with power aggregation logic - AuthorizedActionTakers::Group(group) => { - Self::is_action_taker_authorized(group, action_taker) - } - } - } - - /// Helper method to check if action takers meet the group's required power threshold. - fn is_action_taker_authorized(group: &Group, action_taker: &ActionTaker) -> bool { - match action_taker { - ActionTaker::SingleIdentity(_) => false, - ActionTaker::SpecifiedIdentities(action_takers) => { - // Calculate the total power of action takers who are members of the group - let total_power: GroupMemberPower = group - .members() - .iter() - .filter(|(member_id, _)| action_takers.contains(*member_id)) - .map(|(_, power)| *power) - .sum(); - - // Compare total power to the group's required power - total_power >= group.required_power() as GroupMemberPower - } - } - } -} - -#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] -pub struct ChangeControlRules { - /// This is who is authorized to make such a change - authorized_to_make_change: AuthorizedActionTakers, - /// This is who is authorized to make such a change to the people authorized to make a change - authorized_to_change_authorized_action_takers: AuthorizedActionTakers, - /// Are we allowed to change to None in the future - changing_authorized_action_takers_to_no_one_allowed: bool, - /// Are we allowed to change to None in the future - changing_authorized_action_takers_to_contract_owner_allowed: bool, -} - -impl ChangeControlRules { - pub fn can_change_to( - &self, - other: &ChangeControlRules, - contract_owner_id: &Identifier, - main_group: &Group, - action_taker: &ActionTaker, - ) -> bool { - // First, check if the action taker is allowed to make any changes at all - if !self.authorized_to_make_change.allowed_for_action_taker( - contract_owner_id, - main_group, - action_taker, - ) { - return false; - } - - // Check if authorized_to_make_change is being modified - if self.authorized_to_make_change != other.authorized_to_make_change { - // Changing the authorized action takers requires the action_taker to be allowed by - // authorized_to_change_authorized_action_takers in the current rules - if !self - .authorized_to_change_authorized_action_takers - .allowed_for_action_taker(contract_owner_id, main_group, action_taker) - { - return false; - } - - // If we are changing to NoOne, ensure it's allowed - if let AuthorizedActionTakers::NoOne = other.authorized_to_make_change { - if !self.changing_authorized_action_takers_to_no_one_allowed { - return false; - } - } - - // If we are changing to ContractOwner, ensure it's allowed - if let AuthorizedActionTakers::ContractOwner = other.authorized_to_make_change { - if !self.changing_authorized_action_takers_to_contract_owner_allowed { - return false; - } - } - } - - // Check if authorized_to_change_authorized_action_takers is being modified - if self.authorized_to_change_authorized_action_takers - != other.authorized_to_change_authorized_action_takers - { - // Must be allowed by the current authorized_to_change_authorized_action_takers - if !self - .authorized_to_change_authorized_action_takers - .allowed_for_action_taker(contract_owner_id, main_group, action_taker) - { - return false; - } - - // If we are changing to NoOne, ensure it's allowed - if let AuthorizedActionTakers::NoOne = - other.authorized_to_change_authorized_action_takers - { - if !self.changing_authorized_action_takers_to_no_one_allowed { - return false; - } - } - - // If we are changing to ContractOwner, ensure it's allowed - if let AuthorizedActionTakers::ContractOwner = - other.authorized_to_change_authorized_action_takers - { - if !self.changing_authorized_action_takers_to_contract_owner_allowed { - return false; - } - } - } - - // If we reach here, the changes are allowed - true - } -} +use std::fmt; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct TokenConfigurationLocalizationsV0 { + pub should_capitalize: bool, pub singular_form: String, pub plural_form: String, } @@ -166,7 +18,6 @@ pub struct TokenConfigurationLocalizationsV0 { #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct TokenConfigurationConventionV0 { - pub should_capitalize: bool, pub localizations: BTreeMap, pub decimals: u16, } @@ -186,6 +37,30 @@ pub struct TokenConfigurationV0 { pub new_tokens_destination_identity_rules: ChangeControlRules, pub manual_minting_rules: ChangeControlRules, pub manual_burning_rules: ChangeControlRules, + pub freeze_rules: ChangeControlRules, + pub unfreeze_rules: ChangeControlRules, pub main_control_group: Option<(BTreeSet, RequiredSigners)>, pub main_control_group_can_be_modified: AuthorizedActionTakers, } + +impl fmt::Display for TokenConfigurationV0 { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Using debug formatting for nested fields + write!( + f, + "TokenConfigurationV0 {{ conventions: {:?}, base_supply: {}, max_supply: {:?}, max_supply_change_rules: {:?}, new_tokens_destination_identity: {:?}, new_tokens_destination_identity_rules: {:?}, manual_minting_rules: {:?}, manual_burning_rules: {:?}, freeze_rules: {:?}, unfreeze_rules: {:?}, main_control_group: {:?}, main_control_group_can_be_modified: {:?} }}", + self.conventions, + self.base_supply, + self.max_supply, + self.max_supply_change_rules, + self.new_tokens_destination_identity, + self.new_tokens_destination_identity_rules, + self.manual_minting_rules, + self.manual_burning_rules, + self.freeze_rules, + self.unfreeze_rules, + self.main_control_group, + self.main_control_group_can_be_modified + ) + } +} diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs b/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs new file mode 100644 index 00000000000..e099c8cbd9b --- /dev/null +++ b/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs @@ -0,0 +1,65 @@ +use crate::data_contract::group::accessors::v0::GroupV0Getters; +use crate::data_contract::group::{Group, GroupMemberPower}; +use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use crate::multi_identity_events::ActionTaker; +use platform_value::Identifier; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +pub enum AuthorizedActionTakers { + NoOne, + ContractOwner, + MainGroup, + Group(Group), +} + +impl AuthorizedActionTakers { + pub fn allowed_for_action_taker( + &self, + contract_owner_id: &Identifier, + main_group: &Group, + action_taker: &ActionTaker, + ) -> bool { + match self { + // No one is allowed + AuthorizedActionTakers::NoOne => false, + + // Only the contract owner is allowed + AuthorizedActionTakers::ContractOwner => match action_taker { + ActionTaker::SingleIdentity(action_taker) => action_taker == contract_owner_id, + ActionTaker::SpecifiedIdentities(action_takers) => { + action_takers.contains(contract_owner_id) + } + }, + + // MainGroup allows multiparty actions with specific power requirements + AuthorizedActionTakers::MainGroup => { + Self::is_action_taker_authorized(main_group, action_taker) + } + + // Group-specific permissions with power aggregation logic + AuthorizedActionTakers::Group(group) => { + Self::is_action_taker_authorized(group, action_taker) + } + } + } + + /// Helper method to check if action takers meet the group's required power threshold. + fn is_action_taker_authorized(group: &Group, action_taker: &ActionTaker) -> bool { + match action_taker { + ActionTaker::SingleIdentity(_) => false, + ActionTaker::SpecifiedIdentities(action_takers) => { + // Calculate the total power of action takers who are members of the group + let total_power: GroupMemberPower = group + .members() + .iter() + .filter(|(member_id, _)| action_takers.contains(*member_id)) + .map(|(_, power)| *power) + .sum(); + + // Compare total power to the group's required power + total_power >= group.required_power() as GroupMemberPower + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs new file mode 100644 index 00000000000..efa7304690a --- /dev/null +++ b/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs @@ -0,0 +1,30 @@ +pub mod authorized_action_takers; +mod v0; + +use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; +use crate::data_contract::group::Group; +use crate::multi_identity_events::ActionTaker; +use bincode::{Decode, Encode}; +use platform_value::Identifier; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +pub enum ChangeControlRules { + V0(ChangeControlRulesV0), +} + +impl ChangeControlRules { + pub fn can_change_to( + &self, + other: &ChangeControlRules, + contract_owner_id: &Identifier, + main_group: &Group, + action_taker: &ActionTaker, + ) -> bool { + match (self, other) { + (ChangeControlRules::V0(v0), ChangeControlRules::V0(v0_other)) => { + v0.can_change_to(v0_other, contract_owner_id, main_group, action_taker) + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs new file mode 100644 index 00000000000..2e4b3439b11 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs @@ -0,0 +1,97 @@ +use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; +use crate::data_contract::group::Group; +use crate::multi_identity_events::ActionTaker; +use bincode::{Decode, Encode}; +use platform_value::Identifier; +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +pub struct ChangeControlRulesV0 { + /// This is who is authorized to make such a change + authorized_to_make_change: AuthorizedActionTakers, + /// This is who is authorized to make such a change to the people authorized to make a change + authorized_to_change_authorized_action_takers: AuthorizedActionTakers, + /// Are we allowed to change to None in the future + changing_authorized_action_takers_to_no_one_allowed: bool, + /// Are we allowed to change to None in the future + changing_authorized_action_takers_to_contract_owner_allowed: bool, +} + +impl ChangeControlRulesV0 { + pub fn can_change_to( + &self, + other: &ChangeControlRulesV0, + contract_owner_id: &Identifier, + main_group: &Group, + action_taker: &ActionTaker, + ) -> bool { + // First, check if the action taker is allowed to make any changes at all + if !self.authorized_to_make_change.allowed_for_action_taker( + contract_owner_id, + main_group, + action_taker, + ) { + return false; + } + + // Check if authorized_to_make_change is being modified + if self.authorized_to_make_change != other.authorized_to_make_change { + // Changing the authorized action takers requires the action_taker to be allowed by + // authorized_to_change_authorized_action_takers in the current rules + if !self + .authorized_to_change_authorized_action_takers + .allowed_for_action_taker(contract_owner_id, main_group, action_taker) + { + return false; + } + + // If we are changing to NoOne, ensure it's allowed + if let AuthorizedActionTakers::NoOne = other.authorized_to_make_change { + if !self.changing_authorized_action_takers_to_no_one_allowed { + return false; + } + } + + // If we are changing to ContractOwner, ensure it's allowed + if let AuthorizedActionTakers::ContractOwner = other.authorized_to_make_change { + if !self.changing_authorized_action_takers_to_contract_owner_allowed { + return false; + } + } + } + + // Check if authorized_to_change_authorized_action_takers is being modified + if self.authorized_to_change_authorized_action_takers + != other.authorized_to_change_authorized_action_takers + { + // Must be allowed by the current authorized_to_change_authorized_action_takers + if !self + .authorized_to_change_authorized_action_takers + .allowed_for_action_taker(contract_owner_id, main_group, action_taker) + { + return false; + } + + // If we are changing to NoOne, ensure it's allowed + if let AuthorizedActionTakers::NoOne = + other.authorized_to_change_authorized_action_takers + { + if !self.changing_authorized_action_takers_to_no_one_allowed { + return false; + } + } + + // If we are changing to ContractOwner, ensure it's allowed + if let AuthorizedActionTakers::ContractOwner = + other.authorized_to_change_authorized_action_takers + { + if !self.changing_authorized_action_takers_to_contract_owner_allowed { + return false; + } + } + } + + // If we reach here, the changes are allowed + true + } +} diff --git a/packages/rs-dpp/src/data_contract/conversion/value/mod.rs b/packages/rs-dpp/src/data_contract/conversion/value/mod.rs index bc54e6e80a1..305ac8c9db6 100644 --- a/packages/rs-dpp/src/data_contract/conversion/value/mod.rs +++ b/packages/rs-dpp/src/data_contract/conversion/value/mod.rs @@ -32,12 +32,14 @@ impl DataContractValueConversionMethodsV0 for DataContract { fn to_value(&self, platform_version: &PlatformVersion) -> Result { match self { DataContract::V0(v0) => v0.to_value(platform_version), + DataContract::V1(v1) => v1.to_value(platform_version), } } fn into_value(self, platform_version: &PlatformVersion) -> Result { match self { DataContract::V0(v0) => v0.into_value(platform_version), + DataContract::V1(v1) => v1.into_value(platform_version), } } } diff --git a/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs index 80ccb05111f..620fb154974 100644 --- a/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs @@ -1,6 +1,6 @@ use crate::data_contract::document_type::property_names; use crate::data_contract::errors::DataContractError; -use crate::data_contract::serialized_version::v0::property_names as contract_property_names; +use crate::data_contract::serialized_version::property_names as contract_property_names; use platform_value::{Value, ValueMapHelper}; pub const DATA_CONTRACT_SCHEMA_URI_V0: &str = diff --git a/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs index 048ef06b6e7..9951c2b638b 100644 --- a/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/v0/mod.rs @@ -13,7 +13,6 @@ use crate::data_contract::document_type::restricted_creation::CreationRestrictio use crate::document::transfer::Transferable; use crate::identity::SecurityLevel; use crate::nft::TradeMode; -use crate::tokens::allowed_currency::AllowedCurrency; use platform_value::{Identifier, Value}; mod accessors; @@ -56,8 +55,6 @@ pub struct DocumentTypeV0 { pub(in crate::data_contract) documents_transferable: Transferable, /// How are these documents traded? pub(in crate::data_contract) trade_mode: TradeMode, - /// How are these documents traded? - pub(in crate::data_contract) allowed_trade_currencies: Vec, /// Is document creation restricted? pub(in crate::data_contract) creation_restriction_mode: CreationRestrictionMode, /// The data contract id diff --git a/packages/rs-dpp/src/data_contract/factory/v0/mod.rs b/packages/rs-dpp/src/data_contract/factory/v0/mod.rs index 7b9949e5f88..c9eafdf0216 100644 --- a/packages/rs-dpp/src/data_contract/factory/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/factory/v0/mod.rs @@ -9,10 +9,10 @@ use crate::data_contract::config::DataContractConfig; #[cfg(feature = "data-contract-value-conversion")] use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; use crate::data_contract::created_data_contract::CreatedDataContract; -#[cfg(feature = "data-contract-value-conversion")] -use crate::data_contract::data_contract::DataContractV0; use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; use crate::data_contract::serialized_version::DataContractInSerializationFormat; +#[cfg(feature = "data-contract-value-conversion")] +use crate::data_contract::v0::DataContractV0; use crate::data_contract::{DataContract, INITIAL_DATA_CONTRACT_VERSION}; use crate::serialization::PlatformDeserializableWithPotentialValidationFromVersionedStructure; #[cfg(feature = "state-transitions")] diff --git a/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs index b6d6d39df81..ed082f3d5ef 100644 --- a/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs @@ -1,3 +1,4 @@ +use crate::data_contract::group::GroupRequiredPower; use platform_value::Identifier; use std::collections::BTreeMap; @@ -10,7 +11,7 @@ pub trait GroupV0Getters { fn members_mut(&mut self) -> &mut BTreeMap; /// Returns the required power of the group - fn required_power(&self) -> u8; + fn required_power(&self) -> GroupRequiredPower; } /// Setters for GroupV0 @@ -25,5 +26,5 @@ pub trait GroupV0Setters { fn remove_member(&mut self, member_id: &Identifier) -> bool; /// Sets the required power of the group - fn set_required_power(&mut self, required_power: u8); + fn set_required_power(&mut self, required_power: GroupRequiredPower); } diff --git a/packages/rs-dpp/src/data_contract/methods/schema/mod.rs b/packages/rs-dpp/src/data_contract/methods/schema/mod.rs index 63748fb45f8..b048cd44ffe 100644 --- a/packages/rs-dpp/src/data_contract/methods/schema/mod.rs +++ b/packages/rs-dpp/src/data_contract/methods/schema/mod.rs @@ -26,6 +26,13 @@ impl DataContractSchemaMethodsV0 for DataContract { validation_operations, platform_version, ), + DataContract::V1(v1) => v1.set_document_schemas( + schemas, + defs, + full_validation, + validation_operations, + platform_version, + ), } } @@ -45,18 +52,27 @@ impl DataContractSchemaMethodsV0 for DataContract { validation_operations, platform_version, ), + DataContract::V1(v1) => v1.set_document_schema( + name, + schema, + full_validation, + validation_operations, + platform_version, + ), } } fn document_schemas(&self) -> BTreeMap { match self { DataContract::V0(v0) => v0.document_schemas(), + DataContract::V1(v1) => v1.document_schemas(), } } fn schema_defs(&self) -> Option<&BTreeMap> { match self { DataContract::V0(v0) => v0.schema_defs(), + DataContract::V1(v1) => v1.schema_defs(), } } @@ -74,6 +90,12 @@ impl DataContractSchemaMethodsV0 for DataContract { validation_operations, platform_version, ), + DataContract::V1(v1) => v1.set_schema_defs( + defs, + full_validation, + validation_operations, + platform_version, + ), } } } diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index f8fdc07b787..d27856454bd 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -17,8 +17,8 @@ mod generate_data_contract; pub mod created_data_contract; pub mod document_type; -mod v0; -mod v1; +pub mod v0; +pub mod v1; #[cfg(feature = "factories")] pub mod factory; @@ -34,13 +34,11 @@ pub mod serialized_version; pub use methods::*; pub mod accessors; pub mod associated_token; +mod change_control_rules; pub mod config; mod group; pub mod storage_requirements; -pub use v0::*; -pub use v1::*; - use crate::data_contract::serialized_version::{ DataContractInSerializationFormat, CONTRACT_DESERIALIZATION_LIMIT, }; @@ -50,6 +48,8 @@ use crate::version::{FeatureVersion, PlatformVersion}; use crate::ProtocolError; use crate::ProtocolError::{PlatformDeserializationError, PlatformSerializationError}; +use crate::data_contract::v0::DataContractV0; +use crate::data_contract::v1::DataContractV1; use platform_version::TryIntoPlatformVersioned; use platform_versioning::PlatformVersioned; pub use serde_json::Value as JsonValue; diff --git a/packages/rs-dpp/src/data_contract/serialized_version/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/mod.rs index e59b10a1868..fce0a9eb677 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/mod.rs @@ -1,9 +1,11 @@ -use crate::data_contract::data_contract::DataContractV0; use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; use crate::data_contract::{DataContract, DefinitionName, DocumentName}; -use crate::version::{FeatureVersion, PlatformVersion}; +use crate::version::PlatformVersion; use std::collections::BTreeMap; +use crate::data_contract::serialized_version::v1::DataContractInSerializationFormatV1; +use crate::data_contract::v0::DataContractV0; +use crate::data_contract::v1::DataContractV1; use crate::validation::operations::ProtocolValidationOperation; use crate::ProtocolError; use bincode::{Decode, Encode}; @@ -66,7 +68,7 @@ impl DataContractInSerializationFormat { pub fn schema_defs(&self) -> Option<&BTreeMap> { match self { DataContractInSerializationFormat::V0(v0) => v0.schema_defs.as_ref(), - DataContractInSerializationFormat::V1(v1) => &v1.schema_defs.as_ref(), + DataContractInSerializationFormat::V1(v1) => v1.schema_defs.as_ref(), } } @@ -140,6 +142,68 @@ impl TryFromPlatformVersioned<&DataContractV0> for DataContractInSerializationFo } } +impl TryFromPlatformVersioned for DataContractInSerializationFormat { + type Error = ProtocolError; + + fn try_from_platform_versioned( + value: DataContractV1, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .dpp + .contract_versions + .contract_serialization_version + .default_current_version + { + 0 => { + let v0_format: DataContractInSerializationFormatV0 = DataContract::V1(value).into(); + Ok(v0_format.into()) + } + 1 => { + let v1_format: DataContractInSerializationFormatV1 = DataContract::V1(value).into(); + Ok(v1_format.into()) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::serialize_to_default_current_version".to_string(), + known_versions: vec![0, 1], + received: version, + }), + } + } +} + +impl TryFromPlatformVersioned<&DataContractV1> for DataContractInSerializationFormat { + type Error = ProtocolError; + + fn try_from_platform_versioned( + value: &DataContractV1, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .dpp + .contract_versions + .contract_serialization_version + .default_current_version + { + 0 => { + let v0_format: DataContractInSerializationFormatV0 = + DataContract::V1(value.to_owned()).into(); + Ok(v0_format.into()) + } + 1 => { + let v1_format: DataContractInSerializationFormatV1 = + DataContract::V1(value.to_owned()).into(); + Ok(v1_format.into()) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DataContract::serialize_to_default_current_version".to_string(), + known_versions: vec![0, 1], + received: version, + }), + } + } +} + impl TryFromPlatformVersioned<&DataContract> for DataContractInSerializationFormat { type Error = ProtocolError; @@ -212,98 +276,20 @@ impl DataContract { .contract_versions .contract_structure_version { - 0 => match value { - DataContractInSerializationFormat::V0(serialization_format_v0) => { - match platform_version - .dpp - .contract_versions - .contract_structure_version - { - 0 => { - let data_contract = DataContractV0::try_from_platform_versioned_v0( - serialization_format_v0, - full_validation, - validation_operations, - platform_version, - )?; - Ok(data_contract.into()) - } - version => Err(ProtocolError::UnknownVersionMismatch { - method: "DataContract::try_from_platform_versioned".to_string(), - known_versions: vec![0], - received: version, - }), - } - } - DataContractInSerializationFormat::V1(serialization_format_v1) => { - match platform_version - .dpp - .contract_versions - .contract_structure_version - { - 0 => { - let data_contract = DataContractV0::try_from_platform_versioned_v1( - serialization_format_v1, - full_validation, - validation_operations, - platform_version, - )?; - Ok(data_contract.into()) - } - version => Err(ProtocolError::UnknownVersionMismatch { - method: "DataContract::try_from_platform_versioned".to_string(), - known_versions: vec![0], - received: version, - }), - } - } - }, - 1 => match value { - DataContractInSerializationFormat::V0(serialization_format_v0) => { - match platform_version - .dpp - .contract_versions - .contract_structure_version - { - 0 => { - let data_contract = DataContractV0::try_from_platform_versioned_v0( - serialization_format_v0, - full_validation, - validation_operations, - platform_version, - )?; - Ok(data_contract.into()) - } - version => Err(ProtocolError::UnknownVersionMismatch { - method: "DataContract::from_serialization_format".to_string(), - known_versions: vec![0], - received: version, - }), - } - } - DataContractInSerializationFormat::V1(serialization_format_v1) => { - match platform_version - .dpp - .contract_versions - .contract_structure_version - { - 0 => { - let data_contract = DataContractV0::try_from_platform_versioned_v1( - serialization_format_v1, - full_validation, - validation_operations, - platform_version, - )?; - Ok(data_contract.into()) - } - version => Err(ProtocolError::UnknownVersionMismatch { - method: "DataContract::from_serialization_format".to_string(), - known_versions: vec![0], - received: version, - }), - } - } - }, + 0 => DataContractV0::try_from_platform_versioned( + value, + full_validation, + validation_operations, + platform_version, + ) + .map(|contract| contract.into()), + 1 => DataContractV1::try_from_platform_versioned( + value, + full_validation, + validation_operations, + platform_version, + ) + .map(|contract| contract.into()), version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContract::try_from_platform_versioned".to_string(), known_versions: vec![0, 1], diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs index 5be1f7be854..03591d44fea 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs @@ -3,6 +3,7 @@ use crate::data_contract::config::DataContractConfig; use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::v0::DataContractV0; +use crate::data_contract::v1::DataContractV1; use crate::data_contract::{DataContract, DefinitionName, DocumentName}; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use platform_value::{Identifier, Value}; @@ -46,6 +47,29 @@ impl From for DataContractInSerializationFormatV0 { .. } = v0; + DataContractInSerializationFormatV0 { + id, + config, + version, + owner_id, + document_schemas: document_types + .into_iter() + .map(|(key, document_type)| (key, document_type.schema_owned())) + .collect(), + schema_defs, + } + } + DataContract::V1(v1) => { + let DataContractV1 { + id, + config, + version, + owner_id, + schema_defs, + document_types, + .. + } = v1; + DataContractInSerializationFormatV0 { id, config, diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index 7eda5daaad7..67f36a11ace 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -2,8 +2,11 @@ use crate::data_contract::config::v0::DataContractConfigV0; use crate::data_contract::config::DataContractConfig; use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::group::{Group, GroupName}; use crate::data_contract::v0::DataContractV0; -use crate::data_contract::{DataContract, DefinitionName, DocumentName}; +use crate::data_contract::v1::DataContractV1; +use crate::data_contract::{DataContract, DefinitionName, DocumentName, TokenName}; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; @@ -30,9 +33,15 @@ pub struct DataContractInSerializationFormatV1 { /// Document JSON Schemas per type pub document_schemas: BTreeMap, + + /// Groups that allow for specific multiparty actions on the contract + pub groups: BTreeMap, + + /// The tokens on the contract. + pub tokens: BTreeMap, } -impl From for DataContractInSerializationFormatV0 { +impl From for DataContractInSerializationFormatV1 { fn from(value: DataContract) -> Self { match value { DataContract::V0(v0) => { @@ -46,16 +55,45 @@ impl From for DataContractInSerializationFormatV0 { .. } = v0; - DataContractInSerializationFormatV0 { + DataContractInSerializationFormatV1 { id, config, version, owner_id, + schema_defs, document_schemas: document_types .into_iter() .map(|(key, document_type)| (key, document_type.schema_owned())) .collect(), + groups: Default::default(), + tokens: Default::default(), + } + } + DataContract::V1(v1) => { + let DataContractV1 { + id, + config, + version, + owner_id, schema_defs, + document_types, + groups, + tokens, + .. + } = v1; + + DataContractInSerializationFormatV1 { + id, + config, + version, + owner_id, + schema_defs, + document_schemas: document_types + .into_iter() + .map(|(key, document_type)| (key, document_type.schema_owned())) + .collect(), + groups, + tokens, } } } diff --git a/packages/rs-dpp/src/data_contract/v0/conversion/cbor.rs b/packages/rs-dpp/src/data_contract/v0/conversion/cbor.rs index af497027fd3..c2aba05b124 100644 --- a/packages/rs-dpp/src/data_contract/v0/conversion/cbor.rs +++ b/packages/rs-dpp/src/data_contract/v0/conversion/cbor.rs @@ -1,6 +1,6 @@ use crate::data_contract::conversion::cbor::DataContractCborConversionMethodsV0; use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; -use crate::data_contract::data_contract::DataContractV0; +use crate::data_contract::v0::DataContractV0; use crate::util::cbor_value::CborCanonicalMap; use crate::version::PlatformVersion; diff --git a/packages/rs-dpp/src/data_contract/v0/conversion/value.rs b/packages/rs-dpp/src/data_contract/v0/conversion/value.rs index 3ed0a987135..db16bc497d7 100644 --- a/packages/rs-dpp/src/data_contract/v0/conversion/value.rs +++ b/packages/rs-dpp/src/data_contract/v0/conversion/value.rs @@ -1,9 +1,8 @@ use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; -use crate::data_contract::data_contract::DataContractV0; -use crate::data_contract::serialized_version::v0::{ - property_names, DataContractInSerializationFormatV0, -}; +use crate::data_contract::serialized_version::property_names; +use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; use crate::data_contract::serialized_version::DataContractInSerializationFormat; +use crate::data_contract::v0::DataContractV0; use crate::version::PlatformVersion; use crate::ProtocolError; use platform_value::{ReplacementType, Value}; diff --git a/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs b/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs index eb5e6a57266..e6dca7127e8 100644 --- a/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs +++ b/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs @@ -7,6 +7,7 @@ use crate::data_contract::DataContract; use crate::version::{PlatformVersion, PlatformVersionCurrentVersion}; use crate::ProtocolError; +use crate::data_contract::serialized_version::v1::DataContractInSerializationFormatV1; use crate::validation::operations::ProtocolValidationOperation; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -49,27 +50,24 @@ impl DataContractV0 { ) -> Result { match value { DataContractInSerializationFormat::V0(serialization_format_v0) => { - match platform_version - .dpp - .contract_versions - .contract_structure_version - { - 0 => { - let data_contract = DataContractV0::try_from_platform_versioned_v0( - serialization_format_v0, - full_validation, - validation_operations, - platform_version, - )?; - - Ok(data_contract) - } - version => Err(ProtocolError::UnknownVersionMismatch { - method: "DataContractV0::from_serialization_format".to_string(), - known_versions: vec![0], - received: version, - }), - } + let data_contract = DataContractV0::try_from_platform_versioned_v0( + serialization_format_v0, + full_validation, + validation_operations, + platform_version, + )?; + + Ok(data_contract) + } + DataContractInSerializationFormat::V1(serialization_format_v1) => { + let data_contract = DataContractV0::try_from_platform_versioned_v1( + serialization_format_v1, + full_validation, + validation_operations, + platform_version, + )?; + + Ok(data_contract) } } } @@ -120,13 +118,14 @@ impl DataContractV0 { validation_operations: &mut Vec, platform_version: &PlatformVersion, ) -> Result { - let DataContractInSerializationFormatV0 { + let DataContractInSerializationFormatV1 { id, config, version, owner_id, document_schemas, schema_defs, + .. } = data_contract_data; let document_types = DocumentType::create_document_types_from_document_schemas( diff --git a/packages/rs-dpp/src/data_contract/v1/conversion/value.rs b/packages/rs-dpp/src/data_contract/v1/conversion/value.rs index b521b7d4b75..f51e6b36529 100644 --- a/packages/rs-dpp/src/data_contract/v1/conversion/value.rs +++ b/packages/rs-dpp/src/data_contract/v1/conversion/value.rs @@ -1,9 +1,7 @@ use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; -use crate::data_contract::data_contract::DataContractV1; -use crate::data_contract::serialized_version::v0::{ - property_names, DataContractInSerializationFormatV0, -}; -use crate::data_contract::serialized_version::DataContractInSerializationFormat; + +use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; +use crate::data_contract::serialized_version::{property_names, DataContractInSerializationFormat}; use crate::data_contract::DataContractV1; use crate::version::PlatformVersion; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs b/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs index 63ad37f0f47..56e79d1c994 100644 --- a/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs @@ -30,7 +30,7 @@ impl<'de> Deserialize<'de> for DataContractV1 { let current_version = PlatformVersion::get_current().map_err(|e| serde::de::Error::custom(e.to_string()))?; // when deserializing from json/platform_value/cbor we always want to validate (as this is not coming from the state) - DataContractV1::try_from_platform_versioned_v0( + DataContractV1::try_from_platform_versioned( serialization_format, true, &mut vec![], @@ -49,27 +49,24 @@ impl DataContractV1 { ) -> Result { match value { DataContractInSerializationFormat::V0(serialization_format_v0) => { - match platform_version - .dpp - .contract_versions - .contract_structure_version - { - 0 => { - let data_contract = DataContractV1::try_from_platform_versioned_v0( - serialization_format_v0, - full_validation, - validation_operations, - platform_version, - )?; - - Ok(data_contract) - } - version => Err(ProtocolError::UnknownVersionMismatch { - method: "DataContractV1::from_serialization_format".to_string(), - known_versions: vec![0], - received: version, - }), - } + let data_contract = DataContractV1::try_from_platform_versioned_v0( + serialization_format_v0, + full_validation, + validation_operations, + platform_version, + )?; + + Ok(data_contract) + } + DataContractInSerializationFormat::V1(serialization_format_v1) => { + let data_contract = DataContractV1::try_from_platform_versioned_v1( + serialization_format_v1, + full_validation, + validation_operations, + platform_version, + )?; + + Ok(data_contract) } } } @@ -109,6 +106,8 @@ impl DataContractV1 { metadata: None, config, schema_defs, + groups: Default::default(), + tokens: Default::default(), }; Ok(data_contract) @@ -120,13 +119,15 @@ impl DataContractV1 { validation_operations: &mut Vec, platform_version: &PlatformVersion, ) -> Result { - let DataContractInSerializationFormatV0 { + let DataContractInSerializationFormatV1 { id, config, version, owner_id, document_schemas, schema_defs, + groups, + tokens, } = data_contract_data; let document_types = DocumentType::create_document_types_from_document_schemas( @@ -149,6 +150,8 @@ impl DataContractV1 { metadata: None, config, schema_defs, + groups, + tokens, }; Ok(data_contract) diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index 2b24a1e2801..bb6ed170f8b 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -9,10 +9,11 @@ use crate::consensus::basic::data_contract::InvalidJsonSchemaRefError; use crate::consensus::basic::data_contract::{ ContestedUniqueIndexOnMutableDocumentTypeError, ContestedUniqueIndexWithUniqueIndexError, DataContractHaveNewUniqueIndexError, DataContractImmutablePropertiesUpdateError, - DataContractInvalidIndexDefinitionUpdateError, DataContractUniqueIndicesChangedError, - DuplicateIndexError, DuplicateIndexNameError, IncompatibleDataContractSchemaError, - IncompatibleDocumentTypeSchemaError, IncompatibleRe2PatternError, InvalidCompoundIndexError, - InvalidDataContractIdError, InvalidDataContractVersionError, InvalidDocumentTypeNameError, + DataContractInvalidIndexDefinitionUpdateError, DataContractTokenConfigurationUpdateError, + DataContractUniqueIndicesChangedError, DuplicateIndexError, DuplicateIndexNameError, + IncompatibleDataContractSchemaError, IncompatibleDocumentTypeSchemaError, + IncompatibleRe2PatternError, InvalidCompoundIndexError, InvalidDataContractIdError, + InvalidDataContractVersionError, InvalidDocumentTypeNameError, InvalidDocumentTypeRequiredSecurityLevelError, InvalidIndexPropertyTypeError, InvalidIndexedPropertyConstraintError, SystemPropertyIndexAlreadyPresentError, UndefinedIndexPropertyError, UniqueIndicesLimitReachedError, @@ -182,6 +183,9 @@ pub enum BasicError { #[error(transparent)] DataContractImmutablePropertiesUpdateError(DataContractImmutablePropertiesUpdateError), + #[error(transparent)] + DataContractTokenConfigurationUpdateError(DataContractTokenConfigurationUpdateError), + #[error(transparent)] DataContractUniqueIndicesChangedError(DataContractUniqueIndicesChangedError), diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/data_contract_token_configuration_update_error.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/data_contract_token_configuration_update_error.rs new file mode 100644 index 00000000000..a367fb8ad20 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/data_contract_token_configuration_update_error.rs @@ -0,0 +1,63 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::errors::ProtocolError; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; + +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use bincode::{Decode, Encode}; + +#[derive( + Error, Debug, Clone, PartialEq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Forbidden operation '{operation}' on '{field_path}', old config is {old_config}, new config is {new_config}")] +#[platform_serialize(unversioned)] +pub struct DataContractTokenConfigurationUpdateError { + /* + + DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION + + */ + operation: String, + field_path: String, + old_config: TokenConfiguration, + new_config: TokenConfiguration, +} + +impl DataContractTokenConfigurationUpdateError { + pub fn new( + operation: String, + field_path: String, + old_config: TokenConfiguration, + new_config: TokenConfiguration, + ) -> Self { + Self { + operation, + field_path, + old_config, + new_config, + } + } + + pub fn operation(&self) -> String { + self.operation.clone() + } + + pub fn field_path(&self) -> String { + self.field_path.clone() + } + + pub fn old_config(&self) -> TokenConfiguration { + self.old_config.clone() + } + + pub fn new_config(&self) -> TokenConfiguration { + self.new_config.clone() + } +} + +impl From for ConsensusError { + fn from(err: DataContractTokenConfigurationUpdateError) -> Self { + Self::BasicError(BasicError::DataContractTokenConfigurationUpdateError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs index 9e7bedab0d9..1553f179989 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs @@ -4,6 +4,7 @@ mod data_contract_have_new_unique_index_error; mod data_contract_immutable_properties_update_error; mod data_contract_invalid_index_definition_update_error; pub mod data_contract_max_depth_exceed_error; +mod data_contract_token_configuration_update_error; mod data_contract_unique_indices_changed_error; mod document_types_are_missing_error; mod duplicate_index_error; @@ -32,6 +33,7 @@ mod unknown_transferable_type_error; pub use data_contract_have_new_unique_index_error::*; pub use data_contract_immutable_properties_update_error::*; pub use data_contract_invalid_index_definition_update_error::*; +pub use data_contract_token_configuration_update_error::*; pub use data_contract_unique_indices_changed_error::*; pub use document_types_are_missing_error::*; pub use duplicate_index_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index b238f55c028..aff0563c53d 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -98,6 +98,7 @@ impl ErrorWithCode for BasicError { Self::ContractError(DataContractError::RegexError(_)) => 10247, Self::ContestedUniqueIndexOnMutableDocumentTypeError(_) => 10248, Self::ContestedUniqueIndexWithUniqueIndexError(_) => 10249, + Self::DataContractTokenConfigurationUpdateError { .. } => 10250, // Document Errors: 10400-10499 Self::DataContractNotPresentError { .. } => 10400, diff --git a/packages/rs-dpp/src/nft/mod.rs b/packages/rs-dpp/src/nft/mod.rs index f81092f0790..bec8e4742a3 100644 --- a/packages/rs-dpp/src/nft/mod.rs +++ b/packages/rs-dpp/src/nft/mod.rs @@ -2,7 +2,6 @@ use crate::consensus::basic::data_contract::UnknownTradeModeError; use crate::consensus::basic::BasicError; use crate::consensus::ConsensusError; use crate::ProtocolError; -use platform_value::Identifier; use std::fmt; use std::fmt::{Display, Formatter}; #[derive(Debug, PartialEq, Clone, Copy)] diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/mod.rs index 27c968b20bb..53f9d4cf538 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/mod.rs @@ -386,7 +386,7 @@ impl DocumentFromCreateTransitionV0 for Document { #[cfg(test)] mod test { - use crate::data_contract::data_contract::DataContractV0; + use crate::data_contract::v0::DataContractV0; use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransition; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::{platform_value, BinaryData, Bytes32, Identifier}; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs index 755a7b2d876..4662a75997e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs @@ -1,6 +1,5 @@ pub mod v0_methods; -use crate::prelude::Revision; use bincode::{Decode, Encode}; use derive_more::Display; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs index eb720839121..65310370403 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs @@ -1,5 +1,4 @@ use platform_value::Identifier; -use crate::prelude::Revision; use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::documents_batch_transition::TokenTransferTransition; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs index eeb7104420b..b68cd97892b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/methods/v0/mod.rs @@ -5,6 +5,7 @@ use crate::{ state_transition::StateTransition, ProtocolError, }; +#[cfg(feature = "state-transition-signing")] use platform_value::Identifier; #[cfg(feature = "state-transition-signing")] use platform_version::version::{FeatureVersion, PlatformVersion}; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs index cf376b9b83a..bbcd3780c05 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/v0_methods.rs @@ -8,10 +8,12 @@ use crate::{ state_transition::StateTransition, ProtocolError, }; +#[cfg(feature = "state-transition-signing")] use platform_value::Identifier; use crate::state_transition::identity_credit_transfer_transition::methods::IdentityCreditTransferTransitionMethodsV0; use crate::state_transition::identity_credit_transfer_transition::v0::IdentityCreditTransferTransitionV0; +#[cfg(feature = "state-transition-signing")] use crate::state_transition::GetDataContractSecurityLevelRequirementFn; #[cfg(feature = "state-transition-signing")] use platform_version::version::{FeatureVersion, PlatformVersion}; diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/mod.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/mod.rs index ebaa11678f9..c794e0ae1be 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/mod.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/mod.rs @@ -15,6 +15,7 @@ pub struct DPPValidationVersions { pub struct DataContractValidationVersions { pub validate: FeatureVersion, pub validate_config_update: FeatureVersion, + pub validate_token_config_update: FeatureVersion, pub validate_index_definitions: FeatureVersion, pub validate_index_naming_duplicates: FeatureVersion, pub validate_not_defined_properties: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v1.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v1.rs index e698694e626..38dd978bf06 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v1.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v1.rs @@ -13,6 +13,7 @@ pub const DPP_VALIDATION_VERSIONS_V1: DPPValidationVersions = DPPValidationVersi data_contract: DataContractValidationVersions { validate: 0, validate_config_update: 0, + validate_token_config_update: 0, validate_index_definitions: 0, validate_index_naming_duplicates: 0, validate_not_defined_properties: 0, diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v2.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v2.rs index 71223907111..dcc7727e156 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v2.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_validation_versions/v2.rs @@ -13,6 +13,7 @@ pub const DPP_VALIDATION_VERSIONS_V2: DPPValidationVersions = DPPValidationVersi data_contract: DataContractValidationVersions { validate: 0, validate_config_update: 0, + validate_token_config_update: 0, validate_index_definitions: 0, validate_index_naming_duplicates: 0, validate_not_defined_properties: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index a173f38ac94..bcf858b3dc2 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -4,9 +4,14 @@ use crate::version::drive_versions::drive_token_method_versions::{ }; pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenMethodVersions { - fetch: DriveTokenFetchMethodVersions {}, + fetch: DriveTokenFetchMethodVersions { balance: 0 }, prove: DriveTokenProveMethodVersions {}, update: DriveTokenUpdateMethodVersions { create_token_root_tree: 0, + burn: 0, + mint: 0, + transfer: 0, + add_to_token_total_supply: 0, + remove_from_token_total_supply: 0, }, }; From f886d8d9ecd5a949fa74a4bda0625fd8eed01136 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 15 Dec 2024 01:04:38 +0300 Subject: [PATCH 16/61] more fixes --- .../document/batch_transition.rs | 23 +++++++ .../document/mod.rs | 1 + .../document/token_issuance_transition.rs | 1 + .../document_transition/mod.rs | 2 +- .../token_burn_transition_action/mod.rs | 9 +++ .../token_burn_transition_action/v0/mod.rs | 2 +- .../token_issuance_transition_action/mod.rs | 62 +++++++------------ .../v0/mod.rs | 47 +++++++++++++- .../token_transfer_transition_action/mod.rs | 8 +++ .../v0/mod.rs | 7 +++ .../document/documents_batch/mod.rs | 54 ++++++++-------- .../src/util/batch/drive_op_batch/mod.rs | 2 +- .../src/util/batch/drive_op_batch/token.rs | 4 +- .../v0/mod.rs | 4 +- 14 files changed, 150 insertions(+), 76 deletions(-) create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs new file mode 100644 index 00000000000..054bea175cd --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs @@ -0,0 +1,23 @@ +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::BatchTransitionAction; +use crate::util::batch::DriveOperation; +use dpp::block::epoch::Epoch; +use dpp::prelude::Identifier; +use dpp::version::PlatformVersion; + +impl DriveHighLevelDocumentOperationConverter for BatchTransitionAction { + fn into_high_level_document_drive_operations<'b>( + self, + epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match self { + BatchTransitionAction::DocumentAction(document_action) => document_action + .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + BatchTransitionAction::TokenAction(token_action) => token_action + .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs index 8df3a3906e7..dbe4d386613 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs @@ -4,6 +4,7 @@ use dpp::block::epoch::Epoch; use dpp::platform_value::Identifier; use dpp::version::PlatformVersion; +mod batch_transition; mod document_create_transition; mod document_delete_transition; mod document_purchase_transition; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs index 21541aedd98..822d6a3fbf8 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs @@ -44,6 +44,7 @@ impl DriveHighLevelDocumentOperationConverter for TokenIssuanceTransitionAction contract_info: DataContractFetchInfo(contract_fetch_info), token_position: self.token_position(), token_id: self.token_id(), + identity_balance_holder_id: Default::default(), mint_amount: self.issuance_amount(), })); diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index 9d642fb7c57..b60cef0e32b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -37,7 +37,7 @@ use crate::state_transition_action::system::bump_identity_data_contract_nonce_ac use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors, TokenTransferTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; /// version pub const DOCUMENT_TRANSITION_ACTION_VERSION: u32 = 0; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs index 5bd20100683..6b45125d361 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs @@ -27,6 +27,9 @@ pub trait TokenBurnTransitionActionAccessorsV0 { /// Returns a reference to the base token transition action fn base(&self) -> &TokenBaseTransitionAction; + /// Returns the base token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + /// Returns the burn amount fn burn_amount(&self) -> u64; @@ -73,6 +76,12 @@ impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionAction { } } + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenBurnTransitionAction::V0(v0) => v0.base, + } + } + fn burn_amount(&self) -> u64 { match self { TokenBurnTransitionAction::V0(v0) => v0.burn_amount, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs index ac2d734442a..7b63337dc96 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs @@ -1,5 +1,5 @@ mod transformer; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessors}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; /// Token burn transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs index ca088bd3211..45c08e8d084 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs @@ -23,60 +23,40 @@ pub enum TokenIssuanceTransitionAction { V0(TokenIssuanceTransitionActionV0), } -/// Accessors trait for TokenIssuanceTransitionAction for version 0 fields -pub trait TokenIssuanceTransitionActionAccessorsV0 { - /// Returns a reference to the base token transition action - fn base(&self) -> &TokenBaseTransitionAction; - - /// Returns the issuance amount - fn issuance_amount(&self) -> u64; - - /// Returns the token position in the contract - fn token_position(&self) -> u16 { - self.base().token_position() - } - - /// Returns the token ID - fn token_id(&self) -> Identifier { - self.base().token_id() - } - - /// Returns the data contract ID - fn data_contract_id(&self) -> Identifier { - self.base().data_contract_id() - } - - /// Returns a reference to the data contract fetch info - fn data_contract_fetch_info_ref(&self) -> &Arc { - self.base().data_contract_fetch_info_ref() +impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenIssuanceTransitionAction::V0(v0) => &v0.base, + } } - /// Returns the data contract fetch info - fn data_contract_fetch_info(&self) -> Arc { - self.base().data_contract_fetch_info() + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenIssuanceTransitionAction::V0(v0) => v0.base, + } } - /// Returns the identity contract nonce - fn identity_contract_nonce(&self) -> IdentityNonce { - self.base().identity_contract_nonce() + fn issuance_amount(&self) -> u64 { + match self { + TokenIssuanceTransitionAction::V0(v0) => v0.issuance_amount, + } } - /// Returns the ID of the token issuance transition - fn id(&self) -> Identifier { - self.base().id() + fn set_issuance_amount(&mut self, amount: u64) { + match self { + TokenIssuanceTransitionAction::V0(v0) => v0.issuance_amount = amount, + } } -} -impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionAction { - fn base(&self) -> &TokenBaseTransitionAction { + fn identity_balance_holder_id(&self) -> Identifier { match self { - TokenIssuanceTransitionAction::V0(v0) => &v0.base, + TokenIssuanceTransitionAction::V0(v0) => v0.identity_balance_holder_id, } } - fn issuance_amount(&self) -> u64 { + fn set_identity_balance_holder_id(&mut self, id: Identifier) { match self { - TokenIssuanceTransitionAction::V0(v0) => v0.issuance_amount, + TokenIssuanceTransitionAction::V0(v0) => v0.identity_balance_holder_id = id, } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs index c8f73a9a960..f031158bd85 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs @@ -1,5 +1,9 @@ mod transformer; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessors}; + +use std::sync::Arc; +use dpp::identifier::Identifier; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; /// Token issuance transition action v0 #[derive(Debug, Clone)] @@ -8,6 +12,8 @@ pub struct TokenIssuanceTransitionActionV0 { pub base: TokenBaseTransitionAction, /// The amount of tokens to create pub issuance_amount: u64, + /// The identity to credit the token to + pub identity_balance_holder_id: Identifier, } /// Accessors for `TokenIssuanceTransitionActionV0` @@ -23,6 +29,37 @@ pub trait TokenIssuanceTransitionActionAccessorsV0 { /// Sets the amount of tokens to issuance fn set_issuance_amount(&mut self, amount: u64); + + /// Consumes self and returns the identity balance holder ID + fn identity_balance_holder_id(&self) -> Identifier; + + /// Sets the identity balance holder ID + fn set_identity_balance_holder_id(&mut self, id: Identifier); + + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } + + /// Returns the token ID + fn token_id(&self) -> Identifier { + self.base().token_id() + } + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } } impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV0 { @@ -41,4 +78,12 @@ impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV fn set_issuance_amount(&mut self, amount: u64) { self.issuance_amount = amount; } + + fn identity_balance_holder_id(&self) -> Identifier { + self.identity_balance_holder_id + } + + fn set_identity_balance_holder_id(&mut self, id: Identifier) { + self.identity_balance_holder_id = id; + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs index c46b4a9209a..13150a88b90 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs @@ -24,6 +24,9 @@ pub trait TokenTransferTransitionActionAccessors { /// Returns a reference to the base token transition action fn base(&self) -> &TokenBaseTransitionAction; + /// Returns a reference to the base token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + /// Returns the amount of tokens to transfer fn amount(&self) -> u64; @@ -72,6 +75,11 @@ impl TokenTransferTransitionActionAccessors for TokenTransferTransitionAction { TokenTransferTransitionAction::V0(v0) => v0.base(), } } + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenTransferTransitionAction::V0(v0) => v0.base_owned(), + } + } fn amount(&self) -> u64 { match self { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs index 538ef76f120..cc5ee8a3489 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs @@ -26,6 +26,9 @@ pub trait TokenTransferTransitionActionAccessorsV0 { /// Returns the base token transition action fn base(&self) -> &TokenBaseTransitionAction; + /// Returns the base owned token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + /// Returns the amount of tokens to transfer fn amount(&self) -> u64; @@ -68,6 +71,10 @@ impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionActionV &self.base } + fn base_owned(self) -> TokenBaseTransitionAction { + self.base + } + fn amount(&self) -> u64 { self.amount } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs index 665baa8f14c..6617c4ccc4b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs @@ -31,21 +31,21 @@ impl DocumentsBatchTransitionAction { } /// transitions - pub fn transitions(&self) -> &Vec { + pub fn transitions(&self) -> &Vec { match self { DocumentsBatchTransitionAction::V0(v0) => &v0.transitions, } } /// transitions - pub fn transitions_mut(&mut self) -> &mut Vec { + pub fn transitions_mut(&mut self) -> &mut Vec { match self { DocumentsBatchTransitionAction::V0(v0) => &mut v0.transitions, } } /// transitions - pub fn transitions_take(&mut self) -> Vec { + pub fn transitions_take(&mut self) -> Vec { match self { DocumentsBatchTransitionAction::V0(v0) => std::mem::take(&mut v0.transitions), } @@ -59,7 +59,7 @@ impl DocumentsBatchTransitionAction { } /// set transitions - pub fn set_transitions(&mut self, transitions: Vec) { + pub fn set_transitions(&mut self, transitions: Vec) { match self { DocumentsBatchTransitionAction::V0(v0) => v0.transitions = transitions, } @@ -136,28 +136,30 @@ impl DocumentsBatchTransitionAction { let mut highest_security_level = SecurityLevel::lowest_level(); for transition in self.transitions().iter() { - let document_type_name = transition - .base() - .ok_or(ProtocolError::CorruptedCodeExecution( - "expecting action to have a base".to_string(), - ))? - .document_type_name(); - let data_contract_info = transition - .base() - .ok_or(ProtocolError::CorruptedCodeExecution( - "expecting action to have a base".to_string(), - ))? - .data_contract_fetch_info(); - - let document_type = data_contract_info - .contract - .document_type_for_name(document_type_name)?; - - let document_security_level = document_type.security_level_requirement(); - - // lower enum enum representation means higher in security - if document_security_level < highest_security_level { - highest_security_level = document_security_level + if let BatchTransitionAction::DocumentAction(document_transition) = transition { + let document_type_name = document_transition + .base() + .ok_or(ProtocolError::CorruptedCodeExecution( + "expecting action to have a base".to_string(), + ))? + .document_type_name(); + let data_contract_info = document_transition + .base() + .ok_or(ProtocolError::CorruptedCodeExecution( + "expecting action to have a base".to_string(), + ))? + .data_contract_fetch_info(); + + let document_type = data_contract_info + .contract + .document_type_for_name(document_type_name)?; + + let document_security_level = document_type.security_level_requirement(); + + // lower enum enum representation means higher in security + if document_security_level < highest_security_level { + highest_security_level = document_security_level + } } } Ok(if highest_security_level == SecurityLevel::MASTER { diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs index bf351d6ac1d..79a9e096356 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs @@ -72,7 +72,7 @@ pub enum DriveOperation<'a> { /// A document operation DocumentOperation(DocumentOperationType<'a>), /// A token operation - TokenOperation(TokenOperationType<'a>), + TokenOperation(TokenOperationType), /// Withdrawal operation WithdrawalOperation(WithdrawalOperationType), /// An identity operation diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index 3fb3fd4acea..d3ea4825f72 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -14,7 +14,7 @@ use std::collections::HashMap; /// Operations on Documents #[derive(Clone, Debug)] -pub enum TokenOperationType<'a> { +pub enum TokenOperationType { /// Burns token from the account issuing the . TokenBurn { /// The token id @@ -46,7 +46,7 @@ pub enum TokenOperationType<'a> { }, } -impl DriveLowLevelOperationConverter for TokenOperationType<'_> { +impl DriveLowLevelOperationConverter for TokenOperationType { fn into_low_level_drive_operations( self, drive: &Drive, diff --git a/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs b/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs index d424fbe3289..906d5d4c7e7 100644 --- a/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs +++ b/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs @@ -21,11 +21,9 @@ use dpp::state_transition::identity_credit_withdrawal_transition::accessors::Ide use dpp::state_transition::identity_topup_transition::accessors::IdentityTopUpTransitionAccessorsV0; use dpp::state_transition::identity_update_transition::accessors::IdentityUpdateTransitionAccessorsV0; use dpp::state_transition::{StateTransition, StateTransitionLike}; +use dpp::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use dpp::state_transition::documents_batch_transition::document_create_transition::DocumentFromCreateTransition; -use dpp::state_transition::documents_batch_transition::document_delete_transition::v0::v0_methods::DocumentDeleteTransitionV0Methods; use dpp::state_transition::documents_batch_transition::document_replace_transition::DocumentFromReplaceTransition; -use dpp::state_transition::documents_batch_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use dpp::state_transition::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; use dpp::state_transition::documents_batch_transition::document_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; use dpp::state_transition::masternode_vote_transition::accessors::MasternodeVoteTransitionAccessorsV0; From dc8e57547bf5cebc94115ac1d61f9f0d2d254fab Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 15 Dec 2024 12:28:54 +0300 Subject: [PATCH 17/61] more work --- .../rs-dpp/src/data_contract/accessors/mod.rs | 84 +++++++- .../src/data_contract/accessors/v1/mod.rs | 12 +- .../token_configuration/accessors/mod.rs | 193 ++++++++++++++++++ .../token_configuration/accessors/v0/mod.rs | 87 ++++++++ .../token_configuration/mod.rs | 1 + .../token_configuration/v0/accessors.rs | 142 +++++++++++++ .../token_configuration/v0/mod.rs | 2 + packages/rs-dpp/src/data_contract/mod.rs | 10 + .../serialized_version/v1/mod.rs | 4 +- .../src/data_contract/v1/accessors/mod.rs | 16 +- .../src/data_contract/v1/data_contract.rs | 4 +- packages/rs-dpp/src/errors/protocol_error.rs | 10 + packages/rs-dpp/src/lib.rs | 2 +- .../token_base_transition/fields.rs | 3 +- .../token_base_transition/v0/mod.rs | 9 +- .../token_base_transition/v0/v0_methods.rs | 26 +-- .../token_base_transition/v0_methods.rs | 20 +- .../token_issuance_transition/v0/mod.rs | 27 ++- packages/rs-dpp/src/tokens/errors.rs | 7 + packages/rs-dpp/src/tokens/mod.rs | 1 + .../add_to_previous_token_balance/mod.rs | 63 ++++++ .../add_to_previous_token_balance/v0/mod.rs | 36 ++++ .../rs-drive/src/drive/tokens/balance/mod.rs | 4 + .../src/drive/tokens/balance/queries.rs | 1 - .../remove_from_identity_token_balance/mod.rs | 117 +++++++++++ .../v0/mod.rs | 127 ++++++++++++ .../rs-drive/src/drive/tokens/burn/v0/mod.rs | 6 +- .../system/create_token_root_tree/mod.rs | 1 - .../src/drive/tokens/transfer/v0/mod.rs | 19 +- .../document/token_burn_transition.rs | 3 +- .../document/token_issuance_transition.rs | 9 +- .../document/token_transfer_transition.rs | 5 +- .../token_base_transition_action/mod.rs | 9 - .../token_base_transition_action/v0/mod.rs | 12 +- .../v0/transformer.rs | 10 +- .../token_burn_transition_action/mod.rs | 5 - .../v0/transformer.rs | 2 +- .../token_issuance_transition_action/mod.rs | 5 - .../v0/transformer.rs | 46 ++++- .../token_transfer_transition_action/mod.rs | 5 - .../v0/mod.rs | 5 - .../document/documents_batch/mod.rs | 2 +- .../document/documents_batch/v0/mod.rs | 16 +- .../src/util/batch/drive_op_batch/token.rs | 3 - .../drive_token_method_versions/mod.rs | 2 + .../drive_token_method_versions/v1.rs | 2 + 46 files changed, 1013 insertions(+), 162 deletions(-) create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs create mode 100644 packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs create mode 100644 packages/rs-dpp/src/tokens/errors.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index bbdd413de6b..52b1076c3a9 100644 --- a/packages/rs-dpp/src/data_contract/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/mod.rs @@ -1,13 +1,16 @@ use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use crate::data_contract::config::DataContractConfig; use crate::data_contract::document_type::{DocumentType, DocumentTypeRef}; -use crate::data_contract::DocumentName; +use crate::data_contract::{DocumentName, TokenContractPosition, EMPTY_GROUPS, EMPTY_TOKENS}; use crate::metadata::Metadata; use crate::prelude::DataContract; use platform_value::Identifier; +use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1Setters}; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::errors::DataContractError; +use crate::data_contract::group::{Group, GroupName}; use std::collections::BTreeMap; pub mod v0; @@ -180,3 +183,82 @@ impl DataContractV0Setters for DataContract { } } } + +/// Implementing DataContractV1Getters for DataContract +impl DataContractV1Getters for DataContract { + /// Returns a reference to the groups map. + fn groups(&self) -> &BTreeMap { + match self { + DataContract::V0(_) => &EMPTY_GROUPS, + DataContract::V1(v1) => &v1.groups, + } + } + + /// Returns a mutable reference to the groups map. + /// Returns `None` for V0 since it doesn't have groups. + fn groups_mut(&mut self) -> Option<&mut BTreeMap> { + match self { + DataContract::V0(_) => None, + DataContract::V1(v1) => Some(&mut v1.groups), + } + } + + /// Returns a reference to the tokens map. + fn tokens(&self) -> &BTreeMap { + match self { + DataContract::V0(_) => &EMPTY_TOKENS, + DataContract::V1(v1) => &v1.tokens, + } + } + + /// Returns a mutable reference to the tokens map. + /// Returns `None` for V0 since it doesn't have tokens. + fn tokens_mut(&mut self) -> Option<&mut BTreeMap> { + match self { + DataContract::V0(_) => None, + DataContract::V1(v1) => Some(&mut v1.tokens), + } + } +} + +impl DataContractV1Setters for DataContract { + /// Sets the groups map for the data contract. + fn set_groups(&mut self, groups: BTreeMap) { + match self { + DataContract::V0(_) => {} + DataContract::V1(v1) => { + v1.groups = groups; + } + } + } + + /// Sets the tokens map for the data contract. + fn set_tokens(&mut self, tokens: BTreeMap) { + match self { + DataContract::V0(_) => {} + DataContract::V1(v1) => { + v1.tokens = tokens; + } + } + } + + /// Adds or updates a single group in the groups map. + fn add_group(&mut self, name: GroupName, group: Group) { + match self { + DataContract::V0(_) => {} + DataContract::V1(v1) => { + v1.groups.insert(name, group); + } + } + } + + /// Adds or updates a single token configuration in the tokens map. + fn add_token(&mut self, id: TokenContractPosition, token: TokenConfiguration) { + match self { + DataContract::V0(_) => {} + DataContract::V1(v1) => { + v1.tokens.insert(id, token); + } + } + } +} diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs index b53d89a2eeb..9d23a0e8374 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -1,7 +1,7 @@ use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::group::{Group, GroupName}; -use crate::data_contract::TokenName; +use crate::data_contract::TokenContractPosition; use std::collections::BTreeMap; pub trait DataContractV1Getters: DataContractV0Getters { @@ -9,13 +9,13 @@ pub trait DataContractV1Getters: DataContractV0Getters { fn groups(&self) -> &BTreeMap; /// Returns a mutable reference to the groups map. - fn groups_mut(&mut self) -> &mut BTreeMap; + fn groups_mut(&mut self) -> Option<&mut BTreeMap>; /// Returns a reference to the tokens map. - fn tokens(&self) -> &BTreeMap; + fn tokens(&self) -> &BTreeMap; /// Returns a mutable reference to the tokens map. - fn tokens_mut(&mut self) -> &mut BTreeMap; + fn tokens_mut(&mut self) -> Option<&mut BTreeMap>; } pub trait DataContractV1Setters: DataContractV0Setters { @@ -23,11 +23,11 @@ pub trait DataContractV1Setters: DataContractV0Setters { fn set_groups(&mut self, groups: BTreeMap); /// Sets the tokens map for the data contract. - fn set_tokens(&mut self, tokens: BTreeMap); + fn set_tokens(&mut self, tokens: BTreeMap); /// Adds or updates a single group in the groups map. fn add_group(&mut self, name: GroupName, group: Group); /// Adds or updates a single token configuration in the tokens map. - fn add_token(&mut self, name: TokenName, token: TokenConfiguration); + fn add_token(&mut self, pos: TokenContractPosition, token: TokenConfiguration); } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs new file mode 100644 index 00000000000..8c51014c0a6 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs @@ -0,0 +1,193 @@ +pub mod v0; + +use crate::data_contract::associated_token::token_configuration::accessors::v0::{ + TokenConfigurationV0Getters, TokenConfigurationV0Setters, +}; +use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationConventionV0; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; +use crate::data_contract::change_control_rules::ChangeControlRules; +use crate::data_contract::group::RequiredSigners; +use platform_value::Identifier; +use std::collections::BTreeSet; + +/// Implementing TokenConfigurationV0Getters for TokenConfiguration +impl TokenConfigurationV0Getters for TokenConfiguration { + /// Returns a reference to the conventions. + fn conventions(&self) -> &TokenConfigurationConventionV0 { + match self { + TokenConfiguration::V0(v0) => v0.conventions(), + } + } + + /// Returns a mutable reference to the conventions. + fn conventions_mut(&mut self) -> &mut TokenConfigurationConventionV0 { + match self { + TokenConfiguration::V0(v0) => v0.conventions_mut(), + } + } + + /// Returns the base supply. + fn base_supply(&self) -> u64 { + match self { + TokenConfiguration::V0(v0) => v0.base_supply(), + } + } + + /// Returns the maximum supply. + fn max_supply(&self) -> Option { + match self { + TokenConfiguration::V0(v0) => v0.max_supply(), + } + } + + /// Returns the max supply change rules. + fn max_supply_change_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.max_supply_change_rules(), + } + } + + /// Returns the new tokens destination identity. + fn new_tokens_destination_identity(&self) -> Option { + match self { + TokenConfiguration::V0(v0) => v0.new_tokens_destination_identity(), + } + } + + /// Returns the new tokens destination identity rules. + fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.new_tokens_destination_identity_rules(), + } + } + + /// Returns the manual minting rules. + fn manual_minting_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.manual_minting_rules(), + } + } + + /// Returns the manual burning rules. + fn manual_burning_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.manual_burning_rules(), + } + } + + /// Returns the freeze rules. + fn freeze_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.freeze_rules(), + } + } + + /// Returns the unfreeze rules. + fn unfreeze_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.unfreeze_rules(), + } + } + + /// Returns the main control group. + fn main_control_group(&self) -> Option<&(BTreeSet, RequiredSigners)> { + match self { + TokenConfiguration::V0(v0) => v0.main_control_group(), + } + } + + /// Returns the main control group can be modified. + fn main_control_group_can_be_modified(&self) -> &AuthorizedActionTakers { + match self { + TokenConfiguration::V0(v0) => v0.main_control_group_can_be_modified(), + } + } +} + +/// Implementing TokenConfigurationV0Setters for TokenConfiguration +impl TokenConfigurationV0Setters for TokenConfiguration { + /// Sets the conventions. + fn set_conventions(&mut self, conventions: TokenConfigurationConventionV0) { + match self { + TokenConfiguration::V0(v0) => v0.set_conventions(conventions), + } + } + + /// Sets the base supply. + fn set_base_supply(&mut self, base_supply: u64) { + match self { + TokenConfiguration::V0(v0) => v0.set_base_supply(base_supply), + } + } + + /// Sets the maximum supply. + fn set_max_supply(&mut self, max_supply: Option) { + match self { + TokenConfiguration::V0(v0) => v0.set_max_supply(max_supply), + } + } + + /// Sets the max supply change rules. + fn set_max_supply_change_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_max_supply_change_rules(rules), + } + } + + /// Sets the new tokens destination identity. + fn set_new_tokens_destination_identity(&mut self, id: Option) { + match self { + TokenConfiguration::V0(v0) => v0.set_new_tokens_destination_identity(id), + } + } + + /// Sets the new tokens destination identity rules. + fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_new_tokens_destination_identity_rules(rules), + } + } + + /// Sets the manual minting rules. + fn set_manual_minting_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_manual_minting_rules(rules), + } + } + + /// Sets the manual burning rules. + fn set_manual_burning_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_manual_burning_rules(rules), + } + } + + /// Sets the freeze rules. + fn set_freeze_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_freeze_rules(rules), + } + } + + /// Sets the unfreeze rules. + fn set_unfreeze_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_unfreeze_rules(rules), + } + } + + /// Sets the main control group. + fn set_main_control_group(&mut self, group: Option<(BTreeSet, RequiredSigners)>) { + match self { + TokenConfiguration::V0(v0) => v0.set_main_control_group(group), + } + } + + /// Sets the main control group can be modified. + fn set_main_control_group_can_be_modified(&mut self, action_takers: AuthorizedActionTakers) { + match self { + TokenConfiguration::V0(v0) => v0.set_main_control_group_can_be_modified(action_takers), + } + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs new file mode 100644 index 00000000000..866a400658b --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -0,0 +1,87 @@ +use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationConventionV0; +use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; +use crate::data_contract::change_control_rules::ChangeControlRules; +use crate::data_contract::group::RequiredSigners; +use platform_value::Identifier; +use std::collections::BTreeSet; + +/// Accessor trait for getters of `TokenConfigurationV0` +pub trait TokenConfigurationV0Getters { + /// Returns a reference to the conventions. + fn conventions(&self) -> &TokenConfigurationConventionV0; + + /// Returns a mutable reference to the conventions. + fn conventions_mut(&mut self) -> &mut TokenConfigurationConventionV0; + + /// Returns the base supply. + fn base_supply(&self) -> u64; + + /// Returns the maximum supply. + fn max_supply(&self) -> Option; + + /// Returns the max supply change rules. + fn max_supply_change_rules(&self) -> &ChangeControlRules; + + /// Returns the new tokens destination identity. + fn new_tokens_destination_identity(&self) -> Option; + + /// Returns the new tokens destination identity rules. + fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules; + + /// Returns the manual minting rules. + fn manual_minting_rules(&self) -> &ChangeControlRules; + + /// Returns the manual burning rules. + fn manual_burning_rules(&self) -> &ChangeControlRules; + + /// Returns the freeze rules. + fn freeze_rules(&self) -> &ChangeControlRules; + + /// Returns the unfreeze rules. + fn unfreeze_rules(&self) -> &ChangeControlRules; + + /// Returns the main control group. + fn main_control_group(&self) -> Option<&(BTreeSet, RequiredSigners)>; + + /// Returns the main control group can be modified. + fn main_control_group_can_be_modified(&self) -> &AuthorizedActionTakers; +} + +/// Accessor trait for setters of `TokenConfigurationV0` +pub trait TokenConfigurationV0Setters { + /// Sets the conventions. + fn set_conventions(&mut self, conventions: TokenConfigurationConventionV0); + + /// Sets the base supply. + fn set_base_supply(&mut self, base_supply: u64); + + /// Sets the maximum supply. + fn set_max_supply(&mut self, max_supply: Option); + + /// Sets the max supply change rules. + fn set_max_supply_change_rules(&mut self, rules: ChangeControlRules); + + /// Sets the new tokens destination identity. + fn set_new_tokens_destination_identity(&mut self, id: Option); + + /// Sets the new tokens destination identity rules. + fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules); + + /// Sets the manual minting rules. + fn set_manual_minting_rules(&mut self, rules: ChangeControlRules); + + /// Sets the manual burning rules. + fn set_manual_burning_rules(&mut self, rules: ChangeControlRules); + + /// Sets the freeze rules. + fn set_freeze_rules(&mut self, rules: ChangeControlRules); + + /// Sets the unfreeze rules. + fn set_unfreeze_rules(&mut self, rules: ChangeControlRules); + + /// Sets the main control group. + fn set_main_control_group(&mut self, group: Option<(BTreeSet, RequiredSigners)>); + + /// Sets the main control group can be modified. + fn set_main_control_group_can_be_modified(&mut self, action_takers: AuthorizedActionTakers); +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs index 5cfe1f5541c..30cf70ffa64 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::fmt; +mod accessors; mod methods; mod v0; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs new file mode 100644 index 00000000000..538297c5782 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs @@ -0,0 +1,142 @@ +use crate::data_contract::associated_token::token_configuration::accessors::v0::{ + TokenConfigurationV0Getters, TokenConfigurationV0Setters, +}; +use crate::data_contract::associated_token::token_configuration::v0::{ + TokenConfigurationConventionV0, TokenConfigurationV0, +}; +use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; +use crate::data_contract::change_control_rules::ChangeControlRules; +use crate::data_contract::group::RequiredSigners; +use platform_value::Identifier; +use std::collections::BTreeSet; + +/// Implementing `TokenConfigurationV0Getters` for `TokenConfigurationV0` +impl TokenConfigurationV0Getters for TokenConfigurationV0 { + /// Returns a reference to the conventions. + fn conventions(&self) -> &TokenConfigurationConventionV0 { + &self.conventions + } + + /// Returns a mutable reference to the conventions. + fn conventions_mut(&mut self) -> &mut TokenConfigurationConventionV0 { + &mut self.conventions + } + + /// Returns the base supply. + fn base_supply(&self) -> u64 { + self.base_supply + } + + /// Returns the maximum supply. + fn max_supply(&self) -> Option { + self.max_supply + } + + /// Returns the max supply change rules. + fn max_supply_change_rules(&self) -> &ChangeControlRules { + &self.max_supply_change_rules + } + + /// Returns the new tokens destination identity. + fn new_tokens_destination_identity(&self) -> Option { + self.new_tokens_destination_identity + } + + /// Returns the new tokens destination identity rules. + fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules { + &self.new_tokens_destination_identity_rules + } + + /// Returns the manual minting rules. + fn manual_minting_rules(&self) -> &ChangeControlRules { + &self.manual_minting_rules + } + + /// Returns the manual burning rules. + fn manual_burning_rules(&self) -> &ChangeControlRules { + &self.manual_burning_rules + } + + /// Returns the freeze rules. + fn freeze_rules(&self) -> &ChangeControlRules { + &self.freeze_rules + } + + /// Returns the unfreeze rules. + fn unfreeze_rules(&self) -> &ChangeControlRules { + &self.unfreeze_rules + } + + /// Returns the main control group. + fn main_control_group(&self) -> Option<&(BTreeSet, RequiredSigners)> { + self.main_control_group.as_ref() + } + + /// Returns the main control group can be modified. + fn main_control_group_can_be_modified(&self) -> &AuthorizedActionTakers { + &self.main_control_group_can_be_modified + } +} + +/// Implementing `TokenConfigurationV0Setters` for `TokenConfigurationV0` +impl TokenConfigurationV0Setters for TokenConfigurationV0 { + /// Sets the conventions. + fn set_conventions(&mut self, conventions: TokenConfigurationConventionV0) { + self.conventions = conventions; + } + + /// Sets the base supply. + fn set_base_supply(&mut self, base_supply: u64) { + self.base_supply = base_supply; + } + + /// Sets the maximum supply. + fn set_max_supply(&mut self, max_supply: Option) { + self.max_supply = max_supply; + } + + /// Sets the max supply change rules. + fn set_max_supply_change_rules(&mut self, rules: ChangeControlRules) { + self.max_supply_change_rules = rules; + } + + /// Sets the new tokens destination identity. + fn set_new_tokens_destination_identity(&mut self, id: Option) { + self.new_tokens_destination_identity = id; + } + + /// Sets the new tokens destination identity rules. + fn set_new_tokens_destination_identity_rules(&mut self, rules: ChangeControlRules) { + self.new_tokens_destination_identity_rules = rules; + } + + /// Sets the manual minting rules. + fn set_manual_minting_rules(&mut self, rules: ChangeControlRules) { + self.manual_minting_rules = rules; + } + + /// Sets the manual burning rules. + fn set_manual_burning_rules(&mut self, rules: ChangeControlRules) { + self.manual_burning_rules = rules; + } + + /// Sets the freeze rules. + fn set_freeze_rules(&mut self, rules: ChangeControlRules) { + self.freeze_rules = rules; + } + + /// Sets the unfreeze rules. + fn set_unfreeze_rules(&mut self, rules: ChangeControlRules) { + self.unfreeze_rules = rules; + } + + /// Sets the main control group. + fn set_main_control_group(&mut self, group: Option<(BTreeSet, RequiredSigners)>) { + self.main_control_group = group; + } + + /// Sets the main control group can be modified. + fn set_main_control_group_can_be_modified(&mut self, action_takers: AuthorizedActionTakers) { + self.main_control_group_can_be_modified = action_takers; + } +} diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 457eb0a730d..55f8699692c 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -1,3 +1,5 @@ +mod accessors; + use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::group::RequiredSigners; diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index d27856454bd..d609e535e34 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -3,10 +3,12 @@ use crate::serialization::{ PlatformDeserializableWithPotentialValidationFromVersionedStructure, PlatformLimitDeserializableFromVersionedStructure, PlatformSerializableWithPlatformVersion, }; +use std::collections::BTreeMap; use derive_more::From; use bincode::config::{BigEndian, Configuration}; +use once_cell::sync::Lazy; pub mod errors; pub mod extra; @@ -48,6 +50,8 @@ use crate::version::{FeatureVersion, PlatformVersion}; use crate::ProtocolError; use crate::ProtocolError::{PlatformDeserializationError, PlatformSerializationError}; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::group::{Group, GroupName}; use crate::data_contract::v0::DataContractV0; use crate::data_contract::v1::DataContractV1; use platform_version::TryIntoPlatformVersioned; @@ -58,10 +62,16 @@ type JsonSchema = JsonValue; type DefinitionName = String; pub type DocumentName = String; pub type TokenName = String; +pub type TokenContractPosition = u16; type PropertyPath = String; pub const INITIAL_DATA_CONTRACT_VERSION: u32 = 1; +// Define static empty BTreeMaps +static EMPTY_GROUPS: Lazy> = Lazy::new(|| BTreeMap::new()); +static EMPTY_TOKENS: Lazy> = + Lazy::new(|| BTreeMap::new()); + /// Understanding Data Contract versioning /// Data contract versioning is both for the code structure and for serialization. /// diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index 67f36a11ace..de7c8cbac79 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -6,7 +6,7 @@ use crate::data_contract::associated_token::token_configuration::TokenConfigurat use crate::data_contract::group::{Group, GroupName}; use crate::data_contract::v0::DataContractV0; use crate::data_contract::v1::DataContractV1; -use crate::data_contract::{DataContract, DefinitionName, DocumentName, TokenName}; +use crate::data_contract::{DataContract, DefinitionName, DocumentName, TokenContractPosition}; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; @@ -38,7 +38,7 @@ pub struct DataContractInSerializationFormatV1 { pub groups: BTreeMap, /// The tokens on the contract. - pub tokens: BTreeMap, + pub tokens: BTreeMap, } impl From for DataContractInSerializationFormatV1 { diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs index 667b11da30e..23d1be1113e 100644 --- a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -4,7 +4,7 @@ use crate::data_contract::document_type::{DocumentType, DocumentTypeRef}; use crate::data_contract::errors::DataContractError; use crate::data_contract::v1::DataContractV1; -use crate::data_contract::{DocumentName, TokenName}; +use crate::data_contract::{DocumentName, TokenContractPosition}; use crate::metadata::Metadata; use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1Setters}; @@ -147,16 +147,16 @@ impl DataContractV1Getters for DataContractV1 { &self.groups } - fn groups_mut(&mut self) -> &mut BTreeMap { - &mut self.groups + fn groups_mut(&mut self) -> Option<&mut BTreeMap> { + Some(&mut self.groups) } - fn tokens(&self) -> &BTreeMap { + fn tokens(&self) -> &BTreeMap { &self.tokens } - fn tokens_mut(&mut self) -> &mut BTreeMap { - &mut self.tokens + fn tokens_mut(&mut self) -> Option<&mut BTreeMap> { + Some(&mut self.tokens) } } @@ -165,7 +165,7 @@ impl DataContractV1Setters for DataContractV1 { self.groups = groups; } - fn set_tokens(&mut self, tokens: BTreeMap) { + fn set_tokens(&mut self, tokens: BTreeMap) { self.tokens = tokens; } @@ -173,7 +173,7 @@ impl DataContractV1Setters for DataContractV1 { self.groups.insert(name, group); } - fn add_token(&mut self, name: TokenName, token: TokenConfiguration) { + fn add_token(&mut self, name: TokenContractPosition, token: TokenConfiguration) { self.tokens.insert(name, token); } } diff --git a/packages/rs-dpp/src/data_contract/v1/data_contract.rs b/packages/rs-dpp/src/data_contract/v1/data_contract.rs index e555f61f237..554d9ba475d 100644 --- a/packages/rs-dpp/src/data_contract/v1/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/v1/data_contract.rs @@ -7,7 +7,7 @@ use crate::data_contract::associated_token::token_configuration::TokenConfigurat use crate::data_contract::config::DataContractConfig; use crate::data_contract::document_type::DocumentType; use crate::data_contract::group::{Group, GroupName}; -use crate::data_contract::{DefinitionName, DocumentName, TokenName}; +use crate::data_contract::{DefinitionName, DocumentName, TokenContractPosition}; use crate::metadata::Metadata; /// `DataContractV1` represents a data contract in a decentralized platform. @@ -69,5 +69,5 @@ pub struct DataContractV1 { pub groups: BTreeMap, /// The tokens on the contract. - pub tokens: BTreeMap, + pub tokens: BTreeMap, } diff --git a/packages/rs-dpp/src/errors/protocol_error.rs b/packages/rs-dpp/src/errors/protocol_error.rs index 2164b339f19..e9fa0a7a0a2 100644 --- a/packages/rs-dpp/src/errors/protocol_error.rs +++ b/packages/rs-dpp/src/errors/protocol_error.rs @@ -40,6 +40,7 @@ use crate::{ use dashcore::consensus::encode::Error as DashCoreError; +use crate::tokens::errors::TokenError; use crate::version::FeatureVersion; use platform_value::{Error as ValueError, Value}; use platform_version::error::PlatformVersionError; @@ -134,6 +135,9 @@ pub enum ProtocolError { #[error(transparent)] Document(Box), + #[error(transparent)] + Token(Box), + #[error("Generic Error: {0}")] Generic(String), @@ -273,6 +277,12 @@ impl From for ProtocolError { } } +impl From for ProtocolError { + fn from(e: TokenError) -> Self { + ProtocolError::Token(Box::new(e)) + } +} + impl From for ProtocolError { fn from(e: SerdeParsingError) -> Self { ProtocolError::ParsingError(e.to_string()) diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 31cc2481356..302a6d10047 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -53,7 +53,7 @@ pub mod signing; #[cfg(feature = "system_contracts")] pub mod system_data_contracts; -mod tokens; +pub mod tokens; pub mod voting; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs index 0ae1c2b9731..fee916e0386 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs @@ -1,9 +1,8 @@ pub(in crate::state_transition::state_transitions::document::documents_batch_transition) mod property_names { - pub const ID: &str = "$id"; pub const DATA_CONTRACT_ID: &str = "$dataContractId"; pub const TOKEN_ID: &str = "$tokenId"; pub const ACTION: &str = "$action"; pub const IDENTITY_CONTRACT_NONCE: &str = "$identityContractNonce"; } -pub const IDENTIFIER_FIELDS: [&str; 2] = [property_names::ID, property_names::DATA_CONTRACT_ID]; +pub const IDENTIFIER_FIELDS: [&str; 1] = [property_names::DATA_CONTRACT_ID]; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs index 30824d49d50..6a6957746ac 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs @@ -38,9 +38,6 @@ use crate::{data_contract::DataContract, errors::ProtocolError}; "data_contract_id" )] pub struct TokenBaseTransitionV0 { - /// The document ID - #[cfg_attr(feature = "state-transition-serde-conversion", serde(rename = "$id"))] - pub id: Identifier, #[cfg_attr( feature = "state-transition-serde-conversion", serde(rename = "$identity-contract-nonce") @@ -49,9 +46,9 @@ pub struct TokenBaseTransitionV0 { /// ID of the token within the contract #[cfg_attr( feature = "state-transition-serde-conversion", - serde(rename = "$tokenId") + serde(rename = "$tokenContractPosition") )] - pub token_id: u16, + pub token_contract_position: u16, /// Data contract ID generated from the data contract's `owner_id` and `entropy` #[cfg_attr( feature = "state-transition-serde-conversion", @@ -73,7 +70,7 @@ impl TokenBaseTransitionV0 { .map_err(ProtocolError::ValueError)?, ), identity_contract_nonce, - token_id: map + token_contract_position: map .remove_integer(property_names::TOKEN_ID) .map_err(ProtocolError::ValueError)?, data_contract_id: Identifier::new( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs index 563b8fa7252..7ab114c61d2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs @@ -4,17 +4,11 @@ use platform_value::Identifier; /// A trait that contains getter and setter methods for `TokenBaseTransitionV0` pub trait TokenBaseTransitionV0Methods { - /// Returns the document ID. - fn id(&self) -> Identifier; - - /// Sets the document ID. - fn set_id(&mut self, id: Identifier); - /// Returns the document type name. - fn token_id(&self) -> u16; + fn token_contract_position(&self) -> u16; /// Sets the token id. - fn set_token_id(&mut self, token_id: u16); + fn set_token_contract_position(&mut self, token_id: u16); /// Returns the data contract ID. fn data_contract_id(&self) -> Identifier; @@ -27,20 +21,12 @@ pub trait TokenBaseTransitionV0Methods { } impl TokenBaseTransitionV0Methods for TokenBaseTransitionV0 { - fn id(&self) -> Identifier { - self.id - } - - fn set_id(&mut self, id: Identifier) { - self.id = id; - } - - fn token_id(&self) -> u16 { - self.token_id + fn token_contract_position(&self) -> u16 { + self.token_contract_position } - fn set_token_id(&mut self, token_id: u16) { - self.token_id = token_id; + fn set_token_contract_position(&mut self, token_contract_position: u16) { + self.token_contract_position = token_contract_position; } fn data_contract_id(&self) -> Identifier { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs index 29848b71700..cd1dcdc6b70 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs @@ -4,27 +4,15 @@ use crate::state_transition::documents_batch_transition::token_base_transition:: use platform_value::Identifier; impl TokenBaseTransitionV0Methods for TokenBaseTransition { - fn id(&self) -> Identifier { + fn token_contract_position(&self) -> u16 { match self { - TokenBaseTransition::V0(v0) => v0.id(), + TokenBaseTransition::V0(v0) => v0.token_contract_position(), } } - fn set_id(&mut self, id: Identifier) { + fn set_token_contract_position(&mut self, token_id: u16) { match self { - TokenBaseTransition::V0(v0) => v0.set_id(id), - } - } - - fn token_id(&self) -> u16 { - match self { - TokenBaseTransition::V0(v0) => v0.token_id(), - } - } - - fn set_token_id(&mut self, token_id: u16) { - match self { - TokenBaseTransition::V0(v0) => v0.set_token_id(token_id), + TokenBaseTransition::V0(v0) => v0.set_token_contract_position(token_id), } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs index 11ab6dc928e..fe7ebe5c691 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs @@ -2,9 +2,11 @@ pub mod v0_methods; use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; use bincode::{Decode, Encode}; -use derive_more::Display; +use platform_value::string_encoding::Encoding; +use platform_value::Identifier; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; +use std::fmt; mod property_names { pub const AMOUNT: &str = "$amount"; @@ -12,18 +14,37 @@ mod property_names { /// The Identifier fields in [`TokenIssuanceTransition`] pub use super::super::document_base_transition::IDENTIFIER_FIELDS; -#[derive(Debug, Clone, Default, Encode, Decode, PartialEq, Display)] +#[derive(Debug, Clone, Default, Encode, Decode, PartialEq)] #[cfg_attr( feature = "state-transition-serde-conversion", derive(Serialize, Deserialize), serde(rename_all = "camelCase") )] -#[display("Base: {base}, Amount: {amount}")] pub struct TokenIssuanceTransitionV0 { /// Document Base Transition #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] pub base: TokenBaseTransition, + /// Who should we issue the token to? If this is not set then we issue to the identity set in + /// contract settings. If such an operation is allowed. + pub issued_to_identity_id: Option, + /// How much should we issue pub amount: u64, } + +impl fmt::Display for TokenIssuanceTransitionV0 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Format the base transition (assuming `TokenBaseTransition` implements Display) + write!( + f, + "Base: {}, Amount: {}, To: {}", + self.base, // Assuming `TokenBaseTransition` implements `Display` + self.amount, + self.issued_to_identity_id + .as_ref() + .map_or("(Identity Set By Contract)".to_string(), |id| id + .to_string(Encoding::Base58)) + ) + } +} diff --git a/packages/rs-dpp/src/tokens/errors.rs b/packages/rs-dpp/src/tokens/errors.rs new file mode 100644 index 00000000000..4a0fa2eb39b --- /dev/null +++ b/packages/rs-dpp/src/tokens/errors.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum TokenError { + #[error("There is no destination identity to put the token balance to")] + DestinationIdentityForMintingNotSetError, +} diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs index 8219bad9d2d..1980cdf712f 100644 --- a/packages/rs-dpp/src/tokens/mod.rs +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -1 +1,2 @@ pub mod allowed_currency; +pub mod errors; diff --git a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs new file mode 100644 index 00000000000..7a62530a15b --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs @@ -0,0 +1,63 @@ +mod v0; + +use crate::drive::identity::update::add_to_previous_balance_outcome::AddToPreviousBalanceOutcome; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::fee::Credits; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// The method to add balance to the previous balance for a token. This function is version controlled. + /// + /// # Arguments + /// + /// * `identity_id` - The ID of the Identity. + /// * `previous_balance` - The previous balance of the Identity. + /// * `added_balance` - The balance to be added. + /// * `apply` - Whether to apply the operations. + /// * `transaction` - The current transaction. + /// * `drive_operations` - The vector of LowLevelDriveOperations. + /// * `drive_version` - The drive version. + /// + /// # Returns + /// + /// * `Result` - The outcome if successful, or an error. + pub(in crate::drive::tokens) fn add_to_previous_token_balance( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + previous_balance: Credits, + added_balance: Credits, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive + .methods + .token + .update + .add_to_previous_token_balance + { + 0 => self.add_to_previous_token_balance_v0( + token_id, + identity_id, + previous_balance, + added_balance, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_to_previous_token_balance".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs new file mode 100644 index 00000000000..eb42514dfa1 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs @@ -0,0 +1,36 @@ +use crate::drive::Drive; +use crate::error::identity::IdentityError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::fee::Credits; + +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// The method to add balance to the previous balance. This function is version controlled. + pub(super) fn add_to_previous_token_balance_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + previous_balance: Credits, + added_balance: Credits, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + // Deduct added balance from existing one + let new_balance = previous_balance + .checked_add(added_balance) + .ok_or(Error::Identity(IdentityError::CriticalBalanceOverflow( + "identity balance add overflow error", + )))?; + + Ok(AddToPreviousBalanceOutcomeV0 { + balance_modified: Some(new_balance), + negative_credit_balance_modified: None, + } + .into()) + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/mod.rs index 403f48d6ab2..7bc82048e39 100644 --- a/packages/rs-drive/src/drive/tokens/balance/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/mod.rs @@ -1,7 +1,11 @@ #[cfg(feature = "server")] +mod add_to_previous_token_balance; +#[cfg(feature = "server")] mod fetch; #[cfg(feature = "server")] mod prove; mod queries; #[cfg(feature = "server")] +mod remove_from_identity_token_balance; +#[cfg(feature = "server")] mod update; diff --git a/packages/rs-drive/src/drive/tokens/balance/queries.rs b/packages/rs-drive/src/drive/tokens/balance/queries.rs index d800225ad94..fc32d25e6a8 100644 --- a/packages/rs-drive/src/drive/tokens/balance/queries.rs +++ b/packages/rs-drive/src/drive/tokens/balance/queries.rs @@ -1,4 +1,3 @@ -use crate::drive::balances::balance_path_vec; use crate::drive::tokens::token_balances_path_vec; use crate::drive::Drive; use crate::query::{Query, QueryItem}; diff --git a/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/mod.rs new file mode 100644 index 00000000000..c80eb72789c --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/mod.rs @@ -0,0 +1,117 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::fee::Credits; + +use dpp::fee::default_costs::CachedEpochIndexFeeVersions; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// The operations for removing a certain amount of credits from an identity's balance. This function is version controlled. + /// + /// # Arguments + /// + /// * `token_id` - The ID of the Token. + /// * `identity_id` - The ID of the Identity from whose balance credits are to be removed. + /// * `balance_to_remove` - The amount of credits to be removed from the identity's balance. + /// * `block_info` - Information about the current block. + /// * `apply` - A boolean indicating whether the operation should be applied or not. + /// * `transaction` - The transaction information related to the operation. + /// * `drive_version` - The drive version. + /// + /// # Returns + /// + /// * `Result` - The resulting fee result if successful, or an error. + pub fn remove_from_identity_token_balance( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + balance_to_remove: Credits, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + previous_fee_versions: Option<&CachedEpochIndexFeeVersions>, + ) -> Result { + match platform_version + .drive + .methods + .token + .update + .remove_from_identity_token_balance + { + 0 => self.remove_from_identity_token_balance_v0( + token_id, + identity_id, + balance_to_remove, + block_info, + apply, + transaction, + platform_version, + previous_fee_versions, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "remove_from_identity_balance".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Removes a specified amount of credits from an identity balance. This function doesn't allow the balance to go below zero. + /// Balances are stored under key 0 in the identity. Operations are determined based on the `apply` flag (stateful vs stateless). + /// + /// # Arguments + /// + /// * `token_id` - The ID of the Token. + /// * `identity_id` - The ID of the Identity from which credits are to be removed. + /// * `balance_to_remove` - The amount of credits to be removed from the identity's balance. + /// * `estimated_costs_only_with_layer_info` - Estimated costs with layer information, if any. + /// * `transaction` - The transaction information related to the operation. + /// * `drive_version` - The drive version. + /// + /// # Returns + /// + /// * `Result, Error>` - The resulting low level drive operations if successful, or an error. + pub(crate) fn remove_from_identity_token_balance_operations( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + balance_to_remove: Credits, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .update + .remove_from_identity_token_balance + { + 0 => self.remove_from_identity_token_balance_operations_v0( + token_id, + identity_id, + balance_to_remove, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "remove_from_identity_token_balance_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs new file mode 100644 index 00000000000..4c3fffd78f6 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs @@ -0,0 +1,127 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::identity::IdentityError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::balances::credits::MAX_CREDITS; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::fee::Credits; + +use dpp::fee::default_costs::CachedEpochIndexFeeVersions; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Balances are stored in the balance tree under the identity's id + pub(in crate::drive::tokens) fn remove_from_identity_token_balance_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + balance_to_remove: Credits, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + previous_fee_versions: Option<&CachedEpochIndexFeeVersions>, + ) -> Result { + let mut estimated_costs_only_with_layer_info = if apply { + None::> + } else { + Some(HashMap::new()) + }; + + let batch_operations = self.remove_from_identity_token_balance_operations_v0( + token_id, + identity_id, + balance_to_remove, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + let mut drive_operations: Vec = vec![]; + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + &mut drive_operations, + &platform_version.drive, + )?; + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + previous_fee_versions, + )?; + Ok(fees) + } + + /// Removes specified amount of credits from identity balance + /// This function doesn't go below nil balance (negative balance) + /// + /// Balances are stored in the identity under key 0 + /// This gets operations based on apply flag (stateful vs stateless) + pub(in crate::drive::tokens) fn remove_from_identity_token_balance_operations_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + balance_to_remove: Credits, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { + Self::add_estimation_costs_for_balances( + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + Self::add_estimation_costs_for_negative_credit( + identity_id, + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + } + + let previous_balance = if estimated_costs_only_with_layer_info.is_none() { + self.fetch_identity_token_balance_operations( + token_id, + identity_id, + estimated_costs_only_with_layer_info.is_none(), + transaction, + &mut drive_operations, + platform_version, + )? + .ok_or(Error::Drive(DriveError::CorruptedCodeExecution( + "there should always be a balance if apply is set to true", + )))? + } else { + MAX_CREDITS + }; + + // we do not have enough balance + // there is a part we absolutely need to pay for + if balance_to_remove > previous_balance { + return Err(Error::Identity(IdentityError::IdentityInsufficientBalance( + format!( + "identity with token balance {} does not have the required balance to remove {}", + previous_balance, balance_to_remove + ), + ))); + } + + drive_operations.push(self.update_identity_token_balance_operation_v0( + identity_id, + previous_balance - balance_to_remove, + )?); + + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs b/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs index e6b2b223f08..fc42ebf078c 100644 --- a/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs @@ -103,7 +103,8 @@ impl Drive { // Fetch current balance let current_balance = self - .fetch_identity_balance_operations( + .fetch_identity_token_balance_operations( + token_id, identity_id, estimated_costs_only_with_layer_info.is_none(), transaction, @@ -123,7 +124,8 @@ impl Drive { let new_balance = current_balance - burn_amount; // Update identity balance - drive_operations.push(self.update_identity_balance_operation_v0(identity_id, new_balance)?); + drive_operations + .push(self.update_identity_token_balance_operation_v0(identity_id, new_balance)?); // Update total supply for the token (subtract burn_amount) let current_supply = self diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs index 5e8f2c660ac..4833f51e092 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs @@ -6,7 +6,6 @@ use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; -use dpp::identity::Identity; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; diff --git a/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs b/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs index 04a74dfaaea..56c7a7456d2 100644 --- a/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs @@ -99,17 +99,7 @@ impl Drive { // Estimation if let Some(esti) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_balances(esti, &platform_version.drive)?; - Self::add_estimation_costs_for_negative_credit( - from_identity_id, - esti, - &platform_version.drive, - )?; - Self::add_estimation_costs_for_negative_credit( - to_identity_id, - esti, - &platform_version.drive, - )?; + Self::add_estimation_costs_for_token_balances(esti, &platform_version.drive)?; } // Fetch sender balance @@ -132,8 +122,9 @@ impl Drive { } let new_from_balance = from_balance - amount; - drive_operations - .push(self.update_identity_balance_operation_v0(from_identity_id, new_from_balance)?); + drive_operations.push( + self.update_identity_token_balance_operation_v0(from_identity_id, new_from_balance)?, + ); // Fetch recipient balance let to_balance = self @@ -153,7 +144,7 @@ impl Drive { "overflow on recipient balance".to_string(), )))?; drive_operations - .push(self.update_identity_balance_operation_v0(to_identity_id, new_to_balance)?); + .push(self.update_identity_token_balance_operation_v0(to_identity_id, new_to_balance)?); // Total supply remains the same. Ok(drive_operations) diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs index 9bed296313b..1d73a197565 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs @@ -41,9 +41,8 @@ impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { )]; ops.push(TokenOperation(TokenOperationType::TokenBurn { - contract_info: DataContractFetchInfo(contract_fetch_info), - token_position: self.token_position(), token_id: self.token_id(), + identity_balance_holder_id: owner_id, burn_amount: self.burn_amount(), })); diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs index 822d6a3fbf8..80173ab4d6b 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs @@ -9,11 +9,10 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::TokenOperationType; use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; -use crate::util::object_size_info::DataContractInfo::DataContractFetchInfo; impl DriveHighLevelDocumentOperationConverter for TokenIssuanceTransitionAction { fn into_high_level_document_drive_operations<'b>( - mut self, + self, _epoch: &Epoch, owner_id: Identifier, platform_version: &PlatformVersion, @@ -28,8 +27,6 @@ impl DriveHighLevelDocumentOperationConverter for TokenIssuanceTransitionAction 0 => { let data_contract_id = self.base().data_contract_id(); - let contract_fetch_info = self.base().data_contract_fetch_info(); - let identity_contract_nonce = self.base().identity_contract_nonce(); let mut ops = vec![IdentityOperation( @@ -41,10 +38,8 @@ impl DriveHighLevelDocumentOperationConverter for TokenIssuanceTransitionAction )]; ops.push(TokenOperation(TokenOperationType::TokenMint { - contract_info: DataContractFetchInfo(contract_fetch_info), - token_position: self.token_position(), token_id: self.token_id(), - identity_balance_holder_id: Default::default(), + identity_balance_holder_id: owner_id, mint_amount: self.issuance_amount(), })); diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs index b02870222b7..10b60444b53 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs @@ -28,8 +28,6 @@ impl DriveHighLevelDocumentOperationConverter for TokenTransferTransitionAction 0 => { let data_contract_id = self.base().data_contract_id(); - let contract_fetch_info = self.base().data_contract_fetch_info(); - let identity_contract_nonce = self.base().identity_contract_nonce(); let mut ops = vec![IdentityOperation( @@ -41,9 +39,8 @@ impl DriveHighLevelDocumentOperationConverter for TokenTransferTransitionAction )]; ops.push(TokenOperation(TokenOperationType::TokenTransfer { - contract_info: DataContractFetchInfo(contract_fetch_info), - token_position: self.token_position(), token_id: self.token_id(), + sender_id: owner_id, recipient_id: self.recipient_id(), amount: self.amount(), })); diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs index c20c622ede0..bf72f96f5f2 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs @@ -1,8 +1,5 @@ use derive_more::From; -use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::platform_value::Identifier; - -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::IdentityNonce; use std::sync::Arc; @@ -22,12 +19,6 @@ pub enum TokenBaseTransitionAction { } impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionAction { - fn id(&self) -> Identifier { - match self { - TokenBaseTransitionAction::V0(v0) => v0.id, - } - } - fn token_position(&self) -> u16 { match self { TokenBaseTransitionAction::V0(v0) => v0.token_position, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs index 54a49ff5ae8..0724d67cc67 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs @@ -2,8 +2,7 @@ use crate::drive::contract::DataContractFetchInfo; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; -use dpp::util::hash::{hash_double, hash_single}; -use platform_version::version::PlatformVersion; +use dpp::util::hash::hash_double; use std::sync::Arc; /// transformer @@ -12,8 +11,6 @@ pub mod transformer; /// Token base transition action v0 #[derive(Debug, Clone)] pub struct TokenBaseTransitionActionV0 { - /// The token transition ID - pub id: Identifier, /// The identity contract nonce, used to prevent replay attacks pub identity_contract_nonce: IdentityNonce, /// The token position within the data contract @@ -24,9 +21,6 @@ pub struct TokenBaseTransitionActionV0 { /// Token base transition action accessors v0 pub trait TokenBaseTransitionActionAccessorsV0 { - /// Returns the token transition ID - fn id(&self) -> Identifier; - /// The token position within the data contract fn token_position(&self) -> u16; @@ -53,10 +47,6 @@ pub trait TokenBaseTransitionActionAccessorsV0 { } impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { - fn id(&self) -> Identifier { - self.id - } - fn token_position(&self) -> u16 { self.token_position } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index 5271a915b71..0ec720a46f5 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -3,10 +3,8 @@ use std::sync::Arc; use dpp::platform_value::Identifier; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; use dpp::state_transition::documents_batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; impl TokenBaseTransitionActionV0 { @@ -16,13 +14,11 @@ impl TokenBaseTransitionActionV0 { get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { let TokenBaseTransitionV0 { - id, - token_id, + token_contract_position: token_id, data_contract_id, identity_contract_nonce, } = value; Ok(TokenBaseTransitionActionV0 { - id, identity_contract_nonce, token_position: token_id, data_contract: get_data_contract(data_contract_id)?, @@ -35,13 +31,11 @@ impl TokenBaseTransitionActionV0 { get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { let TokenBaseTransitionV0 { - id, - token_id, + token_contract_position: token_id, data_contract_id, identity_contract_nonce, } = value; Ok(TokenBaseTransitionActionV0 { - id: *id, identity_contract_nonce: *identity_contract_nonce, token_position: *token_id, data_contract: get_data_contract(*data_contract_id)?, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs index 6b45125d361..d99a0f88948 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs @@ -62,11 +62,6 @@ pub trait TokenBurnTransitionActionAccessorsV0 { fn identity_contract_nonce(&self) -> IdentityNonce { self.base().identity_contract_nonce() } - - /// Returns the ID of the token burn transition - fn id(&self) -> Identifier { - self.base().id() - } } impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index fd19381a0e4..21f92e04f6b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -5,7 +5,7 @@ use dpp::state_transition::documents_batch_transition::token_burn_transition::v0 use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; impl TokenBurnTransitionActionV0 { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs index 45c08e8d084..00e127de78a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs @@ -1,10 +1,5 @@ use derive_more::From; -use std::sync::Arc; - -use crate::drive::contract::DataContractFetchInfo; use dpp::identifier::Identifier; -use dpp::prelude::IdentityNonce; -use dpp::util::hash::hash_double; /// transformer module for token issuance transition action pub mod transformer; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs index fd678a81d73..60177192fac 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs @@ -3,9 +3,11 @@ use std::sync::Arc; use dpp::identifier::Identifier; use dpp::state_transition::documents_batch_transition::token_issuance_transition::v0::TokenIssuanceTransitionV0; use dpp::ProtocolError; - +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::state_transition::documents_batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use dpp::tokens::errors::TokenError; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::v0::TokenIssuanceTransitionActionV0; impl TokenIssuanceTransitionActionV0 { @@ -23,16 +25,34 @@ impl TokenIssuanceTransitionActionV0 { value: TokenIssuanceTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenIssuanceTransitionV0 { base, amount } = value; + let TokenIssuanceTransitionV0 { + base, + issued_to_identity_id, + amount, + } = value; let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( base, get_data_contract, )?; + let identity_balance_holder_id = issued_to_identity_id + .or_else(|| { + base_action + .data_contract_fetch_info_ref() + .contract + .tokens() + .get(&base.token_contract_position()) + .and_then(|token_configuration| { + token_configuration.new_tokens_destination_identity() + }) + }) + .ok_or(TokenError::DestinationIdentityForMintingNotSetError.into())?; + Ok(TokenIssuanceTransitionActionV0 { base: base_action, issuance_amount: amount, + identity_balance_holder_id, }) } @@ -50,7 +70,11 @@ impl TokenIssuanceTransitionActionV0 { value: &TokenIssuanceTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenIssuanceTransitionV0 { base, amount } = value; + let TokenIssuanceTransitionV0 { + base, + issued_to_identity_id, + amount, + } = value; let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( @@ -58,9 +82,23 @@ impl TokenIssuanceTransitionActionV0 { get_data_contract, )?; + let identity_balance_holder_id = issued_to_identity_id + .or_else(|| { + base_action + .data_contract_fetch_info_ref() + .contract + .tokens() + .get(&base.token_contract_position()) + .and_then(|token_configuration| { + token_configuration.new_tokens_destination_identity() + }) + }) + .ok_or(TokenError::DestinationIdentityForMintingNotSetError.into())?; + Ok(TokenIssuanceTransitionActionV0 { base: base_action, issuance_amount: *amount, + identity_balance_holder_id, }) } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs index 13150a88b90..fb695fab47e 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs @@ -62,11 +62,6 @@ pub trait TokenTransferTransitionActionAccessors { fn identity_contract_nonce(&self) -> IdentityNonce { self.base().identity_contract_nonce() } - - /// Returns the ID of the token transfer transition - fn id(&self) -> Identifier { - self.base().id() - } } impl TokenTransferTransitionActionAccessors for TokenTransferTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs index cc5ee8a3489..acebdbcf653 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs @@ -59,11 +59,6 @@ pub trait TokenTransferTransitionActionAccessorsV0 { fn identity_contract_nonce(&self) -> IdentityNonce { self.base().identity_contract_nonce() } - - /// Returns the transition ID from the base action - fn id(&self) -> Identifier { - self.base().id() - } } impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionActionV0 { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs index 6617c4ccc4b..ec20c751ec6 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs @@ -1,4 +1,4 @@ -use crate::state_transition_action::document::documents_batch::document_transition::{BatchTransitionAction, DocumentTransitionAction}; +use crate::state_transition_action::document::documents_batch::document_transition::BatchTransitionAction; use crate::state_transition_action::document::documents_batch::v0::DocumentsBatchTransitionActionV0; use derive_more::From; use dpp::data_contract::accessors::v0::DataContractV0Getters; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs index d385fc4b388..d71c5843cca 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs @@ -31,7 +31,9 @@ impl DocumentsBatchTransitionActionV0 { .transitions .iter() .filter_map(|transition| match transition { - DocumentTransitionAction::PurchaseAction(purchase) => Some(purchase.price()), + BatchTransitionAction::DocumentAction( + DocumentTransitionAction::PurchaseAction(purchase), + ) => Some(purchase.price()), _ => None, }) .fold((None, false), |(acc, _), price| match acc { @@ -55,12 +57,12 @@ impl DocumentsBatchTransitionActionV0 { .transitions .iter() .filter_map(|transition| match transition { - DocumentTransitionAction::CreateAction(document_create_transition_action) => { - document_create_transition_action - .prefunded_voting_balance() - .iter() - .try_fold(0u64, |acc, &(_, val)| acc.checked_add(val)) - } + BatchTransitionAction::DocumentAction(DocumentTransitionAction::CreateAction( + document_create_transition_action, + )) => document_create_transition_action + .prefunded_voting_balance() + .iter() + .try_fold(0u64, |acc, &(_, val)| acc.checked_add(val)), _ => None, }) .fold((None, false), |(acc, _), price| match acc { diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index d3ea4825f72..99e612f75b7 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -2,8 +2,6 @@ use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use crate::util::batch::drive_op_batch::DriveLowLevelOperationConverter; -use crate::util::batch::IdentityOperationType; -use crate::util::object_size_info::DataContractInfo; use dpp::balances::credits::TokenAmount; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; @@ -87,7 +85,6 @@ impl DriveLowLevelOperationConverter for TokenOperationType { token_id_bytes, identity_id_bytes, mint_amount, - &mut None, estimated_costs_only_with_layer_info, transaction, platform_version, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 5ab0a46da49..b94e4bd89c6 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -25,4 +25,6 @@ pub struct DriveTokenUpdateMethodVersions { pub transfer: FeatureVersion, pub add_to_token_total_supply: FeatureVersion, pub remove_from_token_total_supply: FeatureVersion, + pub remove_from_identity_token_balance: FeatureVersion, + pub add_to_previous_token_balance: FeatureVersion, } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index bcf858b3dc2..ea9508b7023 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -13,5 +13,7 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM transfer: 0, add_to_token_total_supply: 0, remove_from_token_total_supply: 0, + remove_from_identity_token_balance: 0, + add_to_previous_token_balance: 0, }, }; From b07e1a66bca711fc483b4cc192a5f5ac1f9bbbf3 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 18 Dec 2024 06:13:54 +0400 Subject: [PATCH 18/61] more token work --- .../insert/add_new_identity/v0/mod.rs | 2 +- .../methods/add_to_identity_balance/v0/mod.rs | 2 +- .../remove_from_identity_balance/v0/mod.rs | 2 +- .../src/drive/initialization/v0/mod.rs | 4 +- packages/rs-drive/src/drive/mod.rs | 10 +- .../add_to_previous_token_balance/mod.rs | 99 +++++++++--- .../add_to_previous_token_balance/v0/mod.rs | 145 +++++++++++++++--- .../src/drive/tokens/balance/fetch/mod.rs | 2 +- .../src/drive/tokens/balance/fetch/v0/mod.rs | 4 +- .../v0/mod.rs | 27 ++-- .../rs-drive/src/drive/tokens/burn/v0/mod.rs | 2 +- .../estimated_costs/for_token_balances/mod.rs | 45 ++++++ .../for_token_balances/v0/mod.rs | 137 +++++++++++++++++ .../src/drive/tokens/estimated_costs/mod.rs | 1 + .../rs-drive/src/drive/tokens/mint/v0/mod.rs | 37 ++--- packages/rs-drive/src/drive/tokens/mod.rs | 60 +++++++- .../system/create_token_root_tree/v0/mod.rs | 4 +- .../src/util/batch/grovedb_op_batch/mod.rs | 2 +- .../drive_token_method_versions/mod.rs | 2 +- .../drive_token_method_versions/v1.rs | 2 +- 20 files changed, 481 insertions(+), 108 deletions(-) create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs diff --git a/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs b/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs index f7562344318..96804a98f1e 100644 --- a/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs @@ -234,7 +234,7 @@ impl Drive { } if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_balances( + Self::add_estimation_costs_for_token_balances( estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/identity/update/methods/add_to_identity_balance/v0/mod.rs b/packages/rs-drive/src/drive/identity/update/methods/add_to_identity_balance/v0/mod.rs index 8876c58ce12..5ff9c020569 100644 --- a/packages/rs-drive/src/drive/identity/update/methods/add_to_identity_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/update/methods/add_to_identity_balance/v0/mod.rs @@ -74,7 +74,7 @@ impl Drive { let mut drive_operations = vec![]; let drive_version = &platform_version.drive; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_balances( + Self::add_estimation_costs_for_token_balances( estimated_costs_only_with_layer_info, drive_version, )?; diff --git a/packages/rs-drive/src/drive/identity/update/methods/remove_from_identity_balance/v0/mod.rs b/packages/rs-drive/src/drive/identity/update/methods/remove_from_identity_balance/v0/mod.rs index 491bd63bd47..347d48e920b 100644 --- a/packages/rs-drive/src/drive/identity/update/methods/remove_from_identity_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/update/methods/remove_from_identity_balance/v0/mod.rs @@ -76,7 +76,7 @@ impl Drive { ) -> Result, Error> { let mut drive_operations = vec![]; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_balances( + Self::add_estimation_costs_for_token_balances( estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/initialization/v0/mod.rs b/packages/rs-drive/src/drive/initialization/v0/mod.rs index ff30075d680..b612aad5a2e 100644 --- a/packages/rs-drive/src/drive/initialization/v0/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v0/mod.rs @@ -61,7 +61,7 @@ impl Drive { self.grove_insert_empty_tree( SubtreePath::empty(), - &[RootTree::TokenBalances as u8], + &[RootTree::Tokens as u8], transaction, None, &mut drive_operations, @@ -302,7 +302,7 @@ mod tests { // Merk Level 2 let mut query = Query::new(); - query.insert_key(vec![RootTree::TokenBalances as u8]); + query.insert_key(vec![RootTree::Tokens as u8]); let root_path_query = PathQuery::new( vec![], SizedQuery { diff --git a/packages/rs-drive/src/drive/mod.rs b/packages/rs-drive/src/drive/mod.rs index 5b28351f547..f23dbdf2d90 100644 --- a/packages/rs-drive/src/drive/mod.rs +++ b/packages/rs-drive/src/drive/mod.rs @@ -113,8 +113,8 @@ pub enum RootTree { WithdrawalTransactions = 80, /// Balances (For identities) Balances = 96, - /// Token Balances - TokenBalances = 16, + /// Token Balances and Info + Tokens = 16, /// Versions desired by proposers Versions = 120, /// Registered votes @@ -138,7 +138,7 @@ impl fmt::Display for RootTree { RootTree::Misc => "Misc", RootTree::WithdrawalTransactions => "WithdrawalTransactions", RootTree::Balances => "Balances", - RootTree::TokenBalances => "TokenBalances", + RootTree::Tokens => "TokenBalances", RootTree::Versions => "Versions", RootTree::Votes => "Votes", }; @@ -181,7 +181,7 @@ impl TryFrom for RootTree { 104 => Ok(RootTree::Misc), 80 => Ok(RootTree::WithdrawalTransactions), 96 => Ok(RootTree::Balances), - 16 => Ok(RootTree::TokenBalances), + 16 => Ok(RootTree::Tokens), 120 => Ok(RootTree::Versions), 112 => Ok(RootTree::Votes), _ => Err(Error::Drive(DriveError::NotSupported( @@ -205,7 +205,7 @@ impl From for &'static [u8; 1] { RootTree::Misc => &[104], RootTree::WithdrawalTransactions => &[80], RootTree::Balances => &[96], - RootTree::TokenBalances => &[16], + RootTree::Tokens => &[16], RootTree::NonUniquePublicKeyKeyHashesToIdentities => &[8], RootTree::Versions => &[120], RootTree::Votes => &[112], diff --git a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs index 7a62530a15b..24cf8ad32a8 100644 --- a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs @@ -1,60 +1,115 @@ mod v0; -use crate::drive::identity::update::add_to_previous_balance_outcome::AddToPreviousBalanceOutcome; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; use dpp::fee::Credits; + +use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::version::PlatformVersion; -use grovedb::TransactionArg; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; impl Drive { - /// The method to add balance to the previous balance for a token. This function is version controlled. + /// The operations for adding a certain amount of credits to an identity's balance. This function is version controlled. /// /// # Arguments /// - /// * `identity_id` - The ID of the Identity. - /// * `previous_balance` - The previous balance of the Identity. - /// * `added_balance` - The balance to be added. - /// * `apply` - Whether to apply the operations. - /// * `transaction` - The current transaction. - /// * `drive_operations` - The vector of LowLevelDriveOperations. - /// * `drive_version` - The drive version. + /// * `token_id` - The ID of the Token. + /// * `identity_id` - The ID of the Identity to which credits are to be added. + /// * `balance_to_add` - The amount of credits to be added to the identity's balance. + /// * `block_info` - Information about the current block. + /// * `apply` - A boolean indicating whether the operation should be applied or not. + /// * `transaction` - The transaction information related to the operation. + /// * `platform_version` - The platform version. + /// * `previous_fee_versions` - Cached fee versions, if any. /// /// # Returns /// - /// * `Result` - The outcome if successful, or an error. - pub(in crate::drive::tokens) fn add_to_previous_token_balance( + /// * `Result` - The resulting fee result if successful, or an error. + pub fn add_to_identity_token_balance( &self, token_id: [u8; 32], identity_id: [u8; 32], - previous_balance: Credits, - added_balance: Credits, + balance_to_add: Credits, + block_info: &BlockInfo, apply: bool, transaction: TransactionArg, - drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result { + previous_fee_versions: Option<&CachedEpochIndexFeeVersions>, + ) -> Result { match platform_version .drive .methods .token .update - .add_to_previous_token_balance + .add_to_identity_token_balance { - 0 => self.add_to_previous_token_balance_v0( + 0 => self.add_to_identity_token_balance_v0( token_id, identity_id, - previous_balance, - added_balance, + balance_to_add, + block_info, apply, transaction, - drive_operations, + platform_version, + previous_fee_versions, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_to_identity_token_balance".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds a specified amount of credits to an identity balance. This function checks for overflows and ensures the balance does not exceed `MAX_CREDITS`. + /// Balances are stored under the identity's ID in the token balance tree. + /// + /// # Arguments + /// + /// * `token_id` - The ID of the Token. + /// * `identity_id` - The ID of the Identity to which credits are to be added. + /// * `balance_to_add` - The amount of credits to be added to the identity's balance. + /// * `estimated_costs_only_with_layer_info` - Estimated costs with layer information, if any. + /// * `transaction` - The transaction information related to the operation. + /// * `platform_version` - The platform version. + /// + /// # Returns + /// + /// * `Result, Error>` - The resulting low level drive operations if successful, or an error. + pub(crate) fn add_to_identity_token_balance_operations( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + balance_to_add: Credits, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .update + .add_to_identity_token_balance + { + 0 => self.add_to_identity_token_balance_operations_v0( + token_id, + identity_id, + balance_to_add, + estimated_costs_only_with_layer_info, + transaction, platform_version, ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { - method: "add_to_previous_token_balance".to_string(), + method: "add_to_identity_token_balance_operations".to_string(), known_versions: vec![0], received: version, })), diff --git a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs index eb42514dfa1..14499ff242b 100644 --- a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs @@ -1,36 +1,143 @@ use crate::drive::Drive; -use crate::error::identity::IdentityError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; +use dpp::balances::credits::TokenAmount; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; use dpp::fee::Credits; +use crate::drive::tokens::token_balances_path_vec; +use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::version::PlatformVersion; -use grovedb::TransactionArg; +use dpp::ProtocolError; +use grovedb::batch::KeyInfoPath; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; impl Drive { - /// The method to add balance to the previous balance. This function is version controlled. - pub(super) fn add_to_previous_token_balance_v0( + /// Adds specified amount of credits to identity balance + /// This function checks for overflows and does not exceed MAX_CREDITS + /// + /// Balances are stored in the balance tree under the identity's id + pub(in crate::drive::tokens) fn add_to_identity_token_balance_v0( &self, token_id: [u8; 32], identity_id: [u8; 32], - previous_balance: Credits, - added_balance: Credits, + balance_to_add: Credits, + block_info: &BlockInfo, apply: bool, transaction: TransactionArg, - drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result { - // Deduct added balance from existing one - let new_balance = previous_balance - .checked_add(added_balance) - .ok_or(Error::Identity(IdentityError::CriticalBalanceOverflow( - "identity balance add overflow error", - )))?; - - Ok(AddToPreviousBalanceOutcomeV0 { - balance_modified: Some(new_balance), - negative_credit_balance_modified: None, + previous_fee_versions: Option<&CachedEpochIndexFeeVersions>, + ) -> Result { + let mut estimated_costs_only_with_layer_info = if apply { + None::> + } else { + Some(HashMap::new()) + }; + + let batch_operations = self.add_to_identity_token_balance_operations_v0( + token_id, + identity_id, + balance_to_add, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + let mut drive_operations: Vec = vec![]; + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + &mut drive_operations, + &platform_version.drive, + )?; + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + previous_fee_versions, + )?; + Ok(fees) + } + + /// Adds specified amount of credits to identity balance + /// This function checks for overflows and does not exceed MAX_CREDITS + /// + /// Balances are stored in the identity under key 0 + /// This gets operations based on apply flag (stateful vs stateless) + pub(in crate::drive::tokens) fn add_to_identity_token_balance_operations_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + balance_to_add: TokenAmount, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { + Self::add_estimation_costs_for_token_balances( + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + } + + let apply = estimated_costs_only_with_layer_info.is_none(); + + let previous_balance = if apply { + self.fetch_identity_token_balance_operations( + token_id, + identity_id, + apply, + transaction, + &mut drive_operations, + platform_version, + )? + } else { + None // worse case is that we insert + }; + + let balance_path = token_balances_path_vec(token_id); + + if let Some(previous_balance) = previous_balance { + // Check for overflow + let new_balance = (previous_balance as i64) + .checked_add(balance_to_add as i64) + .ok_or( + ProtocolError::CriticalCorruptedCreditsCodeExecution( + "Overflow of total token balance".to_string(), + ) + .into(), + )?; + + drive_operations.push(LowLevelDriveOperation::replace_for_known_path_key_element( + balance_path, + identity_id.to_vec(), + Element::new_sum_item(new_balance), + )); + } else { + if balance_to_add > i64::MAX as u64 { + return Err( + ProtocolError::CriticalCorruptedCreditsCodeExecution(format!( + "Token balance to add over i64 max, is {}", + balance_to_add + )) + .into(), + ); + } + drive_operations.push(LowLevelDriveOperation::insert_for_known_path_key_element( + balance_path, + identity_id.to_vec(), + Element::new_sum_item(balance_to_add as i64), + )); } - .into()) + + Ok(drive_operations) } } diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs index b229848387b..dd79be761a4 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs @@ -105,7 +105,7 @@ impl Drive { transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result, Error> { + ) -> Result, Error> { match platform_version.drive.methods.token.fetch.balance { 0 => self.fetch_identity_token_balance_operations_v0( token_id, diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs index ba713f72a20..22d4fdbdb63 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs @@ -1,4 +1,4 @@ -use crate::drive::tokens::token_balances_path_vec; +use crate::drive::tokens::{token_balances_path, token_balances_path_vec}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; @@ -48,7 +48,7 @@ impl Drive { } }; - let balance_path = token_balances_path_vec(token_id); + let balance_path = token_balances_path(&token_id); match self.grove_get_raw_optional( (&balance_path).into(), diff --git a/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs index 4c3fffd78f6..4c69f2bb742 100644 --- a/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs @@ -8,10 +8,11 @@ use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::fee::Credits; +use crate::drive::tokens::token_balances_path_vec; use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; use std::collections::HashMap; impl Drive { @@ -79,22 +80,19 @@ impl Drive { ) -> Result, Error> { let mut drive_operations = vec![]; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_balances( - estimated_costs_only_with_layer_info, - &platform_version.drive, - )?; - Self::add_estimation_costs_for_negative_credit( - identity_id, + Self::add_estimation_costs_for_token_balances( estimated_costs_only_with_layer_info, &platform_version.drive, )?; } - let previous_balance = if estimated_costs_only_with_layer_info.is_none() { + let apply = estimated_costs_only_with_layer_info.is_none(); + + let previous_balance = if apply { self.fetch_identity_token_balance_operations( token_id, identity_id, - estimated_costs_only_with_layer_info.is_none(), + apply, transaction, &mut drive_operations, platform_version, @@ -117,10 +115,13 @@ impl Drive { ))); } - drive_operations.push(self.update_identity_token_balance_operation_v0( - identity_id, - previous_balance - balance_to_remove, - )?); + let balance_path = token_balances_path_vec(token_id); + + drive_operations.push(LowLevelDriveOperation::replace_for_known_path_key_element( + balance_path, + identity_id.to_vec(), + Element::new_sum_item((previous_balance - balance_to_remove) as i64), + )); Ok(drive_operations) } diff --git a/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs b/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs index fc42ebf078c..891e4d3562d 100644 --- a/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs @@ -93,7 +93,7 @@ impl Drive { // Add estimation info if needed if let Some(esti) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_balances(esti, &platform_version.drive)?; + Self::add_estimation_costs_for_token_balances(esti, &platform_version.drive)?; Self::add_estimation_costs_for_negative_credit( identity_id, esti, diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs new file mode 100644 index 00000000000..80aff8019b8 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs @@ -0,0 +1,45 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use dpp::version::drive_versions::DriveVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerInformation; +use std::collections::HashMap; + +impl Drive { + /// Adds estimation costs for balances. + /// + /// It operates on the provided HashMap, `estimated_costs_only_with_layer_info`, and adds + /// new entries to it, representing the estimated costs for different layers of the balance tree. + /// + /// # Parameters + /// - `estimated_costs_only_with_layer_info`: A mutable reference to a HashMap storing + /// the `KeyInfoPath` and `EstimatedLayerInformation`. + /// + /// # Returns + /// - `Ok(())` if successful. + /// - `Err(DriveError::UnknownVersionMismatch)` if the method version doesn't match any known versions. + /// + /// # Errors + /// This function will return an error if the method version doesn't match any known versions. + pub(crate) fn add_estimation_costs_for_token_balances( + estimated_costs_only_with_layer_info: &mut HashMap, + drive_version: &DriveVersion, + ) -> Result<(), Error> { + match drive_version.methods.identity.cost_estimation.for_balances { + 0 => { + Self::add_estimation_costs_for_token_balances_v0( + estimated_costs_only_with_layer_info, + ); + Ok(()) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_estimation_costs_for_token_balances".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs new file mode 100644 index 00000000000..fc7a96d09c1 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs @@ -0,0 +1,137 @@ +use crate::drive::constants::AVERAGE_BALANCE_SIZE; + +use crate::drive::Drive; + +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; +use grovedb::EstimatedLayerInformation; +use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; + +use crate::drive::tokens::{ + token_balances_path, token_identity_infos_path, token_path, tokens_root_path, +}; +use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; +use grovedb::EstimatedSumTrees::{AllSumTrees, NoSumTrees, SomeSumTrees}; +use std::collections::HashMap; + +pub const ESTIMATED_TOKEN_INFO_SIZE_BYTES: u16 = 256; + +impl Drive { + /// Adds estimation costs for token balances in Drive for version 0. + /// + /// This function provides a mechanism to estimate the costs of token balances + /// in the drive by updating the provided `HashMap` with layer information + /// relevant to balances. + /// + /// # Parameters + /// + /// * `estimated_costs_only_with_layer_info`: A mutable reference to a `HashMap` + /// that stores estimated layer information based on the key information path. + /// + /// # Notes + /// + /// The function estimates costs for three layers: + /// + /// 1. **Top Layer**: + /// - Contains general balance information and is assumed to be located on + /// layer 3 (third level in the hierarchy). The update will involve modifying: + /// - 1 normal tree for token balances. + /// - 1 normal tree for identities. + /// - 1 normal tree for contract/documents. + /// + /// 2. **Token Balances or Info Layer**: + /// - This layer contains two nodes, either for representing the token balances or info. + /// + /// 3. **All Token Balances Layer**: + /// - This layer contains the token balance root path and is considered to be + /// a normal tree that will require updates to an average of 10 nodes. + /// + /// 3. **Token Layer**: + /// - This layer contains the contract-specific token balance information, which + /// is a sum tree structure with all token amounts for all identities that have a balance. + /// ``` + pub(super) fn add_estimation_costs_for_token_balances_v0( + token_id: [u8; 32], + estimated_costs_only_with_layer_info: &mut HashMap, + with_info: bool, + ) { + // we have constructed the top layer so contract/documents tree are at the top + // since balance will be on layer 3 (level 2 on left then left) + // updating will mean we will update: + // 1 normal tree (token balances) + // 1 normal tree (identities) + // 1 normal tree (contract/documents) + // hence we should give an equal weight to both + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path([]), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(2, false), + estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), + }, + ); + + // there is one tree for the root path + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(tokens_root_path()), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(10, false), // We estimate that on average we need to update 10 nodes + estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), + }, + ); + + if with_info { + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(token_path(&token_id)), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(1, false), + estimated_layer_sizes: AllSubtrees( + 1, + SomeSumTrees { + sum_trees_weight: 1, + non_sum_trees_weight: 1, + }, + None, + ), + }, + ); + } else { + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(token_path(&token_id)), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(0, false), + estimated_layer_sizes: AllSubtrees(1, AllSumTrees, None), + }, + ); + } + + if with_info { + // there is one tree for the root path + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(token_identity_infos_path(&token_id)), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: PotentiallyAtMaxElements, + estimated_layer_sizes: AllItems( + DEFAULT_HASH_SIZE_U8, + ESTIMATED_TOKEN_INFO_SIZE_BYTES, + None, + ), + }, + ); + } + + // this is where the balances are + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(token_balances_path(&token_id)), + EstimatedLayerInformation { + is_sum_tree: true, + estimated_layer_count: PotentiallyAtMaxElements, + estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, AVERAGE_BALANCE_SIZE, None), + }, + ); + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs new file mode 100644 index 00000000000..79d8e293682 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs @@ -0,0 +1 @@ +pub mod for_token_balances; diff --git a/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs b/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs index b789ad0e414..0fcdb250809 100644 --- a/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs @@ -1,5 +1,4 @@ use crate::drive::Drive; -use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use dpp::block::block_info::BlockInfo; @@ -89,36 +88,20 @@ impl Drive { // Estimation if let Some(esti) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_balances(esti, &platform_version.drive)?; - Self::add_estimation_costs_for_negative_credit( - identity_id, - esti, - &platform_version.drive, - )?; + Self::add_estimation_costs_for_token_balances(esti, &platform_version.drive)?; } - // Fetch current balance - let current_balance = self - .fetch_identity_token_balance_operations( - token_id, - identity_id, - estimated_costs_only_with_layer_info.is_none(), - transaction, - &mut drive_operations, - platform_version, - )? - .unwrap_or(0); - - let new_balance = current_balance - .checked_add(issuance_amount) - .ok_or(Error::Drive(DriveError::CorruptedDriveState( - "overflow when adding issuance_amount".to_string(), - )))?; - // Update identity balance - drive_operations.push(self.update_identity_balance_operation_v0(identity_id, new_balance)?); + drive_operations.extend(self.add_to_identity_token_balance_operations( + token_id, + identity_id, + issuance_amount, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); - drive_operations.push(self.add_to_token_total_supply_operations( + drive_operations.extend(self.add_to_token_total_supply_operations( token_id, issuance_amount, estimated_costs_only_with_layer_info, diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index 26bb174acb5..bef64c6819a 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -2,33 +2,77 @@ use crate::drive::RootTree; pub mod balance; pub mod burn; +pub mod estimated_costs; pub mod mint; pub mod system; pub mod transfer; +pub const TOKEN_IDENTITY_INFO_KEY: u8 = 64; +pub const TOKEN_BALANCES_KEY: u8 = 128; + /// The path for the balances tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_balances_root_path() -> [&'static [u8]; 1] { - [Into::<&[u8; 1]>::into(RootTree::TokenBalances)] +pub(crate) fn tokens_root_path() -> [&'static [u8]; 1] { + [Into::<&[u8; 1]>::into(RootTree::Tokens)] } /// The path for the balances tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_balances_root_path_vec() -> Vec> { - vec![Into::<&[u8; 1]>::into(RootTree::TokenBalances).to_vec()] +pub(crate) fn tokens_root_path_vec() -> Vec> { + vec![Into::<&[u8; 1]>::into(RootTree::Tokens).to_vec()] } -/// The path for the balances tree +/// The path for the token tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_balances_path(token_id: &[u8; 32]) -> [&[u8]; 2] { +pub(crate) fn token_path(token_id: &[u8; 32]) -> [&[u8]; 2] { [ Into::<&[u8; 1]>::into(RootTree::DataContractDocuments), token_id, ] } -/// The path for the balances tree +/// The path for the token tree +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn token_path_vec(token_id: [u8; 32]) -> Vec> { + vec![vec![RootTree::Tokens as u8], token_id.to_vec()] +} + +/// The path for the token balances tree +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn token_balances_path(token_id: &[u8; 32]) -> [&[u8]; 3] { + [ + Into::<&[u8; 1]>::into(RootTree::DataContractDocuments), + token_id, + &[TOKEN_BALANCES_KEY], + ] +} + +/// The path for the token balances tree #[cfg(any(feature = "server", feature = "verify"))] pub(crate) fn token_balances_path_vec(token_id: [u8; 32]) -> Vec> { - vec![vec![RootTree::TokenBalances as u8], token_id.to_vec()] + vec![ + vec![RootTree::Tokens as u8], + token_id.to_vec(), + vec![TOKEN_BALANCES_KEY], + ] +} + +/// The path for the token info tree +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn token_identity_infos_path(token_id: &[u8; 32]) -> [&[u8]; 3] { + [ + Into::<&[u8; 1]>::into(RootTree::DataContractDocuments), + token_id, + &[TOKEN_IDENTITY_INFO_KEY], + ] +} + +/// The path for the token info tree +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn token_identity_infos_path_vec(token_id: [u8; 32]) -> Vec> { + vec![ + vec![RootTree::Tokens as u8], + token_id.to_vec(), + vec![TOKEN_IDENTITY_INFO_KEY], + ] } diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs index a20e5c8e8f5..2be68ed7350 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs @@ -1,4 +1,4 @@ -use crate::drive::tokens::token_balances_root_path; +use crate::drive::tokens::tokens_root_path; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; @@ -111,7 +111,7 @@ impl Drive { // Insert an empty tree for this token if it doesn't exist let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey((token_balances_root_path(), token_id.to_vec())), + PathFixedSizeKey((tokens_root_path(), token_id.to_vec())), true, None, // No storage flags apply_type, diff --git a/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs b/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs index 67d5f8908ea..8fba7f7970e 100644 --- a/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs @@ -71,7 +71,7 @@ impl From for KnownPath { RootTree::Misc => KnownPath::MiscRoot, RootTree::WithdrawalTransactions => KnownPath::WithdrawalTransactionsRoot, RootTree::Balances => KnownPath::BalancesRoot, - RootTree::TokenBalances => KnownPath::TokenBalancesRoot, + RootTree::Tokens => KnownPath::TokenBalancesRoot, RootTree::Versions => KnownPath::VersionsRoot, RootTree::Votes => KnownPath::VotesRoot, } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index b94e4bd89c6..830d594c99b 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -26,5 +26,5 @@ pub struct DriveTokenUpdateMethodVersions { pub add_to_token_total_supply: FeatureVersion, pub remove_from_token_total_supply: FeatureVersion, pub remove_from_identity_token_balance: FeatureVersion, - pub add_to_previous_token_balance: FeatureVersion, + pub add_to_identity_token_balance: FeatureVersion, } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index ea9508b7023..0eee66aa507 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -14,6 +14,6 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM add_to_token_total_supply: 0, remove_from_token_total_supply: 0, remove_from_identity_token_balance: 0, - add_to_previous_token_balance: 0, + add_to_identity_token_balance: 0, }, }; From a5a16c40ed845bd17fb4c603e70e4cd35225c874 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 20 Dec 2024 21:32:42 +0700 Subject: [PATCH 19/61] tokens compiling --- .../token_configuration/mod.rs | 2 +- packages/rs-drive/src/drive/balances/mod.rs | 60 +++++++++++- .../insert/add_new_identity/v0/mod.rs | 4 +- .../methods/add_to_identity_balance/v0/mod.rs | 2 +- .../remove_from_identity_balance/v0/mod.rs | 2 +- .../add_to_previous_token_balance/v0/mod.rs | 11 +-- .../src/drive/tokens/balance/fetch/v0/mod.rs | 2 +- .../v0/mod.rs | 2 + .../rs-drive/src/drive/tokens/burn/mod.rs | 4 - .../rs-drive/src/drive/tokens/burn/v0/mod.rs | 76 +++----------- .../estimated_costs/for_token_balances/mod.rs | 13 ++- .../for_token_balances/v0/mod.rs | 8 +- .../for_token_total_supply/mod.rs | 50 ++++++++++ .../for_token_total_supply/v0/mod.rs | 98 +++++++++++++++++++ .../src/drive/tokens/estimated_costs/mod.rs | 1 + .../rs-drive/src/drive/tokens/mint/mod.rs | 6 ++ .../rs-drive/src/drive/tokens/mint/v0/mod.rs | 11 ++- .../system/add_to_token_total_supply/mod.rs | 6 ++ .../add_to_token_total_supply/v0/mod.rs | 73 +++++++++----- .../remove_from_token_total_supply/mod.rs | 4 - .../remove_from_token_total_supply/v0/mod.rs | 56 ++++++----- .../rs-drive/src/drive/tokens/transfer/mod.rs | 4 - .../src/drive/tokens/transfer/v0/mod.rs | 72 ++++---------- .../document/token_burn_transition.rs | 5 +- .../document/token_issuance_transition.rs | 1 + .../document/token_transfer_transition.rs | 3 +- .../token_issuance_transition_action/mod.rs | 4 +- .../v0/transformer.rs | 13 ++- .../token_transfer_transition_action/mod.rs | 2 + .../v0/transformer.rs | 2 +- .../src/util/batch/drive_op_batch/token.rs | 8 +- packages/rs-drive/src/util/type_constants.rs | 2 + .../drive_identity_method_versions/mod.rs | 2 + .../drive_identity_method_versions/v1.rs | 2 + 34 files changed, 393 insertions(+), 218 deletions(-) create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs index 30cf70ffa64..899fe85b0da 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use std::borrow::Cow; use std::fmt; -mod accessors; +pub mod accessors; mod methods; mod v0; diff --git a/packages/rs-drive/src/drive/balances/mod.rs b/packages/rs-drive/src/drive/balances/mod.rs index 39f15f42985..23c74cd12ac 100644 --- a/packages/rs-drive/src/drive/balances/mod.rs +++ b/packages/rs-drive/src/drive/balances/mod.rs @@ -22,10 +22,14 @@ use crate::drive::RootTree; use crate::query::Query; use grovedb::{PathQuery, SizedQuery}; -/// Storage fee pool key +/// Total system credits storage #[cfg(any(feature = "server", feature = "verify"))] pub const TOTAL_SYSTEM_CREDITS_STORAGE_KEY: &[u8; 1] = b"D"; +/// Total token supplies storage +#[cfg(any(feature = "server", feature = "verify"))] +pub const TOTAL_TOKEN_SUPPLIES_STORAGE_KEY: &[u8; 1] = b"T"; + /// The path for all the credits in the system #[cfg(any(feature = "server", feature = "verify"))] pub fn total_credits_path() -> [&'static [u8]; 2] { @@ -57,6 +61,60 @@ pub fn total_credits_on_platform_path_query() -> PathQuery { } } +/// The path for the root of all token supplies +#[cfg(any(feature = "server", feature = "verify"))] +pub fn total_tokens_root_supply_path() -> [&'static [u8]; 2] { + [ + Into::<&[u8; 1]>::into(RootTree::Misc), + TOTAL_TOKEN_SUPPLIES_STORAGE_KEY, + ] +} + +/// The path as a vec for the root of all token supplies +#[cfg(any(feature = "server", feature = "verify"))] +pub fn total_tokens_root_supply_path_vec() -> Vec> { + vec![ + vec![RootTree::Misc as u8], + TOTAL_TOKEN_SUPPLIES_STORAGE_KEY.to_vec(), + ] +} + +/// The path for the token supply for a given token +#[cfg(any(feature = "server", feature = "verify"))] +pub fn total_token_supply_path(token_id: &[u8; 32]) -> [&[u8]; 3] { + [ + Into::<&[u8; 1]>::into(RootTree::Misc), + TOTAL_TOKEN_SUPPLIES_STORAGE_KEY, + token_id, + ] +} + +/// The path as a vec for the token supply for a given token +#[cfg(any(feature = "server", feature = "verify"))] +pub fn total_token_supply_path_vec(token_id: [u8; 32]) -> Vec> { + vec![ + vec![RootTree::Misc as u8], + TOTAL_TOKEN_SUPPLIES_STORAGE_KEY.to_vec(), + token_id.to_vec(), + ] +} + +/// A path query helper to get the total token supply for a given token on Platform +#[cfg(any(feature = "server", feature = "verify"))] +pub fn total_supply_for_token_on_platform_path_query(token_id: [u8; 32]) -> PathQuery { + PathQuery { + path: vec![ + vec![RootTree::Misc as u8], + TOTAL_TOKEN_SUPPLIES_STORAGE_KEY.to_vec(), + ], + query: SizedQuery { + query: Query::new_single_key(token_id.to_vec()), + limit: Some(1), + offset: None, + }, + } +} + /// The path for the balances tree #[cfg(any(feature = "server", feature = "verify"))] pub(crate) fn balance_path() -> [&'static [u8]; 1] { diff --git a/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs b/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs index 96804a98f1e..64f7dd35021 100644 --- a/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs @@ -234,7 +234,7 @@ impl Drive { } if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_token_balances( + Self::add_estimation_costs_for_balances( estimated_costs_only_with_layer_info, &platform_version.drive, )?; @@ -257,7 +257,7 @@ impl Drive { let mut create_tree_keys_operations = self.create_key_tree_with_keys_operations( id.to_buffer(), public_keys.into_values().collect(), - // if we are a masternode identity, we want to register all keys as non unique + // if we are a masternode identity, we want to register all keys as non-unique is_masternode_identity, &block_info.epoch, estimated_costs_only_with_layer_info, diff --git a/packages/rs-drive/src/drive/identity/update/methods/add_to_identity_balance/v0/mod.rs b/packages/rs-drive/src/drive/identity/update/methods/add_to_identity_balance/v0/mod.rs index 5ff9c020569..8876c58ce12 100644 --- a/packages/rs-drive/src/drive/identity/update/methods/add_to_identity_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/update/methods/add_to_identity_balance/v0/mod.rs @@ -74,7 +74,7 @@ impl Drive { let mut drive_operations = vec![]; let drive_version = &platform_version.drive; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_token_balances( + Self::add_estimation_costs_for_balances( estimated_costs_only_with_layer_info, drive_version, )?; diff --git a/packages/rs-drive/src/drive/identity/update/methods/remove_from_identity_balance/v0/mod.rs b/packages/rs-drive/src/drive/identity/update/methods/remove_from_identity_balance/v0/mod.rs index 347d48e920b..491bd63bd47 100644 --- a/packages/rs-drive/src/drive/identity/update/methods/remove_from_identity_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/update/methods/remove_from_identity_balance/v0/mod.rs @@ -76,7 +76,7 @@ impl Drive { ) -> Result, Error> { let mut drive_operations = vec![]; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_token_balances( + Self::add_estimation_costs_for_balances( estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs index 14499ff242b..5d3a0ebac7e 100644 --- a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs @@ -83,6 +83,8 @@ impl Drive { let mut drive_operations = vec![]; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { Self::add_estimation_costs_for_token_balances( + token_id, + false, estimated_costs_only_with_layer_info, &platform_version.drive, )?; @@ -109,12 +111,9 @@ impl Drive { // Check for overflow let new_balance = (previous_balance as i64) .checked_add(balance_to_add as i64) - .ok_or( - ProtocolError::CriticalCorruptedCreditsCodeExecution( - "Overflow of total token balance".to_string(), - ) - .into(), - )?; + .ok_or(ProtocolError::CriticalCorruptedCreditsCodeExecution( + "Overflow of total token balance".to_string(), + ))?; drive_operations.push(LowLevelDriveOperation::replace_for_known_path_key_element( balance_path, diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs index 22d4fdbdb63..40c941cc0a5 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs @@ -1,4 +1,4 @@ -use crate::drive::tokens::{token_balances_path, token_balances_path_vec}; +use crate::drive::tokens::token_balances_path; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; diff --git a/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs index 4c69f2bb742..4367a872a80 100644 --- a/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs @@ -81,6 +81,8 @@ impl Drive { let mut drive_operations = vec![]; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { Self::add_estimation_costs_for_token_balances( + token_id, + false, estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/tokens/burn/mod.rs b/packages/rs-drive/src/drive/tokens/burn/mod.rs index a7301ea8711..e7c733df77b 100644 --- a/packages/rs-drive/src/drive/tokens/burn/mod.rs +++ b/packages/rs-drive/src/drive/tokens/burn/mod.rs @@ -47,7 +47,6 @@ impl Drive { identity_id: [u8; 32], burn_amount: u64, apply: bool, - previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, @@ -58,7 +57,6 @@ impl Drive { identity_id, burn_amount, apply, - previous_batch_operations, transaction, drive_operations, platform_version, @@ -77,7 +75,6 @@ impl Drive { token_id: [u8; 32], identity_id: [u8; 32], burn_amount: u64, - previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -89,7 +86,6 @@ impl Drive { token_id, identity_id, burn_amount, - previous_batch_operations, estimated_costs_only_with_layer_info, transaction, platform_version, diff --git a/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs b/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs index 891e4d3562d..3beb0c5e06d 100644 --- a/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/burn/v0/mod.rs @@ -1,5 +1,4 @@ use crate::drive::Drive; -use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use dpp::block::block_info::BlockInfo; @@ -26,7 +25,6 @@ impl Drive { identity_id, burn_amount, apply, - &mut None, transaction, &mut drive_operations, platform_version, @@ -50,7 +48,6 @@ impl Drive { identity_id: [u8; 32], burn_amount: u64, apply: bool, - previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, @@ -62,7 +59,6 @@ impl Drive { token_id, identity_id, burn_amount, - previous_batch_operations, &mut estimated_costs_only_with_layer_info, transaction, platform_version, @@ -82,7 +78,6 @@ impl Drive { token_id: [u8; 32], identity_id: [u8; 32], burn_amount: u64, - _previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -91,63 +86,22 @@ impl Drive { ) -> Result, Error> { let mut drive_operations = vec![]; - // Add estimation info if needed - if let Some(esti) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_token_balances(esti, &platform_version.drive)?; - Self::add_estimation_costs_for_negative_credit( - identity_id, - esti, - &platform_version.drive, - )?; - } - - // Fetch current balance - let current_balance = self - .fetch_identity_token_balance_operations( - token_id, - identity_id, - estimated_costs_only_with_layer_info.is_none(), - transaction, - &mut drive_operations, - platform_version, - )? - .ok_or(Error::Drive(DriveError::CorruptedDriveState( - "there should be a balance when burning tokens".to_string(), - )))?; - - if current_balance < burn_amount { - return Err(Error::Drive(DriveError::CorruptedDriveState( - "cannot burn more tokens than currently owned".to_string(), - ))); - } - - let new_balance = current_balance - burn_amount; - - // Update identity balance - drive_operations - .push(self.update_identity_token_balance_operation_v0(identity_id, new_balance)?); - - // Update total supply for the token (subtract burn_amount) - let current_supply = self - .fetch_token_total_supply_operations( - token_id, - estimated_costs_only_with_layer_info.is_none(), - transaction, - &mut drive_operations, - platform_version, - )? - .ok_or(Error::Drive(DriveError::CorruptedDriveState( - "token should have a total supply".to_string(), - )))?; - - if current_supply < burn_amount { - return Err(Error::Drive(DriveError::CorruptedDriveState( - "cannot burn more tokens than total supply".to_string(), - ))); - } + drive_operations.extend(self.remove_from_identity_token_balance_operations( + token_id, + identity_id, + burn_amount, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); - let new_supply = current_supply - burn_amount; - drive_operations.push(self.update_token_total_supply_operation_v0(token_id, new_supply)?); + drive_operations.extend(self.remove_from_token_total_supply_operations( + token_id, + burn_amount, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); Ok(drive_operations) } diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs index 80aff8019b8..d4eb0bff2ed 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs @@ -9,7 +9,7 @@ use grovedb::EstimatedLayerInformation; use std::collections::HashMap; impl Drive { - /// Adds estimation costs for balances. + /// Adds estimation costs for token balance changes. /// /// It operates on the provided HashMap, `estimated_costs_only_with_layer_info`, and adds /// new entries to it, representing the estimated costs for different layers of the balance tree. @@ -25,12 +25,21 @@ impl Drive { /// # Errors /// This function will return an error if the method version doesn't match any known versions. pub(crate) fn add_estimation_costs_for_token_balances( + token_id: [u8; 32], + with_info_tree: bool, estimated_costs_only_with_layer_info: &mut HashMap, drive_version: &DriveVersion, ) -> Result<(), Error> { - match drive_version.methods.identity.cost_estimation.for_balances { + match drive_version + .methods + .identity + .cost_estimation + .for_token_balances + { 0 => { Self::add_estimation_costs_for_token_balances_v0( + token_id, + with_info_tree, estimated_costs_only_with_layer_info, ); Ok(()) diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs index fc7a96d09c1..1386c7979cd 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs @@ -14,7 +14,7 @@ use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; use grovedb::EstimatedSumTrees::{AllSumTrees, NoSumTrees, SomeSumTrees}; use std::collections::HashMap; -pub const ESTIMATED_TOKEN_INFO_SIZE_BYTES: u16 = 256; +pub const ESTIMATED_TOKEN_INFO_SIZE_BYTES: u32 = 256; impl Drive { /// Adds estimation costs for token balances in Drive for version 0. @@ -52,8 +52,8 @@ impl Drive { /// ``` pub(super) fn add_estimation_costs_for_token_balances_v0( token_id: [u8; 32], + with_info_tree: bool, estimated_costs_only_with_layer_info: &mut HashMap, - with_info: bool, ) { // we have constructed the top layer so contract/documents tree are at the top // since balance will be on layer 3 (level 2 on left then left) @@ -81,7 +81,7 @@ impl Drive { }, ); - if with_info { + if with_info_tree { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(token_path(&token_id)), EstimatedLayerInformation { @@ -108,7 +108,7 @@ impl Drive { ); } - if with_info { + if with_info_tree { // there is one tree for the root path estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(token_identity_infos_path(&token_id)), diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/mod.rs new file mode 100644 index 00000000000..51e3fc30f26 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/mod.rs @@ -0,0 +1,50 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use dpp::version::drive_versions::DriveVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerInformation; +use std::collections::HashMap; + +impl Drive { + /// Adds estimation costs for token total supply changes. + /// + /// It operates on the provided HashMap, `estimated_costs_only_with_layer_info`, and adds + /// new entries to it, representing the estimated costs for different layers of the balance tree. + /// + /// # Parameters + /// - `estimated_costs_only_with_layer_info`: A mutable reference to a HashMap storing + /// the `KeyInfoPath` and `EstimatedLayerInformation`. + /// + /// # Returns + /// - `Ok(())` if successful. + /// - `Err(DriveError::UnknownVersionMismatch)` if the method version doesn't match any known versions. + /// + /// # Errors + /// This function will return an error if the method version doesn't match any known versions. + pub(crate) fn add_estimation_costs_for_token_total_supply( + estimated_costs_only_with_layer_info: &mut HashMap, + drive_version: &DriveVersion, + ) -> Result<(), Error> { + match drive_version + .methods + .identity + .cost_estimation + .for_token_total_supply + { + 0 => { + Self::add_estimation_costs_for_token_total_supply_v0( + estimated_costs_only_with_layer_info, + ); + Ok(()) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_estimation_costs_for_token_total_supply".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs new file mode 100644 index 00000000000..e8f61934d07 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs @@ -0,0 +1,98 @@ +use crate::drive::Drive; + +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerCount::EstimatedLevel; +use grovedb::EstimatedLayerInformation; +use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; + +use crate::drive::balances::total_tokens_root_supply_path; +use crate::drive::system::misc_path; +use crate::util::type_constants::{DEFAULT_HASH_SIZE_U8, U64_SIZE_U32}; +use grovedb::EstimatedSumTrees::{NoSumTrees, SomeSumTrees}; +use std::collections::HashMap; + +impl Drive { + /// Adds estimation costs for token total supply in Drive for version 0. + /// + /// This function estimates the storage and update costs associated with token total supply + /// in Drive, providing detailed information about the layer structure and required updates + /// for each relevant path. The provided `HashMap` will be updated with the estimated costs + /// for each layer involved in the process. + /// + /// # Parameters + /// + /// * `estimated_costs_only_with_layer_info`: A mutable reference to a `HashMap` + /// that stores the estimated layer information for each key information path. + /// This map will be populated with the relevant layer information for the token supply + /// data and other associated trees. + /// + /// # Notes + /// + /// The function estimates costs for the following layers: + /// + /// 1. **Top Layer**: + /// - Contains general balance information and is assumed to be located on + /// level 3 of the hierarchy. It involves updating: + /// - 1 normal tree for contract/documents. + /// - 1 sum tree for balances. + /// - 1 normal for votes. + /// - 1 normal tree for misc. + /// - This layer has an equal weight distribution between normal and sum trees. + /// + /// 2. **Misc Layer**: + /// - A normal tree that contains miscellaneous data relevant to the total supply + /// process. + /// + /// 3. **Total Tokens Root Supply Path**: + /// - This path represents the root for the total tokens supply and is updated + /// with the corresponding token supply information. It is estimated to update + /// an average of 10 nodes in a normal tree structure. + pub(super) fn add_estimation_costs_for_token_total_supply_v0( + estimated_costs_only_with_layer_info: &mut HashMap, + ) { + // we have constructed the top layer so contract/documents tree are at the top + // since balance will be on layer 4 (level 3 on right, then right, then left) + // updating will mean we will update: + // 1 normal tree (misc) + // 1 normal tree (votes) + // 1 sum tree (balances) + // 1 normal tree (contract/documents) + // hence we should give an equal weight to both + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path([]), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(3, false), + // 17 because we have 2 layers at 32 and two layers at 2 + estimated_layer_sizes: AllSubtrees( + 17, + SomeSumTrees { + sum_trees_weight: 1, + non_sum_trees_weight: 3, + }, + None, + ), + }, + ); + + // in the misc tree + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(misc_path()), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(2, false), + estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), + }, + ); + + // in the total tokens root supply path + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(total_tokens_root_supply_path()), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(10, false), + estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, U64_SIZE_U32, None), + }, + ); + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs index 79d8e293682..d9e96b7e250 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs @@ -1 +1,2 @@ pub mod for_token_balances; +pub mod for_token_total_supply; diff --git a/packages/rs-drive/src/drive/tokens/mint/mod.rs b/packages/rs-drive/src/drive/tokens/mint/mod.rs index a28686838d8..ddcab0a8560 100644 --- a/packages/rs-drive/src/drive/tokens/mint/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mint/mod.rs @@ -17,6 +17,7 @@ impl Drive { token_id: [u8; 32], identity_id: [u8; 32], issuance_amount: u64, + allow_first_mint: bool, block_info: &BlockInfo, apply: bool, transaction: TransactionArg, @@ -27,6 +28,7 @@ impl Drive { token_id, identity_id, issuance_amount, + allow_first_mint, block_info, apply, transaction, @@ -46,6 +48,7 @@ impl Drive { token_id: [u8; 32], identity_id: [u8; 32], issuance_amount: u64, + allow_first_mint: bool, apply: bool, transaction: TransactionArg, drive_operations: &mut Vec, @@ -56,6 +59,7 @@ impl Drive { token_id, identity_id, issuance_amount, + allow_first_mint, apply, transaction, drive_operations, @@ -75,6 +79,7 @@ impl Drive { token_id: [u8; 32], identity_id: [u8; 32], issuance_amount: u64, + allow_first_mint: bool, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -86,6 +91,7 @@ impl Drive { token_id, identity_id, issuance_amount, + allow_first_mint, estimated_costs_only_with_layer_info, transaction, platform_version, diff --git a/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs b/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs index 0fcdb250809..f0d737455a0 100644 --- a/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mint/v0/mod.rs @@ -13,6 +13,7 @@ impl Drive { token_id: [u8; 32], identity_id: [u8; 32], issuance_amount: u64, + allow_first_mint: bool, block_info: &BlockInfo, apply: bool, transaction: TransactionArg, @@ -24,6 +25,7 @@ impl Drive { token_id, identity_id, issuance_amount, + allow_first_mint, apply, transaction, &mut drive_operations, @@ -47,6 +49,7 @@ impl Drive { token_id: [u8; 32], identity_id: [u8; 32], issuance_amount: u64, + allow_first_mint: bool, apply: bool, transaction: TransactionArg, drive_operations: &mut Vec, @@ -59,6 +62,7 @@ impl Drive { token_id, identity_id, issuance_amount, + allow_first_mint, &mut estimated_costs_only_with_layer_info, transaction, platform_version, @@ -78,6 +82,7 @@ impl Drive { token_id: [u8; 32], identity_id: [u8; 32], issuance_amount: u64, + allow_first_mint: bool, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -86,11 +91,6 @@ impl Drive { ) -> Result, Error> { let mut drive_operations = vec![]; - // Estimation - if let Some(esti) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_token_balances(esti, &platform_version.drive)?; - } - // Update identity balance drive_operations.extend(self.add_to_identity_token_balance_operations( token_id, @@ -104,6 +104,7 @@ impl Drive { drive_operations.extend(self.add_to_token_total_supply_operations( token_id, issuance_amount, + allow_first_mint, estimated_costs_only_with_layer_info, transaction, platform_version, diff --git a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/mod.rs b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/mod.rs index c4315b91d0e..4daa069ec8d 100644 --- a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/mod.rs @@ -17,6 +17,7 @@ impl Drive { &self, token_id: [u8; 32], amount: u64, + allow_first_mint: bool, block_info: &BlockInfo, apply: bool, transaction: TransactionArg, @@ -32,6 +33,7 @@ impl Drive { 0 => self.add_to_token_total_supply_v0( token_id, amount, + allow_first_mint, block_info, apply, transaction, @@ -50,6 +52,7 @@ impl Drive { &self, token_id: [u8; 32], amount: u64, + allow_first_mint: bool, apply: bool, transaction: TransactionArg, drive_operations: &mut Vec, @@ -65,6 +68,7 @@ impl Drive { 0 => self.add_to_token_total_supply_add_to_operations_v0( token_id, amount, + allow_first_mint, apply, transaction, drive_operations, @@ -83,6 +87,7 @@ impl Drive { &self, token_id: [u8; 32], amount: u64, + allow_first_mint: bool, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -99,6 +104,7 @@ impl Drive { 0 => self.add_to_token_total_supply_operations_v0( token_id, amount, + allow_first_mint, estimated_costs_only_with_layer_info, transaction, platform_version, diff --git a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs index 8058a7ec16f..ddfc7ef1c89 100644 --- a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs @@ -1,12 +1,17 @@ +use crate::drive::balances::{total_token_supply_path, total_token_supply_path_vec}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; +use crate::fees::op::LowLevelDriveOperation::GroveOperation; +use crate::util::grove_operations::DirectQueryType; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::version::PlatformVersion; -use grovedb::batch::KeyInfoPath; +use grovedb::batch::{KeyInfoPath, QualifiedGroveDbOp}; +use grovedb::Element::Item; use grovedb::{EstimatedLayerInformation, TransactionArg}; +use integer_encoding::VarInt; use std::collections::HashMap; impl Drive { @@ -14,6 +19,7 @@ impl Drive { &self, token_id: [u8; 32], amount: u64, + allow_first_mint: bool, block_info: &BlockInfo, apply: bool, transaction: TransactionArg, @@ -25,6 +31,7 @@ impl Drive { token_id, amount, apply, + allow_first_mint, transaction, &mut drive_operations, platform_version, @@ -46,6 +53,7 @@ impl Drive { &self, token_id: [u8; 32], amount: u64, + allow_first_mint: bool, apply: bool, transaction: TransactionArg, drive_operations: &mut Vec, @@ -57,6 +65,7 @@ impl Drive { let batch_operations = self.add_to_token_total_supply_operations_v0( token_id, amount, + allow_first_mint, &mut estimated_costs_only_with_layer_info, transaction, platform_version, @@ -75,6 +84,7 @@ impl Drive { &self, token_id: [u8; 32], amount: u64, + allow_first_mint: bool, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -84,36 +94,51 @@ impl Drive { let mut drive_operations = vec![]; // If we only estimate, add estimation costs - if let Some(esti) = estimated_costs_only_with_layer_info { + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { // Add your estimation logic similar to add_to_system_credits_operations_v0 // For example: - Self::add_estimation_costs_for_token_total_supply_update( - esti, + Self::add_estimation_costs_for_token_total_supply( + estimated_costs_only_with_layer_info, &platform_version.drive, )?; } - // Fetch current total supply - let current_supply = self - .fetch_token_total_supply_operations( - token_id, - estimated_costs_only_with_layer_info.is_none(), - transaction, - &mut drive_operations, - platform_version, - )? - .ok_or(Error::Drive(DriveError::CorruptedDriveState( - "token should have a total supply before adding".to_string(), - )))?; - - let new_supply = current_supply.checked_add(amount).ok_or(Error::Drive( - DriveError::CorruptedDriveState( - "overflow when adding to token total supply".to_string(), - ), - ))?; + let path_holding_total_token_supply = total_token_supply_path(&token_id); + let path_holding_total_token_supply_vec = total_token_supply_path_vec(token_id); + let total_token_supply_in_platform = self.grove_get_raw_value_u64_from_encoded_var_vec( + (&path_holding_total_token_supply).into(), + &token_id, + DirectQueryType::StatefulDirectQuery, + transaction, + &mut drive_operations, + &platform_version.drive, + )?; - // Update token total supply - drive_operations.push(self.update_token_total_supply_operation_v0(token_id, new_supply)?); + if let Some(total_token_supply_in_platform) = total_token_supply_in_platform { + let new_total = + total_token_supply_in_platform + .checked_add(amount) + .ok_or(Error::Drive(DriveError::CriticalCorruptedState( + "trying to add an amount that would underflow total supply", + )))?; + let replace_op = QualifiedGroveDbOp::replace_op( + path_holding_total_token_supply_vec, + token_id.to_vec(), + Item(new_total.encode_var_vec(), None), + ); + drive_operations.push(GroveOperation(replace_op)); + } else if allow_first_mint { + let insert_op = QualifiedGroveDbOp::insert_only_op( + path_holding_total_token_supply_vec, + token_id.to_vec(), + Item(amount.encode_var_vec(), None), + ); + drive_operations.push(GroveOperation(insert_op)); + } else { + return Err(Error::Drive(DriveError::CriticalCorruptedState( + "Total supply for token not found in Platform", + ))); + } Ok(drive_operations) } diff --git a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/mod.rs b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/mod.rs index 9219e8dcefb..4ede94b6322 100644 --- a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/mod.rs @@ -50,7 +50,6 @@ impl Drive { token_id: [u8; 32], amount: u64, apply: bool, - previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, @@ -66,7 +65,6 @@ impl Drive { token_id, amount, apply, - previous_batch_operations, transaction, drive_operations, platform_version, @@ -84,7 +82,6 @@ impl Drive { &self, token_id: [u8; 32], amount: u64, - previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -101,7 +98,6 @@ impl Drive { 0 => self.remove_from_token_total_supply_operations_v0( token_id, amount, - previous_batch_operations, estimated_costs_only_with_layer_info, transaction, platform_version, diff --git a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs index 11a618803e1..b5a94e75825 100644 --- a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs @@ -1,11 +1,17 @@ +use crate::drive::balances::{total_token_supply_path, total_token_supply_path_vec}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; +use crate::fees::op::LowLevelDriveOperation::GroveOperation; +use crate::util::grove_operations::DirectQueryType; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::version::PlatformVersion; +use grovedb::batch::QualifiedGroveDbOp; +use grovedb::Element::Item; use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use integer_encoding::VarInt; use std::collections::HashMap; impl Drive { @@ -24,7 +30,6 @@ impl Drive { token_id, amount, apply, - &mut None, transaction, &mut drive_operations, platform_version, @@ -47,7 +52,6 @@ impl Drive { token_id: [u8; 32], amount: u64, apply: bool, - previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, @@ -58,7 +62,6 @@ impl Drive { let batch_operations = self.remove_from_token_total_supply_operations_v0( token_id, amount, - previous_batch_operations, &mut estimated_costs_only_with_layer_info, transaction, platform_version, @@ -77,7 +80,6 @@ impl Drive { &self, token_id: [u8; 32], amount: u64, - _previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -87,38 +89,40 @@ impl Drive { let mut drive_operations = vec![]; // If we only estimate, add estimation costs - if let Some(esti) = estimated_costs_only_with_layer_info { + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { // Add your estimation logic similar to add_to_token_total_supply if needed // For example (this is a placeholder method, you must implement similarly as others): - Self::add_estimation_costs_for_token_total_supply_update( - esti, + Self::add_estimation_costs_for_token_total_supply( + estimated_costs_only_with_layer_info, &platform_version.drive, )?; } - // Fetch current total supply - let current_supply = self - .fetch_token_total_supply_operations( - token_id, - estimated_costs_only_with_layer_info.is_none(), + let path_holding_total_token_supply = total_token_supply_path(&token_id); + let total_token_supply_in_platform = self + .grove_get_raw_value_u64_from_encoded_var_vec( + (&path_holding_total_token_supply).into(), + &token_id, + DirectQueryType::StatefulDirectQuery, transaction, &mut drive_operations, - platform_version, + &platform_version.drive, )? - .ok_or(Error::Drive(DriveError::CorruptedDriveState( - "token should have a total supply before removing".to_string(), + .ok_or(Error::Drive(DriveError::CriticalCorruptedState( + "Total supply for Token not found in Platform", )))?; - - if current_supply < amount { - return Err(Error::Drive(DriveError::CorruptedDriveState( - "cannot remove more from total supply than currently exists".to_string(), - ))); - } - - let new_supply = current_supply - amount; - - // Update token total supply - drive_operations.push(self.update_token_total_supply_operation_v0(token_id, new_supply)?); + let new_total = total_token_supply_in_platform + .checked_sub(amount) + .ok_or(Error::Drive(DriveError::CriticalCorruptedState( + "trying to subtract an amount that would underflow total supply", + )))?; + let path_holding_total_token_supply_vec = total_token_supply_path_vec(token_id); + let replace_op = QualifiedGroveDbOp::replace_op( + path_holding_total_token_supply_vec, + token_id.to_vec(), + Item(new_total.encode_var_vec(), None), + ); + drive_operations.push(GroveOperation(replace_op)); Ok(drive_operations) } diff --git a/packages/rs-drive/src/drive/tokens/transfer/mod.rs b/packages/rs-drive/src/drive/tokens/transfer/mod.rs index 10bef172b7e..bb18a9220be 100644 --- a/packages/rs-drive/src/drive/tokens/transfer/mod.rs +++ b/packages/rs-drive/src/drive/tokens/transfer/mod.rs @@ -50,7 +50,6 @@ impl Drive { to_identity_id: [u8; 32], amount: u64, apply: bool, - previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, @@ -62,7 +61,6 @@ impl Drive { to_identity_id, amount, apply, - previous_batch_operations, transaction, drive_operations, platform_version, @@ -82,7 +80,6 @@ impl Drive { from_identity_id: [u8; 32], to_identity_id: [u8; 32], amount: u64, - previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -95,7 +92,6 @@ impl Drive { from_identity_id, to_identity_id, amount, - previous_batch_operations, estimated_costs_only_with_layer_info, transaction, platform_version, diff --git a/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs b/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs index 56c7a7456d2..6e1f95689bc 100644 --- a/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/transfer/v0/mod.rs @@ -1,6 +1,4 @@ -// token_transfer/v0.rs use crate::drive::Drive; -use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use dpp::block::block_info::BlockInfo; @@ -29,7 +27,6 @@ impl Drive { to_identity_id, amount, apply, - &mut None, transaction, &mut drive_operations, platform_version, @@ -54,7 +51,6 @@ impl Drive { to_identity_id: [u8; 32], amount: u64, apply: bool, - previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, @@ -67,7 +63,6 @@ impl Drive { from_identity_id, to_identity_id, amount, - previous_batch_operations, &mut estimated_costs_only_with_layer_info, transaction, platform_version, @@ -84,11 +79,10 @@ impl Drive { pub(super) fn token_transfer_operations_v0( &self, - _token_id: [u8; 32], + token_id: [u8; 32], from_identity_id: [u8; 32], to_identity_id: [u8; 32], amount: u64, - _previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, @@ -97,54 +91,22 @@ impl Drive { ) -> Result, Error> { let mut drive_operations = vec![]; - // Estimation - if let Some(esti) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_token_balances(esti, &platform_version.drive)?; - } - - // Fetch sender balance - let from_balance = self - .fetch_identity_balance_operations( - from_identity_id, - estimated_costs_only_with_layer_info.is_none(), - transaction, - &mut drive_operations, - platform_version, - )? - .ok_or(Error::Drive(DriveError::CorruptedDriveState( - "sender identity must have a balance".to_string(), - )))?; - - if from_balance < amount { - return Err(Error::Drive(DriveError::CorruptedDriveState( - "sender does not have enough balance to transfer".to_string(), - ))); - } - - let new_from_balance = from_balance - amount; - drive_operations.push( - self.update_identity_token_balance_operation_v0(from_identity_id, new_from_balance)?, - ); - - // Fetch recipient balance - let to_balance = self - .fetch_identity_balance_operations( - to_identity_id, - estimated_costs_only_with_layer_info.is_none(), - transaction, - &mut drive_operations, - platform_version, - )? - .unwrap_or(0); - - let new_to_balance = - to_balance - .checked_add(amount) - .ok_or(Error::Drive(DriveError::CorruptedDriveState( - "overflow on recipient balance".to_string(), - )))?; - drive_operations - .push(self.update_identity_token_balance_operation_v0(to_identity_id, new_to_balance)?); + drive_operations.extend(self.remove_from_identity_token_balance_operations( + token_id, + from_identity_id, + amount, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); + drive_operations.extend(self.add_to_identity_token_balance_operations( + token_id, + to_identity_id, + amount, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); // Total supply remains the same. Ok(drive_operations) diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs index 1d73a197565..82e08b7b9d6 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs @@ -9,11 +9,10 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::TokenOperationType; use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; -use crate::util::object_size_info::DataContractInfo::DataContractFetchInfo; impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { fn into_high_level_document_drive_operations<'b>( - mut self, + self, _epoch: &Epoch, owner_id: Identifier, platform_version: &PlatformVersion, @@ -28,8 +27,6 @@ impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { 0 => { let data_contract_id = self.base().data_contract_id(); - let contract_fetch_info = self.base().data_contract_fetch_info(); - let identity_contract_nonce = self.base().identity_contract_nonce(); let mut ops = vec![IdentityOperation( diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs index 80173ab4d6b..a746913fd07 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs @@ -41,6 +41,7 @@ impl DriveHighLevelDocumentOperationConverter for TokenIssuanceTransitionAction token_id: self.token_id(), identity_balance_holder_id: owner_id, mint_amount: self.issuance_amount(), + allow_first_mint: false, })); Ok(ops) diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs index 10b60444b53..a00416e1799 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs @@ -9,11 +9,10 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::TokenOperationType; use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; -use crate::util::object_size_info::DataContractInfo::DataContractFetchInfo; impl DriveHighLevelDocumentOperationConverter for TokenTransferTransitionAction { fn into_high_level_document_drive_operations<'b>( - mut self, + self, _epoch: &Epoch, owner_id: Identifier, platform_version: &PlatformVersion, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs index 00e127de78a..2e49f290025 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs @@ -7,9 +7,7 @@ mod v0; pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{ - TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0, -}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; /// Token issuance transition action #[derive(Debug, Clone, From)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs index 60177192fac..64d4c9f0153 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs @@ -9,6 +9,7 @@ use dpp::tokens::errors::TokenError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::v0::TokenIssuanceTransitionActionV0; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; impl TokenIssuanceTransitionActionV0 { /// Attempt to convert a `TokenIssuanceTransitionV0` into a `TokenIssuanceTransitionActionV0` using a data contract lookup function. @@ -31,6 +32,8 @@ impl TokenIssuanceTransitionActionV0 { amount, } = value; + let position = base.token_contract_position(); + let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( base, get_data_contract, @@ -42,12 +45,14 @@ impl TokenIssuanceTransitionActionV0 { .data_contract_fetch_info_ref() .contract .tokens() - .get(&base.token_contract_position()) + .get(&position) .and_then(|token_configuration| { token_configuration.new_tokens_destination_identity() }) }) - .ok_or(TokenError::DestinationIdentityForMintingNotSetError.into())?; + .ok_or(ProtocolError::Token( + TokenError::DestinationIdentityForMintingNotSetError.into(), + ))?; Ok(TokenIssuanceTransitionActionV0 { base: base_action, @@ -93,7 +98,9 @@ impl TokenIssuanceTransitionActionV0 { token_configuration.new_tokens_destination_identity() }) }) - .ok_or(TokenError::DestinationIdentityForMintingNotSetError.into())?; + .ok_or(ProtocolError::Token( + TokenError::DestinationIdentityForMintingNotSetError.into(), + ))?; Ok(TokenIssuanceTransitionActionV0 { base: base_action, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs index fb695fab47e..060b7a408ae 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs @@ -11,8 +11,10 @@ use crate::drive::contract::DataContractFetchInfo; /// transformer module pub mod transformer; +/// v0 pub mod v0; +/// TokenTransferTransitionAction #[derive(Debug, Clone, From)] pub enum TokenTransferTransitionAction { /// v0 diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index e1b1bc7d05e..37a4d937620 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -5,7 +5,7 @@ use dpp::state_transition::documents_batch_transition::token_transfer_transition use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionActionV0; impl TokenTransferTransitionActionV0 { diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index 99e612f75b7..527db6f1693 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -30,6 +30,8 @@ pub enum TokenOperationType { identity_balance_holder_id: Identifier, /// The amount to issue mint_amount: TokenAmount, + /// Should we allow this to be the first ever mint + allow_first_mint: bool, }, /// Adds a document to a contract matching the desired info. TokenTransfer { @@ -51,7 +53,7 @@ impl DriveLowLevelOperationConverter for TokenOperationType { estimated_costs_only_with_layer_info: &mut Option< HashMap, >, - block_info: &BlockInfo, + _block_info: &BlockInfo, transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { @@ -67,7 +69,6 @@ impl DriveLowLevelOperationConverter for TokenOperationType { token_id_bytes, identity_id_bytes, burn_amount, - &mut None, estimated_costs_only_with_layer_info, transaction, platform_version, @@ -78,6 +79,7 @@ impl DriveLowLevelOperationConverter for TokenOperationType { token_id, identity_balance_holder_id, mint_amount, + allow_first_mint, } => { let token_id_bytes: [u8; 32] = token_id.to_buffer(); let identity_id_bytes: [u8; 32] = identity_balance_holder_id.to_buffer(); @@ -85,6 +87,7 @@ impl DriveLowLevelOperationConverter for TokenOperationType { token_id_bytes, identity_id_bytes, mint_amount, + allow_first_mint, estimated_costs_only_with_layer_info, transaction, platform_version, @@ -106,7 +109,6 @@ impl DriveLowLevelOperationConverter for TokenOperationType { sender_id_bytes, recipient_id_bytes, amount, - &mut None, estimated_costs_only_with_layer_info, transaction, platform_version, diff --git a/packages/rs-drive/src/util/type_constants.rs b/packages/rs-drive/src/util/type_constants.rs index 517a08a2751..8979cca62a9 100644 --- a/packages/rs-drive/src/util/type_constants.rs +++ b/packages/rs-drive/src/util/type_constants.rs @@ -11,6 +11,8 @@ pub const DEFAULT_HASH_SIZE_U32: u32 = 32; /// Default float size pub const DEFAULT_FLOAT_SIZE: u32 = 8; /// u64 size +pub const U64_SIZE_U32: u32 = 8; +/// u64 size pub const U64_SIZE_U16: u16 = 8; /// u64 size pub const U64_SIZE_U8: u8 = 8; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs index c44788e4c36..031cd38dfa5 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs @@ -58,6 +58,8 @@ pub struct DriveIdentityContractInfoMethodVersions { pub struct DriveIdentityCostEstimationMethodVersions { pub for_authentication_keys_security_level_in_key_reference_tree: FeatureVersion, pub for_balances: FeatureVersion, + pub for_token_balances: FeatureVersion, + pub for_token_total_supply: FeatureVersion, pub for_contract_info: FeatureVersion, pub for_contract_info_group: FeatureVersion, pub for_contract_info_group_keys: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs index 098f38ab7c2..d0b23ccc1a0 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs @@ -119,6 +119,8 @@ pub const DRIVE_IDENTITY_METHOD_VERSIONS_V1: DriveIdentityMethodVersions = cost_estimation: DriveIdentityCostEstimationMethodVersions { for_authentication_keys_security_level_in_key_reference_tree: 0, for_balances: 0, + for_token_balances: 0, + for_token_total_supply: 0, for_contract_info: 0, for_contract_info_group: 0, for_contract_info_group_keys: 0, From b018d31846de099022e58af596597d0be4c2e87e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 24 Dec 2024 05:41:39 +0700 Subject: [PATCH 20/61] more work on tokens --- .../src/document/document_factory/mod.rs | 8 +- .../src/document/document_factory/v0/mod.rs | 16 +- packages/rs-dpp/src/document/errors.rs | 2 +- .../specialized_document_factory/mod.rs | 8 +- .../specialized_document_factory/v0/mod.rs | 16 +- packages/rs-dpp/src/state_transition/mod.rs | 74 ++- .../src/state_transition/serialization.rs | 12 +- .../state_transition_types.rs | 2 +- .../batch_transition/accessors/mod.rs | 85 +++ .../batch_transition/accessors/v0/mod.rs | 15 + .../document_base_transition_trait.rs | 2 +- .../document_base_transition/fields.rs | 2 +- .../document_base_transition/from_document.rs | 4 +- .../document_base_transition/mod.rs | 2 +- .../v0/from_document.rs | 4 +- .../document_base_transition/v0/mod.rs | 2 +- .../document_base_transition/v0/v0_methods.rs | 2 +- .../document_base_transition/v0_methods.rs | 4 +- .../document_create_transition/convertible.rs | 14 +- .../from_document.rs | 4 +- .../document_create_transition/mod.rs | 2 +- .../v0/from_document.rs | 4 +- .../document_create_transition/v0/mod.rs | 14 +- .../v0/v0_methods.rs | 6 +- .../document_create_transition/v0_methods.rs | 8 +- .../from_document.rs | 4 +- .../document_delete_transition/mod.rs | 0 .../v0/from_document.rs | 10 +- .../document_delete_transition/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 17 + .../document_delete_transition/v0_methods.rs | 6 +- .../from_document.rs | 4 +- .../document_purchase_transition/mod.rs | 0 .../v0/from_document.rs | 10 +- .../document_purchase_transition/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 6 +- .../v0_methods.rs | 8 +- .../from_document.rs | 10 +- .../document_replace_transition/mod.rs | 0 .../v0/from_document.rs | 10 +- .../document_replace_transition/v0/mod.rs | 4 +- .../v0/v0_methods.rs | 6 +- .../document_replace_transition/v0_methods.rs | 8 +- .../from_document.rs | 12 +- .../document_transfer_transition/mod.rs | 0 .../v0/from_document.rs | 12 +- .../document_transfer_transition/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 6 +- .../v0_methods.rs | 8 +- .../document_transition.rs} | 183 +----- .../document_transition_action_type.rs | 2 +- .../from_document.rs | 4 +- .../document_update_price_transition/mod.rs | 0 .../v0/from_document.rs | 4 +- .../v0/mod.rs | 2 +- .../v0/v0_methods.rs | 6 +- .../v0_methods.rs | 8 +- .../batched_transition/mod.rs | 93 +++ .../batched_transition/resolvers.rs | 124 ++++ .../token_base_transition/fields.rs | 3 +- .../token_base_transition/mod.rs | 4 +- .../token_base_transition_accessors.rs | 2 +- .../token_base_transition/v0/mod.rs | 19 +- .../token_base_transition/v0/v0_methods.rs | 20 +- .../token_base_transition/v0_methods.rs | 22 +- .../token_burn_transition/mod.rs | 0 .../token_burn_transition/v0/mod.rs | 2 +- .../token_burn_transition/v0/v0_methods.rs | 6 +- .../token_burn_transition/v0_methods.rs | 8 +- .../token_issuance_transition/mod.rs | 0 .../token_issuance_transition/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 6 +- .../token_issuance_transition/v0_methods.rs | 8 +- .../token_transfer_transition/mod.rs | 0 .../token_transfer_transition/v0/mod.rs | 2 +- .../v0/v0_methods.rs | 6 +- .../token_transfer_transition/v0_methods.rs | 8 +- .../batched_transition/token_transition.rs | 134 ++++ .../token_transition_action_type.rs | 2 +- .../fields.rs | 2 +- .../batch_transition/identity_signed.rs | 26 + .../json_conversion.rs | 8 +- .../methods/mod.rs | 153 ++++- .../methods/v0/mod.rs | 35 +- .../document/batch_transition/mod.rs | 109 ++++ .../batch_transition/resolvers/mod.rs | 1 + .../batch_transition/resolvers/v0/mod.rs | 18 + .../batch_transition/state_transition_like.rs | 79 +++ .../v0/cbor_conversion.rs | 0 .../v0/identity_signed.rs | 4 +- .../batch_transition/v0/json_conversion.rs | 4 + .../v0/mod.rs | 4 +- .../v0/state_transition_like.rs | 20 +- .../v0/types.rs | 8 +- .../v0/v0_methods.rs | 80 ++- .../batch_transition/v0/value_conversion.rs | 4 + .../v0/version.rs | 4 +- .../batch_transition/v1/identity_signed.rs | 23 + .../batch_transition/v1/json_conversion.rs | 4 + .../document/batch_transition/v1/mod.rs | 37 ++ .../v1/state_transition_like.rs | 92 +++ .../document/batch_transition/v1/types.rs | 18 + .../batch_transition/v1/v0_methods.rs | 384 +++++++++++ .../batch_transition/v1/value_conversion.rs | 4 + .../document/batch_transition/v1/version.rs | 9 + .../validation/find_duplicates_by_id/mod.rs | 2 +- .../find_duplicates_by_id/v0/mod.rs | 23 +- .../validation/mod.rs | 0 .../validate_basic_structure/mod.rs | 4 +- .../validate_basic_structure/v0/mod.rs | 41 +- .../value_conversion.rs | 24 +- .../document/batch_transition/version.rs | 12 + .../accessors/mod.rs | 19 - .../accessors/v0/mod.rs | 6 - .../v0/v0_methods.rs | 17 - .../document_transition_methods/mod.rs | 0 .../identity_signed.rs | 27 - .../documents_batch_transition/mod.rs | 601 ------------------ .../state_transition_like.rs | 71 --- .../v0/json_conversion.rs | 4 - .../v0/value_conversion.rs | 4 - .../documents_batch_transition/version.rs | 11 - .../state_transitions/document/mod.rs | 2 +- .../value_conversion.rs | 2 +- .../traits/state_transition_like.rs | 3 +- .../get_document_transitions_fixture.rs | 17 +- .../src/execution/check_tx/v0/mod.rs | 8 +- .../block_fee_processing/tests.rs | 20 +- .../v0/mod.rs | 2 +- .../state_transition/processor/v0/mod.rs | 28 +- .../document_create_transition_action/mod.rs | 4 +- .../document_delete_transition_action/mod.rs | 4 +- .../mod.rs | 4 +- .../document_replace_transition_action/mod.rs | 4 +- .../mod.rs | 4 +- .../mod.rs | 4 +- .../documents_batch/action_validation/mod.rs | 1 + .../token_issuance_transition_action/mod.rs | 103 +++ .../state_v0/mod.rs | 167 +++++ .../structure_v0/mod.rs | 40 ++ .../advanced_structure/v0/mod.rs | 17 +- .../documents_batch/balance/mod.rs | 6 +- .../documents_batch/balance/v0/mod.rs | 12 +- .../data_triggers/bindings/list/mod.rs | 2 +- .../documents_batch/data_triggers/executor.rs | 2 +- .../data_triggers/triggers/dashpay/mod.rs | 2 +- .../data_triggers/triggers/dashpay/v0/mod.rs | 8 +- .../data_triggers/triggers/dpns/mod.rs | 2 +- .../data_triggers/triggers/dpns/v0/mod.rs | 4 +- .../triggers/feature_flags/mod.rs | 2 +- .../data_triggers/triggers/reject/mod.rs | 2 +- .../data_triggers/triggers/withdrawals/mod.rs | 2 +- .../identity_contract_nonce/v0/mod.rs | 10 +- .../documents_batch/is_allowed/mod.rs | 8 +- .../documents_batch/is_allowed/v0/mod.rs | 22 +- .../state_transitions/documents_batch/mod.rs | 254 ++++---- .../state/v0/fetch_documents.rs | 4 +- .../documents_batch/state/v0/mod.rs | 4 +- .../documents_batch/transformer/v0/mod.rs | 21 +- .../state_transition/state_transitions/mod.rs | 24 +- .../state_transition/transformer/mod.rs | 2 +- .../tests/strategy_tests/main.rs | 5 +- .../tests/strategy_tests/strategy.rs | 120 ++-- .../verify_state_transitions.rs | 12 +- .../tests/strategy_tests/voting_tests.rs | 2 +- .../tokens/add_transaction_history/mod.rs | 1 + .../tokens/add_transaction_history/v0/mod.rs | 1 + packages/rs-drive/src/drive/tokens/mod.rs | 1 + .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../document_transition_action_type.rs | 2 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../document_transition/mod.rs | 2 +- .../token_base_transition_action/mod.rs | 16 +- .../transformer.rs | 2 +- .../token_base_transition_action/v0/mod.rs | 40 +- .../v0/transformer.rs | 14 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 4 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../v0/mod.rs | 345 +++++----- .../mod.rs | 3 +- .../v1.rs | 2 +- .../v2.rs | 105 +++ .../drive_abci_validation_versions/mod.rs | 8 +- .../drive_abci_validation_versions/v1.rs | 2 +- .../drive_abci_validation_versions/v2.rs | 2 +- .../drive_abci_validation_versions/v3.rs | 2 +- .../drive_abci_validation_versions/v4.rs | 2 +- .../rs-platform-version/src/version/mod.rs | 1 + .../src/version/protocol_version.rs | 3 +- .../rs-platform-version/src/version/v8.rs | 65 ++ .../platform/transition/purchase_document.rs | 6 +- .../src/platform/transition/put_document.rs | 6 +- .../platform/transition/transfer_document.rs | 6 +- .../transition/update_price_of_document.rs | 31 +- packages/strategy-tests/src/lib.rs | 101 +-- packages/token-history-contract/.eslintrc | 18 + packages/token-history-contract/.mocharc.yml | 2 + packages/token-history-contract/Cargo.toml | 13 + packages/token-history-contract/LICENSE | 20 + packages/token-history-contract/README.md | 26 + .../token-history-contract/lib/systemIds.js | 4 + packages/token-history-contract/package.json | 29 + .../v1/token-history-contract-documents.json | 363 +++++++++++ packages/token-history-contract/src/error.rs | 17 + packages/token-history-contract/src/lib.rs | 37 ++ packages/token-history-contract/src/v1/mod.rs | 21 + .../token-history-contract/test/.eslintrc | 12 + .../token-history-contract/test/bootstrap.js | 30 + .../test/unit/walletContract.spec.js | 187 ++++++ .../errors/document_already_exists_error.rs | 2 +- .../errors/document_not_provided_error.rs | 2 +- .../errors/invalid_document_action_error.rs | 4 +- packages/wasm-dpp/src/document/factory.rs | 2 +- .../document_create_transition.rs | 2 +- .../document_transition/mod.rs | 11 +- .../document_batch_transition/mod.rs | 49 +- .../state_transition/transition_types.rs | 2 +- .../state_transition_factory.rs | 4 +- 236 files changed, 3842 insertions(+), 1931 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/v0/mod.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_base_transition/document_base_transition_trait.rs (84%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_base_transition/fields.rs (75%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_base_transition/from_document.rs (84%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_base_transition/mod.rs (97%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_base_transition/v0/from_document.rs (77%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_base_transition/v0/mod.rs (98%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_base_transition/v0/v0_methods.rs (94%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_base_transition/v0_methods.rs (87%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_create_transition/convertible.rs (90%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_create_transition/from_document.rs (86%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_create_transition/mod.rs (97%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_create_transition/v0/from_document.rs (84%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_create_transition/v0/mod.rs (97%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_create_transition/v0/v0_methods.rs (87%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_create_transition/v0_methods.rs (81%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_delete_transition/from_document.rs (85%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_delete_transition/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_delete_transition/v0/from_document.rs (69%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_delete_transition/v0/mod.rs (85%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/v0_methods.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_delete_transition/v0_methods.rs (59%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_purchase_transition/from_document.rs (85%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_purchase_transition/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_purchase_transition/v0/from_document.rs (79%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_purchase_transition/v0/mod.rs (90%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_purchase_transition/v0/v0_methods.rs (72%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_purchase_transition/v0_methods.rs (67%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_replace_transition/from_document.rs (79%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_replace_transition/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_replace_transition/v0/from_document.rs (79%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_replace_transition/v0/mod.rs (98%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_replace_transition/v0/v0_methods.rs (81%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_replace_transition/v0_methods.rs (73%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_transfer_transition/from_document.rs (84%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_transfer_transition/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_transfer_transition/v0/from_document.rs (79%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_transfer_transition/v0/mod.rs (92%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_transfer_transition/v0/v0_methods.rs (81%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_transfer_transition/v0_methods.rs (74%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition/mod.rs => batch_transition/batched_transition/document_transition.rs} (58%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_transition_action_type.rs (92%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_update_price_transition/from_document.rs (85%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_update_price_transition/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_update_price_transition/v0/from_document.rs (82%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_update_price_transition/v0/mod.rs (99%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_update_price_transition/v0/v0_methods.rs (77%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/document_update_price_transition/v0_methods.rs (70%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_base_transition/fields.rs (63%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_base_transition/mod.rs (93%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_base_transition/token_base_transition_accessors.rs (84%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_base_transition/v0/mod.rs (81%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_base_transition/v0/v0_methods.rs (76%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_base_transition/v0_methods.rs (67%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_burn_transition/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_burn_transition/v0/mod.rs (89%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_burn_transition/v0/v0_methods.rs (66%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_burn_transition/v0_methods.rs (64%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_issuance_transition/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_issuance_transition/v0/mod.rs (94%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_issuance_transition/v0/v0_methods.rs (65%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_issuance_transition/v0_methods.rs (64%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_transfer_transition/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_transfer_transition/v0/mod.rs (91%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_transfer_transition/v0/v0_methods.rs (81%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_transfer_transition/v0_methods.rs (74%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition/document_transition => batch_transition/batched_transition}/token_transition_action_type.rs (90%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/fields.rs (93%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/identity_signed.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/json_conversion.rs (70%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/methods/mod.rs (65%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/methods/v0/mod.rs (81%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/state_transition_like.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/v0/cbor_conversion.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/v0/identity_signed.rs (83%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/json_conversion.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/v0/mod.rs (86%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/v0/state_transition_like.rs (72%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/v0/types.rs (53%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/v0/v0_methods.rs (78%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/value_conversion.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/v0/version.rs (52%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/identity_signed.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/json_conversion.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/state_transition_like.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/types.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/value_conversion.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/version.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/validation/find_duplicates_by_id/mod.rs (84%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/validation/find_duplicates_by_id/v0/mod.rs (73%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/validation/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/validation/validate_basic_structure/mod.rs (88%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/validation/validate_basic_structure/v0/mod.rs (71%) rename packages/rs-dpp/src/state_transition/state_transitions/document/{documents_batch_transition => batch_transition}/value_conversion.rs (81%) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/version.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/accessors/mod.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/accessors/v0/mod.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/v0_methods.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_methods/mod.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/identity_signed.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/state_transition_like.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/json_conversion.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/value_conversion.rs delete mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/version.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/add_transaction_history/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/add_transaction_history/v0/mod.rs create mode 100644 packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v2.rs create mode 100644 packages/rs-platform-version/src/version/v8.rs create mode 100644 packages/token-history-contract/.eslintrc create mode 100644 packages/token-history-contract/.mocharc.yml create mode 100644 packages/token-history-contract/Cargo.toml create mode 100644 packages/token-history-contract/LICENSE create mode 100644 packages/token-history-contract/README.md create mode 100644 packages/token-history-contract/lib/systemIds.js create mode 100644 packages/token-history-contract/package.json create mode 100644 packages/token-history-contract/schema/v1/token-history-contract-documents.json create mode 100644 packages/token-history-contract/src/error.rs create mode 100644 packages/token-history-contract/src/lib.rs create mode 100644 packages/token-history-contract/src/v1/mod.rs create mode 100644 packages/token-history-contract/test/.eslintrc create mode 100644 packages/token-history-contract/test/bootstrap.js create mode 100644 packages/token-history-contract/test/unit/walletContract.spec.js diff --git a/packages/rs-dpp/src/document/document_factory/mod.rs b/packages/rs-dpp/src/document/document_factory/mod.rs index ec445012e6e..158daf9488f 100644 --- a/packages/rs-dpp/src/document/document_factory/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/mod.rs @@ -13,9 +13,9 @@ use crate::document::Document; #[cfg(feature = "extended-document")] use crate::document::ExtendedDocument; #[cfg(feature = "state-transitions")] -use crate::state_transition::documents_batch_transition::{ - document_transition::document_transition_action_type::DocumentTransitionActionType, - DocumentsBatchTransition, +use crate::state_transition::batch_transition::{ + batched_transition::document_transition_action_type::DocumentTransitionActionType, + BatchTransition, }; use crate::util::entropy_generator::EntropyGenerator; pub use v0::DocumentFactoryV0; @@ -121,7 +121,7 @@ impl DocumentFactory { ), >, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce - ) -> Result { + ) -> Result { match self { DocumentFactory::V0(v0) => v0.create_state_transition(documents_iter, nonce_counter), } diff --git a/packages/rs-dpp/src/document/document_factory/v0/mod.rs b/packages/rs-dpp/src/document/document_factory/v0/mod.rs index c16547b1990..5fa252dc973 100644 --- a/packages/rs-dpp/src/document/document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/document_factory/v0/mod.rs @@ -20,18 +20,20 @@ use crate::document::document_methods::DocumentMethodsV0; #[cfg(feature = "extended-document")] use crate::document::{ extended_document::v0::ExtendedDocumentV0, - serialization_traits::DocumentPlatformConversionMethodsV0, ExtendedDocument, + ExtendedDocument, serialization_traits::DocumentPlatformConversionMethodsV0, }; use crate::prelude::{BlockHeight, CoreBlockHeight, TimestampMillis}; #[cfg(feature = "state-transitions")] -use crate::state_transition::documents_batch_transition::{ - document_transition::{ +use crate::state_transition::batch_transition::{ + batched_transition::{ document_transition_action_type::DocumentTransitionActionType, DocumentCreateTransition, - DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransition, + DocumentDeleteTransition, DocumentReplaceTransition, }, - DocumentsBatchTransition, DocumentsBatchTransitionV0, + BatchTransition, BatchTransitionV0, }; use itertools::Itertools; +#[cfg(feature = "state-transitions")] +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; const PROPERTY_FEATURE_VERSION: &str = "$version"; const PROPERTY_ENTROPY: &str = "$entropy"; @@ -210,7 +212,7 @@ impl DocumentFactoryV0 { ), >, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce - ) -> Result { + ) -> Result { let platform_version = PlatformVersion::get(self.protocol_version)?; let documents: Vec<( DocumentTransitionActionType, @@ -275,7 +277,7 @@ impl DocumentFactoryV0 { return Err(DocumentError::NoDocumentsSuppliedError.into()); } - Ok(DocumentsBatchTransitionV0 { + Ok(BatchTransitionV0 { owner_id, transitions, user_fee_increase: 0, diff --git a/packages/rs-dpp/src/document/errors.rs b/packages/rs-dpp/src/document/errors.rs index d16ca16f1ea..9df0c53b500 100644 --- a/packages/rs-dpp/src/document/errors.rs +++ b/packages/rs-dpp/src/document/errors.rs @@ -6,7 +6,7 @@ use crate::errors::consensus::ConsensusError; use crate::document::accessors::v0::DocumentV0Getters; use crate::document::Document; #[cfg(feature = "state-transitions")] -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; #[derive(Error, Debug)] pub enum DocumentError { diff --git a/packages/rs-dpp/src/document/specialized_document_factory/mod.rs b/packages/rs-dpp/src/document/specialized_document_factory/mod.rs index 80f0bf09994..0d7a25b3dcd 100644 --- a/packages/rs-dpp/src/document/specialized_document_factory/mod.rs +++ b/packages/rs-dpp/src/document/specialized_document_factory/mod.rs @@ -13,9 +13,9 @@ use crate::document::Document; #[cfg(feature = "extended-document")] use crate::document::ExtendedDocument; #[cfg(feature = "state-transitions")] -use crate::state_transition::documents_batch_transition::{ - document_transition::document_transition_action_type::DocumentTransitionActionType, - DocumentsBatchTransition, +use crate::state_transition::batch_transition::{ + batched_transition::document_transition_action_type::DocumentTransitionActionType, + BatchTransition, }; use crate::util::entropy_generator::EntropyGenerator; pub use v0::SpecializedDocumentFactoryV0; @@ -124,7 +124,7 @@ impl SpecializedDocumentFactory { ), >, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce - ) -> Result { + ) -> Result { match self { SpecializedDocumentFactory::V0(v0) => { v0.create_state_transition(documents_iter, nonce_counter) diff --git a/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs b/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs index 99982449130..c89c7e34485 100644 --- a/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs +++ b/packages/rs-dpp/src/document/specialized_document_factory/v0/mod.rs @@ -19,18 +19,20 @@ use crate::data_contract::document_type::methods::DocumentTypeV0Methods; #[cfg(feature = "extended-document")] use crate::document::{ extended_document::v0::ExtendedDocumentV0, - serialization_traits::DocumentPlatformConversionMethodsV0, ExtendedDocument, + ExtendedDocument, serialization_traits::DocumentPlatformConversionMethodsV0, }; use crate::prelude::{BlockHeight, CoreBlockHeight, TimestampMillis}; #[cfg(feature = "state-transitions")] -use crate::state_transition::documents_batch_transition::{ - document_transition::{ +use crate::state_transition::batch_transition::{ + batched_transition::{ document_transition_action_type::DocumentTransitionActionType, DocumentCreateTransition, - DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransition, + DocumentDeleteTransition, DocumentReplaceTransition, }, - DocumentsBatchTransition, DocumentsBatchTransitionV0, + BatchTransition, BatchTransitionV0, }; use itertools::Itertools; +#[cfg(feature = "state-transitions")] +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; const PROPERTY_FEATURE_VERSION: &str = "$version"; const PROPERTY_ENTROPY: &str = "$entropy"; @@ -218,7 +220,7 @@ impl SpecializedDocumentFactoryV0 { ), >, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce - ) -> Result { + ) -> Result { let platform_version = PlatformVersion::get(self.protocol_version)?; let documents: Vec<( DocumentTransitionActionType, @@ -283,7 +285,7 @@ impl SpecializedDocumentFactoryV0 { return Err(DocumentError::NoDocumentsSuppliedError.into()); } - Ok(DocumentsBatchTransitionV0 { + Ok(BatchTransitionV0 { owner_id, transitions, user_fee_increase: 0, diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index cd97cae4ae9..4b4ffed7926 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -1,8 +1,7 @@ use derive_more::From; -use documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use documents_batch_transition::document_transition::DocumentTransition; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; +use state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; pub use abstract_state_transition::state_transition_helpers; @@ -72,19 +71,16 @@ use crate::identity::Purpose; use crate::identity::{IdentityPublicKey, KeyType}; use crate::identity::{KeyID, SecurityLevel}; use crate::prelude::{AssetLockProof, UserFeeIncrease}; -use crate::state_transition::masternode_vote_transition::MasternodeVoteTransitionSignable; -pub use state_transitions::*; - use crate::serialization::Signable; +use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use crate::state_transition::batch_transition::batched_transition::BatchedTransitionRef; +use crate::state_transition::batch_transition::{BatchTransition, BatchTransitionSignable}; use crate::state_transition::data_contract_create_transition::{ DataContractCreateTransition, DataContractCreateTransitionSignable, }; use crate::state_transition::data_contract_update_transition::{ DataContractUpdateTransition, DataContractUpdateTransitionSignable, }; -use crate::state_transition::documents_batch_transition::{ - DocumentsBatchTransition, DocumentsBatchTransitionSignable, -}; #[cfg(feature = "state-transition-signing")] use crate::state_transition::errors::InvalidSignaturePublicKeyError; #[cfg(feature = "state-transition-signing")] @@ -108,11 +104,14 @@ use crate::state_transition::identity_topup_transition::{ use crate::state_transition::identity_update_transition::{ IdentityUpdateTransition, IdentityUpdateTransitionSignable, }; +use crate::state_transition::masternode_vote_transition::MasternodeVoteTransitionSignable; +use state_transitions::document::batch_transition::batched_transition::token_transition::TokenTransition; +pub use state_transitions::*; use crate::state_transition::masternode_vote_transition::MasternodeVoteTransition; #[cfg(feature = "state-transition-signing")] -use crate::state_transition::state_transitions::document::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use crate::state_transition::state_transitions::document::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; pub type GetDataContractSecurityLevelRequirementFn = fn(Identifier, String) -> Result; @@ -122,7 +121,7 @@ macro_rules! call_method { match $state_transition { StateTransition::DataContractCreate(st) => st.$method($args), StateTransition::DataContractUpdate(st) => st.$method($args), - StateTransition::DocumentsBatch(st) => st.$method($args), + StateTransition::Batch(st) => st.$method($args), StateTransition::IdentityCreate(st) => st.$method($args), StateTransition::IdentityTopUp(st) => st.$method($args), StateTransition::IdentityCreditWithdrawal(st) => st.$method($args), @@ -135,7 +134,7 @@ macro_rules! call_method { match $state_transition { StateTransition::DataContractCreate(st) => st.$method(), StateTransition::DataContractUpdate(st) => st.$method(), - StateTransition::DocumentsBatch(st) => st.$method(), + StateTransition::Batch(st) => st.$method(), StateTransition::IdentityCreate(st) => st.$method(), StateTransition::IdentityTopUp(st) => st.$method(), StateTransition::IdentityCreditWithdrawal(st) => st.$method(), @@ -151,7 +150,7 @@ macro_rules! call_getter_method_identity_signed { match $state_transition { StateTransition::DataContractCreate(st) => Some(st.$method($args)), StateTransition::DataContractUpdate(st) => Some(st.$method($args)), - StateTransition::DocumentsBatch(st) => Some(st.$method($args)), + StateTransition::Batch(st) => Some(st.$method($args)), StateTransition::IdentityCreate(_) => None, StateTransition::IdentityTopUp(_) => None, StateTransition::IdentityCreditWithdrawal(st) => Some(st.$method($args)), @@ -164,7 +163,7 @@ macro_rules! call_getter_method_identity_signed { match $state_transition { StateTransition::DataContractCreate(st) => Some(st.$method()), StateTransition::DataContractUpdate(st) => Some(st.$method()), - StateTransition::DocumentsBatch(st) => Some(st.$method()), + StateTransition::Batch(st) => Some(st.$method()), StateTransition::IdentityCreate(_) => None, StateTransition::IdentityTopUp(_) => None, StateTransition::IdentityCreditWithdrawal(st) => Some(st.$method()), @@ -180,7 +179,7 @@ macro_rules! call_method_identity_signed { match $state_transition { StateTransition::DataContractCreate(st) => st.$method($args), StateTransition::DataContractUpdate(st) => st.$method($args), - StateTransition::DocumentsBatch(st) => st.$method($args), + StateTransition::Batch(st) => st.$method($args), StateTransition::IdentityCreate(_st) => {} StateTransition::IdentityTopUp(_st) => {} StateTransition::IdentityCreditWithdrawal(st) => st.$method($args), @@ -193,7 +192,7 @@ macro_rules! call_method_identity_signed { match $state_transition { StateTransition::DataContractCreate(st) => st.$method(), StateTransition::DataContractUpdate(st) => st.$method(), - StateTransition::DocumentsBatch(st) => st.$method(), + StateTransition::Batch(st) => st.$method(), StateTransition::IdentityCreate(st) => {} StateTransition::IdentityTopUp(st) => {} StateTransition::IdentityCreditWithdrawal(st) => st.$method(), @@ -210,7 +209,7 @@ macro_rules! call_errorable_method_identity_signed { match $state_transition { StateTransition::DataContractCreate(st) => st.$method($args), StateTransition::DataContractUpdate(st) => st.$method($args), - StateTransition::DocumentsBatch(st) => st.$method($args), + StateTransition::Batch(st) => st.$method($args), StateTransition::IdentityCreate(_st) => Err(ProtocolError::CorruptedCodeExecution( "identity create can not be called for identity signing".to_string(), )), @@ -227,7 +226,7 @@ macro_rules! call_errorable_method_identity_signed { match $state_transition { StateTransition::DataContractCreate(st) => st.$method(), StateTransition::DataContractUpdate(st) => st.$method(), - StateTransition::DocumentsBatch(st) => st.$method(), + StateTransition::Batch(st) => st.$method(), StateTransition::IdentityCreate(st) => Err(ProtocolError::CorruptedCodeExecution( "identity create can not be called for identity signing".to_string(), )), @@ -284,7 +283,7 @@ macro_rules! call_errorable_method_identity_signed { pub enum StateTransition { DataContractCreate(DataContractCreateTransition), DataContractUpdate(DataContractUpdateTransition), - DocumentsBatch(DocumentsBatchTransition), + Batch(BatchTransition), IdentityCreate(IdentityCreateTransition), IdentityTopUp(IdentityTopUpTransition), IdentityCreditWithdrawal(IdentityCreditWithdrawalTransition), @@ -349,22 +348,31 @@ impl StateTransition { match self { Self::DataContractCreate(_) => "DataContractCreate".to_string(), Self::DataContractUpdate(_) => "DataContractUpdate".to_string(), - Self::DocumentsBatch(documents_batch_transition) => { + Self::Batch(batch_transition) => { let mut document_transition_types = vec![]; - match documents_batch_transition { - DocumentsBatchTransition::V0(documents_batch_transition_v0) => { - for transition in documents_batch_transition_v0.transitions().iter() { - let document_transition_name = match transition { - DocumentTransition::Create(_) => "Create", - DocumentTransition::Replace(_) => "Replace", - DocumentTransition::Delete(_) => "Delete", - DocumentTransition::Transfer(_) => "Transfer", - DocumentTransition::UpdatePrice(_) => "UpdatePrice", - DocumentTransition::Purchase(_) => "Purchase", - }; - document_transition_types.push(document_transition_name); + for transition in batch_transition.transitions_iter() { + let document_transition_name = match transition { + BatchedTransitionRef::Document(DocumentTransition::Create(_)) => "Create", + BatchedTransitionRef::Document(DocumentTransition::Replace(_)) => "Replace", + BatchedTransitionRef::Document(DocumentTransition::Delete(_)) => "Delete", + BatchedTransitionRef::Document(DocumentTransition::Transfer(_)) => { + "Transfer" + } + BatchedTransitionRef::Document(DocumentTransition::UpdatePrice(_)) => { + "UpdatePrice" + } + BatchedTransitionRef::Document(DocumentTransition::Purchase(_)) => { + "Purchase" + } + BatchedTransitionRef::Token(TokenTransition::Transfer(_)) => { + "TokenTransfer" + } + BatchedTransitionRef::Token(TokenTransition::Issuance(_)) => { + "TokenIssuance" } - } + BatchedTransitionRef::Token(TokenTransition::Burn(_)) => "TokenBurn", + }; + document_transition_types.push(document_transition_name); } format!("DocumentsBatch([{}])", document_transition_types.join(", ")) } @@ -452,7 +460,7 @@ impl StateTransition { st.verify_public_key_level_and_purpose(identity_public_key)?; st.verify_public_key_is_enabled(identity_public_key)?; } - StateTransition::DocumentsBatch(st) => { + StateTransition::Batch(st) => { if identity_public_key.purpose() != Purpose::AUTHENTICATION { return Err(ProtocolError::WrongPublicKeyPurposeError( WrongPublicKeyPurposeError::new( diff --git a/packages/rs-dpp/src/state_transition/serialization.rs b/packages/rs-dpp/src/state_transition/serialization.rs index a8ed69101c5..bea1ab72cfd 100644 --- a/packages/rs-dpp/src/state_transition/serialization.rs +++ b/packages/rs-dpp/src/state_transition/serialization.rs @@ -27,9 +27,9 @@ mod tests { use crate::state_transition::data_contract_update_transition::{ DataContractUpdateTransition, DataContractUpdateTransitionV0, }; - use crate::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; - use crate::state_transition::documents_batch_transition::{ - DocumentsBatchTransition, DocumentsBatchTransitionV0, + use crate::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; + use crate::state_transition::batch_transition::{ + BatchTransition, BatchTransitionV0, }; use crate::state_transition::identity_create_transition::v0::IdentityCreateTransitionV0; use crate::state_transition::identity_create_transition::IdentityCreateTransition; @@ -39,7 +39,7 @@ mod tests { use crate::state_transition::public_key_in_creation::accessors::IdentityPublicKeyInCreationV0Setters; use crate::state_transition::StateTransition; use crate::tests::fixtures::{ - get_data_contract_fixture, get_document_transitions_fixture, + get_data_contract_fixture, get_batched_transitions_fixture, get_extended_documents_fixture_with_owner_id_from_contract, raw_instant_asset_lock_proof_fixture, }; @@ -338,11 +338,11 @@ mod tests { ) }) .collect::>(); - let transitions = get_document_transitions_fixture( + let transitions = get_batched_transitions_fixture( [(DocumentTransitionActionType::Create, documents)], &mut nonces, ); - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + let documents_batch_transition: BatchTransition = BatchTransitionV0 { owner_id: data_contract.owner_id(), transitions, ..Default::default() diff --git a/packages/rs-dpp/src/state_transition/state_transition_types.rs b/packages/rs-dpp/src/state_transition/state_transition_types.rs index 246f4620631..574d18521ab 100644 --- a/packages/rs-dpp/src/state_transition/state_transition_types.rs +++ b/packages/rs-dpp/src/state_transition/state_transition_types.rs @@ -21,7 +21,7 @@ use serde_repr::{Deserialize_repr, Serialize_repr}; pub enum StateTransitionType { #[default] DataContractCreate = 0, - DocumentsBatch = 1, + Batch = 1, IdentityCreate = 2, IdentityTopUp = 3, DataContractUpdate = 4, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs new file mode 100644 index 00000000000..f085488fc08 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs @@ -0,0 +1,85 @@ +mod v0; + +use std::slice::Iter; +use crate::state_transition::batch_transition::batched_transition::{BatchedTransition, BatchedTransitionRef}; +use crate::state_transition::batch_transition::BatchTransition; +pub use v0::*; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; + +/// Iterator enum for `BatchTransition` that can handle both V0 and V1. +pub enum DocumentBatchIterator<'a> { + V0(Iter<'a, DocumentTransition>), + V1(DocumentBatchV1Iterator<'a>), +} + +/// Iterator for version 1, yielding `BatchedTransitionRef<'a>` items. +pub struct DocumentBatchV1Iterator<'a> { + pub(crate) inner: Iter<'a, BatchedTransition>, +} + +impl<'a> Iterator for DocumentBatchV1Iterator<'a> { + type Item = BatchedTransitionRef<'a>; + + fn next(&mut self) -> Option { + self.inner + .next() + .map(|batched_transition| match batched_transition { + BatchedTransition::Document(doc) => BatchedTransitionRef::Document(doc), + BatchedTransition::Token(tok) => BatchedTransitionRef::Token(tok), + }) + } +} + +impl<'a> Iterator for DocumentBatchIterator<'a> { + type Item = BatchedTransitionRef<'a>; + + fn next(&mut self) -> Option { + match self { + DocumentBatchIterator::V0(iter) => iter.next().map(BatchedTransitionRef::Document), + DocumentBatchIterator::V1(iter) => iter.next(), + } + } +} + +impl DocumentsBatchTransitionAccessorsV0 for BatchTransition { + type IterType<'a> = DocumentBatchIterator<'a> + where + Self: 'a; + + /// Iterator for `BatchedTransitionRef` items. + fn transitions_iter<'a>(&'a self) -> Self::IterType<'a> { + match self { + BatchTransition::V0(v0) => DocumentBatchIterator::V0(v0.transitions.iter()), + BatchTransition::V1(v1) => DocumentBatchIterator::V1(DocumentBatchV1Iterator { + inner: v1.transitions.iter(), + }), + } + } + + fn transitions_len(&self) -> usize { + match self { + BatchTransition::V0(v0) => v0.transitions.len(), + BatchTransition::V1(v1) => v1.transitions.len(), + } + } + + fn transitions_are_empty(&self) -> bool { + match self { + BatchTransition::V0(v0) => v0.transitions.is_empty(), + BatchTransition::V1(v1) => v1.transitions.is_empty(), + } + } + + fn first_transition(&self) -> Option { + match self { + BatchTransition::V0(v0) => v0 + .transitions + .first() + .map(|document_transition| BatchedTransitionRef::Document(document_transition)), + BatchTransition::V1(v1) => v1 + .transitions + .first() + .map(|batch_transition| batch_transition.borrow_as_ref()), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/v0/mod.rs new file mode 100644 index 00000000000..267a95bff65 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/v0/mod.rs @@ -0,0 +1,15 @@ +use crate::state_transition::batch_transition::batched_transition::BatchedTransitionRef; +pub trait DocumentsBatchTransitionAccessorsV0 { + /// Associated type for the iterator. + type IterType<'a>: Iterator> + where + Self: 'a; + + /// Returns an iterator over the `BatchedTransitionRef` items. + fn transitions_iter<'a>(&'a self) -> Self::IterType<'a>; + + fn transitions_len(&self) -> usize; + fn transitions_are_empty(&self) -> bool; + + fn first_transition(&self) -> Option; +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/document_base_transition_trait.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/document_base_transition_trait.rs similarity index 84% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/document_base_transition_trait.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/document_base_transition_trait.rs index efaed10f74d..d9344985342 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/document_base_transition_trait.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/document_base_transition_trait.rs @@ -1,4 +1,4 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; pub trait DocumentBaseTransitionAccessors { /// Returns a reference to the `base` field of the `DocumentCreateTransitionV0`. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/fields.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/fields.rs similarity index 75% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/fields.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/fields.rs index b7e0135ed04..df730f10f96 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/fields.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/fields.rs @@ -1,4 +1,4 @@ -pub(in crate::state_transition::state_transitions::document::documents_batch_transition) mod property_names { +pub(in crate::state_transition::state_transitions::document::batch_transition) mod property_names { pub const ID: &str = "$id"; pub const DATA_CONTRACT_ID: &str = "$dataContractId"; pub const DOCUMENT_TYPE: &str = "$type"; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/from_document.rs similarity index 84% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/from_document.rs index e500bbd5bd5..88c136d585c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/from_document.rs @@ -1,8 +1,8 @@ use crate::data_contract::document_type::DocumentTypeRef; use crate::document::Document; use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::ProtocolError; use platform_version::version::{FeatureVersion, PlatformVersion}; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/mod.rs similarity index 97% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/mod.rs index 3ff9b50f21a..d430a12ba79 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/mod.rs @@ -9,7 +9,7 @@ mod v0_methods; feature = "state-transition-json-conversion" ))] use crate::data_contract::DataContract; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::{ +use crate::state_transition::batch_transition::document_base_transition::v0::{ DocumentBaseTransitionV0, DocumentTransitionObjectLike, }; #[cfg(any( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/from_document.rs similarity index 77% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/from_document.rs index 7d3e6ef348b..b067edad06d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/from_document.rs @@ -2,10 +2,10 @@ use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::document_type::DocumentTypeRef; use crate::document::{Document, DocumentV0Getters}; use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; impl DocumentBaseTransitionV0 { - pub(in crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_base_transition) fn from_document( + pub(in crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_base_transition) fn from_document( document: &Document, document_type: DocumentTypeRef, identity_contract_nonce: IdentityNonce, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/mod.rs similarity index 98% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/mod.rs index f5b245bece7..9477075d480 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/mod.rs @@ -21,7 +21,7 @@ use crate::data_contract::accessors::v0::DataContractV0Getters; use crate::identifier::Identifier; use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::document_base_transition::property_names; +use crate::state_transition::batch_transition::document_base_transition::property_names; #[cfg(any( feature = "state-transition-json-conversion", feature = "state-transition-value-conversion" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/v0_methods.rs similarity index 94% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/v0_methods.rs index c332648a547..f3c6beb7ee1 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0/v0_methods.rs @@ -1,4 +1,4 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; use crate::prelude::IdentityNonce; use platform_value::Identifier; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0_methods.rs similarity index 87% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0_methods.rs index c7a543b5551..053865b0568 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_base_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_base_transition/v0_methods.rs @@ -1,6 +1,6 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use crate::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::prelude::IdentityNonce; use platform_value::Identifier; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/convertible.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/convertible.rs similarity index 90% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/convertible.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/convertible.rs index bca79958bad..b1d5a81ed0e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/convertible.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/convertible.rs @@ -7,24 +7,24 @@ use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; feature = "state-transition-value-conversion" ))] use crate::prelude::DataContract; -#[cfg(feature = "state-transition-json-conversion")] -use crate::state_transition::data_contract_update_transition::IDENTIFIER_FIELDS; #[cfg(any( feature = "state-transition-json-conversion", feature = "state-transition-value-conversion" ))] -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; +use crate::state_transition::batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; #[cfg(feature = "state-transition-json-conversion")] -use crate::state_transition::documents_batch_transition::document_create_transition::v0::BINARY_FIELDS; +use crate::state_transition::batch_transition::document_create_transition::v0::BINARY_FIELDS; #[cfg(any( feature = "state-transition-json-conversion", feature = "state-transition-value-conversion" ))] -use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransition; +use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransition; #[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransitionV0; +use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransitionV0; #[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::fields::property_names::STATE_TRANSITION_PROTOCOL_VERSION; +use crate::state_transition::batch_transition::fields::property_names::STATE_TRANSITION_PROTOCOL_VERSION; +#[cfg(feature = "state-transition-json-conversion")] +use crate::state_transition::data_contract_update_transition::IDENTIFIER_FIELDS; #[cfg(any( feature = "state-transition-json-conversion", feature = "state-transition-value-conversion" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/from_document.rs similarity index 86% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/from_document.rs index e275f726479..7ade005e6cf 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/from_document.rs @@ -1,8 +1,8 @@ use crate::data_contract::document_type::DocumentTypeRef; use crate::document::Document; use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransitionV0; -use crate::state_transition::documents_batch_transition::document_transition::DocumentCreateTransition; +use crate::state_transition::batch_transition::batched_transition::DocumentCreateTransition; +use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransitionV0; use crate::ProtocolError; use platform_version::version::{FeatureVersion, PlatformVersion}; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/mod.rs similarity index 97% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/mod.rs index cde6d5ae296..dfc46828724 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/mod.rs @@ -6,7 +6,7 @@ mod v0_methods; use crate::block::block_info::BlockInfo; use crate::data_contract::document_type::DocumentTypeRef; use crate::document::Document; -use crate::state_transition::documents_batch_transition::document_create_transition::v0::DocumentFromCreateTransitionV0; +use crate::state_transition::batch_transition::document_create_transition::v0::DocumentFromCreateTransitionV0; use crate::ProtocolError; use bincode::{Decode, Encode}; use derive_more::{Display, From}; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/from_document.rs similarity index 84% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/from_document.rs index 3132a4ba07f..633c72ffccd 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/from_document.rs @@ -2,8 +2,8 @@ use crate::data_contract::document_type::methods::DocumentTypeV0Methods; use crate::data_contract::document_type::DocumentTypeRef; use crate::document::{Document, DocumentV0Getters}; use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransitionV0; use crate::ProtocolError; use platform_version::version::{FeatureVersion, PlatformVersion}; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/mod.rs similarity index 97% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/mod.rs index 53f9d4cf538..7296c503821 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/mod.rs @@ -24,17 +24,17 @@ use crate::data_contract::document_type::methods::DocumentTypeV0Methods; use crate::data_contract::document_type::DocumentTypeRef; use crate::document::{Document, DocumentV0}; use crate::fee::Credits; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; #[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use derive_more::Display; #[cfg(feature = "state-transition-value-conversion")] use platform_value::btreemap_extensions::BTreeValueRemoveTupleFromMapHelper; use platform_version::version::PlatformVersion; #[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition; +use crate::state_transition::batch_transition; mod property_names { pub const ENTROPY: &str = "$entropy"; @@ -86,7 +86,9 @@ impl DocumentCreateTransitionV0 { data_contract: DataContract, ) -> Result { let identity_contract_nonce = map - .remove_integer(documents_batch_transition::document_base_transition::property_names::IDENTITY_CONTRACT_NONCE) + .remove_integer( + batch_transition::document_base_transition::property_names::IDENTITY_CONTRACT_NONCE, + ) .map_err(ProtocolError::ValueError)?; Ok(Self { base: DocumentBaseTransition::V0(DocumentBaseTransitionV0::from_value_map_consume( @@ -387,7 +389,7 @@ impl DocumentFromCreateTransitionV0 for Document { #[cfg(test)] mod test { use crate::data_contract::v0::DataContractV0; - use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransition; + use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransition; use platform_value::btreemap_extensions::BTreeValueMapHelper; use platform_value::{platform_value, BinaryData, Bytes32, Identifier}; use platform_version::version::LATEST_PLATFORM_VERSION; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/v0_methods.rs similarity index 87% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/v0_methods.rs index 07850ab77aa..e19bcb8ec8b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0/v0_methods.rs @@ -1,11 +1,11 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransitionV0; use platform_value::Value; use crate::fee::Credits; use std::collections::BTreeMap; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; pub trait DocumentCreateTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `entropy` field of the `DocumentCreateTransitionV0`. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0_methods.rs similarity index 81% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0_methods.rs index 9c959ffd429..da248d53934 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_create_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_create_transition/v0_methods.rs @@ -1,10 +1,10 @@ use std::collections::BTreeMap; use platform_value::{Value}; use crate::fee::Credits; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransition; -use crate::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransition; +use crate::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; impl DocumentBaseTransitionAccessors for DocumentCreateTransition { fn base(&self) -> &DocumentBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/from_document.rs similarity index 85% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/from_document.rs index 3c6dfa6b80a..a3eafe8c329 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/from_document.rs @@ -4,8 +4,8 @@ use crate::prelude::IdentityNonce; use crate::ProtocolError; use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::state_transition::documents_batch_transition::document_transition::{DocumentDeleteTransition}; -use crate::state_transition::documents_batch_transition::document_transition::document_delete_transition::DocumentDeleteTransitionV0; +use crate::state_transition::batch_transition::batched_transition::document_delete_transition::DocumentDeleteTransitionV0; +use crate::state_transition::batch_transition::batched_transition::DocumentDeleteTransition; impl DocumentDeleteTransition { pub fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/from_document.rs similarity index 69% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/from_document.rs index 4fac1aff9f4..9a939350289 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/from_document.rs @@ -1,10 +1,10 @@ -use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::data_contract::document_type::{DocumentTypeRef}; -use crate::document::{Document}; +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::Document; use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::document_delete_transition::DocumentDeleteTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_delete_transition::DocumentDeleteTransitionV0; +use platform_version::version::{FeatureVersion, PlatformVersion}; impl DocumentDeleteTransitionV0 { pub(crate) fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/mod.rs similarity index 85% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/mod.rs index 34d4ac98554..633c7d83818 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/mod.rs @@ -1,7 +1,7 @@ mod from_document; pub mod v0_methods; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use bincode::{Decode, Encode}; use derive_more::Display; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..861334a6027 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0/v0_methods.rs @@ -0,0 +1,17 @@ +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_delete_transition::DocumentDeleteTransitionV0; + +impl DocumentBaseTransitionAccessors for DocumentDeleteTransitionV0 { + fn base(&self) -> &DocumentBaseTransition { + &self.base + } + + fn base_mut(&mut self) -> &mut DocumentBaseTransition { + &mut self.base + } + + fn set_base(&mut self, base: DocumentBaseTransition) { + self.base = base + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0_methods.rs similarity index 59% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0_methods.rs index 20618a4a6bc..8fd1b1f31cf 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_delete_transition/v0_methods.rs @@ -1,6 +1,6 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::DocumentDeleteTransition; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::DocumentDeleteTransition; impl DocumentBaseTransitionAccessors for DocumentDeleteTransition { fn base(&self) -> &DocumentBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/from_document.rs similarity index 85% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/from_document.rs index d4b913405f0..b7f24dc3d1e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/from_document.rs @@ -5,8 +5,8 @@ use crate::prelude::IdentityNonce; use crate::ProtocolError; use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::state_transition::documents_batch_transition::document_transition::{DocumentPurchaseTransition}; -use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::DocumentPurchaseTransitionV0; +use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::DocumentPurchaseTransitionV0; +use crate::state_transition::batch_transition::batched_transition::DocumentPurchaseTransition; impl DocumentPurchaseTransition { pub fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/from_document.rs similarity index 79% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/from_document.rs index 80bfc2115c5..9c2eb59f76e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/from_document.rs @@ -1,12 +1,12 @@ -use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::data_contract::document_type::{DocumentTypeRef}; -use crate::document::{Document, DocumentV0Getters}; +use crate::data_contract::document_type::DocumentTypeRef; use crate::document::errors::DocumentError; +use crate::document::{Document, DocumentV0Getters}; use crate::fee::Credits; use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::DocumentPurchaseTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::DocumentPurchaseTransitionV0; +use platform_version::version::{FeatureVersion, PlatformVersion}; impl DocumentPurchaseTransitionV0 { pub(crate) fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/mod.rs similarity index 90% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/mod.rs index 5a4ca1e8ba4..3b798177be8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/mod.rs @@ -1,7 +1,7 @@ mod from_document; pub mod v0_methods; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use bincode::{Decode, Encode}; use derive_more::Display; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/v0_methods.rs similarity index 72% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/v0_methods.rs index 33df1517da9..41f6b423aff 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0/v0_methods.rs @@ -1,8 +1,8 @@ use crate::fee::Credits; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::DocumentPurchaseTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::DocumentPurchaseTransitionV0; pub trait DocumentPurchaseTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0_methods.rs similarity index 67% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0_methods.rs index 0bb3fc04d16..8918323373d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_purchase_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_purchase_transition/v0_methods.rs @@ -1,9 +1,9 @@ use crate::fee::Credits; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::DocumentPurchaseTransition; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::DocumentPurchaseTransition; impl DocumentBaseTransitionAccessors for DocumentPurchaseTransition { fn base(&self) -> &DocumentBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/from_document.rs similarity index 79% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/from_document.rs index 059da81c223..1d2923a1f34 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/from_document.rs @@ -1,10 +1,10 @@ -use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::data_contract::document_type::{DocumentTypeRef}; -use crate::document::{Document}; +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::Document; use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; +use crate::state_transition::batch_transition::batched_transition::DocumentReplaceTransition; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_transition::{DocumentReplaceTransition}; -use crate::state_transition::documents_batch_transition::document_transition::document_replace_transition::DocumentReplaceTransitionV0; +use platform_version::version::{FeatureVersion, PlatformVersion}; impl DocumentReplaceTransition { pub fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/from_document.rs similarity index 79% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/from_document.rs index 5fbd783eb67..4b5903c87ab 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/from_document.rs @@ -1,11 +1,11 @@ -use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::data_contract::document_type::{DocumentTypeRef}; -use crate::document::{Document, DocumentV0Getters}; +use crate::data_contract::document_type::DocumentTypeRef; use crate::document::errors::DocumentError; +use crate::document::{Document, DocumentV0Getters}; use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_replace_transition::DocumentReplaceTransitionV0; +use platform_version::version::{FeatureVersion, PlatformVersion}; impl DocumentReplaceTransitionV0 { pub(crate) fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/mod.rs similarity index 98% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/mod.rs index 13833cabaf7..1aae0624bfe 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/mod.rs @@ -18,8 +18,8 @@ use platform_version::version::PlatformVersion; use std::collections::BTreeMap; pub use super::super::document_base_transition::IDENTIFIER_FIELDS; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; mod property_names { pub const REVISION: &str = "$revision"; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/v0_methods.rs similarity index 81% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/v0_methods.rs index 034b6c4e275..61dec36af22 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0/v0_methods.rs @@ -3,9 +3,9 @@ use platform_value::Value; use std::collections::BTreeMap; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_replace_transition::DocumentReplaceTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; pub trait DocumentReplaceTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0_methods.rs similarity index 73% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0_methods.rs index 21993559c73..ad52fdadd07 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_replace_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_replace_transition/v0_methods.rs @@ -1,10 +1,10 @@ use std::collections::BTreeMap; use platform_value::Value; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::DocumentReplaceTransition; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::DocumentReplaceTransition; impl DocumentBaseTransitionAccessors for DocumentReplaceTransition { fn base(&self) -> &DocumentBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/from_document.rs similarity index 84% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/from_document.rs index abfbf806df5..17d0166f09f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/from_document.rs @@ -1,10 +1,12 @@ -use platform_value::Identifier; -use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::data_contract::document_type::{DocumentTypeRef}; -use crate::document::{Document}; +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::Document; use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::document_transfer_transition::{ + DocumentTransferTransition, DocumentTransferTransitionV0, +}; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_transition::document_transfer_transition::{DocumentTransferTransition, DocumentTransferTransitionV0}; +use platform_value::Identifier; +use platform_version::version::{FeatureVersion, PlatformVersion}; impl DocumentTransferTransition { pub fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/from_document.rs similarity index 79% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/from_document.rs index 77a4d59c6d3..7f182eb46a6 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/from_document.rs @@ -1,12 +1,12 @@ -use platform_value::Identifier; -use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::data_contract::document_type::{DocumentTypeRef}; -use crate::document::{Document, DocumentV0Getters}; +use crate::data_contract::document_type::DocumentTypeRef; use crate::document::errors::DocumentError; +use crate::document::{Document, DocumentV0Getters}; use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::document_transfer_transition::DocumentTransferTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_transfer_transition::DocumentTransferTransitionV0; +use platform_value::Identifier; +use platform_version::version::{FeatureVersion, PlatformVersion}; impl DocumentTransferTransitionV0 { pub(crate) fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/mod.rs similarity index 92% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/mod.rs index 3708794cf7d..d8a7e7e41fb 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/mod.rs @@ -10,7 +10,7 @@ use platform_value::Identifier; use serde::{Deserialize, Serialize}; pub use super::super::document_base_transition::IDENTIFIER_FIELDS; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; mod property_names { pub const REVISION: &str = "$revision"; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/v0_methods.rs similarity index 81% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/v0_methods.rs index 7d490ecbad8..2dd4b95d4e5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0/v0_methods.rs @@ -1,9 +1,9 @@ use platform_value::Identifier; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_transfer_transition::DocumentTransferTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_transfer_transition::DocumentTransferTransitionV0; pub trait DocumentTransferTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0_methods.rs similarity index 74% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0_methods.rs index 09f1c74da30..e4dc722b788 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transfer_transition/v0_methods.rs @@ -1,9 +1,9 @@ use platform_value::Identifier; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::DocumentTransferTransition; impl DocumentBaseTransitionAccessors for DocumentTransferTransition { fn base(&self) -> &DocumentBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs similarity index 58% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs index 92ee2015e97..eae1a4790f8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs @@ -1,49 +1,21 @@ +use platform_value::{Identifier, Value}; use std::collections::BTreeMap; - -use bincode::{Decode, Encode}; -use derive_more::From; +use derive_more::{Display, From}; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; - -use crate::prelude::{Identifier, IdentityNonce}; -use document_base_transition::DocumentBaseTransition; - -pub mod document_base_transition; -pub mod document_create_transition; -pub mod document_delete_transition; -pub mod document_purchase_transition; -pub mod document_replace_transition; -pub mod document_transfer_transition; -pub mod document_transition_action_type; -pub mod document_update_price_transition; -pub mod token_base_transition; -pub mod token_burn_transition; -pub mod token_issuance_transition; -pub mod token_transfer_transition; -pub mod token_transition_action_type; - -use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use derive_more::Display; -pub use document_create_transition::DocumentCreateTransition; -pub use document_delete_transition::DocumentDeleteTransition; -pub use document_replace_transition::DocumentReplaceTransition; -pub use document_transfer_transition::DocumentTransferTransition; -pub use document_purchase_transition::DocumentPurchaseTransition; -pub use document_update_price_transition::DocumentUpdatePriceTransition; -use platform_value::Value; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; -use crate::state_transition::documents_batch_transition::{TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition}; -use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::documents_batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; -use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; -use crate::state_transition::state_transitions::document::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; - -pub const PROPERTY_ACTION: &str = "$action"; +use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use crate::prelude::{IdentityNonce, Revision}; +use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition}; +use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition}; +use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use crate::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use crate::state_transition::batch_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; +use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; #[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] #[cfg_attr( @@ -70,15 +42,15 @@ pub enum DocumentTransition { Purchase(DocumentPurchaseTransition), } -impl DocumentTransition { - pub fn as_transition_create(&self) -> Option<&DocumentCreateTransition> { +impl BatchTransitionResolversV0 for DocumentTransition { + fn as_transition_create(&self) -> Option<&DocumentCreateTransition> { if let Self::Create(ref t) = self { Some(t) } else { None } } - pub fn as_transition_replace(&self) -> Option<&DocumentReplaceTransition> { + fn as_transition_replace(&self) -> Option<&DocumentReplaceTransition> { if let Self::Replace(ref t) = self { Some(t) } else { @@ -86,7 +58,7 @@ impl DocumentTransition { } } - pub fn as_transition_delete(&self) -> Option<&DocumentDeleteTransition> { + fn as_transition_delete(&self) -> Option<&DocumentDeleteTransition> { if let Self::Delete(ref t) = self { Some(t) } else { @@ -94,7 +66,7 @@ impl DocumentTransition { } } - pub fn as_transition_transfer(&self) -> Option<&DocumentTransferTransition> { + fn as_transition_transfer(&self) -> Option<&DocumentTransferTransition> { if let Self::Transfer(ref t) = self { Some(t) } else { @@ -102,13 +74,25 @@ impl DocumentTransition { } } - pub fn as_transition_purchase(&self) -> Option<&DocumentPurchaseTransition> { + fn as_transition_purchase(&self) -> Option<&DocumentPurchaseTransition> { if let Self::Purchase(ref t) = self { Some(t) } else { None } } + + fn as_transition_token_burn(&self) -> Option<&TokenBurnTransition> { + None + } + + fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { + None + } + + fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition> { + None + } } pub trait DocumentTransitionV0Methods { @@ -280,104 +264,3 @@ impl DocumentTransitionV0Methods for DocumentTransition { } } } - -#[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] -#[cfg_attr( - feature = "state-transition-serde-conversion", - derive(Serialize, Deserialize) -)] -pub enum TokenTransition { - #[display("TokenBurnTransition({})", "_0")] - Burn(TokenBurnTransition), - - #[display("TokenIssuanceTransition({})", "_0")] - Issuance(TokenIssuanceTransition), - - #[display("TokenTransferTransition({})", "_0")] - Transfer(TokenTransferTransition), -} - -impl TokenTransition { - pub fn as_transition_burn(&self) -> Option<&TokenBurnTransition> { - if let Self::Burn(ref t) = self { - Some(t) - } else { - None - } - } - pub fn as_transition_issuance(&self) -> Option<&TokenIssuanceTransition> { - if let Self::Issuance(ref t) = self { - Some(t) - } else { - None - } - } - - pub fn as_transition_transfer(&self) -> Option<&TokenTransferTransition> { - if let Self::Transfer(ref t) = self { - Some(t) - } else { - None - } - } -} - -pub trait TokenTransitionV0Methods { - fn base(&self) -> &TokenBaseTransition; - fn base_mut(&mut self) -> &mut TokenBaseTransition; - /// get the data contract id - fn data_contract_id(&self) -> Identifier; - /// set data contract's ID - fn set_data_contract_id(&mut self, id: Identifier); - - /// get the identity contract nonce - fn identity_contract_nonce(&self) -> IdentityNonce; - /// sets identity contract nonce - fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce); -} - -impl TokenTransitionV0Methods for TokenTransition { - fn base(&self) -> &TokenBaseTransition { - match self { - TokenTransition::Burn(t) => t.base(), - TokenTransition::Issuance(t) => t.base(), - TokenTransition::Transfer(t) => t.base(), - } - } - - fn base_mut(&mut self) -> &mut TokenBaseTransition { - match self { - TokenTransition::Burn(t) => t.base_mut(), - TokenTransition::Issuance(t) => t.base_mut(), - TokenTransition::Transfer(t) => t.base_mut(), - } - } - - fn data_contract_id(&self) -> Identifier { - self.base().data_contract_id() - } - - fn set_data_contract_id(&mut self, id: Identifier) { - self.base_mut().set_data_contract_id(id); - } - - fn identity_contract_nonce(&self) -> IdentityNonce { - self.base().identity_contract_nonce() - } - - fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce) { - self.base_mut().set_identity_contract_nonce(nonce); - } -} - -#[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] -#[cfg_attr( - feature = "state-transition-serde-conversion", - derive(Serialize, Deserialize) -)] -pub enum BatchedTransition { - #[display("DocumentTransition({})", "_0")] - Document(DocumentTransition), - #[display("TokenTransition({})", "_0")] - Token(TokenTransition), -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs similarity index 92% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs index 7a2c30b237e..f86026f6964 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs @@ -1,4 +1,4 @@ -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; use crate::ProtocolError; // @append-only diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/from_document.rs similarity index 85% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/from_document.rs index 4f26ff90bd7..39e2877d601 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/from_document.rs @@ -4,8 +4,8 @@ use crate::document::{Document}; use crate::fee::Credits; use crate::prelude::IdentityNonce; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_transition::DocumentUpdatePriceTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; +use crate::state_transition::batch_transition::batched_transition::DocumentUpdatePriceTransition; +use crate::state_transition::batch_transition::batched_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; impl DocumentUpdatePriceTransition { pub fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/from_document.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/from_document.rs similarity index 82% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/from_document.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/from_document.rs index 570a3fb5610..2a6c7785872 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/from_document.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/from_document.rs @@ -5,8 +5,8 @@ use crate::document::errors::DocumentError; use crate::fee::Credits; use crate::prelude::IdentityNonce; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; impl DocumentUpdatePriceTransitionV0 { pub(crate) fn from_document( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/mod.rs similarity index 99% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/mod.rs index 8e264bba978..fbca7eb6773 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/mod.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use crate::fee::Credits; pub use super::super::document_base_transition::IDENTIFIER_FIELDS; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; mod property_names { pub const REVISION: &str = "$revision"; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/v0_methods.rs similarity index 77% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/v0_methods.rs index 32e87609160..aa96cdc5ccb 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0/v0_methods.rs @@ -1,8 +1,8 @@ use crate::fee::Credits; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; pub trait DocumentUpdatePriceTransitionV0Methods: DocumentBaseTransitionAccessors { /// Returns a reference to the `revision` field of the `DocumentUpdatePriceTransitionV0`. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0_methods.rs similarity index 70% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0_methods.rs index 3beeecbbd3e..bc97724dfcb 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_update_price_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_update_price_transition/v0_methods.rs @@ -1,9 +1,9 @@ use crate::fee::Credits; use crate::prelude::Revision; -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::DocumentUpdatePriceTransition; +use crate::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use crate::state_transition::batch_transition::batched_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::DocumentUpdatePriceTransition; impl DocumentBaseTransitionAccessors for DocumentUpdatePriceTransition { fn base(&self) -> &DocumentBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs new file mode 100644 index 00000000000..9fe8956639c --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs @@ -0,0 +1,93 @@ +use bincode::{Decode, Encode}; +use derive_more::From; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +pub mod document_base_transition; +pub mod document_create_transition; +pub mod document_delete_transition; +pub mod document_purchase_transition; +pub mod document_replace_transition; +pub mod document_transfer_transition; +pub mod document_transition; +pub mod document_transition_action_type; +pub mod document_update_price_transition; +mod resolvers; +pub mod token_base_transition; +pub mod token_burn_transition; +pub mod token_issuance_transition; +pub mod token_transfer_transition; +pub mod token_transition; +pub mod token_transition_action_type; + +use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::token_transition::TokenTransitionV0Methods; +use derive_more::Display; +pub use document_create_transition::DocumentCreateTransition; +pub use document_delete_transition::DocumentDeleteTransition; +pub use document_purchase_transition::DocumentPurchaseTransition; +pub use document_replace_transition::DocumentReplaceTransition; +pub use document_transfer_transition::DocumentTransferTransition; +use document_transition::DocumentTransition; +pub use document_update_price_transition::DocumentUpdatePriceTransition; +use token_transition::TokenTransition; + +pub const PROPERTY_ACTION: &str = "$action"; + +#[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum BatchedTransition { + #[display("DocumentTransition({})", "_0")] + Document(DocumentTransition), + #[display("TokenTransition({})", "_0")] + Token(TokenTransition), +} + +#[derive(Debug, From, Clone, Copy, PartialEq, Display)] +pub enum BatchedTransitionRef<'a> { + #[display("DocumentTransition({})", "_0")] + Document(&'a DocumentTransition), + #[display("TokenTransition({})", "_0")] + Token(&'a TokenTransition), +} + +impl<'a> BatchedTransitionRef<'a> { + pub fn to_owned_transition(&self) -> BatchedTransition { + match self { + BatchedTransitionRef::Document(doc_ref) => { + BatchedTransition::Document((*doc_ref).clone()) + } + BatchedTransitionRef::Token(tok_ref) => BatchedTransition::Token((*tok_ref).clone()), + } + } +} + +impl BatchedTransition { + pub fn borrow_as_ref(&self) -> BatchedTransitionRef { + match self { + BatchedTransition::Document(doc) => { + // Create a reference to a DocumentTransition + BatchedTransitionRef::Document(doc) + } + BatchedTransition::Token(tok) => { + // Create a reference to a TokenTransition + BatchedTransitionRef::Token(tok) + } + } + } + + pub fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce) { + match self { + BatchedTransition::Document(document_transition) => { + document_transition.set_identity_contract_nonce(identity_contract_nonce) + } + BatchedTransition::Token(token_transition) => { + token_transition.set_identity_contract_nonce(identity_contract_nonce) + } + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs new file mode 100644 index 00000000000..fde56d9f9e9 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs @@ -0,0 +1,124 @@ +use crate::state_transition::batch_transition::batched_transition::{ + BatchedTransition, BatchedTransitionRef, DocumentPurchaseTransition, DocumentTransferTransition, +}; +use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; +use crate::state_transition::batch_transition::{ + DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, + TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition, +}; + +impl BatchTransitionResolversV0 for BatchedTransition { + fn as_transition_create(&self) -> Option<&DocumentCreateTransition> { + match self { + BatchedTransition::Document(document) => document.as_transition_create(), + BatchedTransition::Token(_) => None, + } + } + + fn as_transition_replace(&self) -> Option<&DocumentReplaceTransition> { + match self { + BatchedTransition::Document(document) => document.as_transition_replace(), + BatchedTransition::Token(_) => None, + } + } + + fn as_transition_delete(&self) -> Option<&DocumentDeleteTransition> { + match self { + BatchedTransition::Document(document) => document.as_transition_delete(), + BatchedTransition::Token(_) => None, + } + } + + fn as_transition_transfer(&self) -> Option<&DocumentTransferTransition> { + match self { + BatchedTransition::Document(document) => document.as_transition_transfer(), + BatchedTransition::Token(_) => None, + } + } + + fn as_transition_purchase(&self) -> Option<&DocumentPurchaseTransition> { + match self { + BatchedTransition::Document(document) => document.as_transition_purchase(), + BatchedTransition::Token(_) => None, + } + } + + fn as_transition_token_burn(&self) -> Option<&TokenBurnTransition> { + match self { + BatchedTransition::Document(_) => None, + BatchedTransition::Token(token) => token.as_transition_token_burn(), + } + } + + fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { + match self { + BatchedTransition::Document(_) => None, + BatchedTransition::Token(token) => token.as_transition_token_issuance(), + } + } + + fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition> { + match self { + BatchedTransition::Document(_) => None, + BatchedTransition::Token(token) => token.as_transition_token_transfer(), + } + } +} + +impl<'a> BatchTransitionResolversV0 for BatchedTransitionRef<'a> { + fn as_transition_create(&self) -> Option<&DocumentCreateTransition> { + match self { + BatchedTransitionRef::Document(document) => document.as_transition_create(), + BatchedTransitionRef::Token(_) => None, + } + } + + fn as_transition_replace(&self) -> Option<&DocumentReplaceTransition> { + match self { + BatchedTransitionRef::Document(document) => document.as_transition_replace(), + BatchedTransitionRef::Token(_) => None, + } + } + + fn as_transition_delete(&self) -> Option<&DocumentDeleteTransition> { + match self { + BatchedTransitionRef::Document(document) => document.as_transition_delete(), + BatchedTransitionRef::Token(_) => None, + } + } + + fn as_transition_transfer(&self) -> Option<&DocumentTransferTransition> { + match self { + BatchedTransitionRef::Document(document) => document.as_transition_transfer(), + BatchedTransitionRef::Token(_) => None, + } + } + + fn as_transition_purchase(&self) -> Option<&DocumentPurchaseTransition> { + match self { + BatchedTransitionRef::Document(document) => document.as_transition_purchase(), + BatchedTransitionRef::Token(_) => None, + } + } + + fn as_transition_token_burn(&self) -> Option<&TokenBurnTransition> { + match self { + BatchedTransitionRef::Document(_) => None, + BatchedTransitionRef::Token(token) => token.as_transition_token_burn(), + } + } + + fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { + match self { + BatchedTransitionRef::Document(_) => None, + BatchedTransitionRef::Token(token) => token.as_transition_token_issuance(), + } + } + + fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition> { + match self { + BatchedTransitionRef::Document(_) => None, + BatchedTransitionRef::Token(token) => token.as_transition_token_transfer(), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs similarity index 63% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs index fee916e0386..2863c1718d9 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/fields.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs @@ -1,5 +1,6 @@ -pub(in crate::state_transition::state_transitions::document::documents_batch_transition) mod property_names { +pub(in crate::state_transition::state_transitions::document::batch_transition) mod property_names { pub const DATA_CONTRACT_ID: &str = "$dataContractId"; + pub const TOKEN_CONTRACT_POSITION: &str = "$tokenContractPosition"; pub const TOKEN_ID: &str = "$tokenId"; pub const ACTION: &str = "$action"; pub const IDENTITY_CONTRACT_NONCE: &str = "$identityContractNonce"; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/mod.rs similarity index 93% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/mod.rs index b9d12f51212..4b4602e72dd 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/mod.rs @@ -8,8 +8,8 @@ mod v0_methods; feature = "state-transition-json-conversion" ))] use crate::data_contract::DataContract; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; -use crate::state_transition::documents_batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use crate::state_transition::batch_transition::document_base_transition::v0::DocumentTransitionObjectLike; +use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; #[cfg(any( feature = "state-transition-value-conversion", feature = "state-transition-json-conversion" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/token_base_transition_accessors.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/token_base_transition_accessors.rs similarity index 84% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/token_base_transition_accessors.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/token_base_transition_accessors.rs index 5e952d5e1ca..2813dc755de 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/token_base_transition_accessors.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/token_base_transition_accessors.rs @@ -1,4 +1,4 @@ -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; pub trait TokenBaseTransitionAccessors { /// Returns a reference to the `base` field of the `DocumentCreateTransitionV0`. diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs similarity index 81% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs index 6a6957746ac..7a695e5040d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs @@ -18,7 +18,7 @@ use crate::data_contract::accessors::v0::DataContractV0Getters; use crate::identifier::Identifier; use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-value-conversion")] -use crate::state_transition::documents_batch_transition::token_base_transition::property_names; +use crate::state_transition::batch_transition::token_base_transition::property_names; #[cfg(any( feature = "state-transition-json-conversion", feature = "state-transition-value-conversion" @@ -55,6 +55,12 @@ pub struct TokenBaseTransitionV0 { serde(rename = "$dataContractId") )] pub data_contract_id: Identifier, + /// Token ID generated from the data contract ID and the token position + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "$tokenId") + )] + pub token_id: Identifier, } impl TokenBaseTransitionV0 { @@ -65,19 +71,20 @@ impl TokenBaseTransitionV0 { identity_contract_nonce: IdentityNonce, ) -> Result { Ok(TokenBaseTransitionV0 { - id: Identifier::from( - map.remove_hash256_bytes(property_names::ID) - .map_err(ProtocolError::ValueError)?, - ), identity_contract_nonce, token_contract_position: map - .remove_integer(property_names::TOKEN_ID) + .remove_integer(property_names::TOKEN_CONTRACT_POSITION) .map_err(ProtocolError::ValueError)?, data_contract_id: Identifier::new( map.remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID) .map_err(ProtocolError::ValueError)? .unwrap_or(data_contract.id().to_buffer()), ), + token_id: Identifier::new( + map.remove_optional_hash256_bytes(property_names::TOKEN_ID) + .map_err(ProtocolError::ValueError)? + .unwrap_or(data_contract.id().to_buffer()), + ), }) } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs similarity index 76% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs index 7ab114c61d2..70297bddb50 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs @@ -1,5 +1,5 @@ use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use platform_value::Identifier; /// A trait that contains getter and setter methods for `TokenBaseTransitionV0` @@ -14,6 +14,12 @@ pub trait TokenBaseTransitionV0Methods { fn data_contract_id(&self) -> Identifier; fn data_contract_id_ref(&self) -> &Identifier; + /// Returns the token ID. + fn token_id(&self) -> Identifier; + fn token_id_ref(&self) -> &Identifier; + + fn set_token_id(&mut self, token_id: Identifier); + /// Sets the data contract ID. fn set_data_contract_id(&mut self, data_contract_id: Identifier); fn identity_contract_nonce(&self) -> IdentityNonce; @@ -37,10 +43,22 @@ impl TokenBaseTransitionV0Methods for TokenBaseTransitionV0 { &self.data_contract_id } + fn token_id(&self) -> Identifier { + self.token_id + } + + fn token_id_ref(&self) -> &Identifier { + &self.token_id + } + fn set_data_contract_id(&mut self, data_contract_id: Identifier) { self.data_contract_id = data_contract_id; } + fn set_token_id(&mut self, token_id: Identifier) { + self.token_id = token_id; + } + fn identity_contract_nonce(&self) -> IdentityNonce { self.identity_contract_nonce } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs similarity index 67% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs index cd1dcdc6b70..53a3244db1d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_base_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs @@ -1,6 +1,6 @@ use crate::prelude::IdentityNonce; -use crate::state_transition::documents_batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use platform_value::Identifier; impl TokenBaseTransitionV0Methods for TokenBaseTransition { @@ -28,6 +28,24 @@ impl TokenBaseTransitionV0Methods for TokenBaseTransition { } } + fn token_id(&self) -> Identifier { + match self { + TokenBaseTransition::V0(v0) => v0.token_id(), + } + } + + fn set_token_id(&mut self, token_id: Identifier) { + match self { + TokenBaseTransition::V0(v0) => v0.set_token_id(token_id), + } + } + + fn token_id_ref(&self) -> &Identifier { + match self { + TokenBaseTransition::V0(v0) => v0.token_id_ref(), + } + } + fn set_data_contract_id(&mut self, data_contract_id: Identifier) { match self { TokenBaseTransition::V0(v0) => v0.set_data_contract_id(data_contract_id), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs similarity index 89% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs index dac79ad9e2e..dfdb4d57269 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs @@ -1,6 +1,6 @@ pub mod v0_methods; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use bincode::{Decode, Encode}; use derive_more::Display; #[cfg(feature = "state-transition-serde-conversion")] diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs similarity index 66% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs index 07029b9f14d..7f9f99fbfa4 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs @@ -1,6 +1,6 @@ -use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::documents_batch_transition::token_burn_transition::TokenBurnTransitionV0; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_burn_transition::TokenBurnTransitionV0; impl TokenBaseTransitionAccessors for TokenBurnTransitionV0 { fn base(&self) -> &TokenBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs similarity index 64% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs index b2f46acc438..a34139c10e6 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_burn_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs @@ -1,7 +1,7 @@ -use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::documents_batch_transition::token_burn_transition::TokenBurnTransition; -use crate::state_transition::documents_batch_transition::token_burn_transition::v0::v0_methods::TokenBurnTransitionV0Methods; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_burn_transition::TokenBurnTransition; +use crate::state_transition::batch_transition::token_burn_transition::v0::v0_methods::TokenBurnTransitionV0Methods; impl TokenBaseTransitionAccessors for TokenBurnTransition { fn base(&self) -> &TokenBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs similarity index 94% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs index fe7ebe5c691..fe20c85bb72 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs @@ -1,6 +1,6 @@ pub mod v0_methods; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use bincode::{Decode, Encode}; use platform_value::string_encoding::Encoding; use platform_value::Identifier; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs similarity index 65% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs index 8b643593ac6..f8c21f9b18e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs @@ -1,6 +1,6 @@ -use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; impl TokenBaseTransitionAccessors for TokenIssuanceTransitionV0 { fn base(&self) -> &TokenBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs similarity index 64% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs index b4bdc520bc1..fa3137f0222 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_issuance_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs @@ -1,7 +1,7 @@ -use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransition; -use crate::state_transition::documents_batch_transition::token_issuance_transition::v0::v0_methods::TokenIssuanceTransitionV0Methods; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransition; +use crate::state_transition::batch_transition::token_issuance_transition::v0::v0_methods::TokenIssuanceTransitionV0Methods; impl TokenBaseTransitionAccessors for TokenIssuanceTransition { fn base(&self) -> &TokenBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs similarity index 91% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs index 4662a75997e..b2e140b8122 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs @@ -8,7 +8,7 @@ use platform_value::Identifier; use serde::{Deserialize, Serialize}; pub use super::super::token_base_transition::IDENTIFIER_FIELDS; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; mod property_names { pub const AMOUNT: &str = "$amount"; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs similarity index 81% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs index 32d2a4eae06..afa066cea39 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs @@ -1,8 +1,8 @@ use platform_value::Identifier; -use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::TokenTransferTransitionV0; -use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::batched_transition::token_transfer_transition::TokenTransferTransitionV0; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { fn base(&self) -> &TokenBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs similarity index 74% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs index 65310370403..9e0a0617d80 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs @@ -1,8 +1,8 @@ use platform_value::Identifier; -use crate::state_transition::documents_batch_transition::document_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; -use crate::state_transition::documents_batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::TokenTransferTransition; -use crate::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::batched_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::TokenTransferTransition; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; impl TokenBaseTransitionAccessors for TokenTransferTransition { fn base(&self) -> &TokenBaseTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs new file mode 100644 index 00000000000..4c4f8df552e --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs @@ -0,0 +1,134 @@ +use derive_more::{Display, From}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +use platform_value::Identifier; +use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition}; +use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition}; +use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; + +#[derive(Debug, Clone, Encode, Decode, From, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenTransition { + #[display("TokenBurnTransition({})", "_0")] + Burn(TokenBurnTransition), + + #[display("TokenIssuanceTransition({})", "_0")] + Issuance(TokenIssuanceTransition), + + #[display("TokenTransferTransition({})", "_0")] + Transfer(TokenTransferTransition), +} + +impl BatchTransitionResolversV0 for TokenTransition { + fn as_transition_create(&self) -> Option<&DocumentCreateTransition> { + None + } + fn as_transition_replace(&self) -> Option<&DocumentReplaceTransition> { + None + } + + fn as_transition_delete(&self) -> Option<&DocumentDeleteTransition> { + None + } + + fn as_transition_transfer(&self) -> Option<&DocumentTransferTransition> { + None + } + + fn as_transition_purchase(&self) -> Option<&DocumentPurchaseTransition> { + None + } + + fn as_transition_token_burn(&self) -> Option<&TokenBurnTransition> { + if let Self::Burn(ref t) = self { + Some(t) + } else { + None + } + } + fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { + if let Self::Issuance(ref t) = self { + Some(t) + } else { + None + } + } + + fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition> { + if let Self::Transfer(ref t) = self { + Some(t) + } else { + None + } + } +} + +pub trait TokenTransitionV0Methods { + fn base(&self) -> &TokenBaseTransition; + fn base_mut(&mut self) -> &mut TokenBaseTransition; + /// get the data contract ID + fn data_contract_id(&self) -> Identifier; + /// set data contract's ID + fn set_data_contract_id(&mut self, id: Identifier); + + /// get the token ID + fn token_id(&self) -> Identifier; + + /// set the token ID + fn set_token_id(&mut self, id: Identifier); + + /// get the identity contract nonce + fn identity_contract_nonce(&self) -> IdentityNonce; + /// sets identity contract nonce + fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce); +} + +impl TokenTransitionV0Methods for TokenTransition { + fn base(&self) -> &TokenBaseTransition { + match self { + TokenTransition::Burn(t) => t.base(), + TokenTransition::Issuance(t) => t.base(), + TokenTransition::Transfer(t) => t.base(), + } + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + match self { + TokenTransition::Burn(t) => t.base_mut(), + TokenTransition::Issuance(t) => t.base_mut(), + TokenTransition::Transfer(t) => t.base_mut(), + } + } + + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + fn set_data_contract_id(&mut self, id: Identifier) { + self.base_mut().set_data_contract_id(id); + } + + fn token_id(&self) -> Identifier { + self.base().token_id() + } + + fn set_token_id(&mut self, token_id: Identifier) { + self.base_mut().set_token_id(token_id) + } + + fn identity_contract_nonce(&self) -> IdentityNonce { + self.base().identity_contract_nonce() + } + + fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce) { + self.base_mut().set_identity_contract_nonce(nonce); + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs similarity index 90% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs index 5d33edb1164..37bf79f558d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/token_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs @@ -1,4 +1,4 @@ -use crate::state_transition::documents_batch_transition::document_transition::TokenTransition; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::token_transition::TokenTransition; use crate::ProtocolError; // @append-only diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/fields.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/fields.rs similarity index 93% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/fields.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/fields.rs index 06f39e42fc0..8a72a2d50c2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/fields.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/fields.rs @@ -1,7 +1,7 @@ use crate::state_transition::state_transitions; use crate::identity::SecurityLevel; -use crate::state_transition::documents_batch_transition::fields::property_names::{ +use crate::state_transition::batch_transition::fields::property_names::{ OWNER_ID, TRANSITIONS_DATA_CONTRACT_ID, TRANSITIONS_ID, }; pub use state_transitions::common_fields::property_names::{ diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/identity_signed.rs new file mode 100644 index 00000000000..a3aba2340b1 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/identity_signed.rs @@ -0,0 +1,26 @@ +use crate::identity::{KeyID, Purpose, SecurityLevel}; +use crate::state_transition::batch_transition::BatchTransition; +use crate::state_transition::StateTransitionIdentitySigned; + +impl StateTransitionIdentitySigned for BatchTransition { + fn signature_public_key_id(&self) -> KeyID { + match self { + BatchTransition::V0(transition) => transition.signature_public_key_id(), + BatchTransition::V1(transition) => transition.signature_public_key_id(), + } + } + + fn set_signature_public_key_id(&mut self, key_id: KeyID) { + match self { + BatchTransition::V0(transition) => transition.set_signature_public_key_id(key_id), + BatchTransition::V1(transition) => transition.set_signature_public_key_id(key_id), + } + } + + fn security_level_requirement(&self, purpose: Purpose) -> Vec { + match self { + BatchTransition::V0(transition) => transition.security_level_requirement(purpose), + BatchTransition::V1(transition) => transition.security_level_requirement(purpose), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/json_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/json_conversion.rs similarity index 70% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/json_conversion.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/json_conversion.rs index 1fb61df8b22..f74b93740a6 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/json_conversion.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/json_conversion.rs @@ -1,5 +1,5 @@ -use crate::state_transition::documents_batch_transition::DocumentsBatchTransition; -use crate::state_transition::state_transitions::documents_batch_transition::fields::*; +use crate::state_transition::batch_transition::BatchTransition; +use crate::state_transition::state_transitions::batch_transition::fields::*; use crate::state_transition::{ JsonStateTransitionSerializationOptions, StateTransitionJsonConvert, }; @@ -7,13 +7,13 @@ use crate::ProtocolError; use serde_json::Number; use serde_json::Value as JsonValue; -impl<'a> StateTransitionJsonConvert<'a> for DocumentsBatchTransition { +impl<'a> StateTransitionJsonConvert<'a> for BatchTransition { fn to_json( &self, options: JsonStateTransitionSerializationOptions, ) -> Result { match self { - DocumentsBatchTransition::V0(transition) => { + BatchTransition::V0(transition) => { let mut value = transition.to_json(options)?; let map_value = value.as_object_mut().expect("expected an object"); map_value.insert( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs similarity index 65% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/methods/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs index 071ed54f90f..ac0a77f8c9d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs @@ -10,11 +10,11 @@ use crate::identity::IdentityPublicKey; use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-signing")] use crate::prelude::UserFeeIncrease; -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; -use crate::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; -use crate::state_transition::documents_batch_transition::DocumentsBatchTransition; +use crate::state_transition::batch_transition::batched_transition::BatchedTransition; +use crate::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use crate::state_transition::batch_transition::BatchTransition; #[cfg(feature = "state-transition-signing")] -use crate::state_transition::documents_batch_transition::DocumentsBatchTransitionV0; +use crate::state_transition::batch_transition::{BatchTransitionV0, BatchTransitionV1}; #[cfg(feature = "state-transition-signing")] use crate::state_transition::StateTransition; use crate::ProtocolError; @@ -25,10 +25,11 @@ use platform_version::version::{FeatureVersion, PlatformVersion}; pub mod v0; -impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { - fn all_purchases_amount(&self) -> Result, ProtocolError> { +impl DocumentsBatchTransitionMethodsV0 for BatchTransition { + fn all_document_purchases_amount(&self) -> Result, ProtocolError> { match self { - DocumentsBatchTransition::V0(v0) => v0.all_purchases_amount(), + BatchTransition::V0(v0) => v0.all_document_purchases_amount(), + BatchTransition::V1(v1) => v1.all_document_purchases_amount(), } } @@ -36,21 +37,22 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { &self, ) -> Result, ProtocolError> { match self { - DocumentsBatchTransition::V0(v0) => v0.all_conflicting_index_collateral_voting_funds(), + BatchTransition::V0(v0) => v0.all_conflicting_index_collateral_voting_funds(), + BatchTransition::V1(v1) => v1.all_conflicting_index_collateral_voting_funds(), } } - fn set_transitions(&mut self, transitions: Vec) { + fn set_transitions(&mut self, transitions: Vec) { match self { - DocumentsBatchTransition::V0(v0) => v0.set_transitions(transitions), + BatchTransition::V0(v0) => v0.set_transitions(transitions), + BatchTransition::V1(v1) => v1.set_transitions(transitions), } } fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce) { match self { - DocumentsBatchTransition::V0(v0) => { - v0.set_identity_contract_nonce(identity_contract_nonce) - } + BatchTransition::V0(v0) => v0.set_identity_contract_nonce(identity_contract_nonce), + BatchTransition::V1(v1) => v1.set_identity_contract_nonce(identity_contract_nonce), } } @@ -72,11 +74,26 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { platform_version .dpp .state_transition_serialization_versions - .documents_batch_state_transition + .batch_state_transition .default_current_version, ) { 0 => Ok( - DocumentsBatchTransitionV0::new_document_creation_transition_from_document( + BatchTransitionV0::new_document_creation_transition_from_document( + document, + document_type, + entropy, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + create_feature_version, + base_feature_version, + )?, + ), + 1 => Ok( + BatchTransitionV1::new_document_creation_transition_from_document( document, document_type, entropy, @@ -92,7 +109,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { ), version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_created_from_document".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -115,11 +132,25 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { platform_version .dpp .state_transition_serialization_versions - .documents_batch_state_transition + .batch_state_transition .default_current_version, ) { 0 => Ok( - DocumentsBatchTransitionV0::new_document_replacement_transition_from_document( + BatchTransitionV0::new_document_replacement_transition_from_document( + document, + document_type, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + replace_feature_version, + base_feature_version, + )?, + ), + 1 => Ok( + BatchTransitionV1::new_document_replacement_transition_from_document( document, document_type, identity_public_key, @@ -136,7 +167,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { method: "DocumentsBatchTransition::new_document_replacement_transition_from_document" .to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -160,11 +191,26 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { platform_version .dpp .state_transition_serialization_versions - .documents_batch_state_transition + .batch_state_transition .default_current_version, ) { 0 => Ok( - DocumentsBatchTransitionV0::new_document_transfer_transition_from_document( + BatchTransitionV0::new_document_transfer_transition_from_document( + document, + document_type, + recipient_owner_id, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + transfer_feature_version, + base_feature_version, + )?, + ), + 1 => Ok( + BatchTransitionV1::new_document_transfer_transition_from_document( document, document_type, recipient_owner_id, @@ -182,7 +228,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { method: "DocumentsBatchTransition::new_document_replacement_transition_from_document" .to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -205,11 +251,25 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { platform_version .dpp .state_transition_serialization_versions - .documents_batch_state_transition + .batch_state_transition .default_current_version, ) { 0 => Ok( - DocumentsBatchTransitionV0::new_document_deletion_transition_from_document( + BatchTransitionV0::new_document_deletion_transition_from_document( + document, + document_type, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + delete_feature_version, + base_feature_version, + )?, + ), + 1 => Ok( + BatchTransitionV1::new_document_deletion_transition_from_document( document, document_type, identity_public_key, @@ -225,7 +285,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_document_deletion_transition_from_document" .to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -249,11 +309,26 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { platform_version .dpp .state_transition_serialization_versions - .documents_batch_state_transition + .batch_state_transition .default_current_version, ) { 0 => Ok( - DocumentsBatchTransitionV0::new_document_update_price_transition_from_document( + BatchTransitionV0::new_document_update_price_transition_from_document( + document, + document_type, + price, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + update_price_feature_version, + base_feature_version, + )?, + ), + 1 => Ok( + BatchTransitionV1::new_document_update_price_transition_from_document( document, document_type, price, @@ -271,7 +346,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { method: "DocumentsBatchTransition::new_document_update_price_transition_from_document" .to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -296,11 +371,27 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { platform_version .dpp .state_transition_serialization_versions - .documents_batch_state_transition + .batch_state_transition .default_current_version, ) { 0 => Ok( - DocumentsBatchTransitionV0::new_document_purchase_transition_from_document( + BatchTransitionV0::new_document_purchase_transition_from_document( + document, + document_type, + new_owner_id, + price, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + purchase_feature_version, + base_feature_version, + )?, + ), + 1 => Ok( + BatchTransitionV1::new_document_purchase_transition_from_document( document, document_type, new_owner_id, @@ -318,7 +409,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransition { version => Err(ProtocolError::UnknownVersionMismatch { method: "DocumentsBatchTransition::new_document_purchase_transition_from_document" .to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/methods/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v0/mod.rs similarity index 81% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/methods/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v0/mod.rs index ceffcaa7aec..eaadd2777a5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/methods/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v0/mod.rs @@ -11,11 +11,8 @@ use crate::identity::SecurityLevel; use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-signing")] use crate::prelude::UserFeeIncrease; -use crate::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::{ - DocumentTransition, DocumentTransitionV0Methods, -}; +use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use crate::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; #[cfg(feature = "state-transition-signing")] use crate::state_transition::StateTransition; use crate::ProtocolError; @@ -23,6 +20,8 @@ use platform_value::Identifier; #[cfg(feature = "state-transition-signing")] use platform_version::version::{FeatureVersion, PlatformVersion}; use std::convert::TryFrom; +use crate::state_transition::batch_transition::batched_transition::{BatchedTransition, BatchedTransitionRef}; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 { #[cfg(feature = "state-transition-signing")] @@ -129,17 +128,19 @@ pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 // requirement is the highest level across all documents affected by the ST./ let mut highest_security_level = SecurityLevel::lowest_level(); - for transition in self.transitions().iter() { - let document_type_name = transition.base().document_type_name(); - let data_contract_id = transition.base().data_contract_id(); - let document_security_level = get_data_contract_security_level_requirement( - data_contract_id, - document_type_name.to_owned(), - )?; + for transition in self.transitions_iter() { + if let BatchedTransitionRef::Document(document_transition) = transition { + let document_type_name = document_transition.base().document_type_name(); + let data_contract_id = document_transition.base().data_contract_id(); + let document_security_level = get_data_contract_security_level_requirement( + data_contract_id, + document_type_name.to_owned(), + )?; - // lower enum enum representation means higher in security - if document_security_level < highest_security_level { - highest_security_level = document_security_level + // lower enum representation means higher in security + if document_security_level < highest_security_level { + highest_security_level = document_security_level + } } } Ok(if highest_security_level == SecurityLevel::MASTER { @@ -152,7 +153,7 @@ pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 }) } - fn set_transitions(&mut self, transitions: Vec); + fn set_transitions(&mut self, transitions: Vec); fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce); @@ -160,5 +161,5 @@ pub trait DocumentsBatchTransitionMethodsV0: DocumentsBatchTransitionAccessorsV0 &self, ) -> Result, ProtocolError>; - fn all_purchases_amount(&self) -> Result, ProtocolError>; + fn all_document_purchases_amount(&self) -> Result, ProtocolError>; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs new file mode 100644 index 00000000000..0ded71c1f97 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs @@ -0,0 +1,109 @@ +use bincode::{Decode, Encode}; + +use std::convert::TryInto; + +use derive_more::From; + +use platform_value::Value; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +use crate::ProtocolError; +use crate::{identity::SecurityLevel, state_transition::StateTransitionFieldTypes}; + +pub use self::batched_transition::{ + document_base_transition, document_create_transition, + document_create_transition::DocumentCreateTransition, document_delete_transition, + document_delete_transition::DocumentDeleteTransition, document_replace_transition, + document_replace_transition::DocumentReplaceTransition, token_base_transition, + token_burn_transition, token_burn_transition::TokenBurnTransition, token_issuance_transition, + token_issuance_transition::TokenIssuanceTransition, token_transfer_transition, + token_transfer_transition::TokenTransferTransition, +}; + +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize, PlatformSignable}; +use platform_versioning::PlatformVersioned; + +pub mod accessors; +pub mod batched_transition; +pub mod fields; +mod identity_signed; +#[cfg(feature = "state-transition-json-conversion")] +mod json_conversion; +pub mod methods; +pub mod resolvers; +mod state_transition_like; +mod v0; +mod v1; +#[cfg(feature = "validation")] +mod validation; +#[cfg(feature = "state-transition-value-conversion")] +mod value_conversion; +mod version; + +use crate::state_transition::data_contract_update_transition::{ + SIGNATURE, SIGNATURE_PUBLIC_KEY_ID, +}; + +use crate::state_transition::batch_transition::fields::property_names; + +use crate::identity::state_transition::OptionallyAssetLockProved; +pub use v0::*; +pub use v1::*; + +#[derive( + Debug, + Clone, + PartialEq, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PlatformSignable, + PlatformVersioned, + From, +)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(tag = "$version") +)] +#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version +#[platform_version_path_bounds( + "dpp.state_transition_serialization_versions.batch_state_transition" +)] +pub enum BatchTransition { + #[cfg_attr(feature = "state-transition-serde-conversion", serde(rename = "0"))] + V0(BatchTransitionV0), + #[cfg_attr(feature = "state-transition-serde-conversion", serde(rename = "1"))] + V1(BatchTransitionV1), +} + +impl StateTransitionFieldTypes for BatchTransition { + fn binary_property_paths() -> Vec<&'static str> { + vec![SIGNATURE] + } + + fn identifiers_property_paths() -> Vec<&'static str> { + vec![property_names::OWNER_ID] + } + + fn signature_property_paths() -> Vec<&'static str> { + vec![SIGNATURE, SIGNATURE_PUBLIC_KEY_ID] + } +} + +// TODO: Make a DocumentType method +pub fn get_security_level_requirement(v: &Value, default: SecurityLevel) -> SecurityLevel { + let maybe_security_level: Option = v + .get_optional_integer(property_names::SECURITY_LEVEL_REQUIREMENT) + // TODO: Data Contract must already valid so there is no chance that this will fail + .expect("document schema must be a map"); + + match maybe_security_level { + Some(some_level) => (some_level as u8).try_into().unwrap_or(default), + None => default, + } +} + +impl OptionallyAssetLockProved for BatchTransition {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/mod.rs new file mode 100644 index 00000000000..2d24cd45f58 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/mod.rs @@ -0,0 +1 @@ +pub mod v0; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs new file mode 100644 index 00000000000..e1cf7a939c9 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs @@ -0,0 +1,18 @@ +use crate::state_transition::batch_transition::batched_transition::{ + DocumentPurchaseTransition, DocumentTransferTransition, +}; +use crate::state_transition::batch_transition::{ + DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, + TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition, +}; + +pub trait BatchTransitionResolversV0 { + fn as_transition_create(&self) -> Option<&DocumentCreateTransition>; + fn as_transition_replace(&self) -> Option<&DocumentReplaceTransition>; + fn as_transition_delete(&self) -> Option<&DocumentDeleteTransition>; + fn as_transition_transfer(&self) -> Option<&DocumentTransferTransition>; + fn as_transition_purchase(&self) -> Option<&DocumentPurchaseTransition>; + fn as_transition_token_burn(&self) -> Option<&TokenBurnTransition>; + fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition>; + fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition>; +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/state_transition_like.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/state_transition_like.rs new file mode 100644 index 00000000000..0221ced2611 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/state_transition_like.rs @@ -0,0 +1,79 @@ +use crate::prelude::UserFeeIncrease; +use crate::state_transition::batch_transition::BatchTransition; +use crate::state_transition::{StateTransitionLike, StateTransitionType}; +use crate::version::FeatureVersion; +use platform_value::{BinaryData, Identifier}; + +impl StateTransitionLike for BatchTransition { + /// Returns ID of the created contract + fn modified_data_ids(&self) -> Vec { + match self { + BatchTransition::V0(transition) => transition.modified_data_ids(), + BatchTransition::V1(transition) => transition.modified_data_ids(), + } + } + + fn state_transition_protocol_version(&self) -> FeatureVersion { + match self { + BatchTransition::V0(_) => 0, + BatchTransition::V1(_) => 1, + } + } + /// returns the type of State Transition + fn state_transition_type(&self) -> StateTransitionType { + match self { + BatchTransition::V0(transition) => transition.state_transition_type(), + BatchTransition::V1(transition) => transition.state_transition_type(), + } + } + /// returns the signature as a byte-array + fn signature(&self) -> &BinaryData { + match self { + BatchTransition::V0(transition) => transition.signature(), + BatchTransition::V1(transition) => transition.signature(), + } + } + /// set a new signature + fn set_signature(&mut self, signature: BinaryData) { + match self { + BatchTransition::V0(transition) => transition.set_signature(signature), + BatchTransition::V1(transition) => transition.set_signature(signature), + } + } + + fn set_signature_bytes(&mut self, signature: Vec) { + match self { + BatchTransition::V0(transition) => transition.set_signature_bytes(signature), + BatchTransition::V1(transition) => transition.set_signature_bytes(signature), + } + } + + /// returns the fee multiplier + fn user_fee_increase(&self) -> UserFeeIncrease { + match self { + BatchTransition::V0(transition) => transition.user_fee_increase(), + BatchTransition::V1(transition) => transition.user_fee_increase(), + } + } + /// set a fee multiplier + fn set_user_fee_increase(&mut self, user_fee_increase: UserFeeIncrease) { + match self { + BatchTransition::V0(transition) => transition.set_user_fee_increase(user_fee_increase), + BatchTransition::V1(transition) => transition.set_user_fee_increase(user_fee_increase), + } + } + + fn owner_id(&self) -> Identifier { + match self { + BatchTransition::V0(transition) => transition.owner_id(), + BatchTransition::V1(transition) => transition.owner_id(), + } + } + + fn unique_identifiers(&self) -> Vec { + match self { + BatchTransition::V0(transition) => transition.unique_identifiers(), + BatchTransition::V1(transition) => transition.unique_identifiers(), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/cbor_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/cbor_conversion.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/cbor_conversion.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/cbor_conversion.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/identity_signed.rs similarity index 83% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/identity_signed.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/identity_signed.rs index bdc0fe583a2..d0f7084b339 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/identity_signed.rs @@ -1,10 +1,10 @@ use crate::identity::SecurityLevel::{CRITICAL, HIGH, MEDIUM}; use crate::identity::{KeyID, Purpose, SecurityLevel}; -use crate::state_transition::documents_batch_transition::DocumentsBatchTransitionV0; +use crate::state_transition::batch_transition::BatchTransitionV0; use crate::state_transition::StateTransitionIdentitySigned; -impl StateTransitionIdentitySigned for DocumentsBatchTransitionV0 { +impl StateTransitionIdentitySigned for BatchTransitionV0 { fn signature_public_key_id(&self) -> KeyID { self.signature_public_key_id } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/json_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/json_conversion.rs new file mode 100644 index 00000000000..59ec75a2e62 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/json_conversion.rs @@ -0,0 +1,4 @@ +use crate::state_transition::batch_transition::BatchTransitionV0; +use crate::state_transition::StateTransitionJsonConvert; + +impl<'a> StateTransitionJsonConvert<'a> for BatchTransitionV0 {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/mod.rs similarity index 86% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/mod.rs index 4f301bb4520..3bd2cb1d1a0 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/mod.rs @@ -10,7 +10,7 @@ mod version; use crate::identity::KeyID; -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; use crate::ProtocolError; use bincode::{Decode, Encode}; use platform_serialization_derive::PlatformSignable; @@ -26,7 +26,7 @@ use serde::{Deserialize, Serialize}; derive(Serialize, Deserialize) )] #[derive(Default)] -pub struct DocumentsBatchTransitionV0 { +pub struct BatchTransitionV0 { pub owner_id: Identifier, pub transitions: Vec, pub user_fee_increase: UserFeeIncrease, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/state_transition_like.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/state_transition_like.rs similarity index 72% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/state_transition_like.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/state_transition_like.rs index ce3faf2c4b6..83eb9f42442 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/state_transition_like.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/state_transition_like.rs @@ -1,24 +1,24 @@ use crate::prelude::UserFeeIncrease; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransitionV0Methods; -use crate::state_transition::documents_batch_transition::{ - DocumentsBatchTransition, DocumentsBatchTransitionV0, +use crate::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; +use crate::state_transition::batch_transition::{ + BatchTransition, BatchTransitionV0, }; -use crate::state_transition::StateTransitionType::DocumentsBatch; +use crate::state_transition::StateTransitionType::Batch; use crate::state_transition::{StateTransition, StateTransitionLike, StateTransitionType}; use crate::version::FeatureVersion; use base64::prelude::BASE64_STANDARD; use base64::Engine; use platform_value::{BinaryData, Identifier}; -impl From for StateTransition { - fn from(value: DocumentsBatchTransitionV0) -> Self { - let document_batch_transition: DocumentsBatchTransition = value.into(); +impl From for StateTransition { + fn from(value: BatchTransitionV0) -> Self { + let document_batch_transition: BatchTransition = value.into(); document_batch_transition.into() } } -impl StateTransitionLike for DocumentsBatchTransitionV0 { +impl StateTransitionLike for BatchTransitionV0 { /// Returns ID of the created contract fn modified_data_ids(&self) -> Vec { self.transitions.iter().map(|t| t.base().id()).collect() @@ -29,7 +29,7 @@ impl StateTransitionLike for DocumentsBatchTransitionV0 { } /// returns the type of State Transition fn state_transition_type(&self) -> StateTransitionType { - DocumentsBatch + Batch } /// returns the signature as a byte-array fn signature(&self) -> &BinaryData { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/types.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/types.rs similarity index 53% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/types.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/types.rs index 39d85d64372..abe0ef311e8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/types.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/types.rs @@ -1,9 +1,9 @@ -use crate::state_transition::documents_batch_transition::fields::property_names::*; -use crate::state_transition::documents_batch_transition::fields::*; -use crate::state_transition::documents_batch_transition::DocumentsBatchTransitionV0; +use crate::state_transition::batch_transition::fields::property_names::*; +use crate::state_transition::batch_transition::fields::*; +use crate::state_transition::batch_transition::BatchTransitionV0; use crate::state_transition::StateTransitionFieldTypes; -impl StateTransitionFieldTypes for DocumentsBatchTransitionV0 { +impl StateTransitionFieldTypes for BatchTransitionV0 { fn binary_property_paths() -> Vec<&'static str> { vec![SIGNATURE] } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs similarity index 78% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs index 0bafe6b8aeb..1833ee2d1fa 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs @@ -1,3 +1,4 @@ +use std::slice::Iter; #[cfg(feature = "state-transition-signing")] use crate::data_contract::document_type::DocumentTypeRef; #[cfg(feature = "state-transition-signing")] @@ -12,21 +13,19 @@ use crate::prelude::IdentityNonce; use crate::prelude::IdentityPublicKey; #[cfg(feature = "state-transition-signing")] use crate::prelude::UserFeeIncrease; -use crate::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use crate::state_transition::batch_transition::accessors::{DocumentsBatchTransitionAccessorsV0}; #[cfg(feature = "state-transition-signing")] -use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransition; -use crate::state_transition::documents_batch_transition::document_transition::{ - DocumentTransition, DocumentTransitionV0Methods, -}; +use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransition; +use crate::state_transition::batch_transition::batched_transition::{BatchedTransition, BatchedTransitionRef}; #[cfg(feature = "state-transition-signing")] -use crate::state_transition::documents_batch_transition::document_transition::{ - DocumentReplaceTransition, DocumentTransferTransition, DocumentPurchaseTransition, DocumentUpdatePriceTransition, +use crate::state_transition::batch_transition::batched_transition::{ + DocumentPurchaseTransition, DocumentReplaceTransition, DocumentTransferTransition, DocumentUpdatePriceTransition, }; -use crate::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; -use crate::state_transition::documents_batch_transition::DocumentsBatchTransitionV0; +use crate::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use crate::state_transition::batch_transition::BatchTransitionV0; #[cfg(feature = "state-transition-signing")] -use crate::state_transition::documents_batch_transition::{ - DocumentDeleteTransition, DocumentsBatchTransition, +use crate::state_transition::batch_transition::{ + BatchTransition, DocumentDeleteTransition, }; #[cfg(feature = "state-transition-signing")] use crate::state_transition::StateTransition; @@ -35,20 +34,39 @@ use crate::ProtocolError; use platform_value::Identifier; #[cfg(feature = "state-transition-signing")] use platform_version::version::{FeatureVersion, PlatformVersion}; -use crate::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; +use crate::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::document_transition::DocumentTransition; +use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; + +impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV0 { + type IterType<'a> = std::iter::Map, fn(&'a DocumentTransition) -> BatchedTransitionRef<'a>> + where + Self: 'a; + + /// Iterator for `BatchedTransitionRef` items in version 0. + fn transitions_iter<'a>(&'a self) -> Self::IterType<'a> { + self.transitions.iter().map(BatchedTransitionRef::Document) + } -impl DocumentsBatchTransitionAccessorsV0 for DocumentsBatchTransitionV0 { - fn transitions(&self) -> &Vec { - &self.transitions + /// Returns the total number of transitions (document and token) in version 0. + fn transitions_len(&self) -> usize { + self.transitions.len() } - fn transitions_slice(&self) -> &[DocumentTransition] { - self.transitions.as_slice() + /// Checks if there are no transitions in version 0. + fn transitions_are_empty(&self) -> bool { + self.transitions.is_empty() + } + + /// Returns the first transition, if it exists, as a `BatchedTransitionRef`. + fn first_transition(&self) -> Option { + self.transitions.first().map(BatchedTransitionRef::Document) } } -impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { +impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { #[cfg(feature = "state-transition-signing")] fn new_document_creation_transition_from_document( document: Document, @@ -73,7 +91,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { create_feature_version, base_feature_version, )?; - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + let documents_batch_transition: BatchTransition = BatchTransitionV0 { owner_id, transitions: vec![create_transition.into()], user_fee_increase, @@ -112,7 +130,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { replace_feature_version, base_feature_version, )?; - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + let documents_batch_transition: BatchTransition = BatchTransitionV0 { owner_id, transitions: vec![replace_transition.into()], user_fee_increase, @@ -153,7 +171,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { transfer_feature_version, base_feature_version, )?; - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + let documents_batch_transition: BatchTransition = BatchTransitionV0 { owner_id, transitions: vec![transfer_transition.into()], user_fee_increase, @@ -192,7 +210,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { delete_feature_version, base_feature_version, )?; - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + let documents_batch_transition: BatchTransition = BatchTransitionV0 { owner_id, transitions: vec![delete_transition.into()], user_fee_increase, @@ -233,7 +251,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { update_price_feature_version, base_feature_version, )?; - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + let documents_batch_transition: BatchTransition = BatchTransitionV0 { owner_id, transitions: vec![transfer_transition.into()], user_fee_increase, @@ -274,7 +292,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { purchase_feature_version, base_feature_version, )?; - let documents_batch_transition: DocumentsBatchTransition = DocumentsBatchTransitionV0 { + let documents_batch_transition: BatchTransition = BatchTransitionV0 { owner_id: new_owner_id, transitions: vec![purchase_transition.into()], user_fee_increase, @@ -291,8 +309,14 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { Ok(state_transition) } - fn set_transitions(&mut self, transitions: Vec) { - self.transitions = transitions; + fn set_transitions(&mut self, transitions: Vec) { + self.transitions = transitions + .into_iter() + .filter_map(|batched_transition| match batched_transition { + BatchedTransition::Document(document) => Some(document), + BatchedTransition::Token(_) => None, + }) + .collect(); } fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce) { @@ -301,7 +325,7 @@ impl DocumentsBatchTransitionMethodsV0 for DocumentsBatchTransitionV0 { .for_each(|transition| transition.set_identity_contract_nonce(identity_contract_nonce)); } - fn all_purchases_amount(&self) -> Result, ProtocolError> { + fn all_document_purchases_amount(&self) -> Result, ProtocolError> { let (total, any_purchases): (Option, bool) = self .transitions .iter() diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/value_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/value_conversion.rs new file mode 100644 index 00000000000..5438c1e2d09 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/value_conversion.rs @@ -0,0 +1,4 @@ +use crate::state_transition::batch_transition::BatchTransitionV0; +use crate::state_transition::StateTransitionValueConvert; + +impl<'a> StateTransitionValueConvert<'a> for BatchTransitionV0 {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/version.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/version.rs similarity index 52% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/version.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/version.rs index e087f12cb9f..c8a27eafe8f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/version.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/version.rs @@ -1,8 +1,8 @@ -use crate::state_transition::documents_batch_transition::DocumentsBatchTransitionV0; +use crate::state_transition::batch_transition::BatchTransitionV0; use crate::state_transition::FeatureVersioned; use crate::version::FeatureVersion; -impl FeatureVersioned for DocumentsBatchTransitionV0 { +impl FeatureVersioned for BatchTransitionV0 { fn feature_version(&self) -> FeatureVersion { 0 } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/identity_signed.rs new file mode 100644 index 00000000000..cb735d5d76f --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/identity_signed.rs @@ -0,0 +1,23 @@ +use crate::identity::SecurityLevel::{CRITICAL, HIGH, MEDIUM}; +use crate::identity::{KeyID, Purpose, SecurityLevel}; + +use crate::state_transition::batch_transition::BatchTransitionV1; +use crate::state_transition::StateTransitionIdentitySigned; + +impl StateTransitionIdentitySigned for BatchTransitionV1 { + fn signature_public_key_id(&self) -> KeyID { + self.signature_public_key_id + } + + fn set_signature_public_key_id(&mut self, key_id: KeyID) { + self.signature_public_key_id = key_id + } + + fn security_level_requirement(&self, _purpose: Purpose) -> Vec { + // These are the available key levels that must sign the state transition + // However the fact that it is signed by one of these does not guarantee that it + // meets the security level requirement, as that is dictated from within the data + // contract + vec![CRITICAL, HIGH, MEDIUM] + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/json_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/json_conversion.rs new file mode 100644 index 00000000000..b277e90e872 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/json_conversion.rs @@ -0,0 +1,4 @@ +use crate::state_transition::batch_transition::BatchTransitionV1; +use crate::state_transition::StateTransitionJsonConvert; + +impl<'a> StateTransitionJsonConvert<'a> for BatchTransitionV1 {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs new file mode 100644 index 00000000000..763f93b49a0 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/mod.rs @@ -0,0 +1,37 @@ +mod identity_signed; +#[cfg(feature = "state-transition-json-conversion")] +mod json_conversion; +mod state_transition_like; +mod types; +mod v0_methods; +#[cfg(feature = "state-transition-value-conversion")] +mod value_conversion; +mod version; + +use crate::identity::KeyID; + +use crate::state_transition::batch_transition::batched_transition::BatchedTransition; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::PlatformSignable; + +use crate::prelude::UserFeeIncrease; +use platform_value::{BinaryData, Identifier}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, PartialEq, Encode, Decode, PlatformSignable)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +#[derive(Default)] +pub struct BatchTransitionV1 { + pub owner_id: Identifier, + pub transitions: Vec, + pub user_fee_increase: UserFeeIncrease, + #[platform_signable(exclude_from_sig_hash)] + pub signature_public_key_id: KeyID, + #[platform_signable(exclude_from_sig_hash)] + pub signature: BinaryData, +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/state_transition_like.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/state_transition_like.rs new file mode 100644 index 00000000000..f215e8156b4 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/state_transition_like.rs @@ -0,0 +1,92 @@ +use crate::prelude::UserFeeIncrease; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; +use crate::state_transition::batch_transition::{BatchTransition, BatchTransitionV1}; +use crate::state_transition::StateTransitionType::Batch; +use crate::state_transition::{StateTransition, StateTransitionLike, StateTransitionType}; +use crate::version::FeatureVersion; +use base64::prelude::BASE64_STANDARD; +use base64::Engine; +use platform_value::{BinaryData, Identifier}; +use crate::state_transition::batch_transition::batched_transition::BatchedTransition; +use crate::state_transition::batch_transition::batched_transition::token_transition::TokenTransitionV0Methods; +use crate::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; + +impl From for StateTransition { + fn from(value: BatchTransitionV1) -> Self { + let document_batch_transition: BatchTransition = value.into(); + document_batch_transition.into() + } +} + +impl StateTransitionLike for BatchTransitionV1 { + /// Returns ID of the created contract + fn modified_data_ids(&self) -> Vec { + self.transitions + .iter() + .filter_map(|t| match t { + BatchedTransition::Document(document_transition) => { + Some(document_transition.base().id()) + } + BatchedTransition::Token(_) => None, + }) + .collect() + } + + fn state_transition_protocol_version(&self) -> FeatureVersion { + 1 + } + /// returns the type of State Transition + fn state_transition_type(&self) -> StateTransitionType { + Batch + } + /// returns the signature as a byte-array + fn signature(&self) -> &BinaryData { + &self.signature + } + /// set a new signature + fn set_signature(&mut self, signature: BinaryData) { + self.signature = signature + } + + fn set_signature_bytes(&mut self, signature: Vec) { + self.signature = BinaryData::new(signature) + } + + /// Get owner ID + fn owner_id(&self) -> Identifier { + self.owner_id + } + + /// We create a list of unique identifiers for the batch + fn unique_identifiers(&self) -> Vec { + self.transitions + .iter() + .map(|transition| match transition { + BatchedTransition::Document(document_transition) => { + format!( + "{}-{}-{:x}", + BASE64_STANDARD.encode(self.owner_id), + BASE64_STANDARD.encode(document_transition.data_contract_id()), + document_transition.identity_contract_nonce() + ) + } + BatchedTransition::Token(token_transition) => { + format!( + "{}-{}-{:x}", + BASE64_STANDARD.encode(self.owner_id), + BASE64_STANDARD.encode(token_transition.data_contract_id()), + token_transition.identity_contract_nonce() + ) + } + }) + .collect() + } + + fn user_fee_increase(&self) -> UserFeeIncrease { + self.user_fee_increase + } + + fn set_user_fee_increase(&mut self, user_fee_increase: UserFeeIncrease) { + self.user_fee_increase = user_fee_increase + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/types.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/types.rs new file mode 100644 index 00000000000..2a3095b8f96 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/types.rs @@ -0,0 +1,18 @@ +use crate::state_transition::batch_transition::fields::property_names::*; +use crate::state_transition::batch_transition::fields::*; +use crate::state_transition::batch_transition::BatchTransitionV1; +use crate::state_transition::StateTransitionFieldTypes; + +impl StateTransitionFieldTypes for BatchTransitionV1 { + fn binary_property_paths() -> Vec<&'static str> { + vec![SIGNATURE] + } + + fn identifiers_property_paths() -> Vec<&'static str> { + vec![OWNER_ID] + } + + fn signature_property_paths() -> Vec<&'static str> { + vec![SIGNATURE, SIGNATURE_PUBLIC_KEY_ID] + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs new file mode 100644 index 00000000000..37308b6d1ed --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -0,0 +1,384 @@ +#[cfg(feature = "state-transition-signing")] +use crate::data_contract::document_type::DocumentTypeRef; +#[cfg(feature = "state-transition-signing")] +use crate::document::{Document, DocumentV0Getters}; +use crate::fee::Credits; +#[cfg(feature = "state-transition-signing")] +use crate::identity::signer::Signer; +#[cfg(feature = "state-transition-signing")] +use crate::identity::SecurityLevel; +use crate::prelude::IdentityNonce; +#[cfg(feature = "state-transition-signing")] +use crate::prelude::IdentityPublicKey; +#[cfg(feature = "state-transition-signing")] +use crate::prelude::UserFeeIncrease; +use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use crate::state_transition::batch_transition::batched_transition::{ + BatchedTransition, BatchedTransitionRef, +}; +#[cfg(feature = "state-transition-signing")] +use crate::state_transition::batch_transition::batched_transition::{ + DocumentPurchaseTransition, DocumentReplaceTransition, DocumentTransferTransition, + DocumentUpdatePriceTransition, +}; +#[cfg(feature = "state-transition-signing")] +use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransition; +use crate::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use std::iter::Map; +use std::slice::Iter; + +use crate::state_transition::batch_transition::BatchTransitionV1; +#[cfg(feature = "state-transition-signing")] +use crate::state_transition::batch_transition::{ + BatchTransition, DocumentDeleteTransition, +}; +#[cfg(feature = "state-transition-signing")] +use crate::state_transition::StateTransition; +use crate::ProtocolError; +#[cfg(feature = "state-transition-signing")] +use platform_value::Identifier; +#[cfg(feature = "state-transition-signing")] +use platform_version::version::{FeatureVersion, PlatformVersion}; +use crate::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; +use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; + +impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV1 { + type IterType<'a> = Map, fn(&'a BatchedTransition) -> BatchedTransitionRef<'a>> + where + Self: 'a; + + /// Iterator for `BatchedTransitionRef` items in version 1. + fn transitions_iter<'a>(&'a self) -> Self::IterType<'a> { + self.transitions + .iter() + .map(|transition| transition.borrow_as_ref()) + } + + /// Returns the total number of transitions (document and token) in version 1. + fn transitions_len(&self) -> usize { + self.transitions.len() + } + + /// Checks if there are no transitions in version 1. + fn transitions_are_empty(&self) -> bool { + self.transitions.is_empty() + } + + /// Returns the first transition, if it exists, as a `BatchedTransitionRef`. + fn first_transition(&self) -> Option { + self.transitions + .first() + .map(|transition| transition.borrow_as_ref()) + } +} + +impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { + #[cfg(feature = "state-transition-signing")] + fn new_document_creation_transition_from_document( + document: Document, + document_type: DocumentTypeRef, + entropy: [u8; 32], + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + _batch_feature_version: Option, + create_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let owner_id = document.owner_id(); + let create_transition = DocumentCreateTransition::from_document( + document, + document_type, + entropy, + identity_contract_nonce, + platform_version, + create_feature_version, + base_feature_version, + )?; + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Document(create_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + #[cfg(feature = "state-transition-signing")] + fn new_document_replacement_transition_from_document( + document: Document, + document_type: DocumentTypeRef, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + _batch_feature_version: Option, + replace_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let owner_id = document.owner_id(); + let replace_transition = DocumentReplaceTransition::from_document( + document, + document_type, + identity_contract_nonce, + platform_version, + replace_feature_version, + base_feature_version, + )?; + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Document(replace_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + #[cfg(feature = "state-transition-signing")] + fn new_document_transfer_transition_from_document( + document: Document, + document_type: DocumentTypeRef, + recipient_owner_id: Identifier, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + _batch_feature_version: Option, + transfer_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let owner_id = document.owner_id(); + let transfer_transition = DocumentTransferTransition::from_document( + document, + document_type, + identity_contract_nonce, + recipient_owner_id, + platform_version, + transfer_feature_version, + base_feature_version, + )?; + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Document(transfer_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + #[cfg(feature = "state-transition-signing")] + fn new_document_deletion_transition_from_document( + document: Document, + document_type: DocumentTypeRef, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + _batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let owner_id = document.owner_id(); + let delete_transition = DocumentDeleteTransition::from_document( + document, + document_type, + identity_contract_nonce, + platform_version, + delete_feature_version, + base_feature_version, + )?; + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Document(delete_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + #[cfg(feature = "state-transition-signing")] + fn new_document_update_price_transition_from_document( + document: Document, + document_type: DocumentTypeRef, + price: Credits, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + _batch_feature_version: Option, + update_price_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let owner_id = document.owner_id(); + let transfer_transition = DocumentUpdatePriceTransition::from_document( + document, + document_type, + price, + identity_contract_nonce, + platform_version, + update_price_feature_version, + base_feature_version, + )?; + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Document(transfer_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + #[cfg(feature = "state-transition-signing")] + fn new_document_purchase_transition_from_document( + document: Document, + document_type: DocumentTypeRef, + new_owner_id: Identifier, + price: Credits, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + _batch_feature_version: Option, + purchase_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let purchase_transition = DocumentPurchaseTransition::from_document( + document, + document_type, + price, + identity_contract_nonce, + platform_version, + purchase_feature_version, + base_feature_version, + )?; + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id: new_owner_id, + transitions: vec![BatchedTransition::Document(purchase_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + fn set_transitions(&mut self, transitions: Vec) { + self.transitions = transitions; + } + + fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce) { + self.transitions + .iter_mut() + .for_each(|transition| transition.set_identity_contract_nonce(identity_contract_nonce)); + } + + fn all_document_purchases_amount(&self) -> Result, ProtocolError> { + let (total, any_purchases): (Option, bool) = self + .transitions + .iter() + .filter_map(|transition| { + transition + .as_transition_purchase() + .map(|purchase| purchase.price()) + }) + .fold((None, false), |(acc, _), price| match acc { + Some(acc_val) => acc_val + .checked_add(price) + .map_or((None, true), |sum| (Some(sum), true)), + None => (Some(price), true), + }); + + match (total, any_purchases) { + (Some(total), _) => Ok(Some(total)), + (None, true) => Err(ProtocolError::Overflow("overflow in all purchases amount")), // Overflow occurred + _ => Ok(None), // No purchases were found + } + } + + fn all_conflicting_index_collateral_voting_funds( + &self, + ) -> Result, ProtocolError> { + let (total, any_voting_funds): (Option, bool) = self + .transitions + .iter() + .filter_map(|transition| { + transition + .as_transition_create() + .and_then(|document_create_transition| { + // Safely sum up values to avoid overflow. + document_create_transition + .prefunded_voting_balance() + .as_ref() + .map(|(_, credits)| *credits) + }) + }) + .fold((None, false), |(acc, _), price| match acc { + Some(acc_val) => acc_val + .checked_add(price) + .map_or((None, true), |sum| (Some(sum), true)), + None => (Some(price), true), + }); + + match (total, any_voting_funds) { + (Some(total), _) => Ok(Some(total)), + (None, true) => Err(ProtocolError::Overflow( + "overflow in all voting funds amount", + )), // Overflow occurred + _ => Ok(None), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/value_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/value_conversion.rs new file mode 100644 index 00000000000..5438c1e2d09 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/value_conversion.rs @@ -0,0 +1,4 @@ +use crate::state_transition::batch_transition::BatchTransitionV0; +use crate::state_transition::StateTransitionValueConvert; + +impl<'a> StateTransitionValueConvert<'a> for BatchTransitionV0 {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/version.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/version.rs new file mode 100644 index 00000000000..dcedbd28965 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/version.rs @@ -0,0 +1,9 @@ +use crate::state_transition::batch_transition::BatchTransitionV1; +use crate::state_transition::FeatureVersioned; +use crate::version::FeatureVersion; + +impl FeatureVersioned for BatchTransitionV1 { + fn feature_version(&self) -> FeatureVersion { + 1 + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/find_duplicates_by_id/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/find_duplicates_by_id/mod.rs similarity index 84% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/find_duplicates_by_id/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/find_duplicates_by_id/mod.rs index 00206feeb5d..ccb6ab15307 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/find_duplicates_by_id/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/find_duplicates_by_id/mod.rs @@ -1,4 +1,4 @@ -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; use crate::ProtocolError; use platform_version::version::PlatformVersion; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/find_duplicates_by_id/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/find_duplicates_by_id/v0/mod.rs similarity index 73% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/find_duplicates_by_id/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/find_duplicates_by_id/v0/mod.rs index 71e1b19b29f..27f1f46368a 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/find_duplicates_by_id/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/find_duplicates_by_id/v0/mod.rs @@ -1,11 +1,8 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::{ - DocumentTransition, DocumentTransitionV0Methods, -}; - +use crate::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; use platform_value::Identifier; use std::collections::btree_map::Entry; use std::collections::BTreeMap; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; #[derive(Hash, Eq, PartialEq, Ord, PartialOrd)] struct TransitionFingerprint<'a> { @@ -51,14 +48,14 @@ pub(super) fn find_duplicates_by_id<'a>( #[cfg(test)] mod test { use super::*; - use crate::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; - use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; - use crate::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransitionV0; - use crate::state_transition::documents_batch_transition::document_transition::document_delete_transition::DocumentDeleteTransitionV0; - use crate::state_transition::documents_batch_transition::document_transition::DocumentCreateTransition; - use crate::state_transition::documents_batch_transition::document_transition::DocumentReplaceTransition; - use crate::state_transition::documents_batch_transition::document_transition::DocumentDeleteTransition; - use crate::state_transition::documents_batch_transition::document_transition::document_replace_transition::DocumentReplaceTransitionV0; + use crate::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; + use crate::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; + use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransitionV0; + use crate::state_transition::batch_transition::batched_transition::document_delete_transition::DocumentDeleteTransitionV0; + use crate::state_transition::batch_transition::batched_transition::DocumentCreateTransition; + use crate::state_transition::batch_transition::batched_transition::DocumentReplaceTransition; + use crate::state_transition::batch_transition::batched_transition::DocumentDeleteTransition; + use crate::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; #[test] fn test_duplicates() { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/validate_basic_structure/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/mod.rs similarity index 88% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/validate_basic_structure/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/mod.rs index 69891782113..b2f89c158d7 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/validate_basic_structure/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/mod.rs @@ -1,11 +1,11 @@ -use crate::state_transition::documents_batch_transition::DocumentsBatchTransition; +use crate::state_transition::batch_transition::BatchTransition; use crate::validation::SimpleConsensusValidationResult; use crate::ProtocolError; use platform_version::version::PlatformVersion; mod v0; -impl DocumentsBatchTransition { +impl BatchTransition { pub fn validate_base_structure( &self, platform_version: &PlatformVersion, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/validate_basic_structure/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs similarity index 71% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/validate_basic_structure/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs index 1bc2dd8b510..e73bce91e74 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/validation/validate_basic_structure/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs @@ -5,33 +5,31 @@ use crate::consensus::basic::document::{ use crate::consensus::basic::BasicError; use crate::identity::identity_nonce::MISSING_IDENTITY_REVISIONS_FILTER; -use crate::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use crate::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use crate::state_transition::documents_batch_transition::document_transition::{ - DocumentTransition, DocumentTransitionV0Methods, -}; -use crate::state_transition::documents_batch_transition::validation::find_duplicates_by_id::find_duplicates_by_id; -use crate::state_transition::documents_batch_transition::DocumentsBatchTransition; +use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use crate::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use crate::state_transition::batch_transition::validation::find_duplicates_by_id::find_duplicates_by_id; +use crate::state_transition::batch_transition::BatchTransition; use crate::validation::SimpleConsensusValidationResult; use crate::ProtocolError; use platform_value::Identifier; use platform_version::version::PlatformVersion; use std::collections::btree_map::Entry; use std::collections::BTreeMap; +use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; -impl DocumentsBatchTransition { +impl BatchTransition { #[inline(always)] pub(super) fn validate_base_structure_v0( &self, platform_version: &PlatformVersion, ) -> Result { - if self.transitions().is_empty() { + if self.transitions_are_empty() { return Ok(SimpleConsensusValidationResult::new_with_error( DocumentTransitionsAreAbsentError::new().into(), )); } - let transitions_len = self.transitions().len(); + let transitions_len = self.transitions_len(); if transitions_len > u16::MAX as usize || transitions_len as u16 @@ -53,18 +51,19 @@ impl DocumentsBatchTransition { let mut document_transitions_by_contracts: BTreeMap> = BTreeMap::new(); - self.transitions().iter().for_each(|document_transition| { - let contract_identifier = document_transition.data_contract_id(); + self.document_transitions_iter() + .for_each(|document_transition| { + let contract_identifier = document_transition.data_contract_id(); - match document_transitions_by_contracts.entry(contract_identifier) { - Entry::Vacant(vacant) => { - vacant.insert(vec![document_transition]); - } - Entry::Occupied(mut identifiers) => { - identifiers.get_mut().push(document_transition); - } - }; - }); + match document_transitions_by_contracts.entry(contract_identifier) { + Entry::Vacant(vacant) => { + vacant.insert(vec![document_transition]); + } + Entry::Occupied(mut identifiers) => { + identifiers.get_mut().push(document_transition); + } + }; + }); let mut result = SimpleConsensusValidationResult::default(); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/value_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs similarity index 81% rename from packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/value_conversion.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs index 5d02772e077..9df007a4e85 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/value_conversion.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs @@ -4,19 +4,17 @@ use platform_value::Value; use crate::ProtocolError; -use crate::state_transition::documents_batch_transition::{ - DocumentsBatchTransition, DocumentsBatchTransitionV0, -}; -use crate::state_transition::state_transitions::documents_batch_transition::fields::*; +use crate::state_transition::batch_transition::{BatchTransition, BatchTransitionV0}; +use crate::state_transition::state_transitions::batch_transition::fields::*; use crate::state_transition::StateTransitionValueConvert; use platform_value::btreemap_extensions::BTreeValueRemoveFromMapHelper; use platform_version::version::{FeatureVersion, PlatformVersion}; -impl<'a> StateTransitionValueConvert<'a> for DocumentsBatchTransition { +impl<'a> StateTransitionValueConvert<'a> for BatchTransition { fn to_object(&self, skip_signature: bool) -> Result { match self { - DocumentsBatchTransition::V0(transition) => { + BatchTransition::V0(transition) => { let mut value = transition.to_object(skip_signature)?; value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(0))?; Ok(value) @@ -26,7 +24,7 @@ impl<'a> StateTransitionValueConvert<'a> for DocumentsBatchTransition { fn to_canonical_object(&self, skip_signature: bool) -> Result { match self { - DocumentsBatchTransition::V0(transition) => { + BatchTransition::V0(transition) => { let mut value = transition.to_canonical_object(skip_signature)?; value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(0))?; Ok(value) @@ -36,7 +34,7 @@ impl<'a> StateTransitionValueConvert<'a> for DocumentsBatchTransition { fn to_canonical_cleaned_object(&self, skip_signature: bool) -> Result { match self { - DocumentsBatchTransition::V0(transition) => { + BatchTransition::V0(transition) => { let mut value = transition.to_canonical_cleaned_object(skip_signature)?; value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(0))?; Ok(value) @@ -46,7 +44,7 @@ impl<'a> StateTransitionValueConvert<'a> for DocumentsBatchTransition { fn to_cleaned_object(&self, skip_signature: bool) -> Result { match self { - DocumentsBatchTransition::V0(transition) => { + BatchTransition::V0(transition) => { let mut value = transition.to_cleaned_object(skip_signature)?; value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(0))?; Ok(value) @@ -70,7 +68,7 @@ impl<'a> StateTransitionValueConvert<'a> for DocumentsBatchTransition { }); match version { - 0 => Ok(DocumentsBatchTransitionV0::from_object(raw_object, platform_version)?.into()), + 0 => Ok(BatchTransitionV0::from_object(raw_object, platform_version)?.into()), n => Err(ProtocolError::UnknownVersionError(format!( "Unknown DataContractCreateTransition version {n}" ))), @@ -93,9 +91,7 @@ impl<'a> StateTransitionValueConvert<'a> for DocumentsBatchTransition { }); match version { - 0 => Ok( - DocumentsBatchTransitionV0::from_value_map(raw_value_map, platform_version)?.into(), - ), + 0 => Ok(BatchTransitionV0::from_value_map(raw_value_map, platform_version)?.into()), n => Err(ProtocolError::UnknownVersionError(format!( "Unknown DataContractCreateTransition version {n}" ))), @@ -108,7 +104,7 @@ impl<'a> StateTransitionValueConvert<'a> for DocumentsBatchTransition { .map_err(ProtocolError::ValueError)?; match version { - 0 => DocumentsBatchTransitionV0::clean_value(value), + 0 => BatchTransitionV0::clean_value(value), n => Err(ProtocolError::UnknownVersionError(format!( "Unknown DataContractCreateTransition version {n}" ))), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/version.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/version.rs new file mode 100644 index 00000000000..be7d07021e1 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/version.rs @@ -0,0 +1,12 @@ +use crate::state_transition::batch_transition::BatchTransition; +use crate::state_transition::FeatureVersioned; +use crate::version::FeatureVersion; + +impl FeatureVersioned for BatchTransition { + fn feature_version(&self) -> FeatureVersion { + match self { + BatchTransition::V0(v0) => v0.feature_version(), + BatchTransition::V1(v1) => v1.feature_version(), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/accessors/mod.rs deleted file mode 100644 index 34ae8b57ab9..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/accessors/mod.rs +++ /dev/null @@ -1,19 +0,0 @@ -mod v0; - -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; -use crate::state_transition::documents_batch_transition::DocumentsBatchTransition; -pub use v0::*; - -impl DocumentsBatchTransitionAccessorsV0 for DocumentsBatchTransition { - fn transitions(&self) -> &Vec { - match self { - DocumentsBatchTransition::V0(v0) => &v0.transitions, - } - } - - fn transitions_slice(&self) -> &[DocumentTransition] { - match self { - DocumentsBatchTransition::V0(v0) => v0.transitions.as_slice(), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/accessors/v0/mod.rs deleted file mode 100644 index 1e458fad496..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/accessors/v0/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; - -pub trait DocumentsBatchTransitionAccessorsV0 { - fn transitions(&self) -> &Vec; - fn transitions_slice(&self) -> &[DocumentTransition]; -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/v0_methods.rs deleted file mode 100644 index 82b3fd624d2..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_delete_transition/v0/v0_methods.rs +++ /dev/null @@ -1,17 +0,0 @@ -use crate::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use crate::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; -use crate::state_transition::documents_batch_transition::document_transition::document_delete_transition::DocumentDeleteTransitionV0; - -impl DocumentBaseTransitionAccessors for DocumentDeleteTransitionV0 { - fn base(&self) -> &DocumentBaseTransition { - &self.base - } - - fn base_mut(&mut self) -> &mut DocumentBaseTransition { - &mut self.base - } - - fn set_base(&mut self, base: DocumentBaseTransition) { - self.base = base - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/document_transition/document_transition_methods/mod.rs deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/identity_signed.rs deleted file mode 100644 index 3d8a2d1486e..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/identity_signed.rs +++ /dev/null @@ -1,27 +0,0 @@ -use crate::identity::{KeyID, Purpose, SecurityLevel}; -use crate::state_transition::documents_batch_transition::DocumentsBatchTransition; -use crate::state_transition::StateTransitionIdentitySigned; - -impl StateTransitionIdentitySigned for DocumentsBatchTransition { - fn signature_public_key_id(&self) -> KeyID { - match self { - DocumentsBatchTransition::V0(transition) => transition.signature_public_key_id(), - } - } - - fn set_signature_public_key_id(&mut self, key_id: KeyID) { - match self { - DocumentsBatchTransition::V0(transition) => { - transition.set_signature_public_key_id(key_id) - } - } - } - - fn security_level_requirement(&self, purpose: Purpose) -> Vec { - match self { - DocumentsBatchTransition::V0(transition) => { - transition.security_level_requirement(purpose) - } - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs deleted file mode 100644 index 8c7a1891458..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/mod.rs +++ /dev/null @@ -1,601 +0,0 @@ -use bincode::{Decode, Encode}; - -use std::convert::TryInto; - -use derive_more::From; - -use platform_value::Value; -#[cfg(feature = "state-transition-serde-conversion")] -use serde::{Deserialize, Serialize}; - -use crate::ProtocolError; -use crate::{identity::SecurityLevel, state_transition::StateTransitionFieldTypes}; - -pub use self::document_transition::{ - document_base_transition, document_create_transition, - document_create_transition::DocumentCreateTransition, document_delete_transition, - document_delete_transition::DocumentDeleteTransition, document_replace_transition, - document_replace_transition::DocumentReplaceTransition, token_base_transition, - token_burn_transition, token_burn_transition::TokenBurnTransition, token_issuance_transition, - token_issuance_transition::TokenIssuanceTransition, token_transfer_transition, - token_transfer_transition::TokenTransferTransition, -}; - -use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize, PlatformSignable}; -use platform_versioning::PlatformVersioned; - -pub mod accessors; -pub mod document_transition; -pub mod fields; -mod identity_signed; -#[cfg(feature = "state-transition-json-conversion")] -mod json_conversion; -pub mod methods; -mod state_transition_like; -mod v0; -#[cfg(feature = "validation")] -mod validation; -#[cfg(feature = "state-transition-value-conversion")] -mod value_conversion; -mod version; - -use crate::state_transition::data_contract_update_transition::{ - SIGNATURE, SIGNATURE_PUBLIC_KEY_ID, -}; - -use crate::state_transition::documents_batch_transition::fields::property_names; - -use crate::identity::state_transition::OptionallyAssetLockProved; -pub use v0::*; - -#[derive( - Debug, - Clone, - PartialEq, - Encode, - Decode, - PlatformDeserialize, - PlatformSerialize, - PlatformSignable, - PlatformVersioned, - From, -)] -#[cfg_attr( - feature = "state-transition-serde-conversion", - derive(Serialize, Deserialize), - serde(tag = "$version") -)] -#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version -#[platform_version_path_bounds( - "dpp.state_transition_serialization_versions.documents_batch_state_transition" -)] -pub enum DocumentsBatchTransition { - #[cfg_attr(feature = "state-transition-serde-conversion", serde(rename = "0"))] - V0(DocumentsBatchTransitionV0), -} - -// -// impl Default for DocumentsBatchTransition { -// fn default() -> Self { -// match LATEST_PLATFORM_VERSION -// .state_transitions -// .documents_batch_state_transition -// .default_current_version -// { -// 0 => DocumentsBatchTransitionV0::default().into(), -// _ => DocumentsBatchTransitionV0::default().into(), //for now -// } -// } -// } -// -// impl DocumentsBatchTransition { -// #[cfg(feature = "state-transition-json-conversion")] -// pub fn from_json_object( -// json_value: JsonValue, -// data_contracts: Vec, -// ) -> Result { -// let mut json_value = json_value; -// -// let maybe_signature = json_value.get_string(property_names::SIGNATURE).ok(); -// let signature = if let Some(signature) = maybe_signature { -// Some(BinaryData( -// BASE64_STANDARD.decode(signature).context("signature exists but isn't valid base64")?, -// )) -// } else { -// None -// }; -// -// let mut batch_transitions = DocumentsBatchTransition { -// feature_version: json_value -// .get_u64(property_names::STATE_TRANSITION_PROTOCOL_VERSION) -// // js-dpp allows `protocolVersion` to be undefined -// .unwrap_or(LATEST_VERSION as u64) as u16, -// signature, -// signature_public_key_id: json_value -// .get_u64(property_names::SIGNATURE_PUBLIC_KEY_ID) -// .ok() -// .map(|v| v as KeyID), -// owner_id: Identifier::from_string( -// json_value.get_string(property_names::OWNER_ID)?, -// Encoding::Base58, -// )?, -// ..Default::default() -// }; -// -// let mut document_transitions: Vec = vec![]; -// let maybe_transitions = json_value.remove(property_names::TRANSITIONS); -// if let Ok(JsonValue::Array(json_transitions)) = maybe_transitions { -// let data_contracts_map: HashMap, DataContract> = data_contracts -// .into_iter() -// .map(|dc| (dc.id.as_bytes().to_vec(), dc)) -// .collect(); -// -// for json_transition in json_transitions { -// let id = Identifier::from_string( -// json_transition.get_string(property_names::DATA_CONTRACT_ID)?, -// Encoding::Base58, -// )?; -// let data_contract = -// data_contracts_map -// .get(&id.as_bytes().to_vec()) -// .ok_or_else(|| { -// anyhow!( -// "Data Contract doesn't exists for Transition: {:?}", -// json_transition -// ) -// })?; -// let document_transition = -// DocumentTransition::from_json_object(json_transition, data_contract.clone())?; -// document_transitions.push(document_transition); -// } -// } -// -// batch_transitions.transitions = document_transitions; -// Ok(batch_transitions) -// } -// -// /// creates the instance of [`DocumentsBatchTransition`] from raw object -// pub fn from_object_with_contracts( -// raw_object: Value, -// data_contracts: Vec, -// ) -> Result { -// let map = raw_object -// .into_btree_string_map() -// .map_err(ProtocolError::ValueError)?; -// Self::from_value_map(map, data_contracts) -// } -// -// /// creates the instance of [`DocumentsBatchTransition`] from a value map -// pub fn from_value_map( -// mut map: BTreeMap, -// data_contracts: Vec, -// ) -> Result { -// let mut batch_transitions = DocumentsBatchTransition { -// feature_version: map -// .get_integer(property_names::STATE_TRANSITION_PROTOCOL_VERSION) -// // js-dpp allows `protocolVersion` to be undefined -// .unwrap_or(LATEST_VERSION as u64) as u16, -// signature: map -// .get_optional_binary_data(property_names::SIGNATURE) -// .map_err(ProtocolError::ValueError)?, -// signature_public_key_id: map -// .get_optional_integer(property_names::SIGNATURE_PUBLIC_KEY_ID) -// .map_err(ProtocolError::ValueError)?, -// owner_id: Identifier::from( -// map.get_hash256_bytes(property_names::OWNER_ID) -// .map_err(ProtocolError::ValueError)?, -// ), -// ..Default::default() -// }; -// -// let mut document_transitions: Vec = vec![]; -// let maybe_transitions = map.remove(property_names::TRANSITIONS); -// if let Some(Value::Array(raw_transitions)) = maybe_transitions { -// let data_contracts_map: HashMap, DataContract> = data_contracts -// .into_iter() -// .map(|dc| (dc.id.as_bytes().to_vec(), dc)) -// .collect(); -// -// for raw_transition in raw_transitions { -// let mut raw_transition_map = raw_transition -// .into_btree_string_map() -// .map_err(ProtocolError::ValueError)?; -// let data_contract_id = -// raw_transition_map.get_hash256_bytes(property_names::DATA_CONTRACT_ID)?; -// let document_type = raw_transition_map.get_str(property_names::DOCUMENT_TYPE)?; -// let data_contract = data_contracts_map -// .get(data_contract_id.as_slice()) -// .ok_or_else(|| { -// anyhow!( -// "Data Contract doesn't exists for Transition: {:?}", -// raw_transition_map -// ) -// })?; -// -// //Because we don't know how the json came in we need to sanitize it -// let (identifiers, binary_paths): (Vec<_>, Vec<_>) = -// data_contract.get_identifiers_and_binary_paths_owned(document_type)?; -// -// raw_transition_map -// .replace_at_paths( -// identifiers.into_iter().chain( -// document_base_transition::IDENTIFIER_FIELDS -// .iter() -// .map(|a| a.to_string()), -// ), -// ReplacementType::Identifier, -// ) -// .map_err(ProtocolError::ValueError)?; -// raw_transition_map -// .replace_at_paths( -// binary_paths.into_iter().chain( -// document_create_transition::BINARY_FIELDS -// .iter() -// .map(|a| a.to_string()), -// ), -// ReplacementType::BinaryBytes, -// ) -// .map_err(ProtocolError::ValueError)?; -// -// let document_transition = -// DocumentTransition::from_value_map(raw_transition_map, data_contract.clone())?; -// document_transitions.push(document_transition); -// } -// } -// -// batch_transitions.transitions = document_transitions; -// Ok(batch_transitions) -// } -// -// pub fn transitions(&self) -> &Vec { -// &self.transitions -// } -// -// pub fn transitions_slice(&self) -> &[DocumentTransition] { -// self.transitions.as_slice() -// } -// -// pub fn clean_value(value: &mut Value) -> Result<(), platform_value::Error> { -// value.replace_at_paths(IDENTIFIER_FIELDS, ReplacementType::Identifier)?; -// value.replace_integer_type_at_paths(U16_FIELDS, IntegerReplacementType::U16)?; -// Ok(()) -// } -// } -// -// -// impl DocumentsBatchTransition { -// fn to_value(&self, skip_signature: bool) -> Result { -// Ok(self.to_value_map(skip_signature)?.into()) -// } -// -// fn to_value_map(&self, skip_signature: bool) -> Result, ProtocolError> { -// let mut map = BTreeMap::new(); -// map.insert( -// property_names::STATE_TRANSITION_PROTOCOL_VERSION.to_string(), -// Value::U16(self.feature_version), -// ); -// map.insert( -// property_names::TRANSITION_TYPE.to_string(), -// Value::U8(self.transition_type as u8), -// ); -// map.insert( -// property_names::OWNER_ID.to_string(), -// Value::Identifier(self.owner_id.to_buffer()), -// ); -// -// if !skip_signature { -// if let Some(signature) = self.signature.as_ref() { -// map.insert( -// property_names::SIGNATURE.to_string(), -// Value::Bytes(signature.to_vec()), -// ); -// } -// if let Some(signature_key_id) = self.signature_public_key_id { -// map.insert( -// property_names::SIGNATURE.to_string(), -// Value::U32(signature_key_id), -// ); -// } -// } -// let mut transitions = vec![]; -// for transition in self.transitions.iter() { -// transitions.push(transition.to_object()?) -// } -// map.insert( -// property_names::TRANSITIONS.to_string(), -// Value::Array(transitions), -// ); -// -// Ok(map) -// } -// } - -impl StateTransitionFieldTypes for DocumentsBatchTransition { - fn binary_property_paths() -> Vec<&'static str> { - vec![SIGNATURE] - } - - fn identifiers_property_paths() -> Vec<&'static str> { - vec![property_names::OWNER_ID] - } - - fn signature_property_paths() -> Vec<&'static str> { - vec![SIGNATURE, SIGNATURE_PUBLIC_KEY_ID] - } - // - // fn to_json(&self, skip_signature: bool) -> Result { - // self.to_object(skip_signature) - // .and_then(|value| value.try_into().map_err(ProtocolError::ValueError)) - // } - // - // fn to_object(&self, skip_signature: bool) -> Result { - // let mut object: Value = platform_value::to_value(self)?; - // if skip_signature { - // for path in Self::signature_property_paths() { - // let _ = object.remove_values_matching_path(path); - // } - // } - // let mut transitions = vec![]; - // for transition in self.transitions.iter() { - // transitions.push(transition.to_object()?) - // } - // object.insert( - // String::from(property_names::TRANSITIONS), - // Value::Array(transitions), - // )?; - // - // Ok(object) - // } - // - // #[cfg(feature = "state-transition-cbor-conversion")] - // fn to_cbor_buffer(&self, skip_signature: bool) -> Result, ProtocolError> { - // let mut result_buf = self.feature_version.encode_var_vec(); - // let value: CborValue = self.to_object(skip_signature)?.try_into()?; - // - // let map = CborValue::serialized(&value) - // .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - // - // let mut canonical_map: CborCanonicalMap = map.try_into()?; - // canonical_map.remove(property_names::STATE_TRANSITION_PROTOCOL_VERSION); - // - // // Replace binary fields individually for every transition using respective data contract - // if let Some(CborValue::Array(ref mut transitions)) = - // canonical_map.get_mut(&CborValue::Text(property_names::TRANSITIONS.to_string())) - // { - // for (i, cbor_transition) in transitions.iter_mut().enumerate() { - // let transition = self - // .transitions - // .get(i) - // .context(format!("transition with index {} doesn't exist", i))?; - // - // let (identifier_properties, binary_properties) = transition - // .base() - // .data_contract - // .get_identifiers_and_binary_paths( - // &self.transitions[i].base().document_type_name, - // )?; - // - // if transition.get_updated_at().is_none() { - // cbor_transition.remove("$updatedAt"); - // } - // - // cbor_transition.replace_paths( - // identifier_properties - // .into_iter() - // .chain(binary_properties) - // .chain(document_base_transition::IDENTIFIER_FIELDS) - // .chain(document_create_transition::BINARY_FIELDS), - // FieldType::ArrayInt, - // FieldType::Bytes, - // ); - // } - // } - // - // canonical_map.replace_paths( - // Self::binary_property_paths() - // .into_iter() - // .chain(Self::identifiers_property_paths()), - // FieldType::ArrayInt, - // FieldType::Bytes, - // ); - // - // if !skip_signature { - // if self.signature.is_none() { - // canonical_map.insert(property_names::SIGNATURE, CborValue::Null) - // } - // if self.signature_public_key_id.is_none() { - // canonical_map.insert(property_names::SIGNATURE_PUBLIC_KEY_ID, CborValue::Null) - // } - // } - // - // canonical_map.sort_canonical(); - // - // let mut buffer = canonical_map - // .to_bytes() - // .map_err(|e| ProtocolError::EncodingError(e.to_string()))?; - // result_buf.append(&mut buffer); - // - // Ok(result_buf) - // } - // - // fn to_cleaned_object(&self, skip_signature: bool) -> Result { - // let mut object: Value = platform_value::to_value(self)?; - // if skip_signature { - // for path in Self::signature_property_paths() { - // let _ = object.remove_values_matching_path(path); - // } - // } - // let mut transitions = vec![]; - // for transition in self.transitions.iter() { - // transitions.push(transition.to_cleaned_object()?) - // } - // object.insert( - // String::from(property_names::TRANSITIONS), - // Value::Array(transitions), - // )?; - // - // Ok(object) - // } -} - -// TODO: Make a DocumentType method -pub fn get_security_level_requirement(v: &Value, default: SecurityLevel) -> SecurityLevel { - let maybe_security_level: Option = v - .get_optional_integer(property_names::SECURITY_LEVEL_REQUIREMENT) - // TODO: Data Contract must already valid so there is no chance that this will fail - .expect("document schema must be a map"); - - match maybe_security_level { - Some(some_level) => (some_level as u8).try_into().unwrap_or(default), - None => default, - } -} -// -// #[cfg(test)] -// mod test { -// use itertools::Itertools; -// use std::sync::Arc; -// -// use platform_value::Bytes32; -// use serde_json::json; -// -// use crate::tests::fixtures::get_extended_documents_fixture; -// use crate::{ -// document::{ -// document_factory::DocumentFactory, -// fetch_and_validate_data_contract::DataContractFetcherAndValidator, -// }, -// state_repository::MockStateRepositoryLike, -// tests::fixtures::{ -// get_data_contract_fixture, get_document_transitions_fixture, -// get_document_validator_fixture, -// }, -// }; -// -// use super::{document_transition::Action, *}; -// -// #[test] -// fn should_return_highest_sec_level_for_all_transitions() { -// let mut data_contract = get_data_contract_fixture(None).data_contract; -// data_contract -// .documents -// .get_mut("niceDocument") -// .unwrap() -// .insert( -// property_names::SECURITY_LEVEL_REQUIREMENT.to_string(), -// json!(SecurityLevel::MEDIUM), -// ) -// .unwrap(); -// data_contract -// .documents -// .get_mut("prettyDocument") -// .unwrap() -// .insert( -// property_names::SECURITY_LEVEL_REQUIREMENT.to_string(), -// json!(SecurityLevel::MASTER), -// ) -// .unwrap(); -// -// // 0 is niceDocument, -// // 1 and 2 are pretty documents, -// // 3 and 4 are indexed documents that do not have security level specified -// let documents = get_extended_documents_fixture(data_contract).unwrap(); -// let medium_security_document = documents.get(0).unwrap(); -// let master_security_document = documents.get(1).unwrap(); -// let no_security_level_document = documents.get(3).unwrap(); -// -// let document_factory = DocumentFactory::new( -// 1, -// get_document_validator_fixture(), -// DataContractFetcherAndValidator::new(Arc::new(MockStateRepositoryLike::new())), -// ); -// -// let batch_transition = document_factory -// .create_state_transition(vec![( -// Action::Create, -// vec![medium_security_document.to_owned()], -// )]) -// .expect("batch transition should be created"); -// -// assert!(batch_transition -// .get_security_level_requirement() -// .iter() -// .contains(&SecurityLevel::MEDIUM)); -// -// let batch_transition = document_factory -// .create_state_transition(vec![( -// Action::Create, -// vec![ -// medium_security_document.to_owned(), -// master_security_document.to_owned(), -// ], -// )]) -// .expect("batch transition should be created"); -// -// assert!(batch_transition -// .get_security_level_requirement() -// .iter() -// .contains(&SecurityLevel::MASTER)); -// -// let batch_transition = document_factory -// .create_state_transition(vec![( -// Action::Create, -// vec![no_security_level_document.to_owned()], -// )]) -// .expect("batch transition should be created"); -// -// assert!(batch_transition -// .get_security_level_requirement() -// .iter() -// .contains(&SecurityLevel::HIGH)); -// } -// -// #[test] -// fn should_convert_to_batch_transition_to_the_buffer() { -// let transition_id_base58 = "6o8UfoeE2s7dTkxxyPCixuxe8TM5DtCGHTMummUN6t5M"; -// let expected_bytes_hex ="01a5647479706501676f776e657249645820a858bdc49c968148cd12648ee048d34003e9da3fbf2cbc62c31bb4c717bf690d697369676e6174757265f76b7472616e736974696f6e7381a7632469645820561b9b2e90b7c0ca355f729777b45bc646a18f5426a9462f0333c766135a3120646e616d656543757469656524747970656c6e696365446f63756d656e746724616374696f6e006824656e74726f707958202cdbaeda81c14765ba48432ff5cc900a7cacd4538b817fc71f38907aaa7023746a246372656174656441741b000001853a3602876f2464617461436f6e74726163744964582049aea5df2124a51d5d8dcf466e238fbc77fd72601be69daeb6dba75e8d26b30c747369676e61747572655075626c69634b65794964f7" ; -// let data_contract_id_base58 = "5xdDqypFMPfvF6UdWxefCGvRFyxgkPZCAK6TS4pvvw6T"; -// let owner_id_base58 = "CL9ydpdxP4kQniGx6z5JUL8K72gnwcemKT2aJmh7sdwJ"; -// let entropy_base64 = "LNuu2oHBR2W6SEMv9cyQCnys1FOLgX/HHziQeqpwI3Q="; -// -// let transition_id = -// Identifier::from_string(transition_id_base58, Encoding::Base58).unwrap(); -// let expected_bytes = hex::decode(expected_bytes_hex).unwrap(); -// let data_contract_id = -// Identifier::from_string(data_contract_id_base58, Encoding::Base58).unwrap(); -// let owner_id = Identifier::from_string(owner_id_base58, Encoding::Base58).unwrap(); -// let entropy_bytes: [u8; 32] = BASE64_STANDARD.decode(entropy_base64).unwrap().try_into().unwrap(); -// -// let mut data_contract = get_data_contract_fixture(Some(owner_id)).data_contract; -// data_contract.id = data_contract_id; -// -// let documents = get_extended_documents_fixture(data_contract.clone()).unwrap(); -// let mut document = documents.first().unwrap().to_owned(); -// document.entropy = Bytes32::new(entropy_bytes); -// -// let transitions = get_document_transitions_fixture([(DocumentTransitionActionType::Create, vec![document])]); -// let mut transition = transitions.first().unwrap().to_owned(); -// if let DocumentTransition::Create(ref mut t) = transition { -// t.created_at = Some(1671718896263); -// t.base.id = transition_id; -// } -// -// let mut map = BTreeMap::new(); -// map.insert( -// "ownerId".to_string(), -// Value::Identifier(owner_id.to_buffer()), -// ); -// map.insert( -// "transitions".to_string(), -// Value::Array(vec![transition.to_object().unwrap()]), -// ); -// -// let state_transition = DocumentsBatchTransition::from_value_map(map, vec![data_contract]) -// .expect("transition should be created"); -// -// let bytes = state_transition.to_cbor_buffer(false).unwrap(); -// -// assert_eq!(hex::encode(expected_bytes), hex::encode(bytes)); -// } -// } -impl OptionallyAssetLockProved for DocumentsBatchTransition {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/state_transition_like.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/state_transition_like.rs deleted file mode 100644 index 69b5bfa5713..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/state_transition_like.rs +++ /dev/null @@ -1,71 +0,0 @@ -use crate::prelude::UserFeeIncrease; -use crate::state_transition::documents_batch_transition::DocumentsBatchTransition; -use crate::state_transition::{StateTransitionLike, StateTransitionType}; -use crate::version::FeatureVersion; -use platform_value::{BinaryData, Identifier}; - -impl StateTransitionLike for DocumentsBatchTransition { - /// Returns ID of the created contract - fn modified_data_ids(&self) -> Vec { - match self { - DocumentsBatchTransition::V0(transition) => transition.modified_data_ids(), - } - } - - fn state_transition_protocol_version(&self) -> FeatureVersion { - match self { - DocumentsBatchTransition::V0(_) => 0, - } - } - /// returns the type of State Transition - fn state_transition_type(&self) -> StateTransitionType { - match self { - DocumentsBatchTransition::V0(transition) => transition.state_transition_type(), - } - } - /// returns the signature as a byte-array - fn signature(&self) -> &BinaryData { - match self { - DocumentsBatchTransition::V0(transition) => transition.signature(), - } - } - /// set a new signature - fn set_signature(&mut self, signature: BinaryData) { - match self { - DocumentsBatchTransition::V0(transition) => transition.set_signature(signature), - } - } - - fn set_signature_bytes(&mut self, signature: Vec) { - match self { - DocumentsBatchTransition::V0(transition) => transition.set_signature_bytes(signature), - } - } - - /// returns the fee multiplier - fn user_fee_increase(&self) -> UserFeeIncrease { - match self { - DocumentsBatchTransition::V0(transition) => transition.user_fee_increase(), - } - } - /// set a fee multiplier - fn set_user_fee_increase(&mut self, user_fee_increase: UserFeeIncrease) { - match self { - DocumentsBatchTransition::V0(transition) => { - transition.set_user_fee_increase(user_fee_increase) - } - } - } - - fn owner_id(&self) -> Identifier { - match self { - DocumentsBatchTransition::V0(transition) => transition.owner_id(), - } - } - - fn unique_identifiers(&self) -> Vec { - match self { - DocumentsBatchTransition::V0(transition) => transition.unique_identifiers(), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/json_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/json_conversion.rs deleted file mode 100644 index ac62cb41c73..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/json_conversion.rs +++ /dev/null @@ -1,4 +0,0 @@ -use crate::state_transition::documents_batch_transition::DocumentsBatchTransitionV0; -use crate::state_transition::StateTransitionJsonConvert; - -impl<'a> StateTransitionJsonConvert<'a> for DocumentsBatchTransitionV0 {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/value_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/value_conversion.rs deleted file mode 100644 index d82f708df4d..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/v0/value_conversion.rs +++ /dev/null @@ -1,4 +0,0 @@ -use crate::state_transition::documents_batch_transition::DocumentsBatchTransitionV0; -use crate::state_transition::StateTransitionValueConvert; - -impl<'a> StateTransitionValueConvert<'a> for DocumentsBatchTransitionV0 {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/version.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/version.rs deleted file mode 100644 index f65071aabe8..00000000000 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/documents_batch_transition/version.rs +++ /dev/null @@ -1,11 +0,0 @@ -use crate::state_transition::documents_batch_transition::DocumentsBatchTransition; -use crate::state_transition::FeatureVersioned; -use crate::version::FeatureVersion; - -impl FeatureVersioned for DocumentsBatchTransition { - fn feature_version(&self) -> FeatureVersion { - match self { - DocumentsBatchTransition::V0(v0) => v0.feature_version(), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/mod.rs index 01a4fd6ffd8..03238bee69e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/mod.rs @@ -1 +1 @@ -pub mod documents_batch_transition; +pub mod batch_transition; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/value_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/value_conversion.rs index 2ebc3b6f859..6822f7d2c38 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/value_conversion.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/value_conversion.rs @@ -1,5 +1,5 @@ use crate::serialization::ValueConvertible; -use crate::state_transition::documents_batch_transition::fields::property_names::STATE_TRANSITION_PROTOCOL_VERSION; +use crate::state_transition::batch_transition::fields::property_names::STATE_TRANSITION_PROTOCOL_VERSION; use crate::state_transition::public_key_in_creation::v0::IdentityPublicKeyInCreationV0; use crate::state_transition::public_key_in_creation::IdentityPublicKeyInCreation; use crate::state_transition::StateTransitionValueConvert; diff --git a/packages/rs-dpp/src/state_transition/traits/state_transition_like.rs b/packages/rs-dpp/src/state_transition/traits/state_transition_like.rs index 4884fd46b68..e3084b6310d 100644 --- a/packages/rs-dpp/src/state_transition/traits/state_transition_like.rs +++ b/packages/rs-dpp/src/state_transition/traits/state_transition_like.rs @@ -8,8 +8,7 @@ use crate::version::FeatureVersion; use crate::state_transition::StateTransitionType; use crate::state_transition::{StateTransition, StateTransitionFieldTypes}; -pub const DOCUMENT_TRANSITION_TYPES: [StateTransitionType; 1] = - [StateTransitionType::DocumentsBatch]; +pub const DOCUMENT_TRANSITION_TYPES: [StateTransitionType; 1] = [StateTransitionType::Batch]; pub const IDENTITY_TRANSITION_TYPE: [StateTransitionType; 5] = [ StateTransitionType::IdentityCreate, diff --git a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs index 23126df2baf..d50516c4400 100644 --- a/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs +++ b/packages/rs-dpp/src/tests/fixtures/get_document_transitions_fixture.rs @@ -5,12 +5,10 @@ use platform_version::version::PlatformVersion; use std::collections::BTreeMap; use crate::document::Document; -use crate::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; -use crate::state_transition::documents_batch_transition::document_transition::DocumentTransition; - -use crate::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; - -pub fn get_document_transitions_fixture<'a>( +use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use crate::state_transition::batch_transition::batched_transition::BatchedTransition; +use crate::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; +pub fn get_batched_transitions_fixture<'a>( documents: impl IntoIterator< Item = ( DocumentTransitionActionType, @@ -18,7 +16,7 @@ pub fn get_document_transitions_fixture<'a>( ), >, nonce_counter: &mut BTreeMap<(Identifier, Identifier), u64>, //IdentityID/ContractID -> nonce -) -> Vec { +) -> Vec { let protocol_version = PlatformVersion::latest().protocol_version; let document_factory = DocumentFactory::new(protocol_version).expect("expected to get document factory"); @@ -26,6 +24,7 @@ pub fn get_document_transitions_fixture<'a>( document_factory .create_state_transition(documents, nonce_counter) .expect("the transitions should be created") - .transitions() - .to_owned() + .transitions_iter() + .map(|batched_transition_ref| batched_transition_ref.to_owned_transition()) + .collect() } 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 acfb7fca049..8a552fd154e 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 @@ -229,8 +229,8 @@ mod tests { use dpp::serialization::{PlatformSerializable, Signable}; use dpp::native_bls::NativeBlsModule; - use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; - use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; + use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; + use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::identity_create_transition::methods::IdentityCreateTransitionMethodsV0; use dpp::state_transition::identity_create_transition::IdentityCreateTransition; use dpp::state_transition::identity_topup_transition::methods::IdentityTopUpTransitionMethodsV0; @@ -1592,7 +1592,7 @@ mod tests { altered_document.set("avatarUrl", "http://test.com/cat.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -1612,7 +1612,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_update_transition = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document, profile, &key, diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs b/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs index 1cbac74c740..14e8e69fdea 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs @@ -24,8 +24,8 @@ mod refund_tests { use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::{Identity, IdentityPublicKey}; use dpp::platform_value::Bytes32; - use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; - use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; + use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; + use dpp::state_transition::batch_transition::BatchTransition; use drive::util::test_helpers::setup_contract; use platform_version::version::PlatformVersion; use rand::prelude::StdRng; @@ -71,7 +71,7 @@ mod refund_tests { altered_document.set("avatarUrl", "http://test.com/dog.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), profile, entropy.0, @@ -178,7 +178,7 @@ mod refund_tests { assert_eq!(serialized_len, 173); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), profile, entropy.0, @@ -296,7 +296,7 @@ mod refund_tests { setup_initial_document(&platform, profile, &mut rng, &identity, &key, &signer); let documents_batch_delete_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( document, profile, &key, @@ -392,7 +392,7 @@ mod refund_tests { fast_forward_to_block(&platform, 1_200_000_000, 900, 42, 1, false); //next epoch let documents_batch_delete_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( document, profile, &key, @@ -491,7 +491,7 @@ mod refund_tests { fast_forward_to_block(&platform, 1_200_000_000, 900, 42, 40, false); //a year later let documents_batch_delete_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( document, profile, &key, @@ -586,7 +586,7 @@ mod refund_tests { fast_forward_to_block(&platform, 10_200_000_000, 9000, 42, 40 * 25, false); //25 years later let documents_batch_delete_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( document, profile, &key, @@ -681,7 +681,7 @@ mod refund_tests { fast_forward_to_block(&platform, 10_200_000_000, 9000, 42, 40 * 50, false); //50 years later let documents_batch_delete_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( document, profile, &key, @@ -777,7 +777,7 @@ mod refund_tests { fast_forward_to_block(&platform, 1_200_000_000, 900, 42, 10, false); //next epoch let documents_batch_delete_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( document, profile, &key, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_simple_pre_check_balance/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_simple_pre_check_balance/v0/mod.rs index 6f9cfb87adf..9a9e2f8901f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_simple_pre_check_balance/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_simple_pre_check_balance/v0/mod.rs @@ -33,7 +33,7 @@ impl ValidateSimplePreCheckBalanceV0 for StateTransition { .state_transition_min_fees .contract_update } - StateTransition::DocumentsBatch(_) => { + StateTransition::Batch(_) => { platform_version .fee_version .state_transition_min_fees 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 c3f10fa2758..12d7bdd4e06 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 @@ -528,7 +528,7 @@ impl StateTransitionBasicStructureValidationV0 for StateTransition { StateTransition::IdentityCreditWithdrawal(st) => { st.validate_basic_structure(platform_version) } - StateTransition::DocumentsBatch(st) => st.validate_basic_structure(platform_version), + StateTransition::Batch(st) => st.validate_basic_structure(platform_version), StateTransition::IdentityCreditTransfer(st) => { st.validate_basic_structure(platform_version) } @@ -554,7 +554,7 @@ impl StateTransitionNonceValidationV0 for StateTransition { platform_version: &PlatformVersion, ) -> Result { match self { - StateTransition::DocumentsBatch(st) => st.validate_nonces( + StateTransition::Batch(st) => st.validate_nonces( platform, block_info, tx, @@ -618,7 +618,7 @@ impl StateTransitionHasNonceValidationV0 for StateTransition { 0 => { let has_nonce_validation = matches!( self, - StateTransition::DocumentsBatch(_) + StateTransition::Batch(_) | StateTransition::DataContractCreate(_) | StateTransition::DataContractUpdate(_) | StateTransition::IdentityUpdate(_) @@ -632,7 +632,7 @@ impl StateTransitionHasNonceValidationV0 for StateTransition { // Preferably to use match without wildcard arm (_) to avoid missing cases // in the future when new state transitions are added let has_nonce_validation = match self { - StateTransition::DocumentsBatch(_) + StateTransition::Batch(_) | StateTransition::DataContractCreate(_) | StateTransition::DataContractUpdate(_) | StateTransition::IdentityUpdate(_) @@ -666,7 +666,7 @@ impl StateTransitionIdentityBalanceValidationV0 for StateTransition { StateTransition::IdentityCreditWithdrawal(st) => { st.validate_minimum_balance_pre_check(identity, platform_version) } - StateTransition::DocumentsBatch(st) => { + StateTransition::Batch(st) => { st.validate_minimum_balance_pre_check(identity, platform_version) } StateTransition::DataContractCreate(_) @@ -687,7 +687,7 @@ impl StateTransitionIdentityBalanceValidationV0 for StateTransition { | StateTransition::IdentityCreditWithdrawal(_) | StateTransition::DataContractCreate(_) | StateTransition::DataContractUpdate(_) - | StateTransition::DocumentsBatch(_) + | StateTransition::Batch(_) | StateTransition::IdentityUpdate(_) ) } @@ -790,7 +790,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for StateTransition { platform_version: &PlatformVersion, ) -> Result, Error> { match self { - StateTransition::DocumentsBatch(st) => st.validate_advanced_structure_from_state( + StateTransition::Batch(st) => st.validate_advanced_structure_from_state( block_info, network, action, @@ -829,7 +829,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for StateTransition { fn has_advanced_structure_validation_with_state(&self) -> bool { matches!( self, - StateTransition::DocumentsBatch(_) + StateTransition::Batch(_) | StateTransition::IdentityCreate(_) | StateTransition::MasternodeVote(_) ) @@ -838,7 +838,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for StateTransition { /// This means we should transform into the action before validation of the advanced structure, /// and that we must even do this on check_tx fn requires_advanced_structure_validation_with_state_on_check_tx(&self) -> bool { - matches!(self, StateTransition::DocumentsBatch(_)) + matches!(self, StateTransition::Batch(_)) } } @@ -854,7 +854,7 @@ impl StateTransitionIdentityBasedSignatureValidationV0 for StateTransition { StateTransition::DataContractCreate(_) | StateTransition::DataContractUpdate(_) | StateTransition::IdentityCreditTransfer(_) - | StateTransition::DocumentsBatch(_) => { + | StateTransition::Batch(_) => { //Basic signature verification Ok(self.validate_state_transition_identity_signed( drive, @@ -1029,7 +1029,7 @@ impl StateTransitionStateValidationV0 for StateTransition { tx, ), // The replay attack is prevented by identity data contract nonce - StateTransition::DocumentsBatch(st) => st.validate_state( + StateTransition::Batch(st) => st.validate_state( action, platform, validation_mode, @@ -1060,7 +1060,7 @@ impl StateTransitionStateValidationV0 for StateTransition { impl StateTransitionIsAllowedValidationV0 for StateTransition { fn has_is_allowed_validation(&self, platform_version: &PlatformVersion) -> Result { match self { - StateTransition::DocumentsBatch(st) => st.has_is_allowed_validation(platform_version), + StateTransition::Batch(st) => st.has_is_allowed_validation(platform_version), StateTransition::DataContractCreate(_) | StateTransition::DataContractUpdate(_) | StateTransition::IdentityCreate(_) @@ -1078,9 +1078,7 @@ impl StateTransitionIsAllowedValidationV0 for StateTransition { platform_version: &PlatformVersion, ) -> Result, Error> { match self { - StateTransition::DocumentsBatch(st) => { - st.validate_is_allowed(platform, platform_version) - } + StateTransition::Batch(st) => st.validate_is_allowed(platform, platform_version), _ => Err(Error::Execution(ExecutionError::CorruptedCodeExecution( "validate_is_allowed is not implemented for this state transition", ))), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/mod.rs index 7dfa5e8ebab..1cc02198832 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/mod.rs @@ -49,7 +49,7 @@ impl DocumentCreateTransitionActionValidation for DocumentCreateTransitionAction .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_create_transition_structure_validation { 0 => self.validate_structure_v0(owner_id, block_info, network, platform_version), @@ -74,7 +74,7 @@ impl DocumentCreateTransitionActionValidation for DocumentCreateTransitionAction .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_create_transition_state_validation { 0 => self.validate_state_v0( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/mod.rs index b36e68daa93..63bf935fc74 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/mod.rs @@ -40,7 +40,7 @@ impl DocumentDeleteTransitionActionValidation for DocumentDeleteTransitionAction .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_delete_transition_structure_validation { 0 => self.validate_structure_v0(), @@ -65,7 +65,7 @@ impl DocumentDeleteTransitionActionValidation for DocumentDeleteTransitionAction .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_delete_transition_state_validation { 0 => self.validate_state_v0( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/mod.rs index ef6c32b9968..bbc6b4860b6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/mod.rs @@ -41,7 +41,7 @@ impl DocumentPurchaseTransitionActionValidation for DocumentPurchaseTransitionAc .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_purchase_transition_structure_validation { 0 => self.validate_structure_v0(platform_version), @@ -66,7 +66,7 @@ impl DocumentPurchaseTransitionActionValidation for DocumentPurchaseTransitionAc .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_purchase_transition_state_validation { 0 => self.validate_state_v0( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/mod.rs index fe65d922dd6..e147f8d13a9 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/mod.rs @@ -41,7 +41,7 @@ impl DocumentReplaceTransitionActionValidation for DocumentReplaceTransitionActi .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_replace_transition_structure_validation { 0 => self.validate_structure_v0(platform_version), @@ -66,7 +66,7 @@ impl DocumentReplaceTransitionActionValidation for DocumentReplaceTransitionActi .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_replace_transition_state_validation { 0 => self.validate_state_v0( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/mod.rs index 9b4f6e8b55d..59b836fe8ea 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/mod.rs @@ -41,7 +41,7 @@ impl DocumentTransferTransitionActionValidation for DocumentTransferTransitionAc .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_transfer_transition_structure_validation { 0 => self.validate_structure_v0(platform_version), @@ -66,7 +66,7 @@ impl DocumentTransferTransitionActionValidation for DocumentTransferTransitionAc .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_transfer_transition_state_validation { 0 => self.validate_state_v0( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/mod.rs index 39a18561c03..ee46c2d3be2 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/mod.rs @@ -41,7 +41,7 @@ impl DocumentUpdatePriceTransitionActionValidation for DocumentUpdatePriceTransi .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_transfer_transition_structure_validation { 0 => self.validate_structure_v0(platform_version), @@ -66,7 +66,7 @@ impl DocumentUpdatePriceTransitionActionValidation for DocumentUpdatePriceTransi .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .document_transfer_transition_state_validation { 0 => self.validate_state_v0( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/mod.rs index 32c28c43faa..ad7da4d9515 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/mod.rs @@ -4,3 +4,4 @@ pub(crate) mod document_purchase_transition_action; pub(crate) mod document_replace_transition_action; pub(crate) mod document_transfer_transition_action; pub(crate) mod document_update_price_transition_action; +pub(crate) mod token_issuance_transition_action; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/mod.rs new file mode 100644 index 00000000000..379feef5ae9 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/mod.rs @@ -0,0 +1,103 @@ +use dashcore_rpc::dashcore::Network; +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::TokenIssuanceTransitionAction; +use dpp::version::PlatformVersion; +use drive::grovedb::TransactionArg; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::documents_batch::action_validation::token_issuance_transition_action::state_v0::TokenIssuanceTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::documents_batch::action_validation::token_issuance_transition_action::structure_v0::TokenIssuanceTransitionActionStructureValidationV0; +use crate::platform_types::platform::PlatformStateRef; + +mod state_v0; +mod structure_v0; + +pub trait TokenIssuanceTransitionActionValidation { + fn validate_structure( + &self, + owner_id: Identifier, + block_info: &BlockInfo, + network: Network, + platform_version: &PlatformVersion, + ) -> Result; + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} + +impl TokenIssuanceTransitionActionValidation for TokenIssuanceTransitionAction { + fn validate_structure( + &self, + owner_id: Identifier, + block_info: &BlockInfo, + network: Network, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_issuance_transition_structure_validation + { + 0 => self.validate_structure_v0(owner_id, block_info, network, platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenIssuanceTransitionAction::validate_structure".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_issuance_transition_state_validation + { + 0 => self.validate_state_v0( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + // V1 introduces a validation that a contested document does not yet exist (and the + // cost for this operation) + 1 => self.validate_state_v1( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenIssuanceTransitionAction::validate_state".to_string(), + known_versions: vec![0, 1], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..fa679259793 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/state_v0/mod.rs @@ -0,0 +1,167 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::InvalidDocumentTypeError; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; +use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; +use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; +use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; +use dpp::consensus::state::state_error::StateError; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; +use drive::error::drive::DriveError; +use drive::query::TransactionArg; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::error::Error; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_contender::fetch_contender; +use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenIssuanceTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenIssuanceTransitionActionStateValidationV0 for TokenIssuanceTransitionAction { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let contract_fetch_info = self.base().data_contract_fetch_info(); + + let contract = &contract_fetch_info.contract; + + let document_type_name = self.base().to(); + + let Some(document_type) = contract.document_type_optional_for_name(document_type_name) + else { + return Ok(SimpleConsensusValidationResult::new_with_error( + InvalidDocumentTypeError::new(document_type_name.clone(), contract.id()).into(), + )); + }; + + // TODO: Use multi get https://github.com/facebook/rocksdb/wiki/MultiGet-Performance + // We should check to see if a document already exists in the state + let (already_existing_document, fee_result) = fetch_document_with_id( + platform.drive, + contract, + document_type, + self.base().id(), + transaction, + platform_version, + )?; + + execution_context.add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + if already_existing_document.is_some() { + return Ok(ConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::DocumentAlreadyPresentError( + DocumentAlreadyPresentError::new(self.base().id()), + )), + )); + } + + // we also need to validate that the new document wouldn't conflict with any other document + // this means for example having overlapping unique indexes + + if document_type.indexes().values().any(|index| index.unique) { + let validation_result = platform + .drive + .validate_token_issuance_transition_action_uniqueness( + contract, + document_type, + self, + owner_id, + transaction, + platform_version, + ) + .map_err(Error::Drive)?; + + if !validation_result.is_valid() { + return Ok(validation_result); + } + } + + if let Some((contested_document_resource_vote_poll, _)) = self.prefunded_voting_balance() { + if let Some(stored_info) = self.current_store_contest_info() { + // We have previous stored info + match stored_info.vote_poll_status() { + ContestedDocumentVotePollStatus::NotStarted => { + Ok(SimpleConsensusValidationResult::new()) + } + ContestedDocumentVotePollStatus::Awarded(_) => { + // This is weird as it should have already been found when querying the document, however it is possible + // That it was destroyed + Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::DocumentAlreadyPresentError( + DocumentAlreadyPresentError::new(self.base().id()), + )), + )) + } + ContestedDocumentVotePollStatus::Locked => { + Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::DocumentContestCurrentlyLockedError( + DocumentContestCurrentlyLockedError::new( + contested_document_resource_vote_poll.into(), + stored_info.clone(), + platform_version.fee_version.vote_resolution_fund_fees.contested_document_vote_resolution_unlock_fund_required_amount, + ))), + )) + } + ContestedDocumentVotePollStatus::Started(start_block) => { + // We need to make sure that if there is a contest, it is in its first week + // The week might be more or less, as it's a versioned parameter + let time_ms_since_start = block_info.time_ms.checked_sub(start_block.time_ms).ok_or(Error::Drive(drive::error::Error::Drive(DriveError::CorruptedDriveState(format!("it makes no sense that the start block time {} is before our current block time {}", start_block.time_ms, block_info.time_ms)))))?; + + let join_time_allowed = platform_version.dpp.validation.voting.allow_other_contenders_time_mainnet_ms; + + if time_ms_since_start > join_time_allowed { + return Ok(SimpleConsensusValidationResult::new_with_error(ConsensusError::StateError(StateError::DocumentContestNotJoinableError( + DocumentContestNotJoinableError::new( + contested_document_resource_vote_poll.into(), + stored_info.clone(), + start_block.time_ms, + block_info.time_ms, + join_time_allowed, + ))))) + } + + // we need to also make sure that we are not already a contestant + + let (maybe_existing_contender, fee_result) = fetch_contender(platform.drive, contested_document_resource_vote_poll, owner_id, block_info, transaction, platform_version)?; + + execution_context.add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + if maybe_existing_contender.is_some() { + Ok(SimpleConsensusValidationResult::new_with_error(ConsensusError::StateError(StateError::DocumentContestIdentityAlreadyContestantError(DocumentContestIdentityAlreadyContestantError::new(contested_document_resource_vote_poll.into(), owner_id))))) + } else { + Ok(SimpleConsensusValidationResult::new()) + } + } + } + } else { + Ok(SimpleConsensusValidationResult::new()) + } + } else { + Ok(SimpleConsensusValidationResult::new()) + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs new file mode 100644 index 00000000000..cc7861ddc5d --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs @@ -0,0 +1,40 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::{DocumentCreationNotAllowedError, InvalidDocumentTypeError}; +use dpp::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError; +use dpp::dashcore::Network; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; +use dpp::data_contract::document_type::restricted_creation::CreationRestrictionMode; +use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; +use dpp::identifier::Identifier; +use dpp::validation::{SimpleConsensusValidationResult}; +use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::error::Error; + +pub(super) trait TokenIssuanceTransitionActionStructureValidationV0 { + fn validate_structure_v0( + &self, + owner_id: Identifier, + block_info: &BlockInfo, + network: Network, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenIssuanceTransitionActionStructureValidationV0 for TokenIssuanceTransitionAction { + fn validate_structure_v0( + &self, + owner_id: Identifier, + block_info: &BlockInfo, + network: Network, + platform_version: &PlatformVersion, + ) -> Result { + let token_configuration = self.base().token_configuration()?; + + token_configuration.Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs index 5ac5d1630d2..9bd09432f10 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs @@ -6,15 +6,12 @@ use dpp::dashcore::Network; use dpp::document::Document; use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; use dpp::identity::PartialIdentity; -use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::{ +use dpp::state_transition::batch_transition::batched_transition::document_transition::{ DocumentTransition, DocumentTransitionV0Methods, }; - -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::{StateTransitionIdentitySigned, StateTransitionLike}; - use dpp::validation::ConsensusValidationResult; use dpp::version::PlatformVersion; @@ -24,7 +21,7 @@ use drive::state_transition_action::document::documents_batch::DocumentsBatchTra use crate::execution::validation::state_transition::state_transitions::documents_batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::documents_batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::documents_batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; -use dpp::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; use drive::state_transition_action::StateTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::execution::ExecutionError; @@ -47,7 +44,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::docume ) -> Result, Error>; } -impl DocumentsBatchStateTransitionStructureValidationV0 for DocumentsBatchTransition { +impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { fn validate_advanced_structure_from_state_v0( &self, block_info: &BlockInfo, @@ -65,7 +62,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for DocumentsBatchTransi // We only need to bump the first identity data contract nonce as that will make a replay // attack not possible - let first_transition = self.transitions().first().ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution("There must be at least one state transition as this is already verified in basic validation")))?; + let first_transition = self.document_transitions().first().ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution("There must be at least one state transition as this is already verified in basic validation")))?; let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition( @@ -88,7 +85,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for DocumentsBatchTransi } // We should validate that all newly created documents have valid ids - for transition in self.transitions() { + for transition in self.document_transitions() { if let DocumentTransition::Create(create_transition) = transition { // Validate the ID let generated_document_id = Document::generate_document_id_v0( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/mod.rs index b56c2b8ff32..0ef66608537 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/mod.rs @@ -3,12 +3,12 @@ use crate::error::Error; use crate::execution::validation::state_transition::documents_batch::balance::v0::DocumentsBatchTransitionBalanceValidationV0; use crate::execution::validation::state_transition::processor::v0::StateTransitionIdentityBalanceValidationV0; use dpp::identity::PartialIdentity; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::validation::SimpleConsensusValidationResult; use dpp::version::PlatformVersion; pub(crate) mod v0; -impl StateTransitionIdentityBalanceValidationV0 for DocumentsBatchTransition { +impl StateTransitionIdentityBalanceValidationV0 for BatchTransition { fn validate_minimum_balance_pre_check( &self, identity: &PartialIdentity, @@ -18,7 +18,7 @@ impl StateTransitionIdentityBalanceValidationV0 for DocumentsBatchTransition { .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .balance_pre_check { 0 => self.validate_advanced_minimum_balance_pre_check_v0(identity, platform_version), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/v0/mod.rs index 6f2dc0fd993..c95eb57139e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/v0/mod.rs @@ -4,9 +4,9 @@ use dpp::consensus::basic::BasicError; use dpp::consensus::state::identity::IdentityInsufficientBalanceError; use dpp::consensus::ConsensusError; use dpp::identity::PartialIdentity; -use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::ProtocolError; use dpp::validation::SimpleConsensusValidationResult; @@ -23,7 +23,7 @@ pub(in crate::execution::validation::state_transition::state_transitions) trait ) -> Result; } -impl DocumentsBatchTransitionBalanceValidationV0 for DocumentsBatchTransition { +impl DocumentsBatchTransitionBalanceValidationV0 for BatchTransition { fn validate_advanced_minimum_balance_pre_check_v0( &self, identity: &PartialIdentity, @@ -36,7 +36,7 @@ impl DocumentsBatchTransitionBalanceValidationV0 for DocumentsBatchTransition { "expected to have a balance on identity for documents batch transition", )))?; - let purchases_amount = match self.all_purchases_amount() { + let purchases_amount = match self.all_document_purchases_amount() { Ok(purchase_amount) => purchase_amount.unwrap_or_default(), Err(ProtocolError::Overflow(e)) => { return Ok(SimpleConsensusValidationResult::new_with_error( @@ -65,7 +65,7 @@ impl DocumentsBatchTransitionBalanceValidationV0 for DocumentsBatchTransition { Err(e) => return Err(e.into()), }; - let base_fees = match platform_version.fee_version.state_transition_min_fees.document_batch_sub_transition.checked_mul(self.transitions().len() as u64) { + let base_fees = match platform_version.fee_version.state_transition_min_fees.document_batch_sub_transition.checked_mul(self.document_transitions().len() as u64) { None => return Ok(SimpleConsensusValidationResult::new_with_error(ConsensusError::BasicError(BasicError::OverflowError(OverflowError::new("overflow when multiplying base fee and amount of sub transitions in documents batch transition".to_string()))))), Some(base_fees) => base_fees }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/list/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/list/mod.rs index ea2bdcc07a3..76e98dc2a6c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/list/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/list/mod.rs @@ -11,7 +11,7 @@ pub fn data_trigger_bindings_list( .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .data_triggers .bindings { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs index 1606d5a06c1..def79618966 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs @@ -3,7 +3,7 @@ use crate::execution::validation::state_transition::documents_batch::data_trigge }; use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::TransitionActionTypeGetter; +use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::TransitionActionTypeGetter; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use dpp::version::PlatformVersion; use crate::execution::validation::state_transition::documents_batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/mod.rs index 1f2e7fbbf8b..18910ec1b47 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/mod.rs @@ -18,7 +18,7 @@ pub fn create_contact_request_data_trigger( .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .data_triggers .triggers .create_contact_request_data_trigger diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs index 1b1e8bec303..1f5ab44fb7c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs @@ -127,7 +127,7 @@ mod test { use crate::test::helpers::setup::TestPlatformBuilder; use super::*; use dpp::errors::consensus::state::data_trigger::DataTriggerError; - use dpp::tests::fixtures::{get_contact_request_document_fixture, get_dashpay_contract_fixture, get_document_transitions_fixture, get_identity_fixture}; + use dpp::tests::fixtures::{get_contact_request_document_fixture, get_dashpay_contract_fixture, get_batched_transitions_fixture, get_identity_fixture}; use dpp::version::DefaultForPlatformVersion; use drive::drive::contract::DataContractFetchInfo; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; @@ -165,7 +165,7 @@ mod test { .document_type_for_name("contactRequest") .expect("expected a contact request"); - let document_transitions = get_document_transitions_fixture( + let document_transitions = get_batched_transitions_fixture( [( DocumentTransitionActionType::Create, vec![(contact_request_document, document_type, Bytes32::default())], @@ -268,7 +268,7 @@ mod test { .document_type_for_name("contactRequest") .expect("expected a contact request"); - let document_transitions = get_document_transitions_fixture( + let document_transitions = get_batched_transitions_fixture( [( DocumentTransitionActionType::Create, vec![(contact_request_document, document_type, Bytes32::default())], @@ -396,7 +396,7 @@ mod test { .get_identifier("toUserId") .expect("expected to get toUserId"); - let document_transitions = get_document_transitions_fixture( + let document_transitions = get_batched_transitions_fixture( [( DocumentTransitionActionType::Create, vec![(contact_request_document, document_type, Bytes32::default())], diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/mod.rs index efd55c380fa..9619181bae9 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/mod.rs @@ -16,7 +16,7 @@ pub fn create_domain_data_trigger( .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .data_triggers .triggers .create_domain_data_trigger diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs index 349d858ef98..f45dee7d88a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs @@ -431,7 +431,7 @@ mod test { use dpp::platform_value::Bytes32; use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionActionType; - use dpp::tests::fixtures::{get_document_transitions_fixture, get_dpns_data_contract_fixture, get_dpns_parent_document_fixture, ParentDocumentOptions}; + use dpp::tests::fixtures::{get_batched_transitions_fixture, get_dpns_data_contract_fixture, get_dpns_parent_document_fixture, ParentDocumentOptions}; use dpp::tests::utils::generate_random_identifier_struct; use dpp::version::{DefaultForPlatformVersion}; use drive::drive::contract::DataContractFetchInfo; @@ -481,7 +481,7 @@ mod test { let document_type = data_contract .document_type_for_name("domain") .expect("expected to get domain document type"); - let transitions = get_document_transitions_fixture( + let transitions = get_batched_transitions_fixture( [( DocumentTransitionActionType::Create, vec![(document, document_type, Bytes32::default())], diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/mod.rs index 9b0ecd61878..5095cf69471 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/mod.rs @@ -17,7 +17,7 @@ pub fn create_feature_flag_data_trigger( .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .data_triggers .triggers .create_feature_flag_data_trigger diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/mod.rs index 402668738d5..5be16ac1611 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/mod.rs @@ -16,7 +16,7 @@ pub fn reject_data_trigger( .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .data_triggers .triggers .reject_data_trigger diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/mod.rs index ae8758fe067..23dd6e86408 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/mod.rs @@ -18,7 +18,7 @@ pub fn delete_withdrawal_data_trigger( .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .data_triggers .triggers .delete_withdrawal_data_trigger diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/v0/mod.rs index 1487567a4bd..2efc0ae50a9 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/v0/mod.rs @@ -1,10 +1,10 @@ use crate::error::Error; use dpp::block::block_info::BlockInfo; use dpp::identity::identity_nonce::{validate_identity_nonce_update, validate_new_identity_nonce}; -use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransitionV0Methods; +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::StateTransitionLike; use dpp::validation::SimpleConsensusValidationResult; @@ -29,7 +29,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::docume ) -> Result; } -impl DocumentsBatchStateTransitionIdentityContractNonceV0 for DocumentsBatchTransition { +impl DocumentsBatchStateTransitionIdentityContractNonceV0 for BatchTransition { fn validate_identity_contract_nonces_v0( &self, platform: &PlatformStateRef, @@ -39,7 +39,7 @@ impl DocumentsBatchStateTransitionIdentityContractNonceV0 for DocumentsBatchTran platform_version: &PlatformVersion, ) -> Result { // We should validate that all newly created documents have valid ids - for transition in self.transitions() { + for transition in self.document_transitions() { let revision_nonce = transition.identity_contract_nonce(); let identity_id = self.owner_id(); let (existing_nonce, fee) = platform.drive.fetch_identity_contract_nonce_with_fees( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/mod.rs index 8ff239d954b..0e594bc5895 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/mod.rs @@ -2,19 +2,19 @@ use crate::error::execution::ExecutionError; use crate::error::Error; use crate::execution::validation::state_transition::processor::v0::StateTransitionIsAllowedValidationV0; use crate::platform_types::platform::PlatformRef; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::validation::ConsensusValidationResult; use dpp::version::PlatformVersion; mod v0; -impl StateTransitionIsAllowedValidationV0 for DocumentsBatchTransition { +impl StateTransitionIsAllowedValidationV0 for BatchTransition { fn has_is_allowed_validation(&self, platform_version: &PlatformVersion) -> Result { match platform_version .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .is_allowed { 0 => Ok(true), @@ -36,7 +36,7 @@ impl StateTransitionIsAllowedValidationV0 for DocumentsBatchTransition { .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .is_allowed { 0 => Ok(v0::validate_is_allowed_v0(self, platform)), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/v0/mod.rs index a98801ee70b..450a92e11fc 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/v0/mod.rs @@ -2,9 +2,9 @@ use crate::platform_types::platform::PlatformRef; use crate::platform_types::platform_state::v0::PlatformStateV0Methods; use dpp::block::epoch::EpochIndex; use dpp::consensus::basic::document::ContestedDocumentsTemporarilyNotAllowedError; -use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::validation::ConsensusValidationResult; // TARGET_EPOCH_INDEX was introduced without versioning. @@ -15,7 +15,7 @@ pub const TARGET_EPOCH_INDEX: EpochIndex = 4; #[inline(always)] pub fn validate_is_allowed_v0( - state_transition: &DocumentsBatchTransition, + state_transition: &BatchTransition, platform: &PlatformRef, ) -> ConsensusValidationResult<()> { #[cfg(feature = "testing-config")] @@ -33,12 +33,14 @@ pub fn validate_is_allowed_v0( return ConsensusValidationResult::new(); } - let is_contested = state_transition.transitions().iter().any(|transition| { - transition - .as_transition_create() - .and_then(|create| create.prefunded_voting_balance().as_ref()) - .is_some() - }); + let is_contested = state_transition + .document_transitions_iter() + .any(|transition| { + transition + .as_transition_create() + .and_then(|create| create.prefunded_voting_balance().as_ref()) + .is_some() + }); if is_contested { return ConsensusValidationResult::new_with_errors(vec![ 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 1cb7c26a62b..d2995c45074 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 @@ -11,7 +11,7 @@ use dpp::block::block_info::BlockInfo; use dpp::dashcore::Network; use dpp::identity::PartialIdentity; use dpp::prelude::*; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::validation::SimpleConsensusValidationResult; use dpp::version::PlatformVersion; use drive::state_transition_action::StateTransitionAction; @@ -49,7 +49,7 @@ impl ValidationMode { } } -impl StateTransitionActionTransformerV0 for DocumentsBatchTransition { +impl StateTransitionActionTransformerV0 for BatchTransition { fn transform_into_action( &self, platform: &PlatformRef, @@ -64,7 +64,7 @@ impl StateTransitionActionTransformerV0 for DocumentsBatchTransition { .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .transform_into_action { 0 => self.transform_into_action_v0(&platform.into(), block_info, validation_mode, tx), @@ -77,7 +77,7 @@ impl StateTransitionActionTransformerV0 for DocumentsBatchTransition { } } -impl StateTransitionBasicStructureValidationV0 for DocumentsBatchTransition { +impl StateTransitionBasicStructureValidationV0 for BatchTransition { fn validate_basic_structure( &self, platform_version: &PlatformVersion, @@ -86,7 +86,7 @@ impl StateTransitionBasicStructureValidationV0 for DocumentsBatchTransition { .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .basic_structure { 0 => { @@ -103,7 +103,7 @@ impl StateTransitionBasicStructureValidationV0 for DocumentsBatchTransition { } } -impl StateTransitionNonceValidationV0 for DocumentsBatchTransition { +impl StateTransitionNonceValidationV0 for BatchTransition { fn validate_nonces( &self, platform: &PlatformStateRef, @@ -116,7 +116,7 @@ impl StateTransitionNonceValidationV0 for DocumentsBatchTransition { .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .revision { 0 => self.validate_identity_contract_nonces_v0( @@ -135,7 +135,7 @@ impl StateTransitionNonceValidationV0 for DocumentsBatchTransition { } } -impl StateTransitionStructureKnownInStateValidationV0 for DocumentsBatchTransition { +impl StateTransitionStructureKnownInStateValidationV0 for BatchTransition { fn validate_advanced_structure_from_state( &self, block_info: &BlockInfo, @@ -149,7 +149,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for DocumentsBatchTransiti .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .advanced_structure { 0 => { @@ -190,7 +190,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for DocumentsBatchTransiti } } -impl StateTransitionStateValidationV0 for DocumentsBatchTransition { +impl StateTransitionStateValidationV0 for BatchTransition { fn validate_state( &self, action: Option, @@ -206,7 +206,7 @@ impl StateTransitionStateValidationV0 for DocumentsBatchTransition { .drive_abci .validation_and_processing .state_transitions - .documents_batch_state_transition + .batch_state_transition .state { 0 => { @@ -262,8 +262,8 @@ mod tests { use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::{Bytes32, Value}; use dpp::serialization::PlatformSerializable; - use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; - use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; + use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; + use dpp::state_transition::batch_transition::BatchTransition; use dpp::tests::json_document::json_document_to_contract; use drive::drive::document::query::QueryDocumentsOutcomeV0Methods; use drive::drive::document::query::QueryDocumentsWithFlagsOutcomeV0Methods; @@ -307,9 +307,9 @@ mod tests { use dpp::dashcore::Network; use dpp::dashcore::Network::Testnet; use dpp::identity::SecurityLevel; - use dpp::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; - use dpp::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransitionV0; - use dpp::state_transition::documents_batch_transition::{DocumentCreateTransition, DocumentsBatchTransitionV0}; + use dpp::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; + use dpp::state_transition::batch_transition::document_create_transition::DocumentCreateTransitionV0; + use dpp::state_transition::batch_transition::{DocumentCreateTransition, BatchTransitionV0}; use dpp::state_transition::StateTransition; use crate::config::PlatformConfig; @@ -352,7 +352,7 @@ mod tests { document.set("avatarUrl", "http://test.com/bob.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -438,7 +438,7 @@ mod tests { document.set("avatarUrl", "http://test.com/bob.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -500,7 +500,7 @@ mod tests { document.set("avatarUrl", "http://test.com/coy.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -605,7 +605,7 @@ mod tests { ); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -785,7 +785,7 @@ mod tests { document_2.set("preorderSalt", salt_2.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1, preorder, entropy.0, @@ -806,7 +806,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_2, preorder, entropy.0, @@ -827,7 +827,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_1, domain, entropy.0, @@ -848,7 +848,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_2, domain, entropy.0, @@ -1208,7 +1208,7 @@ mod tests { document_1.set("preorderSalt", salt_1.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1, preorder, entropy.0, @@ -1244,15 +1244,14 @@ mod tests { prefunded_voting_balance: None, } .into(); - let documents_batch_inner_create_transition_1: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { - owner_id, - transitions: vec![create_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 0, - signature: Default::default(), - } - .into(); + let documents_batch_inner_create_transition_1: BatchTransition = BatchTransitionV0 { + owner_id, + transitions: vec![create_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); let mut documents_batch_create_transition_1: StateTransition = documents_batch_inner_create_transition_1.into(); documents_batch_create_transition_1 @@ -1486,7 +1485,7 @@ mod tests { document_1.set("preorderSalt", salt_1.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1, preorder, entropy.0, @@ -1521,15 +1520,14 @@ mod tests { prefunded_voting_balance: None, } .into(); - let documents_batch_inner_create_transition_1: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { - owner_id, - transitions: vec![create_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 0, - signature: Default::default(), - } - .into(); + let documents_batch_inner_create_transition_1: BatchTransition = BatchTransitionV0 { + owner_id, + transitions: vec![create_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); let mut documents_batch_create_transition_1: StateTransition = documents_batch_inner_create_transition_1.into(); documents_batch_create_transition_1 @@ -1838,7 +1836,7 @@ mod tests { document_3_on_identity_1.set("preorderSalt", salt_3.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1, preorder, entropy.0, @@ -1859,7 +1857,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_2, preorder, entropy.0, @@ -1880,7 +1878,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_3 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_3_on_identity_1, preorder, new_entropy.0, @@ -1901,7 +1899,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_1, domain, entropy.0, @@ -1922,7 +1920,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_2, domain, entropy.0, @@ -1943,7 +1941,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_3 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_3_on_identity_1, domain, entropy.0, @@ -2383,7 +2381,7 @@ mod tests { )); let documents_batch_create_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_1, domain, different_entropy.0, @@ -2616,7 +2614,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -2678,7 +2676,7 @@ mod tests { document.set("defense", 2.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -2787,7 +2785,7 @@ mod tests { altered_document.set("avatarUrl", "http://test.com/cat.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -2831,7 +2829,7 @@ mod tests { .expect("expected to commit transaction"); let documents_batch_update_transition = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document, profile, &key, @@ -2939,7 +2937,7 @@ mod tests { document.set("avatarUrl", "http://test.com/bob.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), profile, entropy.0, @@ -2996,7 +2994,7 @@ mod tests { ); //less than a week let documents_batch_update_transition = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( document.clone(), profile, &key, @@ -3286,7 +3284,7 @@ mod tests { altered_document.set("senderKeyIndex", Value::U32(2)); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, contact_request_document_type, entropy.0, @@ -3330,7 +3328,7 @@ mod tests { .expect("expected to commit transaction"); let documents_batch_update_transition = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document, contact_request_document_type, &key, @@ -3416,7 +3414,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -3512,7 +3510,7 @@ mod tests { document.set("defense", 0.into()); let documents_batch_transfer_transition = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( document, card_document_type, &key, @@ -3620,7 +3618,7 @@ mod tests { altered_document.set("avatarUrl", "http://test.com/cat.jpg".into()); let documents_batch_update_transition = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document, profile, &key, @@ -3722,7 +3720,7 @@ mod tests { altered_document_2.set("avatarUrl", "http://test.com/drapes.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -3787,7 +3785,7 @@ mod tests { assert_eq!(document.to_string(), "v0 : id:GcviwUsEr9Ji4rCrnnsgmVAghNaVPDumsfcagvBbBy45 owner_id:CisQdz2ej7EwWv8JbetSXBNsV4xsf8QsSS8tqp4tEf7V created_at:1970-01-14 21:20:00 updated_at:1970-01-14 21:20:00 avatarFingerprint:bytes d7b0e2b357c10312 avatarHash:bytes32 YonaRoE0hMgat53AYt5LTlQlIkKLReGpB7xNAqJ5HM8= avatarUrl:string http://test.com/bob.[...(23)] displayName:string QBwBNNXXYCngB0er publicMessage:string 8XG7KBGNvm2 "); let documents_batch_update_transition_1 = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document, profile, &key, @@ -3807,7 +3805,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_update_transition_2 = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document_2, profile, &key, @@ -3940,7 +3938,7 @@ mod tests { altered_document_2.set("avatarUrl", "http://test.com/drapes.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -4009,7 +4007,7 @@ mod tests { let platform_state = platform.state.load(); let documents_batch_update_transition_1 = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document, profile, &key, @@ -4029,7 +4027,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_update_transition_2 = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document_2, profile, &key, @@ -4199,7 +4197,7 @@ mod tests { altered_document_2.increment_revision().unwrap(); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -4268,7 +4266,7 @@ mod tests { let platform_state = platform.state.load(); let documents_batch_update_transition_1 = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document, profile, &key, @@ -4288,7 +4286,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_update_transition_2 = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document_2, profile, &key, @@ -4462,7 +4460,7 @@ mod tests { altered_document_2.set("avatarUrl", "http://test.com/drapes.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -4531,7 +4529,7 @@ mod tests { let platform_state = platform.state.load(); let documents_batch_update_transition_1 = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document, profile, &key, @@ -4551,7 +4549,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_update_transition_2 = - DocumentsBatchTransition::new_document_replacement_transition_from_document( + BatchTransition::new_document_replacement_transition_from_document( altered_document_2, profile, &key, @@ -4723,7 +4721,7 @@ mod tests { altered_document.set("avatarUrl", "http://test.com/cat.jpg".into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, profile, entropy.0, @@ -4767,7 +4765,7 @@ mod tests { .expect("expected to commit transaction"); let documents_batch_deletion_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( altered_document, profile, &key, @@ -4904,7 +4902,7 @@ mod tests { altered_document.set("senderKeyIndex", Value::U32(2)); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, contact_request_document_type, entropy.0, @@ -4948,7 +4946,7 @@ mod tests { .expect("expected to commit transaction"); let documents_batch_deletion_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( altered_document, contact_request_document_type, &key, @@ -5069,7 +5067,7 @@ mod tests { altered_document.set("senderKeyIndex", Value::U32(2)); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, contact_request_document_type, entropy.0, @@ -5113,7 +5111,7 @@ mod tests { .expect("expected to commit transaction"); let documents_batch_deletion_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( altered_document, contact_request_document_type, &key, @@ -5234,7 +5232,7 @@ mod tests { altered_document.set("senderKeyIndex", Value::U32(2)); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document, contact_request_document_type, entropy.0, @@ -5278,7 +5276,7 @@ mod tests { .expect("expected to commit transaction"); let documents_batch_deletion_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( altered_document, contact_request_document_type, &key, @@ -5371,7 +5369,7 @@ mod tests { altered_document.set("avatarUrl", "http://test.com/cat.jpg".into()); let documents_batch_delete_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( altered_document, profile, &key, @@ -5484,7 +5482,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -5530,7 +5528,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_transfer_transition = - DocumentsBatchTransition::new_document_transfer_transition_from_document( + BatchTransition::new_document_transfer_transition_from_document( document, card_document_type, receiver.id(), @@ -5639,7 +5637,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -5732,7 +5730,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_transfer_transition = - DocumentsBatchTransition::new_document_transfer_transition_from_document( + BatchTransition::new_document_transfer_transition_from_document( document, card_document_type, receiver.id(), @@ -5864,7 +5862,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -5957,7 +5955,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_transfer_transition = - DocumentsBatchTransition::new_document_transfer_transition_from_document( + BatchTransition::new_document_transfer_transition_from_document( document, card_document_type, receiver.id(), @@ -6109,7 +6107,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_transfer_transition = - DocumentsBatchTransition::new_document_transfer_transition_from_document( + BatchTransition::new_document_transfer_transition_from_document( document, card_document_type, receiver.id(), @@ -6215,7 +6213,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -6308,7 +6306,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_transfer_transition = - DocumentsBatchTransition::new_document_transfer_transition_from_document( + BatchTransition::new_document_transfer_transition_from_document( document.clone(), card_document_type, receiver.id(), @@ -6378,7 +6376,7 @@ mod tests { document.set_owner_id(receiver.id()); let documents_batch_deletion_transition = - DocumentsBatchTransition::new_document_deletion_transition_from_document( + BatchTransition::new_document_deletion_transition_from_document( document, card_document_type, &recipient_key, @@ -6485,7 +6483,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -6555,7 +6553,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_update_price_transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( + BatchTransition::new_document_update_price_transition_from_document( document.clone(), card_document_type, dash_to_credits!(0.1), @@ -6645,7 +6643,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -6738,7 +6736,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_update_price_transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( + BatchTransition::new_document_update_price_transition_from_document( document.clone(), card_document_type, dash_to_credits!(0.1), @@ -6865,7 +6863,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -6984,7 +6982,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_update_price_transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( + BatchTransition::new_document_update_price_transition_from_document( document.clone(), card_document_type, dash_to_credits!(0.1), @@ -7099,7 +7097,7 @@ mod tests { document.set_revision(Some(3)); let documents_batch_purchase_transition = - DocumentsBatchTransition::new_document_purchase_transition_from_document( + BatchTransition::new_document_purchase_transition_from_document( document.clone(), card_document_type, purchaser.id(), @@ -7245,7 +7243,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -7291,7 +7289,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_update_price_transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( + BatchTransition::new_document_update_price_transition_from_document( document.clone(), card_document_type, dash_to_credits!(0.5), @@ -7340,7 +7338,7 @@ mod tests { document.set_revision(Some(3)); let documents_batch_purchase_transition = - DocumentsBatchTransition::new_document_purchase_transition_from_document( + BatchTransition::new_document_purchase_transition_from_document( document.clone(), card_document_type, purchaser.id(), @@ -7439,7 +7437,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -7485,7 +7483,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_update_price_transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( + BatchTransition::new_document_update_price_transition_from_document( document.clone(), card_document_type, dash_to_credits!(0.1), @@ -7534,7 +7532,7 @@ mod tests { document.set_revision(Some(3)); let documents_batch_purchase_transition = - DocumentsBatchTransition::new_document_purchase_transition_from_document( + BatchTransition::new_document_purchase_transition_from_document( document.clone(), card_document_type, identity.id(), @@ -7638,7 +7636,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -7684,7 +7682,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_update_price_transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( + BatchTransition::new_document_update_price_transition_from_document( document.clone(), card_document_type, dash_to_credits!(0.1), @@ -7733,7 +7731,7 @@ mod tests { document.set_revision(Some(3)); let documents_batch_purchase_transition = - DocumentsBatchTransition::new_document_purchase_transition_from_document( + BatchTransition::new_document_purchase_transition_from_document( document.clone(), card_document_type, purchaser.id(), @@ -7845,7 +7843,7 @@ mod tests { document.set_revision(Some(4)); let documents_batch_purchase_transition = - DocumentsBatchTransition::new_document_purchase_transition_from_document( + BatchTransition::new_document_purchase_transition_from_document( document.clone(), card_document_type, identity.id(), @@ -7943,7 +7941,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -8036,7 +8034,7 @@ mod tests { document.set_revision(Some(2)); let documents_batch_update_price_transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( + BatchTransition::new_document_update_price_transition_from_document( document.clone(), card_document_type, dash_to_credits!(0.1), @@ -8129,7 +8127,7 @@ mod tests { document.set_revision(Some(3)); let documents_batch_purchase_transition = - DocumentsBatchTransition::new_document_purchase_transition_from_document( + BatchTransition::new_document_purchase_transition_from_document( document.clone(), card_document_type, receiver.id(), @@ -8223,7 +8221,7 @@ mod tests { document.set("defense", 7.into()); let documents_batch_create_transition = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document.clone(), card_document_type, entropy.0, @@ -8271,7 +8269,7 @@ mod tests { document.set_owner_id(other_identity.id()); // we do this to trick the system let documents_batch_update_price_transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( + BatchTransition::new_document_update_price_transition_from_document( document.clone(), card_document_type, dash_to_credits!(0.1), @@ -8359,7 +8357,7 @@ mod tests { DocumentFieldFillSize, DocumentFieldFillType, }; use dpp::platform_value::Bytes32; - use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; + use dpp::state_transition::batch_transition::BatchTransition; use dpp::util::hash::hash_double; use drive::query::{InternalClauses, OrderClause, WhereClause, WhereOperator}; use drive::util::test_helpers::setup_contract; @@ -8548,7 +8546,7 @@ mod tests { document_3.set("preorderSalt", salt_3.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1, preorder, entropy.0, @@ -8569,7 +8567,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_2, preorder, entropy.0, @@ -8590,7 +8588,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_3 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_3, preorder, entropy.0, @@ -8611,7 +8609,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_1, domain, entropy.0, @@ -8632,7 +8630,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_2, domain, entropy.0, @@ -8653,7 +8651,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_3 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_3.clone(), domain, entropy.0, @@ -8997,7 +8995,7 @@ mod tests { document_3.set("preorderSalt", salt_3.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1, preorder, entropy.0, @@ -9018,7 +9016,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_2, preorder, entropy.0, @@ -9039,7 +9037,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_3 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_3, preorder, entropy.0, @@ -9060,7 +9058,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_1, domain, entropy.0, @@ -9081,7 +9079,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_2, domain, entropy.0, @@ -9102,7 +9100,7 @@ mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_3 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_3.clone(), domain, entropy.0, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs index 8db9245d3f0..c206b54bd57 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs @@ -14,10 +14,10 @@ use crate::platform_types::platform_state::v0::PlatformStateV0Methods; use dpp::document::Document; use dpp::fee::fee_result::FeeResult; use dpp::platform_value::{Identifier, Value}; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::{ +use dpp::state_transition::batch_transition::batched_transition::document_transition::{ DocumentTransition, DocumentTransitionV0Methods, }; +use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; use dpp::validation::ConsensusValidationResult; use dpp::version::PlatformVersion; use drive::drive::document::query::query_contested_documents_storage::QueryContestedDocumentsOutcomeV0Methods; 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 5ee90a17ab4..3ad53a7195c 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 @@ -2,7 +2,7 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::state_error::StateError; use dpp::prelude::ConsensusValidationResult; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::StateTransitionLike; use drive::state_transition_action::StateTransitionAction; use dpp::version::{DefaultForPlatformVersion, PlatformVersion}; @@ -50,7 +50,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::docume ) -> Result, Error>; } -impl DocumentsBatchStateTransitionStateValidationV0 for DocumentsBatchTransition { +impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { fn validate_state_v0( &self, mut state_transition_action: DocumentsBatchTransitionAction, 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 c8797a4c4e6..3e4e2656a6c 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 @@ -25,11 +25,9 @@ use dpp::prelude::Revision; use dpp::validation::SimpleConsensusValidationResult; use dpp::{consensus::ConsensusError, prelude::Identifier, validation::ConsensusValidationResult}; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; -use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; -use dpp::state_transition::documents_batch_transition::document_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; +use dpp::state_transition::batch_transition::BatchTransition; +use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use dpp::state_transition::StateTransitionLike; use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; @@ -42,9 +40,10 @@ use crate::execution::validation::state_transition::documents_batch::state::v0:: use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use dpp::state_transition::documents_batch_transition::document_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::document_replace_transition::v0::v0_methods::DocumentReplaceTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; +use dpp::state_transition::batch_transition::batched_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; use drive::drive::contract::DataContractFetchInfo; use drive::drive::Drive; use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; @@ -120,7 +119,7 @@ trait DocumentsBatchTransitionInternalTransformerV0 { ) -> SimpleConsensusValidationResult; } -impl DocumentsBatchTransitionTransformerV0 for DocumentsBatchTransition { +impl DocumentsBatchTransitionTransformerV0 for BatchTransition { fn try_into_action_v0( &self, platform: &PlatformStateRef, @@ -138,7 +137,7 @@ impl DocumentsBatchTransitionTransformerV0 for DocumentsBatchTransition { > = BTreeMap::new(); // We want to validate by contract, and then for each document type within a contract - for document_transition in self.transitions().iter() { + for document_transition in self.document_transitions().iter() { let document_type = document_transition.base().document_type_name(); let data_contract_id = document_transition.base().data_contract_id_ref(); @@ -200,7 +199,7 @@ impl DocumentsBatchTransitionTransformerV0 for DocumentsBatchTransition { } } -impl DocumentsBatchTransitionInternalTransformerV0 for DocumentsBatchTransition { +impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { fn transform_document_transitions_within_contract_v0( platform: &PlatformStateRef, block_info: &BlockInfo, 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 b0986e026d5..7fcbb17a0de 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 @@ -90,8 +90,8 @@ pub(in crate::execution) mod tests { use dpp::identity::hash::IdentityPublicKeyHashMethodsV0; use dpp::platform_value::{Bytes32, Value}; use dpp::serialization::PlatformSerializable; - use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; - use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; + use dpp::state_transition::batch_transition::BatchTransition; + use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; use dpp::state_transition::masternode_vote_transition::MasternodeVoteTransition; use dpp::state_transition::masternode_vote_transition::methods::MasternodeVoteTransitionMethodsV0; use dpp::state_transition::StateTransition; @@ -1044,7 +1044,7 @@ pub(in crate::execution) mod tests { document_2.set("preorderSalt", salt_2.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1.clone(), preorder, entropy.0, @@ -1065,7 +1065,7 @@ pub(in crate::execution) mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_2.clone(), preorder, entropy.0, @@ -1086,7 +1086,7 @@ pub(in crate::execution) mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_1.clone(), domain, entropy.0, @@ -1106,7 +1106,7 @@ pub(in crate::execution) mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_2.clone(), domain, entropy.0, @@ -1354,7 +1354,7 @@ pub(in crate::execution) mod tests { document_2.set("preorderSalt", salt_2.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1.clone(), preorder, entropy.0, @@ -1375,7 +1375,7 @@ pub(in crate::execution) mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_preorder_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_2.clone(), preorder, entropy.0, @@ -1396,7 +1396,7 @@ pub(in crate::execution) mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_1.clone(), domain, entropy.0, @@ -1416,7 +1416,7 @@ pub(in crate::execution) mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_2 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_2.clone(), domain, entropy.0, @@ -1576,7 +1576,7 @@ pub(in crate::execution) mod tests { document_1.set("preorderSalt", salt_1.into()); let documents_batch_create_preorder_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( preorder_document_1, preorder, entropy.0, @@ -1597,7 +1597,7 @@ pub(in crate::execution) mod tests { .expect("expected documents batch serialized state transition"); let documents_batch_create_transition_1 = - DocumentsBatchTransition::new_document_creation_transition_from_document( + BatchTransition::new_document_creation_transition_from_document( document_1, domain, entropy.0, 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 e078e0c8b64..cb26dd4fbc3 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 @@ -98,7 +98,7 @@ impl StateTransitionActionTransformerV0 for StateTransition { execution_context, tx, ), - StateTransition::DocumentsBatch(st) => st.transform_into_action( + StateTransition::Batch(st) => st.transform_into_action( platform, block_info, validation_mode, diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 03bb92bc1ad..e4e78540512 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -2270,10 +2270,7 @@ mod tests { for tx_results_per_block in outcome.state_transition_results_per_block.values() { for (state_transition, _unused_result) in tx_results_per_block { // We can't ever get a documents batch transition, because the proposer will remove it from a block - assert!(!matches!( - state_transition, - StateTransition::DocumentsBatch(_) - )); + assert!(!matches!(state_transition, StateTransition::Batch(_))); } } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index bf3235ea788..fadc6ecb9dd 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -31,54 +31,61 @@ use drive::drive::identity::key::fetch::{IdentityKeysRequest, KeyRequestType}; use drive::drive::Drive; use drive::util::storage_flags::StorageFlags::SingleEpoch; -use dpp::identity::KeyType::ECDSA_SECP256K1; -use dpp::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; -use dpp::state_transition::data_contract_update_transition::methods::DataContractUpdateTransitionMethodsV0; -use drive::query::DriveDocumentQuery; -use drive_abci::mimic::test_quorum::TestQuorumInfo; -use drive_abci::platform_types::platform::Platform; -use drive_abci::rpc::core::MockCoreRPCLike; -use rand::prelude::{IteratorRandom, SliceRandom, StdRng}; -use rand::Rng; -use strategy_tests::Strategy; -use strategy_tests::transitions::{create_state_transitions_for_identities, create_state_transitions_for_identities_and_proofs, instant_asset_lock_proof_fixture_with_dynamic_range}; -use std::borrow::Cow; -use std::collections::{BTreeMap, HashMap, HashSet}; -use std::ops::RangeInclusive; -use std::str::FromStr; -use tenderdash_abci::proto::abci::{ExecTxResult, ValidatorSetUpdate}; use dpp::dashcore::hashes::Hash; +use dpp::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::data_contract::document_type::v0::DocumentTypeV0; use dpp::identifier::MasternodeIdentifiers; use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::identity_public_key::v0::IdentityPublicKeyV0; use dpp::identity::state_transition::asset_lock_proof::InstantAssetLockProof; +use dpp::identity::KeyType::ECDSA_SECP256K1; use dpp::platform_value::{BinaryData, Value}; use dpp::prelude::{AssetLockProof, Identifier, IdentityNonce}; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; -use dpp::state_transition::documents_batch_transition::document_create_transition::{DocumentCreateTransition, DocumentCreateTransitionV0}; -use dpp::state_transition::documents_batch_transition::document_transition::document_delete_transition::DocumentDeleteTransitionV0; -use dpp::state_transition::documents_batch_transition::document_transition::document_replace_transition::DocumentReplaceTransitionV0; -use dpp::state_transition::documents_batch_transition::{DocumentsBatchTransition, DocumentsBatchTransitionV0}; -use dpp::state_transition::documents_batch_transition::document_transition::{DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransferTransition}; -use drive::drive::document::query::QueryDocumentsOutcomeV0Methods; +use dpp::state_transition::batch_transition::batched_transition::document_delete_transition::DocumentDeleteTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::DocumentTransferTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::{ + DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransferTransition, +}; +use dpp::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use dpp::state_transition::batch_transition::document_create_transition::{ + DocumentCreateTransition, DocumentCreateTransitionV0, +}; +use dpp::state_transition::batch_transition::{BatchTransition, BatchTransitionV0}; use dpp::state_transition::data_contract_create_transition::methods::v0::DataContractCreateTransitionMethodsV0; -use dpp::state_transition::documents_batch_transition::document_transition::document_transfer_transition::DocumentTransferTransitionV0; -use dpp::state_transition::masternode_vote_transition::MasternodeVoteTransition; +use dpp::state_transition::data_contract_update_transition::methods::DataContractUpdateTransitionMethodsV0; use dpp::state_transition::masternode_vote_transition::methods::MasternodeVoteTransitionMethodsV0; +use dpp::state_transition::masternode_vote_transition::MasternodeVoteTransition; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use dpp::voting::vote_polls::VotePoll; -use dpp::voting::votes::resource_vote::ResourceVote; use dpp::voting::votes::resource_vote::v0::ResourceVoteV0; +use dpp::voting::votes::resource_vote::ResourceVote; use dpp::voting::votes::Vote; +use drive::drive::document::query::QueryDocumentsOutcomeV0Methods; +use drive::query::DriveDocumentQuery; use drive_abci::abci::app::FullAbciApplication; -use drive_abci::platform_types::platform_state::v0::PlatformStateV0Methods; use drive_abci::config::PlatformConfig; +use drive_abci::mimic::test_quorum::TestQuorumInfo; +use drive_abci::platform_types::platform::Platform; +use drive_abci::platform_types::platform_state::v0::PlatformStateV0Methods; use drive_abci::platform_types::signature_verification_quorum_set::{ QuorumConfig, Quorums, SigningQuorum, }; use drive_abci::platform_types::withdrawal::unsigned_withdrawal_txs::v0::UnsignedWithdrawalTxs; +use drive_abci::rpc::core::MockCoreRPCLike; +use rand::prelude::{IteratorRandom, SliceRandom, StdRng}; +use rand::Rng; +use std::borrow::Cow; +use std::collections::{BTreeMap, HashMap, HashSet}; +use std::ops::RangeInclusive; +use std::str::FromStr; +use strategy_tests::transitions::{ + create_state_transitions_for_identities, create_state_transitions_for_identities_and_proofs, + instant_asset_lock_proof_fixture_with_dynamic_range, +}; +use strategy_tests::Strategy; +use tenderdash_abci::proto::abci::{ExecTxResult, ValidatorSetUpdate}; use crate::strategy::CoreHeightIncrease::NoCoreHeightIncrease; use simple_signer::signer::SimpleSigner; @@ -648,8 +655,8 @@ impl NetworkStrategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { + let document_batch_transition: BatchTransition = + BatchTransitionV0 { owner_id: identity.id(), transitions: vec![document_create_transition.into()], user_fee_increase: 0, @@ -778,8 +785,8 @@ impl NetworkStrategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { + let document_batch_transition: BatchTransition = + BatchTransitionV0 { owner_id: identity.id(), transitions: vec![document_create_transition.into()], user_fee_increase: 0, @@ -884,15 +891,14 @@ impl NetworkStrategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { - owner_id: identity.id, - transitions: vec![document_delete_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 0, - signature: BinaryData::default(), - } - .into(); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id, + transitions: vec![document_delete_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: BinaryData::default(), + } + .into(); let mut document_batch_transition: StateTransition = document_batch_transition.into(); @@ -987,15 +993,14 @@ impl NetworkStrategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { - owner_id: identity.id, - transitions: vec![document_replace_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 0, - signature: BinaryData::default(), - } - .into(); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id, + transitions: vec![document_replace_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: BinaryData::default(), + } + .into(); let mut document_batch_transition: StateTransition = document_batch_transition.into(); @@ -1098,15 +1103,14 @@ impl NetworkStrategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { - owner_id: identity.id, - transitions: vec![document_transfer_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 0, - signature: BinaryData::default(), - } - .into(); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id, + transitions: vec![document_transfer_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: BinaryData::default(), + } + .into(); let mut document_batch_transition: StateTransition = document_batch_transition.into(); 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 57f347f9775..b2758a2f257 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 @@ -22,7 +22,7 @@ use drive_abci::platform_types::platform::PlatformRef; use drive_abci::rpc::core::MockCoreRPCLike; use tenderdash_abci::proto::abci::ExecTxResult; -use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use dpp::voting::votes::Vote; use drive::drive::votes::resolved::vote_polls::ResolvedVotePoll; use drive::drive::votes::resolved::votes::resolved_resource_vote::accessors::v0::ResolvedResourceVoteGettersV0; @@ -59,11 +59,11 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( .iter() .enumerate() .map(|(num, (state_transition, result))| { - if let StateTransition::DocumentsBatch(batch) = state_transition { - let _first = batch.transitions().first().unwrap(); - - // dbg!(batch.transitions().len(), hex::encode(first.base().id()), state.height(), first.to_string()); - } + // if let StateTransition::DocumentsBatch(batch) = state_transition { + // let _first = batch.document_transitions().first().unwrap(); + // + // // dbg!(batch.transitions().len(), hex::encode(first.base().id()), state.height(), first.to_string()); + // } let mut execution_context = StateTransitionExecutionContext::default_for_platform_version(platform_version) diff --git a/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs index 83834520c0c..c26bc7a51f7 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs @@ -315,7 +315,7 @@ mod tests { .first() .expect("expected a document insert"); - assert_matches!(state_transition, StateTransition::DocumentsBatch(_)); + assert_matches!(state_transition, StateTransition::Batch(_)); assert_eq!(execution_result.code, 0); } diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history/mod.rs new file mode 100644 index 00000000000..e084dffc38f --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history/mod.rs @@ -0,0 +1 @@ +mod v0; diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history/v0/mod.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history/v0/mod.rs @@ -0,0 +1 @@ + diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index bef64c6819a..f19f64aad80 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -1,5 +1,6 @@ use crate::drive::RootTree; +mod add_transaction_history; pub mod balance; pub mod burn; pub mod estimated_costs; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs index 4b86b6efe72..76f74cac5b5 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs @@ -2,7 +2,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use dpp::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/transformer.rs index b639eb421e8..cbe3594ed3d 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/transformer.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use dpp::platform_value::Identifier; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use dpp::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs index 96b76d29065..2eaf9f3dfa0 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs @@ -5,7 +5,7 @@ use grovedb::TransactionArg; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransition; +use dpp::state_transition::batch_transition::document_create_transition::DocumentCreateTransition; use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs index 1cd3025e4d4..eb9b06214b9 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs @@ -6,7 +6,7 @@ use grovedb::TransactionArg; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_create_transition::v0::DocumentCreateTransitionV0; +use dpp::state_transition::batch_transition::document_create_transition::v0::DocumentCreateTransitionV0; use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::ContestedDocumentVotePollStoredInfo; use dpp::voting::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePoll; use platform_version::version::PlatformVersion; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs index e32d5cc1d08..0468e91eaa9 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs @@ -2,7 +2,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentDeleteTransition; +use dpp::state_transition::batch_transition::batched_transition::DocumentDeleteTransition; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::{DocumentDeleteTransitionAction, DocumentDeleteTransitionActionV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs index bdfd2bf8f6b..ee0e3d451ee 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs @@ -2,7 +2,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::document_delete_transition::DocumentDeleteTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_delete_transition::DocumentDeleteTransitionV0; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionV0; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/transformer.rs index 894e13b5bdc..54549dd38c0 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/transformer.rs @@ -4,7 +4,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentPurchaseTransition; +use dpp::state_transition::batch_transition::batched_transition::DocumentPurchaseTransition; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs index 0625690bda3..429f5a61493 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs @@ -5,7 +5,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::document_purchase_transition::DocumentPurchaseTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_purchase_transition::DocumentPurchaseTransitionV0; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::v0::DocumentPurchaseTransitionActionV0; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/transformer.rs index 4c5cfa6316f..f8d03908869 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/transformer.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use dpp::identity::TimestampMillis; use dpp::prelude::{BlockHeight, CoreBlockHeight}; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentReplaceTransition; +use dpp::state_transition::batch_transition::batched_transition::DocumentReplaceTransition; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs index dad93afed20..b88d09aa112 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use dpp::identity::TimestampMillis; use dpp::prelude::{BlockHeight, CoreBlockHeight}; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::document_replace_transition::DocumentReplaceTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::v0::DocumentReplaceTransitionActionV0; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/transformer.rs index 16bbaa4822a..5d1336731c4 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/transformer.rs @@ -4,7 +4,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransferTransition; +use dpp::state_transition::batch_transition::batched_transition::DocumentTransferTransition; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs index 92c0c768d54..214df9b631f 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs @@ -5,7 +5,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::document_transfer_transition::DocumentTransferTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::DocumentTransferTransitionV0; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::v0::DocumentTransferTransitionActionV0; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs index d8765d18a01..b45320eea51 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs @@ -1,5 +1,5 @@ use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::{ +use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::{ DocumentTransitionActionType, TransitionActionTypeGetter, }; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/transformer.rs index f52e99d0d61..f0339b8c4f3 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/transformer.rs @@ -4,7 +4,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentUpdatePriceTransition; +use dpp::state_transition::batch_transition::batched_transition::DocumentUpdatePriceTransition; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs index c32bb5bc166..7f5d57629f6 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs @@ -5,7 +5,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::document_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::v0::DocumentUpdatePriceTransitionActionV0; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index b60cef0e32b..8f3b6f772b3 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -22,7 +22,7 @@ pub mod token_issuance_transition_action; /// token_transfer_transition_action pub mod token_transfer_transition_action; -pub use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; +pub use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; use derive_more::From; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs index bf72f96f5f2..33447ccc016 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs @@ -1,4 +1,5 @@ use derive_more::From; +use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; use dpp::platform_value::Identifier; use dpp::prelude::IdentityNonce; use std::sync::Arc; @@ -9,6 +10,7 @@ mod v0; use crate::drive::contract::DataContractFetchInfo; +use crate::error::Error; pub use v0::*; /// document base transition action @@ -21,7 +23,13 @@ pub enum TokenBaseTransitionAction { impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionAction { fn token_position(&self) -> u16 { match self { - TokenBaseTransitionAction::V0(v0) => v0.token_position, + TokenBaseTransitionAction::V0(v0) => v0.token_contract_position, + } + } + + fn token_id(&self) -> Identifier { + match self { + TokenBaseTransitionAction::V0(v0) => v0.token_id, } } @@ -43,6 +51,12 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionAction { } } + fn token_configuration(&self) -> Result<&TokenConfiguration, Error> { + match self { + TokenBaseTransitionAction::V0(v0) => v0.token_configuration(), + } + } + fn identity_contract_nonce(&self) -> IdentityNonce { match self { TokenBaseTransitionAction::V0(v0) => v0.identity_contract_nonce(), diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs index 0cd8d3f4517..46939f2f56e 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs @@ -2,7 +2,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::token_base_transition::TokenBaseTransition; +use dpp::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs index 0724d67cc67..b6c63703c56 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs @@ -1,8 +1,11 @@ use crate::drive::contract::DataContractFetchInfo; +use crate::error::Error; use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; -use dpp::util::hash::hash_double; +use dpp::ProtocolError; use std::sync::Arc; /// transformer @@ -11,10 +14,12 @@ pub mod transformer; /// Token base transition action v0 #[derive(Debug, Clone)] pub struct TokenBaseTransitionActionV0 { + /// Token Id + pub token_id: Identifier, /// The identity contract nonce, used to prevent replay attacks pub identity_contract_nonce: IdentityNonce, /// The token position within the data contract - pub token_position: u16, + pub token_contract_position: u16, /// A potential data contract pub data_contract: Arc, } @@ -25,13 +30,7 @@ pub trait TokenBaseTransitionActionAccessorsV0 { fn token_position(&self) -> u16; /// The token id - fn token_id(&self) -> Identifier { - // Prepare the data for hashing - let mut bytes = b"token".to_vec(); - bytes.extend_from_slice(self.data_contract_id().as_bytes()); - bytes.extend_from_slice(&self.token_position().to_be_bytes()); - hash_double(bytes).into() - } + fn token_id(&self) -> Identifier; /// Returns the data contract ID fn data_contract_id(&self) -> Identifier; @@ -44,11 +43,18 @@ pub trait TokenBaseTransitionActionAccessorsV0 { /// Returns the identity contract nonce fn identity_contract_nonce(&self) -> IdentityNonce; + + /// Gets the token configuration associated to the action + fn token_configuration(&self) -> Result<&TokenConfiguration, Error>; } impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { fn token_position(&self) -> u16 { - self.token_position + self.token_contract_position + } + + fn token_id(&self) -> Identifier { + self.token_id } fn data_contract_id(&self) -> Identifier { @@ -66,4 +72,18 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { fn identity_contract_nonce(&self) -> IdentityNonce { self.identity_contract_nonce } + + fn token_configuration(&self) -> Result<&TokenConfiguration, Error> { + self.data_contract + .as_ref() + .contract + .tokens() + .get(&self.token_contract_position) + .ok_or(Error::Protocol(ProtocolError::CorruptedCodeExecution( + format!( + "data contract does not have a token at position {}", + self.token_contract_position + ), + ))) + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index 0ec720a46f5..1b4efe5527c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use dpp::platform_value::Identifier; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; @@ -14,13 +14,15 @@ impl TokenBaseTransitionActionV0 { get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { let TokenBaseTransitionV0 { - token_contract_position: token_id, + token_contract_position, data_contract_id, identity_contract_nonce, + token_id, } = value; Ok(TokenBaseTransitionActionV0 { + token_id, identity_contract_nonce, - token_position: token_id, + token_contract_position, data_contract: get_data_contract(data_contract_id)?, }) } @@ -31,13 +33,15 @@ impl TokenBaseTransitionActionV0 { get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { let TokenBaseTransitionV0 { - token_contract_position: token_id, + token_contract_position, data_contract_id, identity_contract_nonce, + token_id, } = value; Ok(TokenBaseTransitionActionV0 { + token_id: *token_id, identity_contract_nonce: *identity_contract_nonce, - token_position: *token_id, + token_contract_position: *token_contract_position, data_contract: get_data_contract(*data_contract_id)?, }) } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs index 0c30139ef25..9e7c757a102 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs @@ -7,7 +7,7 @@ use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{ TokenBurnTransitionAction, TokenBurnTransitionActionV0, }; -use dpp::state_transition::documents_batch_transition::token_burn_transition::TokenBurnTransition; +use dpp::state_transition::batch_transition::token_burn_transition::TokenBurnTransition; /// Implement methods to transform a `TokenBurnTransition` into a `TokenBurnTransitionAction`. impl TokenBurnTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index 21f92e04f6b..96ac0ef533e 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use dpp::identifier::Identifier; -use dpp::state_transition::documents_batch_transition::token_burn_transition::v0::TokenBurnTransitionV0; +use dpp::state_transition::batch_transition::token_burn_transition::v0::TokenBurnTransitionV0; use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs index b8d58504ae7..4f0458a579e 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs @@ -7,7 +7,7 @@ use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{ TokenIssuanceTransitionAction, TokenIssuanceTransitionActionV0, }; -use dpp::state_transition::documents_batch_transition::token_issuance_transition::TokenIssuanceTransition; +use dpp::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransition; /// Implement methods to transform a `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction`. impl TokenIssuanceTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs index 64d4c9f0153..3e50f810367 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs @@ -1,10 +1,10 @@ use std::sync::Arc; use dpp::identifier::Identifier; -use dpp::state_transition::documents_batch_transition::token_issuance_transition::v0::TokenIssuanceTransitionV0; +use dpp::state_transition::batch_transition::token_issuance_transition::v0::TokenIssuanceTransitionV0; use dpp::ProtocolError; use dpp::data_contract::accessors::v1::DataContractV1Getters; -use dpp::state_transition::documents_batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use dpp::tokens::errors::TokenError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs index 4fa1726b9af..036dac8641c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use dpp::platform_value::Identifier; use dpp::ProtocolError; -use dpp::state_transition::documents_batch_transition::TokenTransferTransition; +use dpp::state_transition::batch_transition::TokenTransferTransition; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionV0; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index 37a4d937620..f543a19b219 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use dpp::identifier::Identifier; -use dpp::state_transition::documents_batch_transition::token_transfer_transition::v0::TokenTransferTransitionV0; +use dpp::state_transition::batch_transition::token_transfer_transition::v0::TokenTransferTransitionV0; use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs index e5c8c190740..225e1266334 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs @@ -2,7 +2,7 @@ use dpp::platform_value::Identifier; use dpp::prelude::UserFeeIncrease; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; -use dpp::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; +use dpp::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition_action::contract::data_contract_update::DataContractUpdateTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::{BumpIdentityDataContractNonceAction, BumpIdentityDataContractNonceActionV0}; diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs index 42a99127900..62b30664078 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs @@ -3,7 +3,7 @@ use dpp::platform_value::Identifier; use dpp::prelude::UserFeeIncrease; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransitionV0; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use dpp::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; use crate::state_transition_action::contract::data_contract_update::v0::DataContractUpdateTransitionActionV0; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceActionV0; diff --git a/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs b/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs index 906d5d4c7e7..7a60f86601d 100644 --- a/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs +++ b/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs @@ -11,21 +11,23 @@ use dpp::identity::PartialIdentity; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::state_transition::data_contract_create_transition::accessors::DataContractCreateTransitionAccessorsV0; use dpp::state_transition::data_contract_update_transition::accessors::DataContractUpdateTransitionAccessorsV0; -use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::BatchedTransitionRef; use dpp::state_transition::identity_create_transition::accessors::IdentityCreateTransitionAccessorsV0; use dpp::state_transition::identity_credit_transfer_transition::accessors::IdentityCreditTransferTransitionAccessorsV0; use dpp::state_transition::identity_credit_withdrawal_transition::accessors::IdentityCreditWithdrawalTransitionAccessorsV0; use dpp::state_transition::identity_topup_transition::accessors::IdentityTopUpTransitionAccessorsV0; use dpp::state_transition::identity_update_transition::accessors::IdentityUpdateTransitionAccessorsV0; use dpp::state_transition::{StateTransition, StateTransitionLike}; -use dpp::state_transition::documents_batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; -use dpp::state_transition::documents_batch_transition::document_create_transition::DocumentFromCreateTransition; -use dpp::state_transition::documents_batch_transition::document_replace_transition::DocumentFromReplaceTransition; -use dpp::state_transition::documents_batch_transition::document_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; +use dpp::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use dpp::state_transition::batch_transition::document_create_transition::DocumentFromCreateTransition; +use dpp::state_transition::batch_transition::document_replace_transition::DocumentFromReplaceTransition; +use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; +use dpp::state_transition::batch_transition::batched_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; use dpp::state_transition::masternode_vote_transition::accessors::MasternodeVoteTransitionAccessorsV0; use dpp::state_transition::proof_result::StateTransitionProofResult; use dpp::state_transition::proof_result::StateTransitionProofResult::{VerifiedBalanceTransfer, VerifiedDataContract, VerifiedDocuments, VerifiedIdentity, VerifiedMasternodeVote, VerifiedPartialIdentity}; @@ -89,11 +91,11 @@ impl Drive { } Ok((root_hash, VerifiedDataContract(contract))) } - StateTransition::DocumentsBatch(documents_batch_transition) => { - if documents_batch_transition.transitions().len() > 1 { + StateTransition::Batch(documents_batch_transition) => { + if documents_batch_transition.transitions_len() > 1 { return Err(Error::Proof(ProofError::InvalidTransition(format!("version {} does not support more than one document in a document batch transition", platform_version.protocol_version)))); } - let Some(transition) = documents_batch_transition.transitions().first() else { + let Some(transition) = documents_batch_transition.first_transition() else { return Err(Error::Proof(ProofError::InvalidTransition( "no transition in a document batch transition".to_string(), ))); @@ -101,168 +103,193 @@ impl Drive { let owner_id = documents_batch_transition.owner_id(); - let data_contract_id = transition.data_contract_id(); + match transition { + BatchedTransitionRef::Document(document_transition) => { + let data_contract_id = document_transition.data_contract_id(); - let contract = known_contracts_provider_fn(&data_contract_id)?.ok_or( - Error::Proof(ProofError::UnknownContract(format!( - "unknown contract with id {}", - data_contract_id - ))), - )?; + let contract = known_contracts_provider_fn(&data_contract_id)?.ok_or( + Error::Proof(ProofError::UnknownContract(format!( + "unknown contract with id {}", + data_contract_id + ))), + )?; - let document_type = contract - .document_type_for_name(transition.document_type_name()) - .map_err(|e| { - Error::Proof(ProofError::UnknownContract(format!( - "cannot fetch contract for document {} with id {}: {}", - transition.document_type_name(), - transition.data_contract_id(), - e - ))) - })?; + let document_type = contract + .document_type_for_name(document_transition.document_type_name()) + .map_err(|e| { + Error::Proof(ProofError::UnknownContract(format!( + "cannot fetch contract for document {} with id {}: {}", + document_transition.document_type_name(), + document_transition.data_contract_id(), + e + ))) + })?; - let contested_status = - if let DocumentTransition::Create(create_transition) = transition { - if create_transition.prefunded_voting_balance().is_some() { - SingleDocumentDriveQueryContestedStatus::Contested - } else { - SingleDocumentDriveQueryContestedStatus::NotContested - } - } else { - SingleDocumentDriveQueryContestedStatus::NotContested - }; + let contested_status = + if let DocumentTransition::Create(create_transition) = + document_transition + { + if create_transition.prefunded_voting_balance().is_some() { + SingleDocumentDriveQueryContestedStatus::Contested + } else { + SingleDocumentDriveQueryContestedStatus::NotContested + } + } else { + SingleDocumentDriveQueryContestedStatus::NotContested + }; - match transition { - DocumentTransition::Create(_) => {} - DocumentTransition::Replace(_) => {} - DocumentTransition::Delete(_) => {} - DocumentTransition::Transfer(_) => {} - DocumentTransition::UpdatePrice(_) => {} - DocumentTransition::Purchase(_) => {} - } + let query = SingleDocumentDriveQuery { + contract_id: document_transition.data_contract_id().into_buffer(), + document_type_name: document_transition.document_type_name().clone(), + document_type_keeps_history: document_type.documents_keep_history(), + document_id: document_transition.base().id().into_buffer(), + block_time_ms: None, //None because we want latest + contested_status, + }; + let (root_hash, document) = + query.verify_proof(false, proof, document_type, platform_version)?; - let query = SingleDocumentDriveQuery { - contract_id: transition.data_contract_id().into_buffer(), - document_type_name: transition.document_type_name().clone(), - document_type_keeps_history: document_type.documents_keep_history(), - document_id: transition.base().id().into_buffer(), - block_time_ms: None, //None because we want latest - contested_status, - }; - let (root_hash, document) = - query.verify_proof(false, proof, document_type, platform_version)?; + match document_transition { + DocumentTransition::Create(create_transition) => { + let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (create)", create_transition.base().id()))))?; + let expected_document = Document::try_from_create_transition( + create_transition, + documents_batch_transition.owner_id(), + block_info, + &document_type, + platform_version, + )?; - match transition { - DocumentTransition::Create(create_transition) => { - let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (create)", create_transition.base().id()))))?; - let expected_document = Document::try_from_create_transition( - create_transition, - documents_batch_transition.owner_id(), - block_info, - &document_type, - platform_version, - )?; + let transient_fields = document_type + .transient_fields() + .iter() + .map(|a| a.as_str()) + .collect(); - let transient_fields = document_type - .transient_fields() - .iter() - .map(|a| a.as_str()) - .collect(); + if !document.is_equal_ignoring_time_based_fields( + &expected_document, + Some(transient_fields), + platform_version, + )? { + return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not contain expected document (time fields were not checked) after create with id {}", create_transition.base().id())))); + } + Ok(( + root_hash, + VerifiedDocuments(BTreeMap::from([( + document.id(), + Some(document), + )])), + )) + } + DocumentTransition::Replace(replace_transition) => { + let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (replace)", replace_transition.base().id()))))?; + let expected_document = Document::try_from_replace_transition( + replace_transition, + documents_batch_transition.owner_id(), + document.created_at(), //we can trust the created at (as we don't care) + document.created_at_block_height(), //we can trust the created at block height (as we don't care) + document.created_at_core_block_height(), //we can trust the created at core block height (as we don't care) + document.created_at(), //we can trust the created at (as we don't care) + document.created_at_block_height(), //we can trust the created at block height (as we don't care) + document.created_at_core_block_height(), //we can trust the created at core block height (as we don't care) + block_info, + &document_type, + platform_version, + )?; - if !document.is_equal_ignoring_time_based_fields( - &expected_document, - Some(transient_fields), - platform_version, - )? { - return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not contain expected document (time fields were not checked) after create with id {}", create_transition.base().id())))); - } - Ok(( - root_hash, - VerifiedDocuments(BTreeMap::from([(document.id(), Some(document))])), - )) - } - DocumentTransition::Replace(replace_transition) => { - let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (replace)", replace_transition.base().id()))))?; - let expected_document = Document::try_from_replace_transition( - replace_transition, - documents_batch_transition.owner_id(), - document.created_at(), //we can trust the created at (as we don't care) - document.created_at_block_height(), //we can trust the created at block height (as we don't care) - document.created_at_core_block_height(), //we can trust the created at core block height (as we don't care) - document.created_at(), //we can trust the created at (as we don't care) - document.created_at_block_height(), //we can trust the created at block height (as we don't care) - document.created_at_core_block_height(), //we can trust the created at core block height (as we don't care) - block_info, - &document_type, - platform_version, - )?; + let transient_fields = document_type + .transient_fields() + .iter() + .map(|a| a.as_str()) + .collect(); - let transient_fields = document_type - .transient_fields() - .iter() - .map(|a| a.as_str()) - .collect(); + if !document.is_equal_ignoring_time_based_fields( + &expected_document, + Some(transient_fields), + platform_version, + )? { + return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not contain expected document (time fields were not checked) after replace with id {}", replace_transition.base().id())))); + } - if !document.is_equal_ignoring_time_based_fields( - &expected_document, - Some(transient_fields), - platform_version, - )? { - return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not contain expected document (time fields were not checked) after replace with id {}", replace_transition.base().id())))); - } + Ok(( + root_hash, + VerifiedDocuments(BTreeMap::from([( + document.id(), + Some(document), + )])), + )) + } + DocumentTransition::Transfer(transfer_transition) => { + let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (transfer)", transfer_transition.base().id()))))?; + let recipient_owner_id = transfer_transition.recipient_owner_id(); - Ok(( - root_hash, - VerifiedDocuments(BTreeMap::from([(document.id(), Some(document))])), - )) - } - DocumentTransition::Transfer(transfer_transition) => { - let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (transfer)", transfer_transition.base().id()))))?; - let recipient_owner_id = transfer_transition.recipient_owner_id(); + if document.owner_id() != recipient_owner_id { + return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not have the transfer executed after expected transfer with id {}", transfer_transition.base().id())))); + } - if document.owner_id() != recipient_owner_id { - return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not have the transfer executed after expected transfer with id {}", transfer_transition.base().id())))); - } + Ok(( + root_hash, + VerifiedDocuments(BTreeMap::from([( + document.id(), + Some(document), + )])), + )) + } + DocumentTransition::Delete(delete_transition) => { + if document.is_some() { + return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution contained document after delete with id {}", delete_transition.base().id())))); + } + Ok(( + root_hash, + VerifiedDocuments(BTreeMap::from([( + delete_transition.base().id(), + None, + )])), + )) + } + DocumentTransition::UpdatePrice(update_price_transition) => { + let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (update price)", update_price_transition.base().id()))))?; + let new_document_price : Credits = document.properties().get_integer(PRICE).map_err(|e| Error::Proof(ProofError::IncorrectProof(format!("proof did not contain a document that contained a price field with id {} expected to exist because of state transition (update price): {}", update_price_transition.base().id(), e))))?; + if new_document_price != update_price_transition.price() { + return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not contain expected document update of price after price update with id {}", update_price_transition.base().id())))); + } + Ok(( + root_hash, + VerifiedDocuments(BTreeMap::from([( + document.id(), + Some(document), + )])), + )) + } + DocumentTransition::Purchase(purchase_transition) => { + let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (purchase)", purchase_transition.base().id()))))?; - Ok(( - root_hash, - VerifiedDocuments(BTreeMap::from([(document.id(), Some(document))])), - )) - } - DocumentTransition::Delete(delete_transition) => { - if document.is_some() { - return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution contained document after delete with id {}", delete_transition.base().id())))); - } - Ok(( - root_hash, - VerifiedDocuments(BTreeMap::from([( - delete_transition.base().id(), - None, - )])), - )) - } - DocumentTransition::UpdatePrice(update_price_transition) => { - let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (update price)", update_price_transition.base().id()))))?; - let new_document_price : Credits = document.properties().get_integer(PRICE).map_err(|e| Error::Proof(ProofError::IncorrectProof(format!("proof did not contain a document that contained a price field with id {} expected to exist because of state transition (update price): {}", update_price_transition.base().id(), e))))?; - if new_document_price != update_price_transition.price() { - return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not contain expected document update of price after price update with id {}", update_price_transition.base().id())))); - } - Ok(( - root_hash, - VerifiedDocuments(BTreeMap::from([(document.id(), Some(document))])), - )) - } - DocumentTransition::Purchase(purchase_transition) => { - let document = document.ok_or(Error::Proof(ProofError::IncorrectProof(format!("proof did not contain document with id {} expected to exist because of state transition (purchase)", purchase_transition.base().id()))))?; + if document.owner_id() != owner_id { + return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not have the transfer executed after expected transfer with id {}", purchase_transition.base().id())))); + } - if document.owner_id() != owner_id { - return Err(Error::Proof(ProofError::IncorrectProof(format!("proof of state transition execution did not have the transfer executed after expected transfer with id {}", purchase_transition.base().id())))); + Ok(( + root_hash, + VerifiedDocuments(BTreeMap::from([( + document.id(), + Some(document), + )])), + )) + } } - - Ok(( - root_hash, - VerifiedDocuments(BTreeMap::from([(document.id(), Some(document))])), - )) + } + BatchedTransitionRef::Token(token_transition) => { + todo!() + //todo + // we need to check if the contract has history + // if it has history we verify the proof of the history + // known_contracts_provider_fn + // let token_id = token_transition.token_id(); + // match token_transition { + // TokenTransition::Burn(_) => {} + // TokenTransition::Issuance(_) => {} + // TokenTransition::Transfer(_) => {} + // } } } } diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/mod.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/mod.rs index 3ad838e5de7..8d69f6f8b6d 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/mod.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/mod.rs @@ -1,6 +1,7 @@ use versioned_feature_core::FeatureVersionBounds; pub mod v1; +pub mod v2; #[derive(Clone, Debug, Default)] pub struct DPPStateTransitionSerializationVersions { @@ -13,7 +14,7 @@ pub struct DPPStateTransitionSerializationVersions { pub masternode_vote_state_transition: FeatureVersionBounds, pub contract_create_state_transition: FeatureVersionBounds, pub contract_update_state_transition: FeatureVersionBounds, - pub documents_batch_state_transition: FeatureVersionBounds, + pub batch_state_transition: FeatureVersionBounds, pub document_base_state_transition: FeatureVersionBounds, pub document_create_state_transition: DocumentFeatureVersionBounds, pub document_replace_state_transition: DocumentFeatureVersionBounds, diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v1.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v1.rs index 917b8405f08..944e613c26f 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v1.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v1.rs @@ -50,7 +50,7 @@ pub const STATE_TRANSITION_SERIALIZATION_VERSIONS_V1: DPPStateTransitionSerializ max_version: 0, default_current_version: 0, }, - documents_batch_state_transition: FeatureVersionBounds { + batch_state_transition: FeatureVersionBounds { min_version: 0, max_version: 0, default_current_version: 0, diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v2.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v2.rs new file mode 100644 index 00000000000..1df489c45e7 --- /dev/null +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_state_transition_serialization_versions/v2.rs @@ -0,0 +1,105 @@ +use crate::version::dpp_versions::dpp_state_transition_serialization_versions::{ + DPPStateTransitionSerializationVersions, DocumentFeatureVersionBounds, +}; +use versioned_feature_core::FeatureVersionBounds; + +pub const STATE_TRANSITION_SERIALIZATION_VERSIONS_V2: DPPStateTransitionSerializationVersions = + DPPStateTransitionSerializationVersions { + identity_public_key_in_creation: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identity_create_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identity_update_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identity_top_up_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identity_credit_withdrawal_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identity_credit_transfer_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + masternode_vote_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + contract_create_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + contract_update_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + batch_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 1, + default_current_version: 1, + }, + document_base_state_transition: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + document_create_state_transition: DocumentFeatureVersionBounds { + bounds: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, + document_replace_state_transition: DocumentFeatureVersionBounds { + bounds: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, + document_delete_state_transition: DocumentFeatureVersionBounds { + bounds: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, + document_transfer_state_transition: DocumentFeatureVersionBounds { + bounds: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, + document_update_price_state_transition: DocumentFeatureVersionBounds { + bounds: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, + document_purchase_state_transition: DocumentFeatureVersionBounds { + bounds: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, + }; diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs index 4bd5ff6269c..27b0f04d166 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs @@ -45,7 +45,7 @@ pub struct DriveAbciStateTransitionValidationVersions { pub masternode_vote_state_transition: DriveAbciStateTransitionValidationVersion, pub contract_create_state_transition: DriveAbciStateTransitionValidationVersion, pub contract_update_state_transition: DriveAbciStateTransitionValidationVersion, - pub documents_batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions, + pub batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions, } #[derive(Clone, Debug, Default)] @@ -97,6 +97,12 @@ pub struct DriveAbciDocumentsStateTransitionValidationVersions { pub document_transfer_transition_state_validation: FeatureVersion, pub document_purchase_transition_state_validation: FeatureVersion, pub document_update_price_transition_state_validation: FeatureVersion, + pub token_issuance_transition_structure_validation: FeatureVersion, + pub token_burn_transition_structure_validation: FeatureVersion, + pub token_transfer_transition_structure_validation: FeatureVersion, + pub token_issuance_transition_state_validation: FeatureVersion, + pub token_burn_transition_state_validation: FeatureVersion, + pub token_transfer_transition_state_validation: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs index 20820165d1d..29e3c37d472 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs @@ -97,7 +97,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V1: DriveAbciValidationVersions = state: 0, transform_into_action: 0, }, - documents_batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { + batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { balance_pre_check: 0, basic_structure: 0, advanced_structure: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs index 7cd1b593538..6c7c5ffcc1c 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs @@ -97,7 +97,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V2: DriveAbciValidationVersions = state: 0, transform_into_action: 0, }, - documents_batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { + batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { balance_pre_check: 0, basic_structure: 0, advanced_structure: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs index 42f4068cdd9..2f71945b50b 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs @@ -97,7 +97,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V3: DriveAbciValidationVersions = state: 0, transform_into_action: 0, }, - documents_batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { + batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { balance_pre_check: 0, basic_structure: 0, advanced_structure: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs index ff70d44107d..d147eb6b9ae 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs @@ -97,7 +97,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V4: DriveAbciValidationVersions = state: 0, transform_into_action: 0, }, - documents_batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { + batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { balance_pre_check: 0, basic_structure: 0, advanced_structure: 0, diff --git a/packages/rs-platform-version/src/version/mod.rs b/packages/rs-platform-version/src/version/mod.rs index b143a1daf15..49d59ca80c4 100644 --- a/packages/rs-platform-version/src/version/mod.rs +++ b/packages/rs-platform-version/src/version/mod.rs @@ -19,6 +19,7 @@ pub mod v4; pub mod v5; pub mod v6; pub mod v7; +mod v8; pub type ProtocolVersion = u32; diff --git a/packages/rs-platform-version/src/version/protocol_version.rs b/packages/rs-platform-version/src/version/protocol_version.rs index d793384c729..d14f75c8bcf 100644 --- a/packages/rs-platform-version/src/version/protocol_version.rs +++ b/packages/rs-platform-version/src/version/protocol_version.rs @@ -22,6 +22,7 @@ use crate::version::v4::PLATFORM_V4; use crate::version::v5::PLATFORM_V5; use crate::version::v6::PLATFORM_V6; use crate::version::v7::PLATFORM_V7; +use crate::version::v8::PLATFORM_V8; use crate::version::ProtocolVersion; pub use versioned_feature_core::*; @@ -53,7 +54,7 @@ pub static PLATFORM_TEST_VERSIONS: OnceLock> = OnceLock::ne #[cfg(feature = "mock-versions")] const DEFAULT_PLATFORM_TEST_VERSIONS: &[PlatformVersion] = &[TEST_PLATFORM_V2, TEST_PLATFORM_V3]; -pub const LATEST_PLATFORM_VERSION: &PlatformVersion = &PLATFORM_V7; +pub const LATEST_PLATFORM_VERSION: &PlatformVersion = &PLATFORM_V8; pub const DESIRED_PLATFORM_VERSION: &PlatformVersion = LATEST_PLATFORM_VERSION; diff --git a/packages/rs-platform-version/src/version/v8.rs b/packages/rs-platform-version/src/version/v8.rs new file mode 100644 index 00000000000..8c60e65ef34 --- /dev/null +++ b/packages/rs-platform-version/src/version/v8.rs @@ -0,0 +1,65 @@ +use crate::version::consensus_versions::ConsensusVersions; +use crate::version::dpp_versions::dpp_asset_lock_versions::v1::DPP_ASSET_LOCK_VERSIONS_V1; +use crate::version::dpp_versions::dpp_contract_versions::v1::CONTRACT_VERSIONS_V1; +use crate::version::dpp_versions::dpp_costs_versions::v1::DPP_COSTS_VERSIONS_V1; +use crate::version::dpp_versions::dpp_document_versions::v1::DOCUMENT_VERSIONS_V1; +use crate::version::dpp_versions::dpp_factory_versions::v1::DPP_FACTORY_VERSIONS_V1; +use crate::version::dpp_versions::dpp_identity_versions::v1::IDENTITY_VERSIONS_V1; +use crate::version::dpp_versions::dpp_method_versions::v1::DPP_METHOD_VERSIONS_V1; +use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2::STATE_TRANSITION_CONVERSION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; +use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; +use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v2::STATE_TRANSITION_SERIALIZATION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANSITION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; +use crate::version::dpp_versions::DPPVersion; +use crate::version::drive_abci_versions::drive_abci_method_versions::v4::DRIVE_ABCI_METHOD_VERSIONS_V4; +use crate::version::drive_abci_versions::drive_abci_query_versions::v1::DRIVE_ABCI_QUERY_VERSIONS_V1; +use crate::version::drive_abci_versions::drive_abci_structure_versions::v1::DRIVE_ABCI_STRUCTURE_VERSIONS_V1; +use crate::version::drive_abci_versions::drive_abci_validation_versions::v4::DRIVE_ABCI_VALIDATION_VERSIONS_V4; +use crate::version::drive_abci_versions::drive_abci_withdrawal_constants::v2::DRIVE_ABCI_WITHDRAWAL_CONSTANTS_V2; +use crate::version::drive_abci_versions::DriveAbciVersion; +use crate::version::drive_versions::v2::DRIVE_VERSION_V2; +use crate::version::fee::v1::FEE_VERSION1; +use crate::version::protocol_version::PlatformVersion; +use crate::version::system_data_contract_versions::v1::SYSTEM_DATA_CONTRACT_VERSIONS_V1; +use crate::version::system_limits::v1::SYSTEM_LIMITS_V1; +use crate::version::ProtocolVersion; + +pub const PROTOCOL_VERSION_8: ProtocolVersion = 8; + +/// This version adds token support. +//todo: make changes +pub const PLATFORM_V8: PlatformVersion = PlatformVersion { + protocol_version: PROTOCOL_VERSION_8, + drive: DRIVE_VERSION_V2, + drive_abci: DriveAbciVersion { + structs: DRIVE_ABCI_STRUCTURE_VERSIONS_V1, + methods: DRIVE_ABCI_METHOD_VERSIONS_V4, + validation_and_processing: DRIVE_ABCI_VALIDATION_VERSIONS_V4, + withdrawal_constants: DRIVE_ABCI_WITHDRAWAL_CONSTANTS_V2, + query: DRIVE_ABCI_QUERY_VERSIONS_V1, + }, + dpp: DPPVersion { + costs: DPP_COSTS_VERSIONS_V1, + validation: DPP_VALIDATION_VERSIONS_V2, + state_transition_serialization_versions: STATE_TRANSITION_SERIALIZATION_VERSIONS_V2, // changed + state_transition_conversion_versions: STATE_TRANSITION_CONVERSION_VERSIONS_V2, + state_transition_method_versions: STATE_TRANSITION_METHOD_VERSIONS_V1, + state_transitions: STATE_TRANSITION_VERSIONS_V2, + contract_versions: CONTRACT_VERSIONS_V1, + document_versions: DOCUMENT_VERSIONS_V1, + identity_versions: IDENTITY_VERSIONS_V1, + voting_versions: VOTING_VERSION_V2, + asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, + methods: DPP_METHOD_VERSIONS_V1, + factory_versions: DPP_FACTORY_VERSIONS_V1, + }, + system_data_contracts: SYSTEM_DATA_CONTRACT_VERSIONS_V1, + fee_version: FEE_VERSION1, + system_limits: SYSTEM_LIMITS_V1, + consensus: ConsensusVersions { + tenderdash_consensus_version: 1, + }, +}; diff --git a/packages/rs-sdk/src/platform/transition/purchase_document.rs b/packages/rs-sdk/src/platform/transition/purchase_document.rs index 1de4aeb43fc..15618c995ec 100644 --- a/packages/rs-sdk/src/platform/transition/purchase_document.rs +++ b/packages/rs-sdk/src/platform/transition/purchase_document.rs @@ -11,8 +11,8 @@ use dpp::fee::Credits; use dpp::identity::signer::Signer; use dpp::identity::IdentityPublicKey; use dpp::prelude::Identifier; -use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::proof_result::StateTransitionProofResult; use dpp::state_transition::StateTransition; @@ -78,7 +78,7 @@ impl PurchaseDocument for Document { let settings = settings.unwrap_or_default(); - let transition = DocumentsBatchTransition::new_document_purchase_transition_from_document( + let transition = BatchTransition::new_document_purchase_transition_from_document( self.clone(), document_type.as_ref(), purchaser_id, diff --git a/packages/rs-sdk/src/platform/transition/put_document.rs b/packages/rs-sdk/src/platform/transition/put_document.rs index 6e8617f953d..f74deaabb27 100644 --- a/packages/rs-sdk/src/platform/transition/put_document.rs +++ b/packages/rs-sdk/src/platform/transition/put_document.rs @@ -7,8 +7,8 @@ use dpp::data_contract::DataContract; use dpp::document::{Document, DocumentV0Getters}; use dpp::identity::signer::Signer; use dpp::identity::IdentityPublicKey; -use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::proof_result::StateTransitionProofResult; use dpp::state_transition::StateTransition; use std::sync::Arc; @@ -70,7 +70,7 @@ impl PutDocument for Document { let settings = settings.unwrap_or_default(); - let transition = DocumentsBatchTransition::new_document_creation_transition_from_document( + let transition = BatchTransition::new_document_creation_transition_from_document( self.clone(), document_type.as_ref(), document_state_transition_entropy, diff --git a/packages/rs-sdk/src/platform/transition/transfer_document.rs b/packages/rs-sdk/src/platform/transition/transfer_document.rs index a64c76cb95f..45ac329fd10 100644 --- a/packages/rs-sdk/src/platform/transition/transfer_document.rs +++ b/packages/rs-sdk/src/platform/transition/transfer_document.rs @@ -13,8 +13,8 @@ use dpp::data_contract::DataContract; use dpp::document::{Document, DocumentV0Getters}; use dpp::identity::signer::Signer; use dpp::identity::IdentityPublicKey; -use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::proof_result::StateTransitionProofResult; use dpp::state_transition::StateTransition; use drive::drive::Drive; @@ -77,7 +77,7 @@ impl TransferDocument for Document { let settings = settings.unwrap_or_default(); - let transition = DocumentsBatchTransition::new_document_transfer_transition_from_document( + let transition = BatchTransition::new_document_transfer_transition_from_document( self.clone(), document_type.as_ref(), recipient_id, diff --git a/packages/rs-sdk/src/platform/transition/update_price_of_document.rs b/packages/rs-sdk/src/platform/transition/update_price_of_document.rs index 0f331cde5de..97d43d5bac1 100644 --- a/packages/rs-sdk/src/platform/transition/update_price_of_document.rs +++ b/packages/rs-sdk/src/platform/transition/update_price_of_document.rs @@ -13,8 +13,8 @@ use dpp::document::{Document, DocumentV0Getters}; use dpp::fee::Credits; use dpp::identity::signer::Signer; use dpp::identity::IdentityPublicKey; -use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::proof_result::StateTransitionProofResult; use dpp::state_transition::StateTransition; use drive::drive::Drive; @@ -77,20 +77,19 @@ impl UpdatePriceOfDocument for Document { let settings = settings.unwrap_or_default(); - let transition = - DocumentsBatchTransition::new_document_update_price_transition_from_document( - self.clone(), - document_type.as_ref(), - price, - &identity_public_key, - new_identity_contract_nonce, - settings.user_fee_increase.unwrap_or_default(), - signer, - sdk.version(), - None, - None, - None, - )?; + let transition = BatchTransition::new_document_update_price_transition_from_document( + self.clone(), + document_type.as_ref(), + price, + &identity_public_key, + new_identity_contract_nonce, + settings.user_fee_increase.unwrap_or_default(), + signer, + sdk.version(), + None, + None, + None, + )?; let request = transition.broadcast_request_for_state_transition()?; diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index efdb702a482..6455feaf401 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -37,34 +37,38 @@ use dpp::state_transition::StateTransition; use dpp::version::PlatformVersion; use drive::drive::identity::key::fetch::{IdentityKeysRequest, KeyRequestType}; +use bincode::{Decode, Encode}; use dpp::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::data_contract::document_type::DocumentType; +use dpp::fee::Credits; +use dpp::identifier::Identifier; +use dpp::identity::accessors::IdentityGettersV0; +use dpp::platform_value::{BinaryData, Bytes32, Value}; +use dpp::state_transition::batch_transition::batched_transition::document_delete_transition::DocumentDeleteTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::DocumentTransferTransitionV0; +use dpp::state_transition::batch_transition::batched_transition::{ + DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransferTransition, +}; +use dpp::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use dpp::state_transition::batch_transition::document_create_transition::{ + DocumentCreateTransition, DocumentCreateTransitionV0, +}; +use dpp::state_transition::batch_transition::{BatchTransition, BatchTransitionV0}; +use dpp::state_transition::data_contract_create_transition::methods::v0::DataContractCreateTransitionMethodsV0; use dpp::state_transition::data_contract_update_transition::methods::DataContractUpdateTransitionMethodsV0; +use dpp::ProtocolError::{PlatformDeserializationError, PlatformSerializationError}; +use dpp::{dash_to_duffs, ProtocolError}; use operations::{DataContractUpdateAction, DataContractUpdateOp}; use platform_version::TryFromPlatformVersioned; use rand::prelude::StdRng; use rand::seq::{IteratorRandom, SliceRandom}; use rand::Rng; -use transitions::create_identity_credit_transfer_transition; +use simple_signer::signer::SimpleSigner; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::ops::RangeInclusive; -use bincode::{Decode, Encode}; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; -use dpp::identifier::Identifier; -use dpp::data_contract::document_type::DocumentType; -use dpp::fee::Credits; -use dpp::identity::accessors::IdentityGettersV0; -use dpp::platform_value::{BinaryData, Bytes32, Value}; -use dpp::{dash_to_duffs, ProtocolError}; -use dpp::ProtocolError::{PlatformDeserializationError, PlatformSerializationError}; -use dpp::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; -use dpp::state_transition::documents_batch_transition::document_create_transition::{DocumentCreateTransition, DocumentCreateTransitionV0}; -use dpp::state_transition::documents_batch_transition::document_transition::document_delete_transition::DocumentDeleteTransitionV0; -use dpp::state_transition::documents_batch_transition::document_transition::document_replace_transition::DocumentReplaceTransitionV0; -use dpp::state_transition::documents_batch_transition::{DocumentsBatchTransition, DocumentsBatchTransitionV0}; -use dpp::state_transition::documents_batch_transition::document_transition::{DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransferTransition}; -use dpp::state_transition::data_contract_create_transition::methods::v0::DataContractCreateTransitionMethodsV0; -use dpp::state_transition::documents_batch_transition::document_transition::document_transfer_transition::DocumentTransferTransitionV0; -use simple_signer::signer::SimpleSigner; +use transitions::create_identity_credit_transfer_transition; pub mod frequency; pub mod operations; @@ -720,8 +724,8 @@ impl Strategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { + let document_batch_transition: BatchTransition = + BatchTransitionV0 { owner_id: identity.id(), transitions: vec![document_create_transition.into()], user_fee_increase: 0, @@ -846,8 +850,8 @@ impl Strategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { + let document_batch_transition: BatchTransition = + BatchTransitionV0 { owner_id: identity.id(), transitions: vec![document_create_transition.into()], user_fee_increase: 0, @@ -936,15 +940,14 @@ impl Strategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { - owner_id: identity.id(), - transitions: vec![document_delete_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 1, - signature: BinaryData::default(), - } - .into(); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id(), + transitions: vec![document_delete_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 1, + signature: BinaryData::default(), + } + .into(); let mut document_batch_transition: StateTransition = document_batch_transition.into(); @@ -1034,15 +1037,14 @@ impl Strategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { - owner_id: identity.id, - transitions: vec![document_replace_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 1, - signature: BinaryData::default(), - } - .into(); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id, + transitions: vec![document_replace_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 1, + signature: BinaryData::default(), + } + .into(); let mut document_batch_transition: StateTransition = document_batch_transition.into(); @@ -1138,15 +1140,14 @@ impl Strategy { } .into(); - let document_batch_transition: DocumentsBatchTransition = - DocumentsBatchTransitionV0 { - owner_id: identity.id, - transitions: vec![document_transfer_transition.into()], - user_fee_increase: 0, - signature_public_key_id: 1, - signature: BinaryData::default(), - } - .into(); + let document_batch_transition: BatchTransition = BatchTransitionV0 { + owner_id: identity.id, + transitions: vec![document_transfer_transition.into()], + user_fee_increase: 0, + signature_public_key_id: 1, + signature: BinaryData::default(), + } + .into(); let mut document_batch_transition: StateTransition = document_batch_transition.into(); diff --git a/packages/token-history-contract/.eslintrc b/packages/token-history-contract/.eslintrc new file mode 100644 index 00000000000..cb6c7636b60 --- /dev/null +++ b/packages/token-history-contract/.eslintrc @@ -0,0 +1,18 @@ +{ + "extends": "airbnb-base", + "rules": { + "no-plusplus": 0, + "eol-last": [ + "error", + "always" + ], + "class-methods-use-this": "off", + "curly": [ + "error", + "all" + ] + }, + "globals": { + "BigInt": true + } +} diff --git a/packages/token-history-contract/.mocharc.yml b/packages/token-history-contract/.mocharc.yml new file mode 100644 index 00000000000..164b941c1b6 --- /dev/null +++ b/packages/token-history-contract/.mocharc.yml @@ -0,0 +1,2 @@ +require: test/bootstrap.js +recursive: true diff --git a/packages/token-history-contract/Cargo.toml b/packages/token-history-contract/Cargo.toml new file mode 100644 index 00000000000..b5ea373f76f --- /dev/null +++ b/packages/token-history-contract/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "wallet-utils-contract" +description = "Wallet data contract schema and tools" +version = "1.6.2" +edition = "2021" +rust-version.workspace = true +license = "MIT" + +[dependencies] +thiserror = "1.0.64" +platform-version = { path = "../rs-platform-version" } +serde_json = { version = "1.0" } +platform-value = { path = "../rs-platform-value" } diff --git a/packages/token-history-contract/LICENSE b/packages/token-history-contract/LICENSE new file mode 100644 index 00000000000..3be95833750 --- /dev/null +++ b/packages/token-history-contract/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2019 Dash Core Group, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/token-history-contract/README.md b/packages/token-history-contract/README.md new file mode 100644 index 00000000000..ce6b5a62333 --- /dev/null +++ b/packages/token-history-contract/README.md @@ -0,0 +1,26 @@ +# Wallet Utils Contract + +[![Build Status](https://github.com/dashpay/platform/actions/workflows/release.yml/badge.svg)](https://github.com/dashpay/platform/actions/workflows/release.yml) +[![NPM version](https://img.shields.io/npm/v/@dashevo/wallet-contract.svg?style=flat-square)](https://npmjs.org/package/@dashevo/wallet-contract) + +JSON Contracts for Dash Wallet apps + +## Table of Contents + +- [Install](#install) +- [Contributing](#contributing) +- [License](#license) + +## Install + +```sh +npm install @dashevo/wallet-contract +``` + +## Contributing + +Feel free to dive in! [Open an issue](https://github.com/dashpay/platform/issues/new/choose) or submit PRs. + +## License + +[MIT](LICENSE) © Dash Core Group, Inc. diff --git a/packages/token-history-contract/lib/systemIds.js b/packages/token-history-contract/lib/systemIds.js new file mode 100644 index 00000000000..a89ad1ed75d --- /dev/null +++ b/packages/token-history-contract/lib/systemIds.js @@ -0,0 +1,4 @@ +module.exports = { + ownerId: '11111111111111111111111111111111', + contractId: 'BqzxK9UQdAeXbE7zY78uq6MfWWk3TrXZWfstnMoHZGh1', +}; diff --git a/packages/token-history-contract/package.json b/packages/token-history-contract/package.json new file mode 100644 index 00000000000..2e3d19ab9d8 --- /dev/null +++ b/packages/token-history-contract/package.json @@ -0,0 +1,29 @@ +{ + "name": "@dashevo/wallet-utils-contract", + "version": "1.6.2", + "description": "A contract and helper scripts for Wallet DApp", + "scripts": { + "lint": "eslint .", + "test": "yarn run test:unit", + "test:unit": "mocha 'test/unit/**/*.spec.js'" + }, + "contributors": [ + { + "name": "Eric Britten", + "email": "eric.britten@dash.org", + "url": "https://github.com/hashengineering" + } + ], + "license": "MIT", + "devDependencies": { + "@dashevo/wasm-dpp": "workspace:*", + "chai": "^4.3.10", + "dirty-chai": "^2.0.1", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.29.0", + "mocha": "^10.2.0", + "sinon": "^17.0.1", + "sinon-chai": "^3.7.0" + } +} diff --git a/packages/token-history-contract/schema/v1/token-history-contract-documents.json b/packages/token-history-contract/schema/v1/token-history-contract-documents.json new file mode 100644 index 00000000000..1f71eb10ee5 --- /dev/null +++ b/packages/token-history-contract/schema/v1/token-history-contract-documents.json @@ -0,0 +1,363 @@ +{ + "burn": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byDate", + "properties": [ + { + "tokenId": "asc" + }, + { + "$createdAt": "asc" + } + ] + }, + { + "name": "byAmount", + "properties": [ + { + "tokenId": "asc" + }, + { + "amount": "asc" + } + ] + }, + { + "name": "byOwnerId", + "properties": [ + { + "tokenId": "asc" + }, + { + "$ownerId": "asc" + }, + { + "$createdAt": "asc" + } + ] + } + ], + "properties": { + "tokenId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The token ID", + "position": 0 + }, + "amount": { + "type": "integer", + "minimum": 0, + "description": "The amount that was burned", + "position": 1 + }, + "note": { + "type": "string", + "maxLength": 2048, + "description": "An optional explanation of why this burn took place", + "position": 2 + } + }, + "required": [ + "tokenId", + "amount", + "$createdAt", + "$createdAtBlockHeight", + "$createdAtCoreBlockHeight" + ], + "additionalProperties": false + }, + "mint": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byDate", + "properties": [ + { + "tokenId": "asc" + }, + { + "$createdAt": "asc" + } + ] + }, + { + "name": "byAmount", + "properties": [ + { + "tokenId": "asc" + }, + { + "amount": "asc" + } + ] + }, + { + "name": "byOwnerId", + "properties": [ + { + "tokenId": "asc" + }, + { + "$ownerId": "asc" + }, + { + "$createdAt": "asc" + } + ] + } + ], + "properties": { + "tokenId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The token ID", + "position": 0 + }, + "amount": { + "type": "integer", + "minimum": 0, + "description": "The amount that was burned", + "position": 1 + }, + "note": { + "type": "string", + "maxLength": 2048, + "description": "An optional explanation of why this burn took place", + "position": 2 + } + }, + "required": [ + "tokenId", + "amount", + "$createdAt", + "$createdAtBlockHeight", + "$createdAtCoreBlockHeight" + ], + "additionalProperties": false + }, + "transfer": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byDate", + "properties": [ + { + "tokenId": "asc" + }, + { + "$createdAt": "asc" + } + ] + }, + { + "name": "byAmount", + "properties": [ + { + "tokenId": "asc" + }, + { + "amount": "asc" + } + ] + }, + { + "name": "from", + "properties": [ + { + "tokenId": "asc" + }, + { + "$ownerId": "asc" + }, + { + "$createdAt": "asc" + } + ] + }, + { + "name": "to", + "properties": [ + { + "tokenId": "asc" + }, + { + "toIdentityId": "asc" + }, + { + "$createdAt": "asc" + } + ] + } + ], + "properties": { + "tokenId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The token ID", + "position": 0 + }, + "amount": { + "type": "integer", + "minimum": 0, + "description": "The amount that was burned", + "position": 1 + }, + "toIdentityId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The identity or the group Id", + "position": 2 + } + }, + "required": [ + "tokenId", + "amount", + "toIdentityId", + "$createdAt", + "$createdAtBlockHeight", + "$createdAtCoreBlockHeight" + ], + "additionalProperties": false + }, + "frozen": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byOwnerId", + "properties": [ + { + "tokenId": "asc" + }, + { + "$ownerId": "asc" + }, + { + "$createdAt": "asc" + } + ] + }, + { + "name": "byFrozenIdentityId", + "properties": [ + { + "tokenId": "asc" + }, + { + "frozenIdentityId": "asc" + }, + { + "$createdAt": "asc" + } + ] + } + ], + "properties": { + "tokenId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The token ID", + "position": 0 + }, + "frozenIdentityId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The identity Id of the frozen token account", + "position": 2 + } + }, + "required": [ + "tokenId", + "frozenIdentityId", + "$createdAt", + "$createdAtBlockHeight" + ], + "additionalProperties": false + }, + "unfrozen": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byOwnerId", + "properties": [ + { + "tokenId": "asc" + }, + { + "$ownerId": "asc" + }, + { + "$createdAt": "asc" + } + ] + }, + { + "name": "byUnfrozenIdentityId", + "properties": [ + { + "tokenId": "asc" + }, + { + "unfrozenIdentityId": "asc" + }, + { + "$createdAt": "asc" + } + ] + } + ], + "properties": { + "tokenId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The token ID", + "position": 0 + }, + "unfrozenIdentityId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The identity Id of the frozen token account", + "position": 2 + } + }, + "required": [ + "tokenId", + "unfrozenIdentityId", + "$createdAt", + "$createdAtBlockHeight" + ], + "additionalProperties": false + } +} diff --git a/packages/token-history-contract/src/error.rs b/packages/token-history-contract/src/error.rs new file mode 100644 index 00000000000..d01bbcc91cf --- /dev/null +++ b/packages/token-history-contract/src/error.rs @@ -0,0 +1,17 @@ +use platform_version::version::FeatureVersion; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + /// Platform expected some specific versions + #[error("platform unknown version on {method}, received: {received}")] + UnknownVersionMismatch { + /// method + method: String, + /// the allowed versions for this method + known_versions: Vec, + /// requested core height + received: FeatureVersion, + }, + #[error("schema deserialize error: {0}")] + InvalidSchemaJson(#[from] serde_json::Error), +} diff --git a/packages/token-history-contract/src/lib.rs b/packages/token-history-contract/src/lib.rs new file mode 100644 index 00000000000..70dafcc26fd --- /dev/null +++ b/packages/token-history-contract/src/lib.rs @@ -0,0 +1,37 @@ +mod error; +pub mod v1; + +pub use crate::error::Error; +use platform_value::{Identifier, IdentifierBytes32}; +use platform_version::version::PlatformVersion; +use serde_json::Value; + +pub const ID_BYTES: [u8; 32] = [ + 92, 20, 14, 101, 92, 2, 101, 187, 194, 168, 8, 113, 109, 225, 132, 121, 133, 19, 89, 24, 173, + 81, 205, 253, 11, 118, 102, 75, 169, 91, 163, 124, +]; + +pub const OWNER_ID_BYTES: [u8; 32] = [0; 32]; + +pub const ID: Identifier = Identifier(IdentifierBytes32(ID_BYTES)); +pub const OWNER_ID: Identifier = Identifier(IdentifierBytes32(OWNER_ID_BYTES)); +pub fn load_definitions(platform_version: &PlatformVersion) -> Result, Error> { + match platform_version.system_data_contracts.withdrawals { + 1 => Ok(None), + version => Err(Error::UnknownVersionMismatch { + method: "wallet_contract::load_definitions".to_string(), + known_versions: vec![1], + received: version, + }), + } +} +pub fn load_documents_schemas(platform_version: &PlatformVersion) -> Result { + match platform_version.system_data_contracts.withdrawals { + 1 => v1::load_documents_schemas(), + version => Err(Error::UnknownVersionMismatch { + method: "wallet_contract::load_documents_schemas".to_string(), + known_versions: vec![1], + received: version, + }), + } +} diff --git a/packages/token-history-contract/src/v1/mod.rs b/packages/token-history-contract/src/v1/mod.rs new file mode 100644 index 00000000000..ddd4fa11153 --- /dev/null +++ b/packages/token-history-contract/src/v1/mod.rs @@ -0,0 +1,21 @@ +use crate::Error; +use serde_json::Value; + +pub mod document_types { + pub mod tx_metadata { + pub const NAME: &str = "tx_metadata"; + + pub mod properties { + pub const KEY_INDEX: &str = "keyIndex"; + pub const ENCRYPTION_KEY_INDEX: &str = "encryptionKeyIndex"; + pub const ENCRYPTED_METADATA: &str = "encryptedMetadata"; + } + } +} + +pub fn load_documents_schemas() -> Result { + serde_json::from_str(include_str!( + "../../schema/v1/token-history-contract-documents.json" + )) + .map_err(Error::InvalidSchemaJson) +} diff --git a/packages/token-history-contract/test/.eslintrc b/packages/token-history-contract/test/.eslintrc new file mode 100644 index 00000000000..720ced73852 --- /dev/null +++ b/packages/token-history-contract/test/.eslintrc @@ -0,0 +1,12 @@ +{ + "env": { + "node": true, + "mocha": true + }, + "rules": { + "import/no-extraneous-dependencies": "off" + }, + "globals": { + "expect": true + } +} diff --git a/packages/token-history-contract/test/bootstrap.js b/packages/token-history-contract/test/bootstrap.js new file mode 100644 index 00000000000..7af04f464d7 --- /dev/null +++ b/packages/token-history-contract/test/bootstrap.js @@ -0,0 +1,30 @@ +const sinon = require('sinon'); +const sinonChai = require('sinon-chai'); + +const { expect, use } = require('chai'); +const dirtyChai = require('dirty-chai'); + +const { + default: loadWasmDpp, +} = require('@dashevo/wasm-dpp'); + +use(dirtyChai); +use(sinonChai); + +exports.mochaHooks = { + beforeAll: loadWasmDpp, + + beforeEach() { + if (!this.sinon) { + this.sinon = sinon.createSandbox(); + } else { + this.sinon.restore(); + } + }, + + afterEach() { + this.sinon.restore(); + }, +}; + +global.expect = expect; diff --git a/packages/token-history-contract/test/unit/walletContract.spec.js b/packages/token-history-contract/test/unit/walletContract.spec.js new file mode 100644 index 00000000000..e13506371c0 --- /dev/null +++ b/packages/token-history-contract/test/unit/walletContract.spec.js @@ -0,0 +1,187 @@ +const crypto = require('crypto'); + +const { + DashPlatformProtocol, + JsonSchemaError, +} = require('@dashevo/wasm-dpp'); +const generateRandomIdentifier = require('@dashevo/wasm-dpp/lib/test/utils/generateRandomIdentifierAsync'); + +const { expect } = require('chai'); +const walletContractDocumentsSchema = require('../../schema/v1/token-history-contract-documents.json'); + +const expectJsonSchemaError = (validationResult, errorCount = 1) => { + const errors = validationResult.getErrors(); + expect(errors) + .to + .have + .length(errorCount); + + const error = validationResult.getErrors()[0]; + expect(error) + .to + .be + .instanceof(JsonSchemaError); + + return error; +}; + +describe('Wallet Contract', () => { + let dpp; + let dataContract; + let identityId; + + beforeEach(async () => { + dpp = new DashPlatformProtocol( + { generate: () => crypto.randomBytes(32) }, + ); + + identityId = await generateRandomIdentifier(); + + dataContract = dpp.dataContract.create(identityId, BigInt(1), walletContractDocumentsSchema); + }); + + it('should have a valid contract definition', async () => { + expect(() => dpp.dataContract.create(identityId, BigInt(1), walletContractDocumentsSchema)) + .to + .not + .throw(); + }); + + describe('documents', () => { + describe('txMetadata', () => { + let rawTxMetadataDocument; + + beforeEach(() => { + rawTxMetadataDocument = { + keyIndex: 0, + encryptionKeyIndex: 100, + encryptedMetadata: crypto.randomBytes(64), + }; + }); + + describe('keyIndex', () => { + it('should be defined', async () => { + delete rawTxMetadataDocument.keyIndex; + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('required'); + expect(error.params.missingProperty) + .to + .equal('keyIndex'); + }); + + it('should be a non-negative integer', async () => { + rawTxMetadataDocument.keyIndex = -1; + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + describe('encryptionKeyIndex', () => { + it('should be defined', async () => { + delete rawTxMetadataDocument.encryptionKeyIndex; + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('required'); + expect(error.params.missingProperty) + .to + .equal('encryptionKeyIndex'); + }); + + it('should be a non-negative integer', async () => { + rawTxMetadataDocument.encryptionKeyIndex = -1; + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + describe('encryptedMetadata', () => { + it('should be defined', async () => { + delete rawTxMetadataDocument.encryptedMetadata; + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('required'); + expect(error.params.missingProperty) + .to + .equal('encryptedMetadata'); + }); + + it('should be not shorter than 32 bytes', async () => { + rawTxMetadataDocument.encryptedMetadata = crypto.randomBytes(31); + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('minItems'); + expect(error.instancePath) + .to + .equal('/encryptedMetadata'); + }); + + it('should be not longer than 4096 bytes', async () => { + rawTxMetadataDocument.encryptedMetadata = crypto.randomBytes(4097); + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('maxItems'); + expect(error.instancePath) + .to + .equal('/encryptedMetadata'); + }); + }); + + it('should not have additional properties', async () => { + rawTxMetadataDocument.someOtherProperty = 42; + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('additionalProperties'); + expect(error.params.additionalProperties) + .to + .deep + .equal(['someOtherProperty']); + }); + + it('should be valid', async () => { + const txMetadata = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + + const result = await txMetadata.validate(dpp.protocolVersion); + + expect(result.isValid()) + .to + .be + .true(); + }); + }); + }); +}); diff --git a/packages/wasm-dpp/src/document/errors/document_already_exists_error.rs b/packages/wasm-dpp/src/document/errors/document_already_exists_error.rs index 111d138b8d4..a4b028f7263 100644 --- a/packages/wasm-dpp/src/document/errors/document_already_exists_error.rs +++ b/packages/wasm-dpp/src/document/errors/document_already_exists_error.rs @@ -1,5 +1,5 @@ // use crate::document::state_transition::document_batch_transition::document_transition::from_document_transition_to_js_value; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransition; use thiserror::Error; use super::*; diff --git a/packages/wasm-dpp/src/document/errors/document_not_provided_error.rs b/packages/wasm-dpp/src/document/errors/document_not_provided_error.rs index 769f1853c48..bc520332441 100644 --- a/packages/wasm-dpp/src/document/errors/document_not_provided_error.rs +++ b/packages/wasm-dpp/src/document/errors/document_not_provided_error.rs @@ -1,5 +1,5 @@ // use crate::document::state_transition::document_batch_transition::document_transition::from_document_transition_to_js_value; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransition; use thiserror::Error; use super::*; diff --git a/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs b/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs index 00c3628694d..309a29cf802 100644 --- a/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs +++ b/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs @@ -1,9 +1,9 @@ // use crate::document::state_transition::document_batch_transition::document_transition::from_document_transition_to_js_value; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransition; use thiserror::Error; use super::*; -use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::TransitionActionTypeGetter; +use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::TransitionActionTypeGetter; #[wasm_bindgen] #[derive(Error, Debug)] diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index e7aa93c253a..769b47c7ce5 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -14,7 +14,7 @@ use dpp::document::Document; use dpp::prelude::ExtendedDocument; use dpp::identifier::Identifier; -use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::DocumentTransitionActionType; +use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; use dpp::version::PlatformVersion; use std::convert::TryFrom; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs index 8cf7b5d0b97..4a5218e30ea 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs @@ -1,6 +1,6 @@ use dpp::prelude::Revision; -use dpp::state_transition::documents_batch_transition::document_create_transition::DocumentCreateTransition; +use dpp::state_transition::batch_transition::document_create_transition::DocumentCreateTransition; use dpp::document::INITIAL_REVISION; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs index d952f2ed3d7..7853a915558 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs @@ -7,13 +7,12 @@ mod document_create_transition; // pub use document_replace_transition::*; use dpp::platform_value::Value; -use dpp::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::document_transition_action_type::TransitionActionTypeGetter; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransitionV0Methods; -use dpp::{ - state_transition::documents_batch_transition::document_transition::DocumentTransition, - util::json_value::JsonValueExt, ProtocolError, +use dpp::state_transition::batch_transition::batched_transition::document_transition::{ + DocumentTransition, DocumentTransitionV0Methods, }; +use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::TransitionActionTypeGetter; +use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use dpp::{util::json_value::JsonValueExt, ProtocolError}; use serde::Serialize; use serde_json::Value as JsonValue; use wasm_bindgen::prelude::*; diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs index d0ebb9ae56d..402c5aa61cc 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs @@ -12,9 +12,9 @@ use dpp::consensus::signature::SignatureError; use dpp::consensus::ConsensusError; use dpp::platform_value::BinaryData; use dpp::serialization::PlatformSerializable; -use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransition; -use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransition; +use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::StateTransition; use wasm_bindgen::prelude::*; @@ -27,7 +27,9 @@ use crate::{ }; use document_transition::DocumentTransitionWasm; -use dpp::state_transition::documents_batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use dpp::ed25519_dalek::ed25519::signature::SignerMut; +use dpp::state_transition::batch_transition::batched_transition::BatchedTransition; +use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; use dpp::state_transition::StateTransitionIdentitySigned; @@ -35,8 +37,8 @@ pub mod document_transition; // pub mod validation; #[derive(Clone, Debug)] -#[wasm_bindgen(js_name = DocumentsBatchTransition)] -pub struct DocumentsBatchTransitionWasm(DocumentsBatchTransition); +#[wasm_bindgen(js_name = BatchTransition)] +pub struct BatchTransitionWasm(BatchTransition); #[derive(Debug, Serialize, Deserialize, Default, Clone, Copy)] #[serde(rename_all = "camelCase")] @@ -47,8 +49,8 @@ pub struct ToObjectOptions { skip_identifiers_conversion: bool, } -#[wasm_bindgen(js_class=DocumentsBatchTransition)] -impl DocumentsBatchTransitionWasm { +#[wasm_bindgen(js_class=BatchTransition)] +impl BatchTransitionWasm { // #[wasm_bindgen(constructor)] // pub fn from_object( // js_raw_transition: JsValue, @@ -90,7 +92,7 @@ impl DocumentsBatchTransitionWasm { #[wasm_bindgen(js_name=getType)] pub fn get_type(&self) -> u8 { - StateTransitionType::DocumentsBatch.into() + StateTransitionType::Batch.into() } #[wasm_bindgen(js_name=getOwnerId)] @@ -101,10 +103,10 @@ impl DocumentsBatchTransitionWasm { #[wasm_bindgen(js_name=getTransitions)] pub fn get_transitions(&self) -> js_sys::Array { let array = js_sys::Array::new(); - let transitions = self.0.transitions(); + let transitions = self.0.document_transitions(); for tr in transitions.iter().cloned() { - let transition: DocumentTransitionWasm = tr.into(); + let transition: BatchTransitionWasm = tr.into(); array.push(&transition.into()); } @@ -115,8 +117,8 @@ impl DocumentsBatchTransitionWasm { pub fn set_transitions(&mut self, js_transitions: Array) -> Result<(), JsValue> { let mut transitions = vec![]; for js_transition in js_transitions.iter() { - let transition: DocumentTransition = js_transition - .to_wasm::("DocumentTransition")? + let transition: BatchedTransition = js_transition + .to_wasm::("BatchedTransition")? .to_owned() .into(); transitions.push(transition) @@ -276,7 +278,7 @@ impl DocumentsBatchTransitionWasm { let bls_adapter = BlsAdapter(bls); // TODO: come up with a better way to set signature to the binding. - let mut state_transition = StateTransition::DocumentsBatch(self.0.clone()); + let mut state_transition = StateTransition::Batch(self.0.clone()); state_transition .sign( &identity_public_key.to_owned().into(), @@ -322,7 +324,7 @@ impl DocumentsBatchTransitionWasm { ) -> Result { let bls_adapter = BlsAdapter(bls); - let verification_result = StateTransition::DocumentsBatch(self.0.clone()) + let verification_result = StateTransition::Batch(self.0.clone()) .verify_signature(&identity_public_key.to_owned().into(), &bls_adapter); match verification_result { @@ -402,10 +404,9 @@ impl DocumentsBatchTransitionWasm { #[wasm_bindgen(js_name=toBuffer)] pub fn to_buffer(&self) -> Result { - let bytes = PlatformSerializable::serialize_to_bytes(&StateTransition::DocumentsBatch( - self.0.clone(), - )) - .with_js_error()?; + let bytes = + PlatformSerializable::serialize_to_bytes(&StateTransition::Batch(self.0.clone())) + .with_js_error()?; Ok(Buffer::from_bytes(&bytes)) } @@ -423,14 +424,14 @@ impl DocumentsBatchTransitionWasm { // } } -impl From for DocumentsBatchTransitionWasm { - fn from(t: DocumentsBatchTransition) -> Self { - DocumentsBatchTransitionWasm(t) +impl From for BatchTransitionWasm { + fn from(t: BatchTransition) -> Self { + BatchTransitionWasm(t) } } -impl From for DocumentsBatchTransition { - fn from(t: DocumentsBatchTransitionWasm) -> Self { +impl From for BatchTransition { + fn from(t: BatchTransitionWasm) -> Self { t.0 } } diff --git a/packages/wasm-dpp/src/identity/state_transition/transition_types.rs b/packages/wasm-dpp/src/identity/state_transition/transition_types.rs index 1a4942726e0..1fa4ee3dd9c 100644 --- a/packages/wasm-dpp/src/identity/state_transition/transition_types.rs +++ b/packages/wasm-dpp/src/identity/state_transition/transition_types.rs @@ -19,7 +19,7 @@ impl From for StateTransitionTypeWasm { fn from(state_transition_type: StateTransitionType) -> Self { match state_transition_type { StateTransitionType::DataContractCreate => StateTransitionTypeWasm::DataContractCreate, - StateTransitionType::DocumentsBatch => StateTransitionTypeWasm::DocumentsBatch, + StateTransitionType::Batch => StateTransitionTypeWasm::DocumentsBatch, StateTransitionType::IdentityCreate => StateTransitionTypeWasm::IdentityCreate, StateTransitionType::IdentityTopUp => StateTransitionTypeWasm::IdentityTopUp, StateTransitionType::DataContractUpdate => StateTransitionTypeWasm::DataContractUpdate, diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index 8b3f8bfa863..f0ba5cde672 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -56,9 +56,7 @@ impl StateTransitionFactoryWasm { StateTransition::IdentityCreditWithdrawal(st) => { Ok(IdentityCreditWithdrawalTransitionWasm::from(st).into()) } - StateTransition::DocumentsBatch(st) => { - Ok(DocumentsBatchTransitionWasm::from(st).into()) - } + StateTransition::Batch(st) => Ok(DocumentsBatchTransitionWasm::from(st).into()), StateTransition::MasternodeVote(st) => { Ok(MasternodeVoteTransitionWasm::from(st).into()) } From 4ecc825bb94c0c340eb4179818b50df1ea63a11d Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 25 Dec 2024 05:40:20 +0700 Subject: [PATCH 21/61] more validation work --- packages/rs-dpp/src/state_transition/mod.rs | 4 +- .../batched_transition/mod.rs | 21 ++ .../batched_transition/token_transition.rs | 8 +- .../token_transition_action_type.rs | 2 +- .../document_create_transition_action/mod.rs | 6 +- .../state_v0/mod.rs | 4 +- .../state_v1/mod.rs | 4 +- .../structure_v0/mod.rs | 0 .../document_delete_transition_action/mod.rs | 4 +- .../state_v0/mod.rs | 2 +- .../structure_v0/mod.rs | 0 .../mod.rs | 4 +- .../state_v0/mod.rs | 0 .../structure_v0/mod.rs | 0 .../document_replace_transition_action/mod.rs | 4 +- .../state_v0/mod.rs | 0 .../structure_v0/mod.rs | 0 .../mod.rs | 4 +- .../state_v0/mod.rs | 0 .../structure_v0/mod.rs | 0 .../mod.rs | 4 +- .../state_v0/mod.rs | 0 .../structure_v0/mod.rs | 0 .../action_validation/mod.rs | 0 .../token_issuance_transition_action/mod.rs | 8 +- .../state_v0/mod.rs | 8 +- .../structure_v0/mod.rs | 4 +- .../advanced_structure/mod.rs | 0 .../batch/advanced_structure/v0/mod.rs | 265 +++++++++++++++++ .../{documents_batch => batch}/balance/mod.rs | 2 +- .../balance/v0/mod.rs | 1 - .../bindings/data_trigger_binding/mod.rs | 2 +- .../bindings/data_trigger_binding/v0/mod.rs | 2 +- .../data_triggers/bindings/list/mod.rs | 2 +- .../data_triggers/bindings/list/v0/mod.rs | 10 +- .../data_triggers/bindings/mod.rs | 0 .../data_triggers/context.rs | 0 .../data_triggers/executor.rs | 6 +- .../data_triggers/mod.rs | 0 .../data_triggers/triggers/dashpay/mod.rs | 6 +- .../data_triggers/triggers/dashpay/v0/mod.rs | 4 +- .../data_triggers/triggers/dpns/mod.rs | 12 +- .../data_triggers/triggers/dpns/v0/mod.rs | 2 +- .../triggers/feature_flags/mod.rs | 4 +- .../triggers/feature_flags/v0/mod.rs | 0 .../data_triggers/triggers/mod.rs | 0 .../data_triggers/triggers/reject/mod.rs | 12 +- .../data_triggers/triggers/reject/v0/mod.rs | 2 +- .../data_triggers/triggers/withdrawals/mod.rs | 4 +- .../triggers/withdrawals/v0/mod.rs | 2 +- .../identity_contract_nonce/mod.rs | 0 .../identity_contract_nonce/v0/mod.rs | 4 +- .../is_allowed/mod.rs | 0 .../is_allowed/v0/mod.rs | 15 +- .../{documents_batch => batch}/mod.rs | 6 +- .../{documents_batch => batch}/state/mod.rs | 0 .../state/v0/data_triggers.rs | 2 +- .../state/v0/fetch_contender.rs | 0 .../state/v0/fetch_documents.rs | 0 .../state_transitions/batch/state/v0/mod.rs | 266 ++++++++++++++++++ .../transformer/mod.rs | 0 .../transformer/v0/mod.rs | 255 ++++++++++++++--- .../advanced_structure/v0/mod.rs | 216 -------------- .../documents_batch/state/v0/mod.rs | 231 --------------- .../state_transition/state_transitions/mod.rs | 2 +- .../document/batch_transition.rs | 13 +- .../document/document_transition.rs | 4 - .../document/token_issuance_transition.rs | 4 +- .../document/token_transition.rs | 2 +- .../document_transition_action_type.rs | 3 - .../document_transition/mod.rs | 56 ++-- .../token_issuance_transition_action/mod.rs | 16 +- .../transformer.rs | 6 +- .../transformer.rs | 2 +- .../document/documents_batch/mod.rs | 28 +- .../document/documents_batch/v0/mod.rs | 12 +- .../v0/mod.rs | 1 - .../drive_abci_validation_versions/v1.rs | 6 + .../drive_abci_validation_versions/v2.rs | 6 + .../drive_abci_validation_versions/v3.rs | 6 + .../drive_abci_validation_versions/v4.rs | 6 + 81 files changed, 937 insertions(+), 660 deletions(-) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_create_transition_action/mod.rs (86%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_create_transition_action/state_v0/mod.rs (97%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_create_transition_action/state_v1/mod.rs (97%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_create_transition_action/structure_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_delete_transition_action/mod.rs (89%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_delete_transition_action/state_v0/mod.rs (97%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_delete_transition_action/structure_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_purchase_transition_action/mod.rs (88%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_purchase_transition_action/state_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_purchase_transition_action/structure_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_replace_transition_action/mod.rs (89%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_replace_transition_action/state_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_replace_transition_action/structure_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_transfer_transition_action/mod.rs (88%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_transfer_transition_action/state_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_transfer_transition_action/structure_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_update_price_transition_action/mod.rs (88%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_update_price_transition_action/state_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/document_update_price_transition_action/structure_v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/token_issuance_transition_action/mod.rs (86%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/token_issuance_transition_action/state_v0/mod.rs (95%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/action_validation/token_issuance_transition_action/structure_v0/mod.rs (92%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/advanced_structure/mod.rs (100%) create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/balance/mod.rs (90%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/balance/v0/mod.rs (97%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/bindings/data_trigger_binding/mod.rs (93%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/bindings/data_trigger_binding/v0/mod.rs (97%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/bindings/list/mod.rs (84%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/bindings/list/v0/mod.rs (89%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/bindings/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/context.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/executor.rs (86%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/dashpay/mod.rs (82%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/dashpay/v0/mod.rs (98%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/dpns/mod.rs (78%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/dpns/v0/mod.rs (99%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/feature_flags/mod.rs (77%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/feature_flags/v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/reject/mod.rs (77%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/reject/v0/mod.rs (95%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/withdrawals/mod.rs (82%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/data_triggers/triggers/withdrawals/v0/mod.rs (98%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/identity_contract_nonce/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/identity_contract_nonce/v0/mod.rs (95%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/is_allowed/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/is_allowed/v0/mod.rs (83%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/mod.rs (99%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/state/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/state/v0/data_triggers.rs (93%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/state/v0/fetch_contender.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/state/v0/fetch_documents.rs (100%) create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/transformer/mod.rs (100%) rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/{documents_batch => batch}/transformer/v0/mod.rs (72%) delete mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs delete mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 4b4ffed7926..793bdf0fe78 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -367,9 +367,7 @@ impl StateTransition { BatchedTransitionRef::Token(TokenTransition::Transfer(_)) => { "TokenTransfer" } - BatchedTransitionRef::Token(TokenTransition::Issuance(_)) => { - "TokenIssuance" - } + BatchedTransitionRef::Token(TokenTransition::Mint(_)) => "TokenIssuance", BatchedTransitionRef::Token(TokenTransition::Burn(_)) => "TokenBurn", }; document_transition_types.push(document_transition_name); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs index 9fe8956639c..f4ff1666aff 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs @@ -31,6 +31,7 @@ pub use document_replace_transition::DocumentReplaceTransition; pub use document_transfer_transition::DocumentTransferTransition; use document_transition::DocumentTransition; pub use document_update_price_transition::DocumentUpdatePriceTransition; +use platform_value::Identifier; use token_transition::TokenTransition; pub const PROPERTY_ACTION: &str = "$action"; @@ -64,6 +65,26 @@ impl<'a> BatchedTransitionRef<'a> { BatchedTransitionRef::Token(tok_ref) => BatchedTransition::Token((*tok_ref).clone()), } } + + pub fn identity_contract_nonce(&self) -> IdentityNonce { + match self { + BatchedTransitionRef::Document(document_transition) => { + document_transition.identity_contract_nonce() + } + BatchedTransitionRef::Token(token_transition) => { + token_transition.identity_contract_nonce() + } + } + } + + pub fn data_contract_id(&self) -> Identifier { + match self { + BatchedTransitionRef::Document(document_transition) => { + document_transition.data_contract_id() + } + BatchedTransitionRef::Token(token_transition) => token_transition.data_contract_id(), + } + } } impl BatchedTransition { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs index 4c4f8df552e..5a143fcd62b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs @@ -21,7 +21,7 @@ pub enum TokenTransition { Burn(TokenBurnTransition), #[display("TokenIssuanceTransition({})", "_0")] - Issuance(TokenIssuanceTransition), + Mint(TokenIssuanceTransition), #[display("TokenTransferTransition({})", "_0")] Transfer(TokenTransferTransition), @@ -55,7 +55,7 @@ impl BatchTransitionResolversV0 for TokenTransition { } } fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { - if let Self::Issuance(ref t) = self { + if let Self::Mint(ref t) = self { Some(t) } else { None @@ -95,7 +95,7 @@ impl TokenTransitionV0Methods for TokenTransition { fn base(&self) -> &TokenBaseTransition { match self { TokenTransition::Burn(t) => t.base(), - TokenTransition::Issuance(t) => t.base(), + TokenTransition::Mint(t) => t.base(), TokenTransition::Transfer(t) => t.base(), } } @@ -103,7 +103,7 @@ impl TokenTransitionV0Methods for TokenTransition { fn base_mut(&mut self) -> &mut TokenBaseTransition { match self { TokenTransition::Burn(t) => t.base_mut(), - TokenTransition::Issuance(t) => t.base_mut(), + TokenTransition::Mint(t) => t.base_mut(), TokenTransition::Transfer(t) => t.base_mut(), } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs index 37bf79f558d..613660dc745 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs @@ -17,7 +17,7 @@ impl TransitionActionTypeGetter for TokenTransition { fn action_type(&self) -> TokenTransitionActionType { match self { TokenTransition::Burn(_) => TokenTransitionActionType::Burn, - TokenTransition::Issuance(_) => TokenTransitionActionType::Issuance, + TokenTransition::Mint(_) => TokenTransitionActionType::Issuance, TokenTransition::Transfer(_) => TokenTransitionActionType::Transfer, } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs similarity index 86% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs index 1cc02198832..9e4a28a3988 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs @@ -8,9 +8,9 @@ use drive::grovedb::TransactionArg; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_create_transition_action::state_v0::DocumentCreateTransitionActionStateValidationV0; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_create_transition_action::state_v1::DocumentCreateTransitionActionStateValidationV1; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_create_transition_action::structure_v0::DocumentCreateTransitionActionStructureValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_create_transition_action::state_v0::DocumentCreateTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_create_transition_action::state_v1::DocumentCreateTransitionActionStateValidationV1; +use crate::execution::validation::state_transition::batch::action_validation::document_create_transition_action::structure_v0::DocumentCreateTransitionActionStructureValidationV0; use crate::platform_types::platform::PlatformStateRef; mod state_v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs similarity index 97% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/state_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs index fdc1c0a2dfa..cf78608b9d8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs @@ -19,8 +19,8 @@ use drive::query::TransactionArg; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_contender::fetch_contender; -use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; use crate::platform_types::platform::PlatformStateRef; pub(super) trait DocumentCreateTransitionActionStateValidationV0 { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/state_v1/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs similarity index 97% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/state_v1/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs index 2e2908d9b56..819d78400bf 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/state_v1/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs @@ -21,8 +21,8 @@ use drive::query::TransactionArg; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_contender::fetch_contender; -use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_documents::{fetch_document_with_id, has_contested_document_with_document_id}; +use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::{fetch_document_with_id, has_contested_document_with_document_id}; use crate::platform_types::platform::PlatformStateRef; pub(super) trait DocumentCreateTransitionActionStateValidationV1 { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_create_transition_action/structure_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs similarity index 89% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs index 63bf935fc74..20ff3378e28 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs @@ -7,8 +7,8 @@ use drive::grovedb::TransactionArg; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_delete_transition_action::state_v0::DocumentDeleteTransitionActionStateValidationV0; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_delete_transition_action::structure_v0::DocumentDeleteTransitionActionStructureValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_delete_transition_action::state_v0::DocumentDeleteTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_delete_transition_action::structure_v0::DocumentDeleteTransitionActionStructureValidationV0; use crate::platform_types::platform::PlatformStateRef; mod state_v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs similarity index 97% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/state_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs index 98ce7ed92b8..71427308baa 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs @@ -17,7 +17,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; use crate::platform_types::platform::PlatformStateRef; pub(super) trait DocumentDeleteTransitionActionStateValidationV0 { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_delete_transition_action/structure_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs similarity index 88% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs index bbc6b4860b6..adf8866600d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs @@ -8,8 +8,8 @@ use drive::grovedb::TransactionArg; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_purchase_transition_action::state_v0::DocumentPurchaseTransitionActionStateValidationV0; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_purchase_transition_action::structure_v0::DocumentPurchaseTransitionActionStructureValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_purchase_transition_action::state_v0::DocumentPurchaseTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_purchase_transition_action::structure_v0::DocumentPurchaseTransitionActionStructureValidationV0; use crate::platform_types::platform::PlatformStateRef; mod state_v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/state_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs similarity index 89% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs index e147f8d13a9..91f910ca794 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs @@ -8,8 +8,8 @@ use drive::grovedb::TransactionArg; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_replace_transition_action::state_v0::DocumentReplaceTransitionActionStateValidationV0; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_replace_transition_action::structure_v0::DocumentReplaceTransitionActionStructureValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_replace_transition_action::state_v0::DocumentReplaceTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_replace_transition_action::structure_v0::DocumentReplaceTransitionActionStructureValidationV0; use crate::platform_types::platform::PlatformStateRef; mod state_v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/state_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_replace_transition_action/structure_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs similarity index 88% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs index 59b836fe8ea..d0a545a7491 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs @@ -8,8 +8,8 @@ use drive::grovedb::TransactionArg; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_transfer_transition_action::state_v0::DocumentTransferTransitionActionStateValidationV0; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_transfer_transition_action::structure_v0::DocumentTransferTransitionActionStructureValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::state_v0::DocumentTransferTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::structure_v0::DocumentTransferTransitionActionStructureValidationV0; use crate::platform_types::platform::PlatformStateRef; mod state_v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/state_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs similarity index 88% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs index ee46c2d3be2..5c1c7dc88b7 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs @@ -8,8 +8,8 @@ use drive::state_transition_action::document::documents_batch::document_transiti use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_update_price_transition_action::state_v0::DocumentUpdatePriceTransitionActionStateValidationV0; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_update_price_transition_action::structure_v0::DocumentUpdatePriceTransitionActionStructureValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::state_v0::DocumentUpdatePriceTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::structure_v0::DocumentUpdatePriceTransitionActionStructureValidationV0; use crate::platform_types::platform::PlatformStateRef; mod state_v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/state_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/mod.rs similarity index 86% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/mod.rs index 379feef5ae9..46d281666a0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/mod.rs @@ -2,14 +2,14 @@ use dashcore_rpc::dashcore::Network; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::TokenIssuanceTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::TokenMintTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::documents_batch::action_validation::token_issuance_transition_action::state_v0::TokenIssuanceTransitionActionStateValidationV0; -use crate::execution::validation::state_transition::documents_batch::action_validation::token_issuance_transition_action::structure_v0::TokenIssuanceTransitionActionStructureValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_issuance_transition_action::state_v0::TokenIssuanceTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_issuance_transition_action::structure_v0::TokenIssuanceTransitionActionStructureValidationV0; use crate::platform_types::platform::PlatformStateRef; mod state_v0; @@ -35,7 +35,7 @@ pub trait TokenIssuanceTransitionActionValidation { ) -> Result; } -impl TokenIssuanceTransitionActionValidation for TokenIssuanceTransitionAction { +impl TokenIssuanceTransitionActionValidation for TokenMintTransitionAction { fn validate_structure( &self, owner_id: Identifier, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/state_v0/mod.rs similarity index 95% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/state_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/state_v0/mod.rs index fa679259793..6d1226d35d6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/state_v0/mod.rs @@ -11,7 +11,7 @@ use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenMintTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; use drive::error::drive::DriveError; @@ -20,8 +20,8 @@ use drive::state_transition_action::document::documents_batch::document_transiti use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_contender::fetch_contender; -use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenIssuanceTransitionActionStateValidationV0 { @@ -35,7 +35,7 @@ pub(super) trait TokenIssuanceTransitionActionStateValidationV0 { platform_version: &PlatformVersion, ) -> Result; } -impl TokenIssuanceTransitionActionStateValidationV0 for TokenIssuanceTransitionAction { +impl TokenIssuanceTransitionActionStateValidationV0 for TokenMintTransitionAction { fn validate_state_v0( &self, platform: &PlatformStateRef, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs similarity index 92% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs index cc7861ddc5d..a00ba08ccac 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs @@ -11,7 +11,7 @@ use dpp::data_contract::validate_document::DataContractDocumentValidationMethods use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenMintTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; @@ -25,7 +25,7 @@ pub(super) trait TokenIssuanceTransitionActionStructureValidationV0 { platform_version: &PlatformVersion, ) -> Result; } -impl TokenIssuanceTransitionActionStructureValidationV0 for TokenIssuanceTransitionAction { +impl TokenIssuanceTransitionActionStructureValidationV0 for TokenMintTransitionAction { fn validate_structure_v0( &self, owner_id: Identifier, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs new file mode 100644 index 00000000000..b945b83f8c1 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs @@ -0,0 +1,265 @@ +use crate::error::Error; +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::InvalidDocumentTransitionIdError; +use dpp::consensus::signature::{InvalidSignaturePublicKeySecurityLevelError, SignatureError}; +use dpp::dashcore::Network; +use dpp::document::Document; +use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; +use dpp::identity::PartialIdentity; +use dpp::state_transition::batch_transition::batched_transition::document_transition::{ + DocumentTransition, DocumentTransitionV0Methods, +}; +use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; +use dpp::state_transition::batch_transition::BatchTransition; +use dpp::state_transition::{StateTransitionIdentitySigned, StateTransitionLike}; +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::state_transition::batch_transition::batched_transition::BatchedTransitionRef; +use dpp::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use dpp::validation::ConsensusValidationResult; + +use dpp::version::PlatformVersion; + +use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; +use drive::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; +use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; +use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; +use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; +use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use drive::state_transition_action::StateTransitionAction; +use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; +use crate::error::execution::ExecutionError; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::action_validation::document_purchase_transition_action::DocumentPurchaseTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_issuance_transition_action::TokenIssuanceTransitionActionValidation; + +pub(in crate::execution::validation::state_transition::state_transitions::batch) trait DocumentsBatchStateTransitionStructureValidationV0 +{ + fn validate_advanced_structure_from_state_v0( + &self, + block_info: &BlockInfo, + network: Network, + action: &DocumentsBatchTransitionAction, + identity: &PartialIdentity, + execution_context: &mut StateTransitionExecutionContext, + platform_version: &PlatformVersion, + ) -> Result, Error>; +} + +impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { + fn validate_advanced_structure_from_state_v0( + &self, + block_info: &BlockInfo, + network: Network, + action: &DocumentsBatchTransitionAction, + identity: &PartialIdentity, + execution_context: &mut StateTransitionExecutionContext, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let security_levels = action.contract_based_security_level_requirement()?; + + let signing_key = identity.loaded_public_keys.get(&self.signature_public_key_id()).ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution("the key must exist for advanced structure validation as we already fetched it during signature validation")))?; + + if !security_levels.contains(&signing_key.security_level()) { + // We only need to bump the first identity data contract nonce as that will make a replay + // attack not possible + + let first_transition = self.document_transitions().first().ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution("There must be at least one state transition as this is already verified in basic validation")))?; + + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition( + first_transition.base(), + self.owner_id(), + self.user_fee_increase(), + ), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + vec![SignatureError::InvalidSignaturePublicKeySecurityLevelError( + InvalidSignaturePublicKeySecurityLevelError::new( + signing_key.security_level(), + security_levels, + ), + ) + .into()], + )); + } + + // We should validate that all newly created documents have valid ids + for transition in self.transitions_iter() { + if let BatchedTransitionRef::Document(DocumentTransition::Create(create_transition)) = + transition + { + // Validate the ID + let generated_document_id = Document::generate_document_id_v0( + create_transition.base().data_contract_id_ref(), + &self.owner_id(), + create_transition.base().document_type_name(), + &create_transition.entropy(), + ); + + // This hash will take 2 blocks (128 bytes) + execution_context.add_operation(ValidationOperation::DoubleSha256(2)); + + let id = create_transition.base().id(); + if generated_document_id != id { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition( + transition.base(), + self.owner_id(), + self.user_fee_increase(), + ), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + vec![ + InvalidDocumentTransitionIdError::new(generated_document_id, id).into(), + ], + )); + } + } + } + + // Next we need to validate the structure of all actions (this means with the data contract) + for transition in action.transitions() { + match transition { + BatchedTransitionAction::DocumentAction(document_action) => match document_action { + DocumentTransitionAction::CreateAction(create_action) => { + let result = create_action.validate_structure( + identity.id, + block_info, + network, + platform_version, + )?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the create action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + DocumentTransitionAction::ReplaceAction(replace_action) => { + let result = replace_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the replace action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + DocumentTransitionAction::DeleteAction(delete_action) => { + let result = delete_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the delete action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + DocumentTransitionAction::TransferAction(transfer_action) => { + let result = transfer_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + DocumentTransitionAction::UpdatePriceAction(update_price_action) => { + let result = update_price_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the update price action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + DocumentTransitionAction::PurchaseAction(purchase_action) => { + let result = purchase_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the purchase action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + DocumentTransitionAction::BumpIdentityDataContractNonce(_) => { + return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( + "we should not have a bump identity contract nonce at this stage", + ))); + } + }, + BatchedTransitionAction::TokenAction(token_action) => match token_action { + TokenTransitionAction::BurnAction(burn_action) => { + let result = burn_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + TokenTransitionAction::MintAction(issuance_action) => { + let result = issuance_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + TokenTransitionAction::TransferAction(transfer_action) => { + let result = transfer_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + }, + } + } + Ok(ConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/mod.rs similarity index 90% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/mod.rs index 0ef66608537..2b46fb66246 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/mod.rs @@ -1,6 +1,6 @@ use crate::error::execution::ExecutionError; use crate::error::Error; -use crate::execution::validation::state_transition::documents_batch::balance::v0::DocumentsBatchTransitionBalanceValidationV0; +use crate::execution::validation::state_transition::batch::balance::v0::DocumentsBatchTransitionBalanceValidationV0; use crate::execution::validation::state_transition::processor::v0::StateTransitionIdentityBalanceValidationV0; use dpp::identity::PartialIdentity; use dpp::state_transition::batch_transition::BatchTransition; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/v0/mod.rs similarity index 97% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/v0/mod.rs index c95eb57139e..cd84c2b4a38 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/balance/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/v0/mod.rs @@ -4,7 +4,6 @@ use dpp::consensus::basic::BasicError; use dpp::consensus::state::identity::IdentityInsufficientBalanceError; use dpp::consensus::ConsensusError; use dpp::identity::PartialIdentity; -use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; use dpp::state_transition::batch_transition::BatchTransition; use dpp::ProtocolError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/data_trigger_binding/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs similarity index 93% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/data_trigger_binding/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs index 6ab41f38000..aff80faa5b1 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/data_trigger_binding/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs @@ -1,4 +1,4 @@ -use crate::execution::validation::state_transition::documents_batch::data_triggers::{ +use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use derive_more::From; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs similarity index 97% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs index 7c390af6f24..15133ad5ddf 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{ +use crate::execution::validation::state_transition::batch::data_triggers::{ DataTrigger, DataTriggerExecutionContext, DataTriggerExecutionResult, }; use dpp::identifier::Identifier; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_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 similarity index 84% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/list/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/mod.rs index 76e98dc2a6c..52c0d8c55b4 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_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 @@ -1,6 +1,6 @@ use dpp::ProtocolError; use dpp::version::PlatformVersion; -use crate::execution::validation::state_transition::documents_batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; +use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/list/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs similarity index 89% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/list/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs index 4e11bd50ee8..a9ffcf11eaf 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/list/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs @@ -1,8 +1,8 @@ -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::dashpay::create_contact_request_data_trigger; -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::dpns::create_domain_data_trigger; -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::reject::reject_data_trigger; -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::withdrawals::delete_withdrawal_data_trigger; -use crate::execution::validation::state_transition::documents_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 crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBindingV0; use dpp::errors::ProtocolError; use dpp::system_data_contracts::withdrawals_contract::v1::document_types::withdrawal; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/bindings/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/context.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/context.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/context.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/context.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs similarity index 86% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs index def79618966..89de6874391 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/executor.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs @@ -1,4 +1,4 @@ -use crate::execution::validation::state_transition::documents_batch::data_triggers::{ +use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; @@ -6,8 +6,8 @@ use drive::state_transition_action::document::documents_batch::document_transiti use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::TransitionActionTypeGetter; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use dpp::version::PlatformVersion; -use crate::execution::validation::state_transition::documents_batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; -use crate::execution::validation::state_transition::documents_batch::data_triggers::bindings::data_trigger_binding::DataTriggerBindingV0Getters; +use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; +use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBindingV0Getters; use crate::error::Error; use crate::error::execution::ExecutionError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs similarity index 82% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs index 18910ec1b47..ba3d38332a7 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs @@ -1,11 +1,11 @@ use crate::error::execution::ExecutionError; use crate::error::Error; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{ +use crate::execution::validation::state_transition::batch::data_triggers::triggers::dashpay::v0::create_contact_request_data_trigger_v0; +use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; use dpp::version::PlatformVersion; -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::dashpay::v0::create_contact_request_data_trigger_v0; +use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs similarity index 98% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs index 1f5ab44fb7c..c7acf83aa34 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dashpay/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs @@ -13,7 +13,7 @@ use dpp::system_data_contracts::dashpay_contract::v1::document_types::contact_re ::{TO_USER_ID}; use dpp::version::PlatformVersion; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContextMethodsV0; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; +use crate::execution::validation::state_transition::batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; /// Creates a data trigger for handling contact request documents. /// @@ -122,7 +122,7 @@ mod test { use dpp::platform_value::{Bytes32}; use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionActionType; - use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::dashpay::create_contact_request_data_trigger; + use crate::execution::validation::state_transition::batch::data_triggers::triggers::dashpay::create_contact_request_data_trigger; use crate::platform_types::platform::PlatformStateRef; use crate::test::helpers::setup::TestPlatformBuilder; use super::*; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs similarity index 78% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs index 9619181bae9..90bffcdd81a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs @@ -1,9 +1,11 @@ -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use dpp::version::PlatformVersion; -use crate::error::Error; use crate::error::execution::ExecutionError; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::dpns::v0::create_domain_data_trigger_v0; +use crate::error::Error; +use crate::execution::validation::state_transition::batch::data_triggers::triggers::dpns::v0::create_domain_data_trigger_v0; +use crate::execution::validation::state_transition::batch::data_triggers::{ + DataTriggerExecutionContext, DataTriggerExecutionResult, +}; +use dpp::version::PlatformVersion; +use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs similarity index 99% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs index f45dee7d88a..f456fc06f83 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/dpns/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs @@ -8,7 +8,7 @@ use std::collections::BTreeMap; use crate::error::execution::ExecutionError; use crate::error::Error; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{ +use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use dpp::document::DocumentV0Getters; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs similarity index 77% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs index 5095cf69471..deb0429fd91 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs @@ -2,8 +2,8 @@ use drive::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use crate::error::Error; use crate::error::execution::ExecutionError; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::feature_flags::v0::create_feature_flag_data_trigger_v0; +use crate::execution::validation::state_transition::batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; +use crate::execution::validation::state_transition::batch::data_triggers::triggers::feature_flags::v0::create_feature_flag_data_trigger_v0; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/feature_flags/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs similarity index 77% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs index 5be16ac1611..67634d29b78 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs @@ -1,9 +1,11 @@ -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use dpp::version::PlatformVersion; -use crate::error::Error; use crate::error::execution::ExecutionError; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::reject::v0::reject_data_trigger_v0; +use crate::error::Error; +use crate::execution::validation::state_transition::batch::data_triggers::triggers::reject::v0::reject_data_trigger_v0; +use crate::execution::validation::state_transition::batch::data_triggers::{ + DataTriggerExecutionContext, DataTriggerExecutionResult, +}; +use dpp::version::PlatformVersion; +use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs similarity index 95% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs index 69c287e6004..3730b7cf961 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/reject/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs @@ -2,7 +2,7 @@ use dpp::consensus::state::data_trigger::data_trigger_condition_error::DataTrigg use dpp::data_contract::accessors::v0::DataContractV0Getters; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; -use crate::execution::validation::state_transition::documents_batch::data_triggers::DataTriggerExecutionResult; +use crate::execution::validation::state_transition::batch::data_triggers::DataTriggerExecutionResult; use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; use crate::error::execution::ExecutionError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs similarity index 82% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs index 23dd6e86408..5e97f176031 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs @@ -1,11 +1,11 @@ use crate::error::execution::ExecutionError; use crate::error::Error; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{ +use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; use dpp::version::PlatformVersion; -use crate::execution::validation::state_transition::documents_batch::data_triggers::triggers::withdrawals::v0::delete_withdrawal_data_trigger_v0; +use crate::execution::validation::state_transition::batch::data_triggers::triggers::withdrawals::v0::delete_withdrawal_data_trigger_v0; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs similarity index 98% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs index e0960ea7151..4b018b1fc1a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/data_triggers/triggers/withdrawals/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs @@ -17,7 +17,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; use dpp::system_data_contracts::withdrawals_contract::v1::document_types::withdrawal; use drive::drive::document::query::QueryDocumentsOutcomeV0Methods; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; +use crate::execution::validation::state_transition::batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; /// Creates a data trigger for handling deletion of withdrawal documents. /// diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/v0/mod.rs similarity index 95% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/v0/mod.rs index 2efc0ae50a9..6059e52b924 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/identity_contract_nonce/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/v0/mod.rs @@ -17,7 +17,7 @@ use crate::platform_types::platform::PlatformStateRef; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -pub(in crate::execution::validation::state_transition::state_transitions::documents_batch) trait DocumentsBatchStateTransitionIdentityContractNonceV0 +pub(in crate::execution::validation::state_transition::state_transitions::batch) trait DocumentsBatchStateTransitionIdentityContractNonceV0 { fn validate_identity_contract_nonces_v0( &self, @@ -39,7 +39,7 @@ impl DocumentsBatchStateTransitionIdentityContractNonceV0 for BatchTransition { platform_version: &PlatformVersion, ) -> Result { // We should validate that all newly created documents have valid ids - for transition in self.document_transitions() { + for transition in self.transitions_iter() { let revision_nonce = transition.identity_contract_nonce(); let identity_id = self.owner_id(); let (existing_nonce, fee) = platform.drive.fetch_identity_contract_nonce_with_fees( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/is_allowed/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/is_allowed/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/is_allowed/v0/mod.rs similarity index 83% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/is_allowed/v0/mod.rs index 450a92e11fc..82f7855f1c6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/is_allowed/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/is_allowed/v0/mod.rs @@ -4,6 +4,7 @@ use dpp::block::epoch::EpochIndex; use dpp::consensus::basic::document::ContestedDocumentsTemporarilyNotAllowedError; use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use dpp::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; use dpp::state_transition::batch_transition::BatchTransition; use dpp::validation::ConsensusValidationResult; @@ -33,14 +34,12 @@ pub fn validate_is_allowed_v0( return ConsensusValidationResult::new(); } - let is_contested = state_transition - .document_transitions_iter() - .any(|transition| { - transition - .as_transition_create() - .and_then(|create| create.prefunded_voting_balance().as_ref()) - .is_some() - }); + let is_contested = state_transition.transitions_iter().any(|transition| { + transition + .as_transition_create() + .and_then(|create| create.prefunded_voting_balance().as_ref()) + .is_some() + }); if is_contested { return ConsensusValidationResult::new_with_errors(vec![ 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/batch/mod.rs similarity index 99% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index d2995c45074..b9127ec0134 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/batch/mod.rs @@ -25,9 +25,9 @@ use crate::execution::types::state_transition_execution_context::StateTransition use crate::platform_types::platform::{PlatformRef, PlatformStateRef}; use crate::rpc::core::CoreRPCLike; -use crate::execution::validation::state_transition::documents_batch::advanced_structure::v0::DocumentsBatchStateTransitionStructureValidationV0; -use crate::execution::validation::state_transition::documents_batch::identity_contract_nonce::v0::DocumentsBatchStateTransitionIdentityContractNonceV0; -use crate::execution::validation::state_transition::documents_batch::state::v0::DocumentsBatchStateTransitionStateValidationV0; +use crate::execution::validation::state_transition::batch::advanced_structure::v0::DocumentsBatchStateTransitionStructureValidationV0; +use crate::execution::validation::state_transition::batch::identity_contract_nonce::v0::DocumentsBatchStateTransitionIdentityContractNonceV0; +use crate::execution::validation::state_transition::batch::state::v0::DocumentsBatchStateTransitionStateValidationV0; use crate::execution::validation::state_transition::processor::v0::{ StateTransitionBasicStructureValidationV0, StateTransitionNonceValidationV0, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/data_triggers.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs similarity index 93% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/data_triggers.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs index 47a71a2e699..577d143a13d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/data_triggers.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::execution::validation::state_transition::documents_batch::data_triggers::{ +use crate::execution::validation::state_transition::batch::data_triggers::{ data_trigger_bindings_list, DataTriggerExecutionContext, DataTriggerExecutionResult, DataTriggerExecutor, }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_contender.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/fetch_contender.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_contender.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/fetch_contender.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/fetch_documents.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/fetch_documents.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/fetch_documents.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs new file mode 100644 index 00000000000..06d4861209c --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs @@ -0,0 +1,266 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::state_error::StateError; +use dpp::prelude::ConsensusValidationResult; +use dpp::state_transition::batch_transition::BatchTransition; +use dpp::state_transition::StateTransitionLike; +use drive::state_transition_action::StateTransitionAction; +use dpp::version::{DefaultForPlatformVersion, PlatformVersion}; +use drive::grovedb::TransactionArg; +use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; +use drive::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; +use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::document_purchase_transition_action::DocumentPurchaseTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_issuance_transition_action::TokenIssuanceTransitionActionValidation; +use crate::execution::validation::state_transition::batch::data_triggers::{data_trigger_bindings_list, DataTriggerExecutionContext, DataTriggerExecutor}; +use crate::platform_types::platform::{PlatformStateRef}; +use crate::execution::validation::state_transition::state_transitions::batch::transformer::v0::BatchTransitionTransformerV0; +use crate::execution::validation::state_transition::ValidationMode; +use crate::platform_types::platform_state::v0::PlatformStateV0Methods; + +mod data_triggers; +pub mod fetch_contender; +pub mod fetch_documents; + +pub(in crate::execution::validation::state_transition::state_transitions::batch) trait DocumentsBatchStateTransitionStateValidationV0 +{ + fn validate_state_v0( + &self, + action: DocumentsBatchTransitionAction, + platform: &PlatformStateRef, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + tx: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error>; + + fn transform_into_action_v0( + &self, + platform: &PlatformStateRef, + block_info: &BlockInfo, + validation_mode: ValidationMode, + tx: TransactionArg, + ) -> Result, Error>; +} + +impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { + fn validate_state_v0( + &self, + mut state_transition_action: DocumentsBatchTransitionAction, + platform: &PlatformStateRef, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut validation_result = ConsensusValidationResult::::new(); + + let state_transition_execution_context = + StateTransitionExecutionContext::default_for_platform_version(platform_version)?; + + let owner_id = state_transition_action.owner_id(); + + let mut validated_transitions = vec![]; + + let data_trigger_bindings = if platform.config.execution.use_document_triggers { + data_trigger_bindings_list(platform_version)? + } else { + vec![] + }; + + // Next we need to validate the structure of all actions (this means with the data contract) + for transition in state_transition_action.transitions_take() { + let transition_validation_result = match &transition { + BatchedTransitionAction::DocumentAction(document_action) => match document_action { + DocumentTransitionAction::CreateAction(create_action) => create_action + .validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + DocumentTransitionAction::ReplaceAction(replace_action) => replace_action + .validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + DocumentTransitionAction::TransferAction(transfer_action) => transfer_action + .validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + DocumentTransitionAction::DeleteAction(delete_action) => delete_action + .validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + DocumentTransitionAction::UpdatePriceAction(update_price_action) => { + update_price_action.validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )? + } + DocumentTransitionAction::PurchaseAction(purchase_action) => purchase_action + .validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + DocumentTransitionAction::BumpIdentityDataContractNonce(..) => { + return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( + "we should never start with a bump identity data contract nonce", + ))); + } + }, + BatchedTransitionAction::TokenAction(token_action) => match token_action { + TokenTransitionAction::BurnAction(burn_action) => burn_action.validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + TokenTransitionAction::MintAction(mint_action) => mint_action.validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + TokenTransitionAction::TransferAction(transfer_action) => transfer_action + .validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + }, + }; + + if !transition_validation_result.is_valid() { + // If a state transition isn't valid we still need to bump the identity data contract nonce + validation_result.add_errors(transition_validation_result.errors); + validated_transitions.push( + DocumentTransitionAction::BumpIdentityDataContractNonce( + BumpIdentityDataContractNonceAction::from_document_base_transition_action( + transition.base_owned().ok_or(Error::Execution( + ExecutionError::CorruptedCodeExecution( + "base should always exist on transition", + ), + ))?, + owner_id, + state_transition_action.user_fee_increase(), + ), + ), + ); + } else if platform.config.execution.use_document_triggers { + if let BatchedTransitionAction::DocumentAction(document_transition) = &transition { + // we should also validate document triggers + let data_trigger_execution_context = DataTriggerExecutionContext { + platform, + transaction, + owner_id: &self.owner_id(), + state_transition_execution_context: &state_transition_execution_context, + }; + let data_trigger_execution_result = document_transition + .validate_with_data_triggers( + &data_trigger_bindings, + &data_trigger_execution_context, + platform_version, + )?; + + if !data_trigger_execution_result.is_valid() { + // If a state transition isn't valid because of data triggers we still need + // to bump the identity data contract nonce + let consensus_errors: Vec = data_trigger_execution_result + .errors + .into_iter() + .map(|e| ConsensusError::StateError(StateError::DataTriggerError(e))) + .collect(); + validation_result.add_errors(consensus_errors); + validated_transitions + .push(DocumentTransitionAction::BumpIdentityDataContractNonce( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action( + document_transition.base().ok_or(Error::Execution( + ExecutionError::CorruptedCodeExecution( + "base should always exist on transition", + ), + ))?, + owner_id, + state_transition_action.user_fee_increase(), + ), + )); + } else { + validated_transitions.push(transition); + } + } else { + validated_transitions.push(transition); + } + } else { + validated_transitions.push(transition); + } + } + + state_transition_action.set_transitions(validated_transitions); + + validation_result.set_data(state_transition_action.into()); + + Ok(validation_result) + } + + fn transform_into_action_v0( + &self, + platform: &PlatformStateRef, + block_info: &BlockInfo, + validation_mode: ValidationMode, + tx: TransactionArg, + ) -> Result, Error> { + let platform_version = platform.state.current_platform_version()?; + + let mut execution_context = + StateTransitionExecutionContext::default_for_platform_version(platform_version)?; + + let validation_result = self.try_into_action_v0( + platform, + block_info, + 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/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/mod.rs 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/batch/transformer/v0/mod.rs similarity index 72% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/transformer/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index 3e4e2656a6c..c2524561b84 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/batch/transformer/v0/mod.rs @@ -24,7 +24,8 @@ use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::prelude::Revision; use dpp::validation::SimpleConsensusValidationResult; use dpp::{consensus::ConsensusError, prelude::Identifier, validation::ConsensusValidationResult}; - +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::state_transition::batch_transition::batched_transition::BatchedTransitionRef; use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; use dpp::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; @@ -32,11 +33,11 @@ use dpp::state_transition::StateTransitionLike; use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; use drive::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; use drive::state_transition_action::document::documents_batch::v0::DocumentsBatchTransitionActionV0; -use crate::execution::validation::state_transition::documents_batch::state::v0::fetch_documents::fetch_documents_for_transitions_knowing_contract_and_document_type; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_documents_for_transitions_knowing_contract_and_document_type; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; @@ -44,17 +45,23 @@ use dpp::state_transition::batch_transition::batched_transition::document_replac use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; use dpp::state_transition::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; use dpp::state_transition::batch_transition::batched_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; +use dpp::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; +use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use drive::drive::contract::DataContractFetchInfo; use drive::drive::Drive; use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::TokenBurnTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::TokenMintTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; use crate::platform_types::platform_state::v0::PlatformStateV0Methods; -pub(in crate::execution::validation::state_transition::state_transitions::documents_batch) trait DocumentsBatchTransitionTransformerV0 +pub(in crate::execution::validation::state_transition::state_transitions::batch) trait BatchTransitionTransformerV0 { fn try_into_action_v0( &self, @@ -66,7 +73,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::docume ) -> Result, Error>; } -trait DocumentsBatchTransitionInternalTransformerV0 { +trait BatchTransitionInternalTransformerV0 { fn transform_document_transitions_within_contract_v0( platform: &PlatformStateRef, block_info: &BlockInfo, @@ -91,7 +98,12 @@ trait DocumentsBatchTransitionInternalTransformerV0 { platform_version: &PlatformVersion, ) -> Result>, Error>; /// The data contract can be of multiple difference versions - fn transform_transition_v0( + fn transform_token_transition_v0( + data_contract_fetch_info: Arc, + transition: &TokenTransition, + ) -> Result, Error>; + /// The data contract can be of multiple difference versions + fn transform_document_transition_v0( drive: &Drive, transaction: TransactionArg, full_validation: bool, @@ -117,9 +129,16 @@ trait DocumentsBatchTransitionInternalTransformerV0 { document_id: Identifier, original_document: &Document, ) -> SimpleConsensusValidationResult; + fn transform_token_transitions_within_contract_v0( + platform: &PlatformStateRef, + data_contract_id: &Identifier, + token_transitions: &Vec<&TokenTransition>, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error>; } -impl DocumentsBatchTransitionTransformerV0 for BatchTransition { +impl BatchTransitionTransformerV0 for BatchTransition { fn try_into_action_v0( &self, platform: &PlatformStateRef, @@ -131,35 +150,56 @@ impl DocumentsBatchTransitionTransformerV0 for BatchTransition { let owner_id = self.owner_id(); let user_fee_increase = self.user_fee_increase(); let platform_version = platform.state.current_platform_version()?; - let mut transitions_by_contracts_and_types: BTreeMap< + let mut document_transitions_by_contracts_and_types: BTreeMap< &Identifier, BTreeMap<&String, Vec<&DocumentTransition>>, > = BTreeMap::new(); + let mut token_transitions_by_contracts: BTreeMap<&Identifier, Vec<&TokenTransition>> = + BTreeMap::new(); + // We want to validate by contract, and then for each document type within a contract - for document_transition in self.document_transitions().iter() { - let document_type = document_transition.base().document_type_name(); - let data_contract_id = document_transition.base().data_contract_id_ref(); + for transition in self.transitions_iter() { + match transition { + BatchedTransitionRef::Document(document_transition) => { + let document_type = document_transition.base().document_type_name(); + let data_contract_id = document_transition.base().data_contract_id_ref(); - match transitions_by_contracts_and_types.entry(data_contract_id) { - Entry::Vacant(v) => { - v.insert(BTreeMap::from([(document_type, vec![document_transition])])); + match document_transitions_by_contracts_and_types.entry(data_contract_id) { + Entry::Vacant(v) => { + v.insert(BTreeMap::from([(document_type, vec![document_transition])])); + } + Entry::Occupied(mut transitions_by_types_in_contract) => { + match transitions_by_types_in_contract + .get_mut() + .entry(document_type) + { + Entry::Vacant(v) => { + v.insert(vec![document_transition]); + } + Entry::Occupied(mut o) => o.get_mut().push(document_transition), + } + } + } } - Entry::Occupied(mut transitions_by_types_in_contract) => { - match transitions_by_types_in_contract - .get_mut() - .entry(document_type) - { + BatchedTransitionRef::Token(token_transition) => { + let data_contract_id = token_transition.base().data_contract_id_ref(); + + match token_transitions_by_contracts.entry(data_contract_id) { Entry::Vacant(v) => { - v.insert(vec![document_transition]); + v.insert(vec![token_transition]); + } + Entry::Occupied(mut transitions_by_tokens_in_contract) => { + transitions_by_tokens_in_contract + .get_mut() + .push(token_transition) } - Entry::Occupied(mut o) => o.get_mut().push(document_transition), } } } } - let validation_result = transitions_by_contracts_and_types + let validation_result = document_transitions_by_contracts_and_types .iter() .map( |(data_contract_id, document_transitions_by_document_type)| { @@ -176,7 +216,19 @@ impl DocumentsBatchTransitionTransformerV0 for BatchTransition { ) }, ) - .collect::>>, Error>>()?; + .chain(token_transitions_by_contracts.iter().map( + |(data_contract_id, token_transitions)| { + Self::transform_token_transitions_within_contract_v0( + platform, + data_contract_id, + token_transitions, + transaction, + platform_version, + ) + }, + )) + .collect::>>, Error>>( + )?; let validation_result = ConsensusValidationResult::flatten(validation_result); if validation_result.has_data() { @@ -199,7 +251,46 @@ impl DocumentsBatchTransitionTransformerV0 for BatchTransition { } } -impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { +impl BatchTransitionInternalTransformerV0 for BatchTransition { + fn transform_token_transitions_within_contract_v0( + platform: &PlatformStateRef, + data_contract_id: &Identifier, + token_transitions: &Vec<&TokenTransition>, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + let drive = platform.drive; + // Data Contract must exist + let Some(data_contract_fetch_info) = drive + .get_contract_with_fetch_info_and_fee( + data_contract_id.0 .0, + None, + false, + transaction, + platform_version, + )? + .1 + else { + return Ok(ConsensusValidationResult::new_with_error( + BasicError::DataContractNotPresentError(DataContractNotPresentError::new( + *data_contract_id, + )) + .into(), + )); + }; + + let validation_result = token_transitions + .iter() + .map(|token_transition| { + Self::transform_token_transition_v0( + data_contract_fetch_info.clone(), + token_transition, + ) + }) + .collect::>, Error>>()?; + let validation_result = ConsensusValidationResult::merge_many(validation_result); + Ok(validation_result) + } fn transform_document_transitions_within_contract_v0( platform: &PlatformStateRef, block_info: &BlockInfo, @@ -210,7 +301,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { execution_context: &mut StateTransitionExecutionContext, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result>, Error> { + ) -> Result>, Error> { let drive = platform.drive; // Data Contract must exist let Some(data_contract_fetch_info) = drive @@ -247,7 +338,8 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { platform_version, ) }) - .collect::>>, Error>>()?; + .collect::>>, Error>>( + )?; Ok(ConsensusValidationResult::flatten(validation_result)) } @@ -262,7 +354,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { execution_context: &mut StateTransitionExecutionContext, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result>, Error> { + ) -> Result>, Error> { // We use temporary execution context without dry run, // because despite the dryRun, we need to get the // data contract to proceed with following logic @@ -324,7 +416,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { .iter() .map(|transition| { // we validate every transition in this document type - Self::transform_transition_v0( + Self::transform_document_transition_v0( platform.drive, transaction, validate_against_state, @@ -337,7 +429,7 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { platform_version, ) }) - .collect::>, Error>>( + .collect::>, Error>>( )?; let result = ConsensusValidationResult::merge_many( @@ -354,7 +446,61 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { } /// The data contract can be of multiple difference versions - fn transform_transition_v0<'a>( + fn transform_token_transition_v0( + data_contract_fetch_info: Arc, + transition: &TokenTransition, + ) -> Result, Error> { + match transition { + TokenTransition::Burn(token_burn_transition) => { + let result = ConsensusValidationResult::::new(); + let token_burn_action = TokenBurnTransitionAction::try_from_borrowed_token_burn_transition_with_contract_lookup(token_burn_transition, |_identifier| { + Ok(data_contract_fetch_info.clone()) + })?; + + if result.is_valid() { + let batched_action = BatchedTransitionAction::TokenAction( + TokenTransitionAction::BurnAction(token_burn_action), + ); + Ok(batched_action.into()) + } else { + Ok(result) + } + } + TokenTransition::Mint(token_mint_transition) => { + let result = ConsensusValidationResult::::new(); + let token_mint_action = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(token_mint_transition, |_identifier| { + Ok(data_contract_fetch_info.clone()) + })?; + + if result.is_valid() { + let batched_action = BatchedTransitionAction::TokenAction( + TokenTransitionAction::MintAction(token_mint_action), + ); + Ok(batched_action.into()) + } else { + Ok(result) + } + } + TokenTransition::Transfer(token_transfer_transition) => { + let result = ConsensusValidationResult::::new(); + let token_transfer_action = TokenTransferTransitionAction::try_from_borrowed_token_transfer_transition_with_contract_lookup(token_transfer_transition, |_identifier| { + Ok(data_contract_fetch_info.clone()) + })?; + + if result.is_valid() { + let batched_action = BatchedTransitionAction::TokenAction( + TokenTransitionAction::TransferAction(token_transfer_action), + ); + Ok(batched_action.into()) + } else { + Ok(result) + } + } + } + } + + /// The data contract can be of multiple difference versions + fn transform_document_transition_v0<'a>( drive: &Drive, transaction: TransactionArg, validate_against_state: bool, @@ -365,10 +511,10 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { owner_id: Identifier, execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, - ) -> Result, Error> { + ) -> Result, Error> { match transition { DocumentTransition::Create(document_create_transition) => { - let result = ConsensusValidationResult::::new(); + let result = ConsensusValidationResult::::new(); let (document_create_action, fee_result) = DocumentCreateTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup( drive, transaction, @@ -380,13 +526,16 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); if result.is_valid() { - Ok(DocumentTransitionAction::CreateAction(document_create_action).into()) + let batched_action = BatchedTransitionAction::DocumentAction( + DocumentTransitionAction::CreateAction(document_create_action), + ); + Ok(batched_action.into()) } else { Ok(result) } } DocumentTransition::Replace(document_replace_transition) => { - let mut result = ConsensusValidationResult::::new(); + let mut result = ConsensusValidationResult::::new(); let validation_result = Self::find_replaced_document_v0(transition, replaced_documents); @@ -399,9 +548,11 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { owner_id, 0, ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action.into(), + batched_action.into(), validation_result.errors, )); } @@ -467,7 +618,10 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { )?; if result.is_valid() { - Ok(DocumentTransitionAction::ReplaceAction(document_replace_action).into()) + let batched_action = BatchedTransitionAction::DocumentAction( + DocumentTransitionAction::ReplaceAction(document_replace_action), + ); + Ok(batched_action.into()) } else { Ok(result) } @@ -476,10 +630,13 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { let action = DocumentDeleteTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup(document_delete_transition, |_identifier| { Ok(data_contract_fetch_info.clone()) })?; - Ok(DocumentTransitionAction::DeleteAction(action).into()) + let batched_action = BatchedTransitionAction::DocumentAction( + DocumentTransitionAction::DeleteAction(action), + ); + Ok(batched_action.into()) } DocumentTransition::Transfer(document_transfer_transition) => { - let mut result = ConsensusValidationResult::::new(); + let mut result = ConsensusValidationResult::::new(); let validation_result = Self::find_replaced_document_v0(transition, replaced_documents); @@ -527,13 +684,16 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { )?; if result.is_valid() { - Ok(DocumentTransitionAction::TransferAction(document_transfer_action).into()) + let batched_action = BatchedTransitionAction::DocumentAction( + DocumentTransitionAction::TransferAction(document_transfer_action), + ); + Ok(batched_action.into()) } else { Ok(result) } } DocumentTransition::UpdatePrice(document_update_price_transition) => { - let mut result = ConsensusValidationResult::::new(); + let mut result = ConsensusValidationResult::::new(); let validation_result = Self::find_replaced_document_v0(transition, replaced_documents); @@ -581,16 +741,16 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { )?; if result.is_valid() { - Ok( - DocumentTransitionAction::UpdatePriceAction(document_update_price_action) - .into(), - ) + let batched_action = BatchedTransitionAction::DocumentAction( + DocumentTransitionAction::UpdatePriceAction(document_update_price_action), + ); + Ok(batched_action.into()) } else { Ok(result) } } DocumentTransition::Purchase(document_purchase_transition) => { - let mut result = ConsensusValidationResult::::new(); + let mut result = ConsensusValidationResult::::new(); let validation_result = Self::find_replaced_document_v0(transition, replaced_documents); @@ -649,7 +809,10 @@ impl DocumentsBatchTransitionInternalTransformerV0 for BatchTransition { )?; if result.is_valid() { - Ok(DocumentTransitionAction::PurchaseAction(document_purchase_action).into()) + let batched_action = BatchedTransitionAction::DocumentAction( + DocumentTransitionAction::PurchaseAction(document_purchase_action), + ); + Ok(batched_action.into()) } else { Ok(result) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs deleted file mode 100644 index 9bd09432f10..00000000000 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs +++ /dev/null @@ -1,216 +0,0 @@ -use crate::error::Error; -use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::InvalidDocumentTransitionIdError; -use dpp::consensus::signature::{InvalidSignaturePublicKeySecurityLevelError, SignatureError}; -use dpp::dashcore::Network; -use dpp::document::Document; -use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; -use dpp::identity::PartialIdentity; -use dpp::state_transition::batch_transition::batched_transition::document_transition::{ - DocumentTransition, DocumentTransitionV0Methods, -}; -use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use dpp::state_transition::batch_transition::BatchTransition; -use dpp::state_transition::{StateTransitionIdentitySigned, StateTransitionLike}; -use dpp::validation::ConsensusValidationResult; - -use dpp::version::PlatformVersion; - -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use drive::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; -use crate::execution::validation::state_transition::state_transitions::documents_batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; -use crate::execution::validation::state_transition::state_transitions::documents_batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; -use crate::execution::validation::state_transition::state_transitions::documents_batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; -use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use drive::state_transition_action::StateTransitionAction; -use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; -use crate::error::execution::ExecutionError; -use crate::execution::types::execution_operation::ValidationOperation; -use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_purchase_transition_action::DocumentPurchaseTransitionActionValidation; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; - -pub(in crate::execution::validation::state_transition::state_transitions::documents_batch) trait DocumentsBatchStateTransitionStructureValidationV0 -{ - fn validate_advanced_structure_from_state_v0( - &self, - block_info: &BlockInfo, - network: Network, - action: &DocumentsBatchTransitionAction, - identity: &PartialIdentity, - execution_context: &mut StateTransitionExecutionContext, - platform_version: &PlatformVersion, - ) -> Result, Error>; -} - -impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { - fn validate_advanced_structure_from_state_v0( - &self, - block_info: &BlockInfo, - network: Network, - action: &DocumentsBatchTransitionAction, - identity: &PartialIdentity, - execution_context: &mut StateTransitionExecutionContext, - platform_version: &PlatformVersion, - ) -> Result, Error> { - let security_levels = action.contract_based_security_level_requirement()?; - - let signing_key = identity.loaded_public_keys.get(&self.signature_public_key_id()).ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution("the key must exist for advanced structure validation as we already fetched it during signature validation")))?; - - if !security_levels.contains(&signing_key.security_level()) { - // We only need to bump the first identity data contract nonce as that will make a replay - // attack not possible - - let first_transition = self.document_transitions().first().ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution("There must be at least one state transition as this is already verified in basic validation")))?; - - let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition( - first_transition.base(), - self.owner_id(), - self.user_fee_increase(), - ), - ); - - return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action, - vec![SignatureError::InvalidSignaturePublicKeySecurityLevelError( - InvalidSignaturePublicKeySecurityLevelError::new( - signing_key.security_level(), - security_levels, - ), - ) - .into()], - )); - } - - // We should validate that all newly created documents have valid ids - for transition in self.document_transitions() { - if let DocumentTransition::Create(create_transition) = transition { - // Validate the ID - let generated_document_id = Document::generate_document_id_v0( - create_transition.base().data_contract_id_ref(), - &self.owner_id(), - create_transition.base().document_type_name(), - &create_transition.entropy(), - ); - - // This hash will take 2 blocks (128 bytes) - execution_context.add_operation(ValidationOperation::DoubleSha256(2)); - - let id = create_transition.base().id(); - if generated_document_id != id { - let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition( - transition.base(), - self.owner_id(), - self.user_fee_increase(), - ), - ); - - return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action, - vec![ - InvalidDocumentTransitionIdError::new(generated_document_id, id).into(), - ], - )); - } - } - } - - // Next we need to validate the structure of all actions (this means with the data contract) - for transition in action.transitions() { - match transition { - DocumentTransitionAction::CreateAction(create_action) => { - let result = create_action.validate_structure( - identity.id, - block_info, - network, - platform_version, - )?; - if !result.is_valid() { - let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the create action"), self.owner_id(), self.user_fee_increase()), - ); - - return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action, - result.errors, - )); - } - } - DocumentTransitionAction::ReplaceAction(replace_action) => { - let result = replace_action.validate_structure(platform_version)?; - if !result.is_valid() { - let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the replace action"), self.owner_id(), self.user_fee_increase()), - ); - - return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action, - result.errors, - )); - } - } - DocumentTransitionAction::DeleteAction(delete_action) => { - let result = delete_action.validate_structure(platform_version)?; - if !result.is_valid() { - let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the delete action"), self.owner_id(), self.user_fee_increase()), - ); - - return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action, - result.errors, - )); - } - } - DocumentTransitionAction::TransferAction(transfer_action) => { - let result = transfer_action.validate_structure(platform_version)?; - if !result.is_valid() { - let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), - ); - - return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action, - result.errors, - )); - } - } - DocumentTransitionAction::UpdatePriceAction(update_price_action) => { - let result = update_price_action.validate_structure(platform_version)?; - if !result.is_valid() { - let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the update price action"), self.owner_id(), self.user_fee_increase()), - ); - - return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action, - result.errors, - )); - } - } - DocumentTransitionAction::PurchaseAction(purchase_action) => { - let result = purchase_action.validate_structure(platform_version)?; - if !result.is_valid() { - let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the purchase action"), self.owner_id(), self.user_fee_increase()), - ); - - return Ok(ConsensusValidationResult::new_with_data_and_errors( - bump_action, - result.errors, - )); - } - } - DocumentTransitionAction::BumpIdentityDataContractNonce(_) => { - return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( - "we should not have a bump identity contract nonce at this stage", - ))); - } - } - } - Ok(ConsensusValidationResult::new()) - } -} 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 deleted file mode 100644 index 3ad53a7195c..00000000000 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs +++ /dev/null @@ -1,231 +0,0 @@ -use dpp::block::block_info::BlockInfo; -use dpp::consensus::ConsensusError; -use dpp::consensus::state::state_error::StateError; -use dpp::prelude::ConsensusValidationResult; -use dpp::state_transition::batch_transition::BatchTransition; -use dpp::state_transition::StateTransitionLike; -use drive::state_transition_action::StateTransitionAction; -use dpp::version::{DefaultForPlatformVersion, PlatformVersion}; -use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use drive::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; -use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; -use crate::error::Error; -use crate::error::execution::ExecutionError; -use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_purchase_transition_action::DocumentPurchaseTransitionActionValidation; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; -use crate::execution::validation::state_transition::documents_batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; -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; -use crate::platform_types::platform_state::v0::PlatformStateV0Methods; - -mod data_triggers; -pub mod fetch_contender; -pub mod fetch_documents; - -pub(in crate::execution::validation::state_transition::state_transitions::documents_batch) trait DocumentsBatchStateTransitionStateValidationV0 -{ - fn validate_state_v0( - &self, - action: DocumentsBatchTransitionAction, - platform: &PlatformStateRef, - block_info: &BlockInfo, - execution_context: &mut StateTransitionExecutionContext, - tx: TransactionArg, - platform_version: &PlatformVersion, - ) -> Result, Error>; - - fn transform_into_action_v0( - &self, - platform: &PlatformStateRef, - block_info: &BlockInfo, - validation_mode: ValidationMode, - tx: TransactionArg, - ) -> Result, Error>; -} - -impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { - fn validate_state_v0( - &self, - mut state_transition_action: DocumentsBatchTransitionAction, - platform: &PlatformStateRef, - block_info: &BlockInfo, - execution_context: &mut StateTransitionExecutionContext, - transaction: TransactionArg, - platform_version: &PlatformVersion, - ) -> Result, Error> { - let mut validation_result = ConsensusValidationResult::::new(); - - let state_transition_execution_context = - StateTransitionExecutionContext::default_for_platform_version(platform_version)?; - - let owner_id = state_transition_action.owner_id(); - - let mut validated_transitions = vec![]; - - let data_trigger_bindings = if platform.config.execution.use_document_triggers { - data_trigger_bindings_list(platform_version)? - } else { - vec![] - }; - - // Next we need to validate the structure of all actions (this means with the data contract) - for transition in state_transition_action.transitions_take() { - let transition_validation_result = match &transition { - DocumentTransitionAction::CreateAction(create_action) => create_action - .validate_state( - platform, - owner_id, - block_info, - execution_context, - transaction, - platform_version, - )?, - DocumentTransitionAction::ReplaceAction(replace_action) => replace_action - .validate_state( - platform, - owner_id, - block_info, - execution_context, - transaction, - platform_version, - )?, - DocumentTransitionAction::TransferAction(transfer_action) => transfer_action - .validate_state( - platform, - owner_id, - block_info, - execution_context, - transaction, - platform_version, - )?, - DocumentTransitionAction::DeleteAction(delete_action) => delete_action - .validate_state( - platform, - owner_id, - block_info, - execution_context, - transaction, - platform_version, - )?, - DocumentTransitionAction::UpdatePriceAction(update_price_action) => { - update_price_action.validate_state( - platform, - owner_id, - block_info, - execution_context, - transaction, - platform_version, - )? - } - DocumentTransitionAction::PurchaseAction(purchase_action) => purchase_action - .validate_state( - platform, - owner_id, - block_info, - execution_context, - transaction, - platform_version, - )?, - DocumentTransitionAction::BumpIdentityDataContractNonce(..) => { - return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( - "we should never start with a bump identity data contract nonce", - ))); - } - }; - - if !transition_validation_result.is_valid() { - // If a state transition isn't valid we still need to bump the identity data contract nonce - validation_result.add_errors(transition_validation_result.errors); - validated_transitions.push( - DocumentTransitionAction::BumpIdentityDataContractNonce( - BumpIdentityDataContractNonceAction::from_document_base_transition_action( - transition.base_owned().ok_or(Error::Execution( - ExecutionError::CorruptedCodeExecution( - "base should always exist on transition", - ), - ))?, - owner_id, - state_transition_action.user_fee_increase(), - ), - ), - ); - } else if platform.config.execution.use_document_triggers { - // we should also validate document triggers - let data_trigger_execution_context = DataTriggerExecutionContext { - platform, - transaction, - owner_id: &self.owner_id(), - state_transition_execution_context: &state_transition_execution_context, - }; - let data_trigger_execution_result = transition.validate_with_data_triggers( - &data_trigger_bindings, - &data_trigger_execution_context, - platform_version, - )?; - - if !data_trigger_execution_result.is_valid() { - // If a state transition isn't valid because of data triggers we still need - // to bump the identity data contract nonce - let consensus_errors: Vec = data_trigger_execution_result - .errors - .into_iter() - .map(|e| ConsensusError::StateError(StateError::DataTriggerError(e))) - .collect(); - validation_result.add_errors(consensus_errors); - validated_transitions - .push(DocumentTransitionAction::BumpIdentityDataContractNonce( - BumpIdentityDataContractNonceAction::from_document_base_transition_action( - transition.base_owned().ok_or(Error::Execution( - ExecutionError::CorruptedCodeExecution( - "base should always exist on transition", - ), - ))?, - owner_id, - state_transition_action.user_fee_increase(), - ), - )); - } else { - validated_transitions.push(transition); - } - } else { - validated_transitions.push(transition); - } - } - - state_transition_action.set_transitions(validated_transitions); - - validation_result.set_data(state_transition_action.into()); - - Ok(validation_result) - } - - fn transform_into_action_v0( - &self, - platform: &PlatformStateRef, - block_info: &BlockInfo, - validation_mode: ValidationMode, - tx: TransactionArg, - ) -> Result, Error> { - let platform_version = platform.state.current_platform_version()?; - - let mut execution_context = - StateTransitionExecutionContext::default_for_platform_version(platform_version)?; - - let validation_result = self.try_into_action_v0( - platform, - block_info, - 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/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/mod.rs index 7fcbb17a0de..c80e0bd3ea4 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 @@ -1,5 +1,5 @@ /// Module containing functionality related to batch processing of documents. -pub mod documents_batch; +pub mod batch; /// Module for creating an identity entity. pub mod identity_create; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs index 054bea175cd..0ef3b467b43 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs @@ -1,12 +1,13 @@ use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::BatchTransitionAction; +use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; use dpp::version::PlatformVersion; -impl DriveHighLevelDocumentOperationConverter for BatchTransitionAction { +impl DriveHighLevelDocumentOperationConverter for BatchedTransitionAction { fn into_high_level_document_drive_operations<'b>( self, epoch: &Epoch, @@ -14,10 +15,14 @@ impl DriveHighLevelDocumentOperationConverter for BatchTransitionAction { platform_version: &PlatformVersion, ) -> Result>, Error> { match self { - BatchTransitionAction::DocumentAction(document_action) => document_action + BatchedTransitionAction::DocumentAction(document_action) => document_action .into_high_level_document_drive_operations(epoch, owner_id, platform_version), - BatchTransitionAction::TokenAction(token_action) => token_action + BatchedTransitionAction::TokenAction(token_action) => token_action .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + BatchedTransitionAction::BumpIdentityDataContractNonce( + bump_identity_contract_nonce_action, + ) => bump_identity_contract_nonce_action + .into_high_level_drive_operations(epoch, platform_version), } } } diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs index 38d4baf3ca2..8319da20122 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs @@ -57,10 +57,6 @@ impl DriveHighLevelDocumentOperationConverter for DocumentTransitionAction { platform_version, ) } - DocumentTransitionAction::BumpIdentityDataContractNonce( - bump_identity_contract_nonce_action, - ) => bump_identity_contract_nonce_action - .into_high_level_drive_operations(epoch, platform_version), } } } diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs index a746913fd07..52a130064a7 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs @@ -5,12 +5,12 @@ use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenMintTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::TokenOperationType; use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; -impl DriveHighLevelDocumentOperationConverter for TokenIssuanceTransitionAction { +impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { fn into_high_level_document_drive_operations<'b>( self, _epoch: &Epoch, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs index e577bf9c9d5..5ecd40d75f8 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs @@ -16,7 +16,7 @@ impl DriveHighLevelDocumentOperationConverter for TokenTransitionAction { match self { TokenTransitionAction::BurnAction(token_burn_transition) => token_burn_transition .into_high_level_document_drive_operations(epoch, owner_id, platform_version), - TokenTransitionAction::IssuanceAction(token_issuance_transition) => { + TokenTransitionAction::MintAction(token_issuance_transition) => { token_issuance_transition.into_high_level_document_drive_operations( epoch, owner_id, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs index b45320eea51..bb2ad121fcd 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs @@ -14,9 +14,6 @@ impl TransitionActionTypeGetter for DocumentTransitionAction { DocumentTransitionAction::UpdatePriceAction(_) => { DocumentTransitionActionType::UpdatePrice } - DocumentTransitionAction::BumpIdentityDataContractNonce(_) => { - DocumentTransitionActionType::IgnoreWhileBumpingRevision - } } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index 8f3b6f772b3..d8d2f7aeae8 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -36,7 +36,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenIssuanceTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenMintTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; /// version @@ -57,34 +57,30 @@ pub enum DocumentTransitionAction { PurchaseAction(DocumentPurchaseTransitionAction), /// update price UpdatePriceAction(DocumentUpdatePriceTransitionAction), - /// bump identity data contract nonce - BumpIdentityDataContractNonce(BumpIdentityDataContractNonceAction), } impl DocumentTransitionAction { /// base - pub fn base(&self) -> Option<&DocumentBaseTransitionAction> { + pub fn base(&self) -> &DocumentBaseTransitionAction { match self { - DocumentTransitionAction::CreateAction(d) => Some(d.base()), - DocumentTransitionAction::DeleteAction(d) => Some(d.base()), - DocumentTransitionAction::ReplaceAction(d) => Some(d.base()), - DocumentTransitionAction::TransferAction(d) => Some(d.base()), - DocumentTransitionAction::PurchaseAction(d) => Some(d.base()), - DocumentTransitionAction::UpdatePriceAction(d) => Some(d.base()), - DocumentTransitionAction::BumpIdentityDataContractNonce(_) => None, + DocumentTransitionAction::CreateAction(d) => d.base(), + DocumentTransitionAction::DeleteAction(d) => d.base(), + DocumentTransitionAction::ReplaceAction(d) => d.base(), + DocumentTransitionAction::TransferAction(d) => d.base(), + DocumentTransitionAction::PurchaseAction(d) => d.base(), + DocumentTransitionAction::UpdatePriceAction(d) => d.base(), } } /// base owned - pub fn base_owned(self) -> Option { + pub fn base_owned(self) -> DocumentBaseTransitionAction { match self { - DocumentTransitionAction::CreateAction(d) => Some(d.base_owned()), - DocumentTransitionAction::DeleteAction(d) => Some(d.base_owned()), - DocumentTransitionAction::ReplaceAction(d) => Some(d.base_owned()), - DocumentTransitionAction::TransferAction(d) => Some(d.base_owned()), - DocumentTransitionAction::PurchaseAction(d) => Some(d.base_owned()), - DocumentTransitionAction::UpdatePriceAction(d) => Some(d.base_owned()), - DocumentTransitionAction::BumpIdentityDataContractNonce(_) => None, + DocumentTransitionAction::CreateAction(d) => d.base_owned(), + DocumentTransitionAction::DeleteAction(d) => d.base_owned(), + DocumentTransitionAction::ReplaceAction(d) => d.base_owned(), + DocumentTransitionAction::TransferAction(d) => d.base_owned(), + DocumentTransitionAction::PurchaseAction(d) => d.base_owned(), + DocumentTransitionAction::UpdatePriceAction(d) => d.base_owned(), } } } @@ -95,36 +91,38 @@ pub enum TokenTransitionAction { /// burn BurnAction(TokenBurnTransitionAction), /// issuance - IssuanceAction(TokenIssuanceTransitionAction), + MintAction(TokenMintTransitionAction), /// transfer TransferAction(TokenTransferTransitionAction), } impl TokenTransitionAction { /// Returns a reference to the base token transition action if available - pub fn base(&self) -> Option<&TokenBaseTransitionAction> { + pub fn base(&self) -> &TokenBaseTransitionAction { match self { - TokenTransitionAction::BurnAction(action) => Some(action.base()), - TokenTransitionAction::IssuanceAction(action) => Some(action.base()), - TokenTransitionAction::TransferAction(action) => Some(action.base()), + TokenTransitionAction::BurnAction(action) => action.base(), + TokenTransitionAction::MintAction(action) => action.base(), + TokenTransitionAction::TransferAction(action) => action.base(), } } /// Consumes self and returns the base token transition action if available - pub fn base_owned(self) -> Option { + pub fn base_owned(self) -> TokenBaseTransitionAction { match self { - TokenTransitionAction::BurnAction(action) => Some(action.base_owned()), - TokenTransitionAction::IssuanceAction(action) => Some(action.base_owned()), - TokenTransitionAction::TransferAction(action) => Some(action.base_owned()), + TokenTransitionAction::BurnAction(action) => action.base_owned(), + TokenTransitionAction::MintAction(action) => action.base_owned(), + TokenTransitionAction::TransferAction(action) => action.base_owned(), } } } /// token action #[derive(Debug, Clone, From)] -pub enum BatchTransitionAction { +pub enum BatchedTransitionAction { /// document DocumentAction(DocumentTransitionAction), /// token TokenAction(TokenTransitionAction), + /// bump identity data contract nonce + BumpIdentityDataContractNonce(BumpIdentityDataContractNonceAction), } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs index 2e49f290025..63dec919bbc 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs @@ -11,45 +11,45 @@ use crate::state_transition_action::document::documents_batch::document_transiti /// Token issuance transition action #[derive(Debug, Clone, From)] -pub enum TokenIssuanceTransitionAction { +pub enum TokenMintTransitionAction { /// v0 V0(TokenIssuanceTransitionActionV0), } -impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionAction { +impl TokenIssuanceTransitionActionAccessorsV0 for TokenMintTransitionAction { fn base(&self) -> &TokenBaseTransitionAction { match self { - TokenIssuanceTransitionAction::V0(v0) => &v0.base, + TokenMintTransitionAction::V0(v0) => &v0.base, } } fn base_owned(self) -> TokenBaseTransitionAction { match self { - TokenIssuanceTransitionAction::V0(v0) => v0.base, + TokenMintTransitionAction::V0(v0) => v0.base, } } fn issuance_amount(&self) -> u64 { match self { - TokenIssuanceTransitionAction::V0(v0) => v0.issuance_amount, + TokenMintTransitionAction::V0(v0) => v0.issuance_amount, } } fn set_issuance_amount(&mut self, amount: u64) { match self { - TokenIssuanceTransitionAction::V0(v0) => v0.issuance_amount = amount, + TokenMintTransitionAction::V0(v0) => v0.issuance_amount = amount, } } fn identity_balance_holder_id(&self) -> Identifier { match self { - TokenIssuanceTransitionAction::V0(v0) => v0.identity_balance_holder_id, + TokenMintTransitionAction::V0(v0) => v0.identity_balance_holder_id, } } fn set_identity_balance_holder_id(&mut self, id: Identifier) { match self { - TokenIssuanceTransitionAction::V0(v0) => v0.identity_balance_holder_id = id, + TokenMintTransitionAction::V0(v0) => v0.identity_balance_holder_id = id, } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs index 4f0458a579e..013146d70d5 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs @@ -5,12 +5,12 @@ use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{ - TokenIssuanceTransitionAction, TokenIssuanceTransitionActionV0, + TokenMintTransitionAction, TokenIssuanceTransitionActionV0, }; use dpp::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransition; /// Implement methods to transform a `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction`. -impl TokenIssuanceTransitionAction { +impl TokenMintTransitionAction { /// Transform a `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction` using the provided data contract lookup. /// /// # Arguments @@ -47,7 +47,7 @@ impl TokenIssuanceTransitionAction { /// # Returns /// /// * `Result` - A `TokenIssuanceTransitionAction` if successful, otherwise `ProtocolError`. - pub fn from_borrowed_token_issuance_transition_with_contract_lookup( + pub fn try_from_borrowed_token_mint_transition_with_contract_lookup( value: &TokenIssuanceTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs index 036dac8641c..708eb7004b7 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs @@ -45,7 +45,7 @@ impl TokenTransferTransitionAction { /// # Returns /// /// * `Result` - A `TokenTransferTransitionAction` if successful, otherwise `ProtocolError`. - pub fn from_borrowed_token_transfer_transition_with_contract_lookup( + pub fn try_from_borrowed_token_transfer_transition_with_contract_lookup( value: &TokenTransferTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs index ec20c751ec6..7869450a1db 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs @@ -1,4 +1,4 @@ -use crate::state_transition_action::document::documents_batch::document_transition::BatchTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; use crate::state_transition_action::document::documents_batch::v0::DocumentsBatchTransitionActionV0; use derive_more::From; use dpp::data_contract::accessors::v0::DataContractV0Getters; @@ -31,35 +31,35 @@ impl DocumentsBatchTransitionAction { } /// transitions - pub fn transitions(&self) -> &Vec { + pub fn transitions(&self) -> &Vec { match self { DocumentsBatchTransitionAction::V0(v0) => &v0.transitions, } } /// transitions - pub fn transitions_mut(&mut self) -> &mut Vec { + pub fn transitions_mut(&mut self) -> &mut Vec { match self { DocumentsBatchTransitionAction::V0(v0) => &mut v0.transitions, } } /// transitions - pub fn transitions_take(&mut self) -> Vec { + pub fn transitions_take(&mut self) -> Vec { match self { DocumentsBatchTransitionAction::V0(v0) => std::mem::take(&mut v0.transitions), } } /// transitions owned - pub fn transitions_owned(self) -> Vec { + pub fn transitions_owned(self) -> Vec { match self { DocumentsBatchTransitionAction::V0(v0) => v0.transitions, } } /// set transitions - pub fn set_transitions(&mut self, transitions: Vec) { + pub fn set_transitions(&mut self, transitions: Vec) { match self { DocumentsBatchTransitionAction::V0(v0) => v0.transitions = transitions, } @@ -136,19 +136,9 @@ impl DocumentsBatchTransitionAction { let mut highest_security_level = SecurityLevel::lowest_level(); for transition in self.transitions().iter() { - if let BatchTransitionAction::DocumentAction(document_transition) = transition { - let document_type_name = document_transition - .base() - .ok_or(ProtocolError::CorruptedCodeExecution( - "expecting action to have a base".to_string(), - ))? - .document_type_name(); - let data_contract_info = document_transition - .base() - .ok_or(ProtocolError::CorruptedCodeExecution( - "expecting action to have a base".to_string(), - ))? - .data_contract_fetch_info(); + if let BatchedTransitionAction::DocumentAction(document_transition) = transition { + let document_type_name = document_transition.base().document_type_name(); + let data_contract_info = document_transition.base().data_contract_fetch_info(); let document_type = data_contract_info .contract diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs index d71c5843cca..d92358ad459 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs @@ -1,5 +1,5 @@ use dpp::fee::Credits; -use crate::state_transition_action::document::documents_batch::document_transition::{BatchTransitionAction, DocumentTransitionAction}; +use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction}; use dpp::identifier::Identifier; use dpp::prelude::UserFeeIncrease; use dpp::ProtocolError; @@ -12,7 +12,7 @@ pub struct DocumentsBatchTransitionActionV0 { /// The owner making the transitions pub owner_id: Identifier, /// The inner transitions - pub transitions: Vec, + pub transitions: Vec, /// fee multiplier pub user_fee_increase: UserFeeIncrease, } @@ -31,7 +31,7 @@ impl DocumentsBatchTransitionActionV0 { .transitions .iter() .filter_map(|transition| match transition { - BatchTransitionAction::DocumentAction( + BatchedTransitionAction::DocumentAction( DocumentTransitionAction::PurchaseAction(purchase), ) => Some(purchase.price()), _ => None, @@ -57,9 +57,9 @@ impl DocumentsBatchTransitionActionV0 { .transitions .iter() .filter_map(|transition| match transition { - BatchTransitionAction::DocumentAction(DocumentTransitionAction::CreateAction( - document_create_transition_action, - )) => document_create_transition_action + BatchedTransitionAction::DocumentAction( + DocumentTransitionAction::CreateAction(document_create_transition_action), + ) => document_create_transition_action .prefunded_voting_balance() .iter() .try_fold(0u64, |acc, &(_, val)| acc.checked_add(val)), diff --git a/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs b/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs index 7a60f86601d..8225f4f6662 100644 --- a/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs +++ b/packages/rs-drive/src/verify/state_transition/verify_state_transition_was_executed_with_proof/v0/mod.rs @@ -27,7 +27,6 @@ use dpp::state_transition::batch_transition::document_replace_transition::Docume use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; use dpp::state_transition::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; use dpp::state_transition::batch_transition::batched_transition::document_update_price_transition::v0::v0_methods::DocumentUpdatePriceTransitionV0Methods; -use dpp::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; use dpp::state_transition::masternode_vote_transition::accessors::MasternodeVoteTransitionAccessorsV0; use dpp::state_transition::proof_result::StateTransitionProofResult; use dpp::state_transition::proof_result::StateTransitionProofResult::{VerifiedBalanceTransfer, VerifiedDataContract, VerifiedDocuments, VerifiedIdentity, VerifiedMasternodeVote, VerifiedPartialIdentity}; diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs index 29e3c37d472..cfd04a63601 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs @@ -129,6 +129,12 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V1: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, + token_issuance_transition_structure_validation: 0, + token_burn_transition_structure_validation: 0, + token_transfer_transition_structure_validation: 0, + token_issuance_transition_state_validation: 0, + token_burn_transition_state_validation: 0, + token_transfer_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs index 6c7c5ffcc1c..39a4e47c059 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs @@ -129,6 +129,12 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V2: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, + token_issuance_transition_structure_validation: 0, + token_burn_transition_structure_validation: 0, + token_transfer_transition_structure_validation: 0, + token_issuance_transition_state_validation: 0, + token_burn_transition_state_validation: 0, + token_transfer_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs index 2f71945b50b..487b248cf44 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs @@ -129,6 +129,12 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V3: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, + token_issuance_transition_structure_validation: 0, + token_burn_transition_structure_validation: 0, + token_transfer_transition_structure_validation: 0, + token_issuance_transition_state_validation: 0, + token_burn_transition_state_validation: 0, + token_transfer_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs index d147eb6b9ae..9d1d685a2f1 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs @@ -129,6 +129,12 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V4: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, + token_issuance_transition_structure_validation: 0, + token_burn_transition_structure_validation: 0, + token_transfer_transition_structure_validation: 0, + token_issuance_transition_state_validation: 0, + token_burn_transition_state_validation: 0, + token_transfer_transition_state_validation: 0, }, }, has_nonce_validation: 1, From 4214369f94be706891667d85ed06a792ea353a99 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Wed, 25 Dec 2024 07:21:07 +0700 Subject: [PATCH 22/61] a lot more validation --- .../src/data_contract/conversion/cbor/mod.rs | 1 + .../src/data_contract/v1/conversion/cbor.rs | 1 - .../validate_basic_structure/v0/mod.rs | 42 +++-- .../batch/action_validation/mod.rs | 4 +- .../token_burn_transition_action/mod.rs | 87 +++++++++ .../state_v0/mod.rs | 52 ++++++ .../structure_v0/mod.rs | 34 ++++ .../state_v0/mod.rs | 167 ----------------- .../token_mint_transition_action/mod.rs | 87 +++++++++ .../state_v0/mod.rs | 52 ++++++ .../structure_v0/mod.rs | 34 ++++ .../mod.rs | 34 ++-- .../state_v0/mod.rs | 52 ++++++ .../structure_v0/mod.rs | 12 +- .../batch/advanced_structure/v0/mod.rs | 54 +++--- .../state_transitions/batch/balance/v0/mod.rs | 6 +- .../batch/data_triggers/executor.rs | 14 +- .../data_triggers/triggers/dashpay/v0/mod.rs | 21 +-- .../data_triggers/triggers/dpns/v0/mod.rs | 84 ++------- .../triggers/feature_flags/v0/mod.rs | 28 +-- .../data_triggers/triggers/reject/v0/mod.rs | 14 +- .../triggers/withdrawals/v0/mod.rs | 14 +- .../batch/state/v0/data_triggers.rs | 6 - .../state_transitions/batch/state/v0/mod.rs | 42 ++--- .../batch/transformer/v0/mod.rs | 8 +- packages/rs-drive-abci/src/query/service.rs | 41 ++++- .../document/token_issuance_transition.rs | 2 +- .../document_transition/mod.rs | 4 +- .../mod.rs | 2 +- .../transformer.rs | 2 +- .../v0/mod.rs | 4 +- .../v0/transformer.rs | 2 +- .../transformer.rs | 169 +++++++++++++++++- .../v0/transformer.rs | 86 ++++++++- .../drive_abci_validation_versions/mod.rs | 2 +- .../drive_abci_validation_versions/v1.rs | 2 +- .../drive_abci_validation_versions/v2.rs | 2 +- .../drive_abci_validation_versions/v3.rs | 2 +- .../drive_abci_validation_versions/v4.rs | 2 +- 39 files changed, 820 insertions(+), 452 deletions(-) create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs delete mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/{token_issuance_transition_action => token_transfer_transition_action}/mod.rs (68%) create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs rename packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/{token_issuance_transition_action => token_transfer_transition_action}/structure_v0/mod.rs (78%) rename packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/{token_issuance_transition_action => token_mint_transition_action}/mod.rs (95%) rename packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/{token_issuance_transition_action => token_mint_transition_action}/transformer.rs (97%) rename packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/{token_issuance_transition_action => token_mint_transition_action}/v0/mod.rs (95%) rename packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/{token_issuance_transition_action => token_mint_transition_action}/v0/transformer.rs (98%) diff --git a/packages/rs-dpp/src/data_contract/conversion/cbor/mod.rs b/packages/rs-dpp/src/data_contract/conversion/cbor/mod.rs index 541fabd5bae..3fe07940141 100644 --- a/packages/rs-dpp/src/data_contract/conversion/cbor/mod.rs +++ b/packages/rs-dpp/src/data_contract/conversion/cbor/mod.rs @@ -59,6 +59,7 @@ impl DataContractCborConversionMethodsV0 for DataContract { fn to_cbor(&self, platform_version: &PlatformVersion) -> Result, ProtocolError> { match self { DataContract::V0(v0) => v0.to_cbor(platform_version), + DataContract::V1(v1) => v1.to_cbor(platform_version), } } diff --git a/packages/rs-dpp/src/data_contract/v1/conversion/cbor.rs b/packages/rs-dpp/src/data_contract/v1/conversion/cbor.rs index ba47910fe18..08e5e700819 100644 --- a/packages/rs-dpp/src/data_contract/v1/conversion/cbor.rs +++ b/packages/rs-dpp/src/data_contract/v1/conversion/cbor.rs @@ -1,6 +1,5 @@ use crate::data_contract::conversion::cbor::DataContractCborConversionMethodsV0; use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; -use crate::data_contract::data_contract::DataContractV1; use crate::util::cbor_value::CborCanonicalMap; use crate::data_contract::DataContractV1; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs index e73bce91e74..68d07f70476 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs @@ -15,6 +15,8 @@ use platform_value::Identifier; use platform_version::version::PlatformVersion; use std::collections::btree_map::Entry; use std::collections::BTreeMap; +use crate::state_transition::batch_transition::batched_transition::BatchedTransitionRef; +use crate::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; impl BatchTransition { @@ -51,18 +53,26 @@ impl BatchTransition { let mut document_transitions_by_contracts: BTreeMap> = BTreeMap::new(); - self.document_transitions_iter() - .for_each(|document_transition| { - let contract_identifier = document_transition.data_contract_id(); + // Group transitions by contract ID + let mut token_transitions: Vec<&TokenTransition> = vec![]; + + self.transitions_iter() + .for_each(|batch_transition| match batch_transition { + BatchedTransitionRef::Document(document_transition) => { + let contract_identifier = document_transition.data_contract_id(); - match document_transitions_by_contracts.entry(contract_identifier) { - Entry::Vacant(vacant) => { - vacant.insert(vec![document_transition]); - } - Entry::Occupied(mut identifiers) => { - identifiers.get_mut().push(document_transition); - } - }; + match document_transitions_by_contracts.entry(contract_identifier) { + Entry::Vacant(vacant) => { + vacant.insert(vec![document_transition]); + } + Entry::Occupied(mut identifiers) => { + identifiers.get_mut().push(document_transition); + } + }; + } + BatchedTransitionRef::Token(token_transition) => { + token_transitions.push(token_transition) + } }); let mut result = SimpleConsensusValidationResult::default(); @@ -98,6 +108,16 @@ impl BatchTransition { } } + for transition in token_transitions { + // We need to make sure that the identity contract nonce is within the allowed bounds + // This means that it is stored on 40 bits + if transition.identity_contract_nonce() & MISSING_IDENTITY_REVISIONS_FILTER > 0 { + result.add_error(BasicError::NonceOutOfBoundsError( + NonceOutOfBoundsError::new(transition.identity_contract_nonce()), + )); + } + } + Ok(result) } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs index ad7da4d9515..dfd63181b30 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs @@ -4,4 +4,6 @@ pub(crate) mod document_purchase_transition_action; pub(crate) mod document_replace_transition_action; pub(crate) mod document_transfer_transition_action; pub(crate) mod document_update_price_transition_action; -pub(crate) mod token_issuance_transition_action; +pub(crate) mod token_burn_transition_action; +pub(crate) mod token_mint_transition_action; +pub(crate) mod token_transfer_transition_action; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs new file mode 100644 index 00000000000..3d94bb7de5d --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs @@ -0,0 +1,87 @@ +use dashcore_rpc::dashcore::Network; +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::TokenBurnTransitionAction; +use dpp::version::PlatformVersion; +use drive::grovedb::TransactionArg; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::token_burn_transition_action::state_v0::TokenBurnTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_burn_transition_action::structure_v0::TokenBurnTransitionActionStructureValidationV0; +use crate::platform_types::platform::PlatformStateRef; + +mod state_v0; +mod structure_v0; + +pub trait TokenBurnTransitionActionValidation { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result; + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} + +impl TokenBurnTransitionActionValidation for TokenBurnTransitionAction { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_burn_transition_structure_validation + { + 0 => self.validate_structure_v0(platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenBurnTransitionAction::validate_structure".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_issuance_transition_state_validation + { + 0 => self.validate_state_v0( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenBurnTransitionAction::validate_state".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..62c099b7f90 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs @@ -0,0 +1,52 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::InvalidDocumentTypeError; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; +use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; +use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; +use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; +use dpp::consensus::state::state_error::StateError; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; +use drive::error::drive::DriveError; +use drive::query::TransactionArg; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::error::Error; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenBurnTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenBurnTransitionActionStateValidationV0 for TokenBurnTransitionAction { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + // todo verify that minting would not break max supply + + Ok(SimpleConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs new file mode 100644 index 00000000000..29127fd7c6a --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs @@ -0,0 +1,34 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::{DocumentCreationNotAllowedError, InvalidDocumentTypeError}; +use dpp::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError; +use dpp::dashcore::Network; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; +use dpp::data_contract::document_type::restricted_creation::CreationRestrictionMode; +use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; +use dpp::identifier::Identifier; +use dpp::validation::{SimpleConsensusValidationResult}; +use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::error::Error; + +pub(super) trait TokenBurnTransitionActionStructureValidationV0 { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenBurnTransitionActionStructureValidationV0 for TokenBurnTransitionAction { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result { + let token_configuration = self.base().token_configuration()?; + + Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/state_v0/mod.rs deleted file mode 100644 index 6d1226d35d6..00000000000 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/state_v0/mod.rs +++ /dev/null @@ -1,167 +0,0 @@ -use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::InvalidDocumentTypeError; -use dpp::consensus::ConsensusError; -use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; -use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; -use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; -use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; -use dpp::consensus::state::state_error::StateError; -use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; -use dpp::prelude::{ConsensusValidationResult, Identifier}; -use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenMintTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; -use dpp::version::PlatformVersion; -use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; -use drive::error::drive::DriveError; -use drive::query::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::error::Error; -use crate::execution::types::execution_operation::ValidationOperation; -use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; -use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; -use crate::platform_types::platform::PlatformStateRef; - -pub(super) trait TokenIssuanceTransitionActionStateValidationV0 { - fn validate_state_v0( - &self, - platform: &PlatformStateRef, - owner_id: Identifier, - block_info: &BlockInfo, - execution_context: &mut StateTransitionExecutionContext, - transaction: TransactionArg, - platform_version: &PlatformVersion, - ) -> Result; -} -impl TokenIssuanceTransitionActionStateValidationV0 for TokenMintTransitionAction { - fn validate_state_v0( - &self, - platform: &PlatformStateRef, - owner_id: Identifier, - block_info: &BlockInfo, - execution_context: &mut StateTransitionExecutionContext, - transaction: TransactionArg, - platform_version: &PlatformVersion, - ) -> Result { - let contract_fetch_info = self.base().data_contract_fetch_info(); - - let contract = &contract_fetch_info.contract; - - let document_type_name = self.base().to(); - - let Some(document_type) = contract.document_type_optional_for_name(document_type_name) - else { - return Ok(SimpleConsensusValidationResult::new_with_error( - InvalidDocumentTypeError::new(document_type_name.clone(), contract.id()).into(), - )); - }; - - // TODO: Use multi get https://github.com/facebook/rocksdb/wiki/MultiGet-Performance - // We should check to see if a document already exists in the state - let (already_existing_document, fee_result) = fetch_document_with_id( - platform.drive, - contract, - document_type, - self.base().id(), - transaction, - platform_version, - )?; - - execution_context.add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); - - if already_existing_document.is_some() { - return Ok(ConsensusValidationResult::new_with_error( - ConsensusError::StateError(StateError::DocumentAlreadyPresentError( - DocumentAlreadyPresentError::new(self.base().id()), - )), - )); - } - - // we also need to validate that the new document wouldn't conflict with any other document - // this means for example having overlapping unique indexes - - if document_type.indexes().values().any(|index| index.unique) { - let validation_result = platform - .drive - .validate_token_issuance_transition_action_uniqueness( - contract, - document_type, - self, - owner_id, - transaction, - platform_version, - ) - .map_err(Error::Drive)?; - - if !validation_result.is_valid() { - return Ok(validation_result); - } - } - - if let Some((contested_document_resource_vote_poll, _)) = self.prefunded_voting_balance() { - if let Some(stored_info) = self.current_store_contest_info() { - // We have previous stored info - match stored_info.vote_poll_status() { - ContestedDocumentVotePollStatus::NotStarted => { - Ok(SimpleConsensusValidationResult::new()) - } - ContestedDocumentVotePollStatus::Awarded(_) => { - // This is weird as it should have already been found when querying the document, however it is possible - // That it was destroyed - Ok(SimpleConsensusValidationResult::new_with_error( - ConsensusError::StateError(StateError::DocumentAlreadyPresentError( - DocumentAlreadyPresentError::new(self.base().id()), - )), - )) - } - ContestedDocumentVotePollStatus::Locked => { - Ok(SimpleConsensusValidationResult::new_with_error( - ConsensusError::StateError(StateError::DocumentContestCurrentlyLockedError( - DocumentContestCurrentlyLockedError::new( - contested_document_resource_vote_poll.into(), - stored_info.clone(), - platform_version.fee_version.vote_resolution_fund_fees.contested_document_vote_resolution_unlock_fund_required_amount, - ))), - )) - } - ContestedDocumentVotePollStatus::Started(start_block) => { - // We need to make sure that if there is a contest, it is in its first week - // The week might be more or less, as it's a versioned parameter - let time_ms_since_start = block_info.time_ms.checked_sub(start_block.time_ms).ok_or(Error::Drive(drive::error::Error::Drive(DriveError::CorruptedDriveState(format!("it makes no sense that the start block time {} is before our current block time {}", start_block.time_ms, block_info.time_ms)))))?; - - let join_time_allowed = platform_version.dpp.validation.voting.allow_other_contenders_time_mainnet_ms; - - if time_ms_since_start > join_time_allowed { - return Ok(SimpleConsensusValidationResult::new_with_error(ConsensusError::StateError(StateError::DocumentContestNotJoinableError( - DocumentContestNotJoinableError::new( - contested_document_resource_vote_poll.into(), - stored_info.clone(), - start_block.time_ms, - block_info.time_ms, - join_time_allowed, - ))))) - } - - // we need to also make sure that we are not already a contestant - - let (maybe_existing_contender, fee_result) = fetch_contender(platform.drive, contested_document_resource_vote_poll, owner_id, block_info, transaction, platform_version)?; - - execution_context.add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); - - if maybe_existing_contender.is_some() { - Ok(SimpleConsensusValidationResult::new_with_error(ConsensusError::StateError(StateError::DocumentContestIdentityAlreadyContestantError(DocumentContestIdentityAlreadyContestantError::new(contested_document_resource_vote_poll.into(), owner_id))))) - } else { - Ok(SimpleConsensusValidationResult::new()) - } - } - } - } else { - Ok(SimpleConsensusValidationResult::new()) - } - } else { - Ok(SimpleConsensusValidationResult::new()) - } - } -} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs new file mode 100644 index 00000000000..2821fcbdd36 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs @@ -0,0 +1,87 @@ +use dashcore_rpc::dashcore::Network; +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionAction; +use dpp::version::PlatformVersion; +use drive::grovedb::TransactionArg; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::token_mint_transition_action::state_v0::TokenMintTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_mint_transition_action::structure_v0::TokenMintTransitionActionStructureValidationV0; +use crate::platform_types::platform::PlatformStateRef; + +mod state_v0; +mod structure_v0; + +pub trait TokenMintTransitionActionValidation { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result; + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} + +impl TokenMintTransitionActionValidation for TokenMintTransitionAction { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_mint_transition_structure_validation + { + 0 => self.validate_structure_v0(platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenMintTransitionAction::validate_structure".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_issuance_transition_state_validation + { + 0 => self.validate_state_v0( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenMintTransitionAction::validate_state".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..820493d91f8 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs @@ -0,0 +1,52 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::InvalidDocumentTypeError; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; +use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; +use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; +use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; +use dpp::consensus::state::state_error::StateError; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; +use drive::error::drive::DriveError; +use drive::query::TransactionArg; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::error::Error; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenMintTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + // todo verify that minting would not break max supply + + Ok(SimpleConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs new file mode 100644 index 00000000000..69473c0f849 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs @@ -0,0 +1,34 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::{DocumentCreationNotAllowedError, InvalidDocumentTypeError}; +use dpp::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError; +use dpp::dashcore::Network; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; +use dpp::data_contract::document_type::restricted_creation::CreationRestrictionMode; +use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; +use dpp::identifier::Identifier; +use dpp::validation::{SimpleConsensusValidationResult}; +use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::error::Error; + +pub(super) trait TokenMintTransitionActionStructureValidationV0 { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenMintTransitionActionStructureValidationV0 for TokenMintTransitionAction { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result { + let token_configuration = self.base().token_configuration()?; + + Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs similarity index 68% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs index 46d281666a0..c79c3fef5d8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs @@ -2,25 +2,23 @@ use dashcore_rpc::dashcore::Network; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::TokenMintTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; -use crate::execution::validation::state_transition::batch::action_validation::token_issuance_transition_action::state_v0::TokenIssuanceTransitionActionStateValidationV0; -use crate::execution::validation::state_transition::batch::action_validation::token_issuance_transition_action::structure_v0::TokenIssuanceTransitionActionStructureValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_transfer_transition_action::state_v0::TokenTransferTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_transfer_transition_action::structure_v0::TokenTransferTransitionActionStructureValidationV0; use crate::platform_types::platform::PlatformStateRef; mod state_v0; mod structure_v0; -pub trait TokenIssuanceTransitionActionValidation { +pub trait TokenTransferTransitionActionValidation { fn validate_structure( &self, owner_id: Identifier, - block_info: &BlockInfo, - network: Network, platform_version: &PlatformVersion, ) -> Result; @@ -35,12 +33,10 @@ pub trait TokenIssuanceTransitionActionValidation { ) -> Result; } -impl TokenIssuanceTransitionActionValidation for TokenMintTransitionAction { +impl TokenTransferTransitionActionValidation for TokenTransferTransitionAction { fn validate_structure( &self, owner_id: Identifier, - block_info: &BlockInfo, - network: Network, platform_version: &PlatformVersion, ) -> Result { match platform_version @@ -48,11 +44,11 @@ impl TokenIssuanceTransitionActionValidation for TokenMintTransitionAction { .validation_and_processing .state_transitions .batch_state_transition - .token_issuance_transition_structure_validation + .token_transfer_transition_structure_validation { - 0 => self.validate_structure_v0(owner_id, block_info, network, platform_version), + 0 => self.validate_structure_v0(owner_id, platform_version), version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { - method: "TokenIssuanceTransitionAction::validate_structure".to_string(), + method: "TokenTransferTransitionAction::validate_structure".to_string(), known_versions: vec![0], received: version, })), @@ -83,19 +79,9 @@ impl TokenIssuanceTransitionActionValidation for TokenMintTransitionAction { transaction, platform_version, ), - // V1 introduces a validation that a contested document does not yet exist (and the - // cost for this operation) - 1 => self.validate_state_v1( - platform, - owner_id, - block_info, - execution_context, - transaction, - platform_version, - ), version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { - method: "TokenIssuanceTransitionAction::validate_state".to_string(), - known_versions: vec![0, 1], + method: "TokenTransferTransitionAction::validate_state".to_string(), + known_versions: vec![0], received: version, })), } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..d1ed855fff0 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs @@ -0,0 +1,52 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::InvalidDocumentTypeError; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; +use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; +use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; +use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; +use dpp::consensus::state::state_error::StateError; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction}; +use dpp::version::PlatformVersion; +use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; +use drive::error::drive::DriveError; +use drive::query::TransactionArg; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::error::Error; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenTransferTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenTransferTransitionActionStateValidationV0 for TokenTransferTransitionAction { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + // todo verify that minting would not break max supply + + Ok(SimpleConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs similarity index 78% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index a00ba08ccac..cf3bd5d5c2c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_issuance_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -11,30 +11,26 @@ use dpp::data_contract::validate_document::DataContractDocumentValidationMethods use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenMintTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; use dpp::version::PlatformVersion; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; -pub(super) trait TokenIssuanceTransitionActionStructureValidationV0 { +pub(super) trait TokenTransferTransitionActionStructureValidationV0 { fn validate_structure_v0( &self, owner_id: Identifier, - block_info: &BlockInfo, - network: Network, platform_version: &PlatformVersion, ) -> Result; } -impl TokenIssuanceTransitionActionStructureValidationV0 for TokenMintTransitionAction { +impl TokenTransferTransitionActionStructureValidationV0 for TokenTransferTransitionAction { fn validate_structure_v0( &self, owner_id: Identifier, - block_info: &BlockInfo, - network: Network, platform_version: &PlatformVersion, ) -> Result { let token_configuration = self.base().token_configuration()?; - token_configuration.Ok(SimpleConsensusValidationResult::default()) + Ok(SimpleConsensusValidationResult::default()) } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs index b945b83f8c1..0d6cbb42173 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs @@ -25,6 +25,13 @@ use crate::execution::validation::state_transition::state_transitions::batch::ac use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentReplaceTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionActionAccessors; use drive::state_transition_action::StateTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::execution::ExecutionError; @@ -33,7 +40,9 @@ use crate::execution::types::state_transition_execution_context::{StateTransitio use crate::execution::validation::state_transition::batch::action_validation::document_purchase_transition_action::DocumentPurchaseTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; -use crate::execution::validation::state_transition::batch::action_validation::token_issuance_transition_action::TokenIssuanceTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_burn_transition_action::TokenBurnTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_mint_transition_action::TokenMintTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_transfer_transition_action::TokenTransferTransitionActionValidation; pub(in crate::execution::validation::state_transition::state_transitions::batch) trait DocumentsBatchStateTransitionStructureValidationV0 { @@ -66,11 +75,11 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { // We only need to bump the first identity data contract nonce as that will make a replay // attack not possible - let first_transition = self.document_transitions().first().ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution("There must be at least one state transition as this is already verified in basic validation")))?; + let first_transition = self.first_transition().ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution("There must be at least one state transition as this is already verified in basic validation")))?; let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition( - first_transition.base(), + BumpIdentityDataContractNonceAction::from_batched_transition_ref( + first_transition, self.owner_id(), self.user_fee_increase(), ), @@ -108,7 +117,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { if generated_document_id != id { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition( - transition.base(), + create_transition.base(), self.owner_id(), self.user_fee_increase(), ), @@ -137,7 +146,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { )?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the create action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(document_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -150,7 +159,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { let result = replace_action.validate_structure(platform_version)?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the replace action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(replace_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -163,7 +172,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { let result = delete_action.validate_structure(platform_version)?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the delete action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(delete_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -176,7 +185,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { let result = transfer_action.validate_structure(platform_version)?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transfer_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -189,7 +198,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { let result = update_price_action.validate_structure(platform_version)?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the update price action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(update_price_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -202,7 +211,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { let result = purchase_action.validate_structure(platform_version)?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the purchase action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(purchase_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -211,18 +220,13 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { )); } } - DocumentTransitionAction::BumpIdentityDataContractNonce(_) => { - return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( - "we should not have a bump identity contract nonce at this stage", - ))); - } }, BatchedTransitionAction::TokenAction(token_action) => match token_action { TokenTransitionAction::BurnAction(burn_action) => { let result = burn_action.validate_structure(platform_version)?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(token_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -231,11 +235,11 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { )); } } - TokenTransitionAction::MintAction(issuance_action) => { - let result = issuance_action.validate_structure(platform_version)?; + TokenTransitionAction::MintAction(mint_action) => { + let result = mint_action.validate_structure(platform_version)?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(mint_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -245,10 +249,11 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { } } TokenTransitionAction::TransferAction(transfer_action) => { - let result = transfer_action.validate_structure(platform_version)?; + let result = transfer_action + .validate_structure(self.owner_id(), platform_version)?; if !result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the transfer action"), self.owner_id(), self.user_fee_increase()), + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(transfer_action.base(), self.owner_id(), self.user_fee_increase()), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -258,6 +263,11 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { } } }, + BatchedTransitionAction::BumpIdentityDataContractNonce(_) => { + return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( + "we should not have a bump identity contract nonce at this stage", + ))); + } } } Ok(ConsensusValidationResult::new()) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/v0/mod.rs index cd84c2b4a38..63b5472314a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/balance/v0/mod.rs @@ -4,11 +4,11 @@ use dpp::consensus::basic::BasicError; use dpp::consensus::state::identity::IdentityInsufficientBalanceError; use dpp::consensus::ConsensusError; use dpp::identity::PartialIdentity; +use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; use dpp::state_transition::batch_transition::BatchTransition; -use dpp::ProtocolError; - use dpp::validation::SimpleConsensusValidationResult; +use dpp::ProtocolError; use crate::error::execution::ExecutionError; use dpp::version::PlatformVersion; @@ -64,7 +64,7 @@ impl DocumentsBatchTransitionBalanceValidationV0 for BatchTransition { Err(e) => return Err(e.into()), }; - let base_fees = match platform_version.fee_version.state_transition_min_fees.document_batch_sub_transition.checked_mul(self.document_transitions().len() as u64) { + let base_fees = match platform_version.fee_version.state_transition_min_fees.document_batch_sub_transition.checked_mul(self.transitions_len() as u64) { None => return Ok(SimpleConsensusValidationResult::new_with_error(ConsensusError::BasicError(BasicError::OverflowError(OverflowError::new("overflow when multiplying base fee and amount of sub transitions in documents batch transition".to_string()))))), Some(base_fees) => base_fees }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs index 89de6874391..1129cd4ee16 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs @@ -27,18 +27,8 @@ impl DataTriggerExecutor for DocumentTransitionAction { context: &DataTriggerExecutionContext, platform_version: &PlatformVersion, ) -> Result { - let data_contract_id = self - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .data_contract_id(); - let document_type_name = self - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .document_type_name(); + let data_contract_id = self.base().data_contract_id(); + let document_type_name = self.base().document_type_name(); let transition_action = self.action_type(); // Match data triggers by action type, contract ID and document type name diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs index c7acf83aa34..eb030fe8c49 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs @@ -36,12 +36,7 @@ pub(super) fn create_contact_request_data_trigger_v0( context: &DataTriggerExecutionContext<'_>, platform_version: &PlatformVersion, ) -> Result { - let data_contract_fetch_info = document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .data_contract_fetch_info(); + let data_contract_fetch_info = document_transition.base().data_contract_fetch_info(); let data_contract = &data_contract_fetch_info.contract; let mut result = DataTriggerExecutionResult::default(); let is_dry_run = context.state_transition_execution_context.in_dry_run(); @@ -52,12 +47,7 @@ pub(super) fn create_contact_request_data_trigger_v0( return Err(Error::Execution(ExecutionError::DataTriggerExecutionError( format!( "the Document Transition {} isn't 'CREATE", - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base" - )))? - .id() + document_transition.base().id() ), ))); }; @@ -72,12 +62,7 @@ pub(super) fn create_contact_request_data_trigger_v0( if !is_dry_run && owner_id == &to_user_id { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), format!("Identity {to_user_id} must not be equal to owner id"), ); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs index f456fc06f83..603c492db0e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs @@ -50,12 +50,7 @@ pub(super) fn create_domain_data_trigger_v0( context: &DataTriggerExecutionContext<'_>, platform_version: &PlatformVersion, ) -> Result { - let data_contract_fetch_info = document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .data_contract_fetch_info(); + let data_contract_fetch_info = document_transition.base().data_contract_fetch_info(); let data_contract = &data_contract_fetch_info.contract; let is_dry_run = context.state_transition_execution_context.in_dry_run(); let document_create_transition = match document_transition { @@ -64,12 +59,7 @@ pub(super) fn create_domain_data_trigger_v0( return Err(Error::Execution(ExecutionError::DataTriggerExecutionError( format!( "the Document Transition {} isn't 'CREATE", - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base" - )))? - .id() + document_transition.base().id() ), ))) } @@ -118,12 +108,7 @@ pub(super) fn create_domain_data_trigger_v0( if full_domain_name.len() > MAX_PRINTABLE_DOMAIN_NAME_LENGTH { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), format!( "Full domain name length can not be more than {} characters long but got {}", MAX_PRINTABLE_DOMAIN_NAME_LENGTH, @@ -137,12 +122,7 @@ pub(super) fn create_domain_data_trigger_v0( if normalized_label != convert_to_homograph_safe_chars(label.as_str()) { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), format!( "Normalized label doesn't match label: {} != {}", normalized_label, label @@ -157,12 +137,7 @@ pub(super) fn create_domain_data_trigger_v0( { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), format!( "Normalized parent domain name doesn't match parent domain name: {} != {}", normalized_parent_domain_name, parent_domain_name @@ -179,12 +154,7 @@ pub(super) fn create_domain_data_trigger_v0( if id != owner_id { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), format!( "ownerId {} doesn't match {} {}", owner_id, DASH_UNIQUE_IDENTITY_ID, id @@ -202,12 +172,7 @@ pub(super) fn create_domain_data_trigger_v0( if id != owner_id { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), format!( "ownerId {} doesn't match {} {}", owner_id, DASH_ALIAS_IDENTITY_ID, id @@ -222,12 +187,7 @@ pub(super) fn create_domain_data_trigger_v0( { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), "Can't create top level domain for this identity".to_string(), ); @@ -299,12 +259,7 @@ pub(super) fn create_domain_data_trigger_v0( if documents.is_empty() { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), "Parent domain is not present".to_string(), ); @@ -317,12 +272,7 @@ pub(super) fn create_domain_data_trigger_v0( if rule_allow_subdomains { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), "Allowing subdomains registration is forbidden for this domain".to_string(), ); @@ -339,12 +289,7 @@ pub(super) fn create_domain_data_trigger_v0( { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), "The subdomain can be created only by the parent domain owner".to_string(), ); @@ -407,12 +352,7 @@ pub(super) fn create_domain_data_trigger_v0( if preorder_documents.is_empty() { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), format!( "preorderDocument was not found with a salted domain hash of {}", hex::encode(salted_domain_hash) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs index 50c867efa68..c337e2ed761 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs @@ -39,12 +39,7 @@ pub(super) fn create_feature_flag_data_trigger_v0( _platform_version: &PlatformVersion, ) -> Result { let mut result = DataTriggerExecutionResult::default(); - let data_contract_fetch_info = document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .data_contract_fetch_info(); + let data_contract_fetch_info = document_transition.base().data_contract_fetch_info(); let data_contract = &data_contract_fetch_info.contract; let document_create_transition = match document_transition { @@ -53,12 +48,7 @@ pub(super) fn create_feature_flag_data_trigger_v0( return Err(Error::Execution(ExecutionError::DataTriggerExecutionError( format!( "the Document Transition {} isn't 'CREATE", - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base" - )))? - .id() + document_transition.base().id() ), ))) } @@ -78,12 +68,7 @@ pub(super) fn create_feature_flag_data_trigger_v0( if enable_at_height < latest_block_height { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), "This identity can't activate selected feature flag".to_string(), ); @@ -95,12 +80,7 @@ pub(super) fn create_feature_flag_data_trigger_v0( if context.owner_id != &feature_flags_contract::OWNER_ID { let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), "This identity can't activate selected feature flag".to_string(), ); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs index 3730b7cf961..3bab88d76d0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs @@ -26,23 +26,13 @@ use crate::error::execution::ExecutionError; pub(super) fn reject_data_trigger_v0( document_transition: &DocumentTransitionAction, ) -> Result { - let data_contract_fetch_info = document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .data_contract_fetch_info(); + let data_contract_fetch_info = document_transition.base().data_contract_fetch_info(); let data_contract = &data_contract_fetch_info.contract; let mut result = DataTriggerExecutionResult::default(); let err = DataTriggerConditionError::new( data_contract.id(), - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .id(), + document_transition.base().id(), "Action is not allowed".to_string(), ); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs index 4b018b1fc1a..8808068b781 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs @@ -39,12 +39,7 @@ pub(super) fn delete_withdrawal_data_trigger_v0( context: &DataTriggerExecutionContext<'_>, platform_version: &PlatformVersion, ) -> Result { - let data_contract_fetch_info = document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base", - )))? - .data_contract_fetch_info(); + let data_contract_fetch_info = document_transition.base().data_contract_fetch_info(); let data_contract = &data_contract_fetch_info.contract; let mut result = DataTriggerExecutionResult::default(); @@ -52,12 +47,7 @@ pub(super) fn delete_withdrawal_data_trigger_v0( return Err(Error::Execution(ExecutionError::DataTriggerExecutionError( format!( "the Document Transition {} isn't 'DELETE", - document_transition - .base() - .ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( - "expecting action to have a base" - )))? - .id() + document_transition.base().id() ), ))); }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs index 577d143a13d..6b0673bbdaa 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs @@ -18,12 +18,6 @@ pub(super) fn execute_data_triggers( let data_trigger_bindings = data_trigger_bindings_list(platform_version)?; for document_transition_action in document_transition_actions { - if matches!( - document_transition_action, - DocumentTransitionAction::BumpIdentityDataContractNonce(_) - ) { - continue; - } let data_trigger_execution_result = document_transition_action .validate_with_data_triggers(&data_trigger_bindings, context, platform_version)?; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs index 06d4861209c..56c26056a3b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs @@ -19,7 +19,9 @@ use crate::execution::validation::state_transition::batch::action_validation::do use crate::execution::validation::state_transition::batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; -use crate::execution::validation::state_transition::batch::action_validation::token_issuance_transition_action::TokenIssuanceTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_burn_transition_action::TokenBurnTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_mint_transition_action::TokenMintTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_transfer_transition_action::TokenTransferTransitionActionValidation; use crate::execution::validation::state_transition::batch::data_triggers::{data_trigger_bindings_list, DataTriggerExecutionContext, DataTriggerExecutor}; use crate::platform_types::platform::{PlatformStateRef}; use crate::execution::validation::state_transition::state_transitions::batch::transformer::v0::BatchTransitionTransformerV0; @@ -135,11 +137,6 @@ impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { transaction, platform_version, )?, - DocumentTransitionAction::BumpIdentityDataContractNonce(..) => { - return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( - "we should never start with a bump identity data contract nonce", - ))); - } }, BatchedTransitionAction::TokenAction(token_action) => match token_action { TokenTransitionAction::BurnAction(burn_action) => burn_action.validate_state( @@ -168,24 +165,23 @@ impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { platform_version, )?, }, + BatchedTransitionAction::BumpIdentityDataContractNonce(_) => { + return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( + "we should never start with a bump identity data contract nonce", + ))); + } }; if !transition_validation_result.is_valid() { // If a state transition isn't valid we still need to bump the identity data contract nonce validation_result.add_errors(transition_validation_result.errors); - validated_transitions.push( - DocumentTransitionAction::BumpIdentityDataContractNonce( - BumpIdentityDataContractNonceAction::from_document_base_transition_action( - transition.base_owned().ok_or(Error::Execution( - ExecutionError::CorruptedCodeExecution( - "base should always exist on transition", - ), - ))?, - owner_id, - state_transition_action.user_fee_increase(), - ), - ), - ); + validated_transitions.push(BatchedTransitionAction::BumpIdentityDataContractNonce( + BumpIdentityDataContractNonceAction::try_from_batched_transition_action( + transition, + owner_id, + state_transition_action.user_fee_increase(), + )?, + )); } else if platform.config.execution.use_document_triggers { if let BatchedTransitionAction::DocumentAction(document_transition) = &transition { // we should also validate document triggers @@ -212,13 +208,9 @@ impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { .collect(); validation_result.add_errors(consensus_errors); validated_transitions - .push(DocumentTransitionAction::BumpIdentityDataContractNonce( + .push(BatchedTransitionAction::BumpIdentityDataContractNonce( BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action( - document_transition.base().ok_or(Error::Execution( - ExecutionError::CorruptedCodeExecution( - "base should always exist on transition", - ), - ))?, + document_transition.base(), owner_id, state_transition_action.user_fee_increase(), ), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index c2524561b84..cee4e970a9e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -54,7 +54,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::TokenBurnTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::TokenMintTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::execution::types::execution_operation::ValidationOperation; @@ -84,7 +84,7 @@ trait BatchTransitionInternalTransformerV0 { execution_context: &mut StateTransitionExecutionContext, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result>, Error>; + ) -> Result>, Error>; fn transform_document_transitions_within_document_type_v0( platform: &PlatformStateRef, block_info: &BlockInfo, @@ -96,7 +96,7 @@ trait BatchTransitionInternalTransformerV0 { execution_context: &mut StateTransitionExecutionContext, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result>, Error>; + ) -> Result>, Error>; /// The data contract can be of multiple difference versions fn transform_token_transition_v0( data_contract_fetch_info: Arc, @@ -114,7 +114,7 @@ trait BatchTransitionInternalTransformerV0 { owner_id: Identifier, execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, - ) -> Result, Error>; + ) -> Result, Error>; fn find_replaced_document_v0<'a>( document_transition: &'a DocumentTransition, fetched_documents: &'a [Document], diff --git a/packages/rs-drive-abci/src/query/service.rs b/packages/rs-drive-abci/src/query/service.rs index 54e51348c0a..039a33a1319 100644 --- a/packages/rs-drive-abci/src/query/service.rs +++ b/packages/rs-drive-abci/src/query/service.rs @@ -22,18 +22,19 @@ use dapi_grpc::platform::v0::{ GetEvonodesProposedEpochBlocksByIdsRequest, GetEvonodesProposedEpochBlocksByRangeRequest, GetEvonodesProposedEpochBlocksResponse, GetIdentitiesBalancesRequest, GetIdentitiesBalancesResponse, GetIdentitiesContractKeysRequest, - GetIdentitiesContractKeysResponse, GetIdentityBalanceAndRevisionRequest, + GetIdentitiesContractKeysResponse, GetIdentitiesTokenBalancesRequest, + GetIdentitiesTokenBalancesResponse, GetIdentityBalanceAndRevisionRequest, GetIdentityBalanceAndRevisionResponse, GetIdentityBalanceRequest, GetIdentityBalanceResponse, GetIdentityByPublicKeyHashRequest, GetIdentityByPublicKeyHashResponse, GetIdentityContractNonceRequest, GetIdentityContractNonceResponse, GetIdentityKeysRequest, GetIdentityKeysResponse, GetIdentityNonceRequest, GetIdentityNonceResponse, GetIdentityRequest, - GetIdentityResponse, GetPathElementsRequest, GetPathElementsResponse, - GetPrefundedSpecializedBalanceRequest, GetPrefundedSpecializedBalanceResponse, - GetProofsRequest, GetProofsResponse, GetProtocolVersionUpgradeStateRequest, - GetProtocolVersionUpgradeStateResponse, GetProtocolVersionUpgradeVoteStatusRequest, - GetProtocolVersionUpgradeVoteStatusResponse, GetStatusRequest, GetStatusResponse, - GetTotalCreditsInPlatformRequest, GetTotalCreditsInPlatformResponse, - GetVotePollsByEndDateRequest, GetVotePollsByEndDateResponse, + GetIdentityResponse, GetIdentityTokenBalancesRequest, GetIdentityTokenBalancesResponse, + GetPathElementsRequest, GetPathElementsResponse, GetPrefundedSpecializedBalanceRequest, + GetPrefundedSpecializedBalanceResponse, GetProofsRequest, GetProofsResponse, + GetProtocolVersionUpgradeStateRequest, GetProtocolVersionUpgradeStateResponse, + GetProtocolVersionUpgradeVoteStatusRequest, GetProtocolVersionUpgradeVoteStatusResponse, + GetStatusRequest, GetStatusResponse, GetTotalCreditsInPlatformRequest, + GetTotalCreditsInPlatformResponse, GetVotePollsByEndDateRequest, GetVotePollsByEndDateResponse, WaitForStateTransitionResultRequest, WaitForStateTransitionResultResponse, }; use dapi_grpc::tonic::{Code, Request, Response, Status}; @@ -609,6 +610,30 @@ impl PlatformService for QueryService { ) .await } + + async fn get_identity_token_balances( + &self, + request: Request, + ) -> Result, Status> { + self.handle_blocking_query( + request, + Platform::::query_identity_token_balances, + "query_identity_token_balances", + ) + .await + } + + async fn get_identities_token_balances( + &self, + request: Request, + ) -> Result, Status> { + self.handle_blocking_query( + request, + Platform::::query_identities_token_balances, + "query_identities_token_balances", + ) + .await + } } fn query_error_into_status(error: QueryError) -> Status { diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs index 52a130064a7..ec3a48d1323 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs @@ -5,7 +5,7 @@ use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenMintTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::TokenOperationType; use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index d8d2f7aeae8..2d9966e5367 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -18,7 +18,7 @@ pub mod token_base_transition_action; /// token_burn_transition_action pub mod token_burn_transition_action; /// token_issuance_transition_action -pub mod token_issuance_transition_action; +pub mod token_mint_transition_action; /// token_transfer_transition_action pub mod token_transfer_transition_action; @@ -36,7 +36,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{TokenMintTransitionAction, TokenIssuanceTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; /// version diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs index 63dec919bbc..28868b09a7a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs @@ -16,7 +16,7 @@ pub enum TokenMintTransitionAction { V0(TokenIssuanceTransitionActionV0), } -impl TokenIssuanceTransitionActionAccessorsV0 for TokenMintTransitionAction { +impl TokenMintTransitionActionAccessorsV0 for TokenMintTransitionAction { fn base(&self) -> &TokenBaseTransitionAction { match self { TokenMintTransitionAction::V0(v0) => &v0.base, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs similarity index 97% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs index 013146d70d5..1ad37b14bed 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs @@ -4,7 +4,7 @@ use dpp::platform_value::Identifier; use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::{ +use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{ TokenMintTransitionAction, TokenIssuanceTransitionActionV0, }; use dpp::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransition; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs index f031158bd85..54ccf11b25d 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs @@ -17,7 +17,7 @@ pub struct TokenIssuanceTransitionActionV0 { } /// Accessors for `TokenIssuanceTransitionActionV0` -pub trait TokenIssuanceTransitionActionAccessorsV0 { +pub trait TokenMintTransitionActionAccessorsV0 { /// Returns a reference to the base token transition action fn base(&self) -> &TokenBaseTransitionAction; @@ -62,7 +62,7 @@ pub trait TokenIssuanceTransitionActionAccessorsV0 { } } -impl TokenIssuanceTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV0 { +impl TokenMintTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV0 { fn base(&self) -> &TokenBaseTransitionAction { &self.base } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs index 3e50f810367..fb563fe6ad9 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_issuance_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs @@ -8,7 +8,7 @@ use dpp::state_transition::batch_transition::token_base_transition::v0::v0_metho use dpp::tokens::errors::TokenError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_issuance_transition_action::v0::TokenIssuanceTransitionActionV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::v0::TokenIssuanceTransitionActionV0; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; impl TokenIssuanceTransitionActionV0 { diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs index 225e1266334..fad24198bcf 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs @@ -1,13 +1,100 @@ use dpp::platform_value::Identifier; use dpp::prelude::UserFeeIncrease; - +use dpp::ProtocolError; +use dpp::state_transition::batch_transition::batched_transition::BatchedTransitionRef; +use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; +use dpp::state_transition::batch_transition::batched_transition::token_transition::TokenTransitionV0Methods; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; use dpp::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; +use dpp::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::error::Error; use crate::state_transition_action::contract::data_contract_update::DataContractUpdateTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::{BumpIdentityDataContractNonceAction, BumpIdentityDataContractNonceActionV0}; impl BumpIdentityDataContractNonceAction { + /// from borrowed base transition + pub fn from_batched_transition_ref( + value: BatchedTransitionRef, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + match value { + BatchedTransitionRef::Document(document) => { + Self::from_borrowed_document_base_transition( + document.base(), + identity_id, + user_fee_increase, + ) + } + BatchedTransitionRef::Token(token) => Self::from_borrowed_token_base_transition( + token.base(), + identity_id, + user_fee_increase, + ), + } + } + + /// helper method + pub fn try_from_batched_transition_action( + value: BatchedTransitionAction, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Result { + match value { + BatchedTransitionAction::DocumentAction(document) => { + Ok(Self::from_document_base_transition_action( + document.base_owned(), + identity_id, + user_fee_increase, + )) + } + BatchedTransitionAction::TokenAction(token) => Ok(Self::from_token_base_transition_action( + token.base_owned(), + identity_id, + user_fee_increase, + )), + BatchedTransitionAction::BumpIdentityDataContractNonce(_) => { + Err(Error::Protocol( + ProtocolError::CorruptedCodeExecution( + "we should never be trying to convert from a BumpIdentityDataContractNonce to a BumpIdentityDataContractNonceAction".to_string(), + ), + )) + } + } + } + + /// helper method + pub fn try_from_borrowed_batched_transition_action( + value: &BatchedTransitionAction, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Result { + match value { + BatchedTransitionAction::DocumentAction(document) => { + Ok(Self::from_borrowed_document_base_transition_action( + document.base(), + identity_id, + user_fee_increase, + )) + } + BatchedTransitionAction::TokenAction(token) => Ok(Self::from_borrowed_token_base_transition_action( + token.base(), + identity_id, + user_fee_increase, + )), + BatchedTransitionAction::BumpIdentityDataContractNonce(_) => { + Err(Error::Protocol( + ProtocolError::CorruptedCodeExecution( + "we should never be trying to convert from a BumpIdentityDataContractNonce to a BumpIdentityDataContractNonceAction".to_string(), + ), + )) + } + } + } + /// from base transition pub fn from_document_base_transition( value: DocumentBaseTransition, @@ -16,7 +103,7 @@ impl BumpIdentityDataContractNonceAction { ) -> Self { match value { DocumentBaseTransition::V0(v0) => { - BumpIdentityDataContractNonceActionV0::from_base_transition( + BumpIdentityDataContractNonceActionV0::from_document_base_transition( v0, identity_id, user_fee_increase, @@ -34,7 +121,7 @@ impl BumpIdentityDataContractNonceAction { ) -> Self { match value { DocumentBaseTransition::V0(v0) => { - BumpIdentityDataContractNonceActionV0::from_borrowed_base_transition( + BumpIdentityDataContractNonceActionV0::from_borrowed_document_base_transition( v0, identity_id, user_fee_increase, @@ -52,7 +139,7 @@ impl BumpIdentityDataContractNonceAction { ) -> Self { match value { DocumentBaseTransitionAction::V0(v0) => { - BumpIdentityDataContractNonceActionV0::from_base_transition_action( + BumpIdentityDataContractNonceActionV0::from_document_base_transition_action( v0, identity_id, user_fee_increase, @@ -70,7 +157,79 @@ impl BumpIdentityDataContractNonceAction { ) -> Self { match value { DocumentBaseTransitionAction::V0(v0) => { - BumpIdentityDataContractNonceActionV0::from_borrowed_base_transition_action( + BumpIdentityDataContractNonceActionV0::from_borrowed_document_base_transition_action( + v0, + identity_id, + user_fee_increase, + ) + .into() + } + } + } + + /// from base transition + pub fn from_token_base_transition( + value: TokenBaseTransition, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + match value { + TokenBaseTransition::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_token_base_transition( + v0, + identity_id, + user_fee_increase, + ) + .into() + } + } + } + + /// from borrowed base transition + pub fn from_borrowed_token_base_transition( + value: &TokenBaseTransition, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + match value { + TokenBaseTransition::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_borrowed_token_base_transition( + v0, + identity_id, + user_fee_increase, + ) + .into() + } + } + } + + /// from base transition + pub fn from_token_base_transition_action( + value: TokenBaseTransitionAction, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + match value { + TokenBaseTransitionAction::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_token_base_transition_action( + v0, + identity_id, + user_fee_increase, + ) + .into() + } + } + } + + /// from borrowed base transition + pub fn from_borrowed_token_base_transition_action( + value: &TokenBaseTransitionAction, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + match value { + TokenBaseTransitionAction::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_borrowed_token_base_transition_action( v0, identity_id, user_fee_increase, diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs index 62b30664078..e377f50fe02 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs @@ -4,13 +4,15 @@ use dpp::prelude::UserFeeIncrease; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransitionV0; use dpp::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; +use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use crate::state_transition_action::contract::data_contract_update::v0::DataContractUpdateTransitionActionV0; use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceActionV0; impl BumpIdentityDataContractNonceActionV0 { /// from base transition - pub fn from_base_transition( + pub fn from_document_base_transition( value: DocumentBaseTransitionV0, identity_id: Identifier, user_fee_increase: UserFeeIncrease, @@ -29,7 +31,7 @@ impl BumpIdentityDataContractNonceActionV0 { } /// from borrowed base transition - pub fn from_borrowed_base_transition( + pub fn from_borrowed_document_base_transition( value: &DocumentBaseTransitionV0, identity_id: Identifier, user_fee_increase: UserFeeIncrease, @@ -48,7 +50,7 @@ impl BumpIdentityDataContractNonceActionV0 { } /// from base transition - pub fn from_base_transition_action( + pub fn from_document_base_transition_action( value: DocumentBaseTransitionActionV0, identity_id: Identifier, user_fee_increase: UserFeeIncrease, @@ -67,7 +69,7 @@ impl BumpIdentityDataContractNonceActionV0 { } /// from borrowed base transition - pub fn from_borrowed_base_transition_action( + pub fn from_borrowed_document_base_transition_action( value: &DocumentBaseTransitionActionV0, identity_id: Identifier, user_fee_increase: UserFeeIncrease, @@ -85,6 +87,82 @@ impl BumpIdentityDataContractNonceActionV0 { } } + /// from base transition + pub fn from_token_base_transition( + value: TokenBaseTransitionV0, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + let TokenBaseTransitionV0 { + data_contract_id, + identity_contract_nonce, + .. + } = value; + BumpIdentityDataContractNonceActionV0 { + identity_id, + data_contract_id, + identity_contract_nonce, + user_fee_increase, + } + } + + /// from borrowed base transition + pub fn from_borrowed_token_base_transition( + value: &TokenBaseTransitionV0, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + let TokenBaseTransitionV0 { + data_contract_id, + identity_contract_nonce, + .. + } = value; + BumpIdentityDataContractNonceActionV0 { + identity_id, + data_contract_id: *data_contract_id, + identity_contract_nonce: *identity_contract_nonce, + user_fee_increase, + } + } + + /// from base transition + pub fn from_token_base_transition_action( + value: TokenBaseTransitionActionV0, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + let TokenBaseTransitionActionV0 { + data_contract, + identity_contract_nonce, + .. + } = value; + BumpIdentityDataContractNonceActionV0 { + identity_id, + data_contract_id: data_contract.contract.id(), + identity_contract_nonce, + user_fee_increase, + } + } + + /// from borrowed base transition + pub fn from_borrowed_token_base_transition_action( + value: &TokenBaseTransitionActionV0, + identity_id: Identifier, + user_fee_increase: UserFeeIncrease, + ) -> Self { + let TokenBaseTransitionActionV0 { + data_contract, + identity_contract_nonce, + .. + } = value; + BumpIdentityDataContractNonceActionV0 { + identity_id, + data_contract_id: data_contract.contract.id(), + identity_contract_nonce: *identity_contract_nonce, + user_fee_increase, + } + } + /// from data contract update pub fn from_data_contract_update(value: DataContractUpdateTransitionV0) -> Self { let DataContractUpdateTransitionV0 { diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs index 27b0f04d166..e6237451806 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs @@ -97,7 +97,7 @@ pub struct DriveAbciDocumentsStateTransitionValidationVersions { pub document_transfer_transition_state_validation: FeatureVersion, pub document_purchase_transition_state_validation: FeatureVersion, pub document_update_price_transition_state_validation: FeatureVersion, - pub token_issuance_transition_structure_validation: FeatureVersion, + pub token_mint_transition_structure_validation: FeatureVersion, pub token_burn_transition_structure_validation: FeatureVersion, pub token_transfer_transition_structure_validation: FeatureVersion, pub token_issuance_transition_state_validation: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs index cfd04a63601..6938728daeb 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs @@ -129,7 +129,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V1: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, - token_issuance_transition_structure_validation: 0, + token_mint_transition_structure_validation: 0, token_burn_transition_structure_validation: 0, token_transfer_transition_structure_validation: 0, token_issuance_transition_state_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs index 39a4e47c059..cb84209f96e 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs @@ -129,7 +129,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V2: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, - token_issuance_transition_structure_validation: 0, + token_mint_transition_structure_validation: 0, token_burn_transition_structure_validation: 0, token_transfer_transition_structure_validation: 0, token_issuance_transition_state_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs index 487b248cf44..2efd6d17c79 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs @@ -129,7 +129,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V3: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, - token_issuance_transition_structure_validation: 0, + token_mint_transition_structure_validation: 0, token_burn_transition_structure_validation: 0, token_transfer_transition_structure_validation: 0, token_issuance_transition_state_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs index 9d1d685a2f1..fa05318a019 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs @@ -129,7 +129,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V4: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, - token_issuance_transition_structure_validation: 0, + token_mint_transition_structure_validation: 0, token_burn_transition_structure_validation: 0, token_transfer_transition_structure_validation: 0, token_issuance_transition_state_validation: 0, From b30ba05a188003bdac720e05d4cc671b0a12ed66 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 27 Dec 2024 03:04:02 +0700 Subject: [PATCH 23/61] compiling --- .../protos/platform/v0/platform.proto | 10 +- .../execution/types/execution_event/mod.rs | 2 +- .../v0/mod.rs | 4 +- .../token_burn_transition_action/mod.rs | 1 - .../state_v0/mod.rs | 14 +- .../structure_v0/mod.rs | 11 - .../batch/advanced_structure/v0/mod.rs | 10 +- .../batch/data_triggers/executor.rs | 1 - .../data_triggers/triggers/reject/v0/mod.rs | 1 - .../batch/identity_contract_nonce/v0/mod.rs | 1 - .../state_transitions/batch/mod.rs | 6 +- .../state_transitions/batch/state/v0/mod.rs | 6 +- .../batch/transformer/v0/mod.rs | 6 +- packages/rs-drive-abci/src/query/mod.rs | 1 + .../identities_token_balances/mod.rs | 66 +++ .../identities_token_balances/v0/mod.rs | 88 ++++ .../identity_token_balances/mod.rs | 62 +++ .../identity_token_balances/v0/mod.rs | 86 ++++ .../src/query/token_queries/mod.rs | 2 + .../verify_state_transitions.rs | 484 +++++++++--------- .../src/drive/tokens/balance/fetch/mod.rs | 16 +- .../fetch_identities_token_balances/mod.rs | 151 ++++++ .../fetch_identities_token_balances/v0/mod.rs | 74 +++ .../fetch_identity_token_balances/mod.rs | 151 ++++++ .../fetch_identity_token_balances/v0/mod.rs | 83 +++ .../rs-drive/src/drive/tokens/balance/mod.rs | 8 + .../prove_identities_token_balances/mod.rs | 149 ++++++ .../prove_identities_token_balances/v0/mod.rs | 53 ++ .../prove_identity_token_balances/mod.rs | 149 ++++++ .../prove_identity_token_balances/v0/mod.rs | 55 ++ .../document/document_transition.rs | 1 - .../document/documents_batch_transition.rs | 4 +- .../action_convert_to_operations/mod.rs | 2 +- .../document_transition/mod.rs | 24 +- .../document/documents_batch/mod.rs | 28 +- .../src/state_transition_action/mod.rs | 8 +- .../drive_abci_query_versions/mod.rs | 7 + .../drive_abci_query_versions/v1.rs | 15 +- .../drive_token_method_versions/mod.rs | 8 +- .../drive_token_method_versions/v1.rs | 10 +- .../src/version/mocks/v2_test.rs | 15 +- .../rs-platform-version/src/version/v8.rs | 1 - 42 files changed, 1543 insertions(+), 331 deletions(-) create mode 100644 packages/rs-drive-abci/src/query/token_queries/identities_token_balances/mod.rs create mode 100644 packages/rs-drive-abci/src/query/token_queries/identities_token_balances/v0/mod.rs create mode 100644 packages/rs-drive-abci/src/query/token_queries/identity_token_balances/mod.rs create mode 100644 packages/rs-drive-abci/src/query/token_queries/identity_token_balances/v0/mod.rs create mode 100644 packages/rs-drive-abci/src/query/token_queries/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balances/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balances/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/prove_identity_token_balances/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/balance/prove_identity_token_balances/v0/mod.rs diff --git a/packages/dapi-grpc/protos/platform/v0/platform.proto b/packages/dapi-grpc/protos/platform/v0/platform.proto index c949faf5aad..73146769665 100644 --- a/packages/dapi-grpc/protos/platform/v0/platform.proto +++ b/packages/dapi-grpc/protos/platform/v0/platform.proto @@ -1221,7 +1221,7 @@ message GetCurrentQuorumsInfoResponse { message GetIdentityTokenBalancesRequest { message GetIdentityTokenBalancesRequestV0 { bytes identity_id = 1; // ID of the identity - repeated bytes contract_ids = 2; // List of token contract IDs + repeated bytes token_ids = 2; // List of token IDs bool prove = 3; // Flag to request a proof as the response } oneof version { @@ -1232,8 +1232,8 @@ message GetIdentityTokenBalancesRequest { message GetIdentityTokenBalancesResponse { message GetIdentityTokenBalancesResponseV0 { message TokenBalanceEntry { - bytes contract_id = 1; // Token contract ID - uint64 balance = 2; // Token balance for the contract + bytes token_id = 1; // Token ID + optional uint64 balance = 2; // Token balance for the contract } message TokenBalances { @@ -1253,7 +1253,7 @@ message GetIdentityTokenBalancesResponse { message GetIdentitiesTokenBalancesRequest { message GetIdentitiesTokenBalancesRequestV0 { - bytes contract_id = 1; // Token contract ID + bytes token_id = 1; // Token ID repeated bytes identity_ids = 2; // List of identity IDs bool prove = 3; // Flag to request a proof as the response } @@ -1266,7 +1266,7 @@ message GetIdentitiesTokenBalancesResponse { message GetIdentitiesTokenBalancesResponseV0 { message IdentityTokenBalanceEntry { bytes identity_id = 1; // Identity ID - uint64 balance = 2; // Token balance for the identity + optional uint64 balance = 2; // Token balance for the identity } message IdentityTokenBalances { diff --git a/packages/rs-drive-abci/src/execution/types/execution_event/mod.rs b/packages/rs-drive-abci/src/execution/types/execution_event/mod.rs index 1150faaca11..73c87119d07 100644 --- a/packages/rs-drive-abci/src/execution/types/execution_event/mod.rs +++ b/packages/rs-drive-abci/src/execution/types/execution_event/mod.rs @@ -162,7 +162,7 @@ impl<'a> ExecutionEvent<'a> { ))) } } - StateTransitionAction::DocumentsBatchAction(document_batch_action) => { + StateTransitionAction::BatchAction(document_batch_action) => { let user_fee_increase = action.user_fee_increase(); let removed_balance = document_batch_action.all_used_balances()?; let operations = diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/asset_lock/transaction/fetch_asset_lock_transaction_output_sync/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/asset_lock/transaction/fetch_asset_lock_transaction_output_sync/v0/mod.rs index 6347c9515c0..b48a79bf8ef 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/asset_lock/transaction/fetch_asset_lock_transaction_output_sync/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/asset_lock/transaction/fetch_asset_lock_transaction_output_sync/v0/mod.rs @@ -5,7 +5,7 @@ use dpp::consensus::basic::identity::{ IdentityAssetLockTransactionIsNotFoundError, IdentityAssetLockTransactionOutputNotFoundError, InvalidAssetLockProofTransactionHeightError, }; -use dpp::dashcore::secp256k1::ThirtyTwoByteHash; +use dpp::dashcore::hashes::Hash; use dpp::dashcore::TxOut; use dpp::identity::state_transition::asset_lock_proof::validate_asset_lock_transaction_structure::validate_asset_lock_transaction_structure; use dpp::prelude::{AssetLockProof, ConsensusValidationResult}; @@ -49,7 +49,7 @@ pub fn fetch_asset_lock_transaction_output_sync_v0( let Some(transaction_info) = maybe_transaction_info else { // Transaction hash bytes needs to be reversed to match actual transaction hash - let mut hash = transaction_hash.as_raw_hash().into_32(); + let mut hash: [u8; 32] = transaction_hash.as_raw_hash().to_byte_array(); hash.reverse(); return Ok(ValidationResult::new_with_error( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs index 3d94bb7de5d..6e72dbf178a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs @@ -1,4 +1,3 @@ -use dashcore_rpc::dashcore::Network; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs index d1ed855fff0..93f1ae55340 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs @@ -1,13 +1,4 @@ use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::InvalidDocumentTypeError; -use dpp::consensus::ConsensusError; -use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; -use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; -use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; -use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; -use dpp::consensus::state::state_error::StateError; -use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; @@ -18,10 +9,7 @@ use drive::error::drive::DriveError; use drive::query::TransactionArg; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; -use crate::execution::types::execution_operation::ValidationOperation; -use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; -use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenTransferTransitionActionStateValidationV0 { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index cf3bd5d5c2c..c385978606c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -1,16 +1,5 @@ -use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::{DocumentCreationNotAllowedError, InvalidDocumentTypeError}; -use dpp::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError; -use dpp::dashcore::Network; -use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::data_contract::accessors::v1::DataContractV1Getters; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; -use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; -use dpp::data_contract::document_type::restricted_creation::CreationRestrictionMode; -use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; use dpp::version::PlatformVersion; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs index 0d6cbb42173..f1e68a7c904 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs @@ -6,9 +6,7 @@ use dpp::dashcore::Network; use dpp::document::Document; use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; use dpp::identity::PartialIdentity; -use dpp::state_transition::batch_transition::batched_transition::document_transition::{ - DocumentTransition, DocumentTransitionV0Methods, -}; +use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransition; use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::{StateTransitionIdentitySigned, StateTransitionLike}; @@ -20,7 +18,7 @@ use dpp::validation::ConsensusValidationResult; use dpp::version::PlatformVersion; use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; +use drive::state_transition_action::document::documents_batch::BatchTransitionAction; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; @@ -50,7 +48,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::batch) &self, block_info: &BlockInfo, network: Network, - action: &DocumentsBatchTransitionAction, + action: &BatchTransitionAction, identity: &PartialIdentity, execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, @@ -62,7 +60,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { &self, block_info: &BlockInfo, network: Network, - action: &DocumentsBatchTransitionAction, + action: &BatchTransitionAction, identity: &PartialIdentity, execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs index 1129cd4ee16..aeed94ba294 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs @@ -9,7 +9,6 @@ use dpp::version::PlatformVersion; use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBindingV0Getters; use crate::error::Error; -use crate::error::execution::ExecutionError; pub trait DataTriggerExecutor { fn validate_with_data_triggers( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs index 3bab88d76d0..0f6a2357115 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs @@ -4,7 +4,6 @@ use drive::state_transition_action::document::documents_batch::document_transiti use crate::error::Error; use crate::execution::validation::state_transition::batch::data_triggers::DataTriggerExecutionResult; use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use crate::error::execution::ExecutionError; /// Creates a data trigger for handling document rejections. /// diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/v0/mod.rs index 6059e52b924..32829c45b70 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/identity_contract_nonce/v0/mod.rs @@ -2,7 +2,6 @@ use crate::error::Error; use dpp::block::block_info::BlockInfo; use dpp::identity::identity_nonce::{validate_identity_nonce_update, validate_new_identity_nonce}; use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::StateTransitionLike; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index b9127ec0134..b089e76a4f4 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -157,8 +157,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for BatchTransition { identity.ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( "The identity must be known on advanced structure validation", )))?; - let StateTransitionAction::DocumentsBatchAction(documents_batch_transition_action) = - action + let StateTransitionAction::BatchAction(documents_batch_transition_action) = action else { return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( "action must be a documents batch transition action", @@ -214,8 +213,7 @@ impl StateTransitionStateValidationV0 for BatchTransition { action.ok_or(Error::Execution(ExecutionError::CorruptedCodeExecution( "documents batch structure validation should have an action", )))?; - let StateTransitionAction::DocumentsBatchAction(documents_batch_transition_action) = - action + let StateTransitionAction::BatchAction(documents_batch_transition_action) = action else { return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( "action must be a documents batch transition action", diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs index 56c26056a3b..202a79655a3 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs @@ -8,7 +8,7 @@ use drive::state_transition_action::StateTransitionAction; use dpp::version::{DefaultForPlatformVersion, PlatformVersion}; use drive::grovedb::TransactionArg; use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; +use drive::state_transition_action::document::documents_batch::BatchTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::Error; use crate::error::execution::ExecutionError; @@ -36,7 +36,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::batch) { fn validate_state_v0( &self, - action: DocumentsBatchTransitionAction, + action: BatchTransitionAction, platform: &PlatformStateRef, block_info: &BlockInfo, execution_context: &mut StateTransitionExecutionContext, @@ -56,7 +56,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::batch) impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { fn validate_state_v0( &self, - mut state_transition_action: DocumentsBatchTransitionAction, + mut state_transition_action: BatchTransitionAction, platform: &PlatformStateRef, block_info: &BlockInfo, execution_context: &mut StateTransitionExecutionContext, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index cee4e970a9e..b0323b9821d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -34,7 +34,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; +use drive::state_transition_action::document::documents_batch::BatchTransitionAction; use drive::state_transition_action::document::documents_batch::v0::DocumentsBatchTransitionActionV0; use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_documents_for_transitions_knowing_contract_and_document_type; @@ -70,7 +70,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::batch) full_validation: bool, transaction: TransactionArg, execution_context: &mut StateTransitionExecutionContext, - ) -> Result, Error>; + ) -> Result, Error>; } trait BatchTransitionInternalTransformerV0 { @@ -146,7 +146,7 @@ impl BatchTransitionTransformerV0 for BatchTransition { validate_against_state: bool, transaction: TransactionArg, execution_context: &mut StateTransitionExecutionContext, - ) -> Result, Error> { + ) -> Result, Error> { let owner_id = self.owner_id(); let user_fee_increase = self.user_fee_increase(); let platform_version = platform.state.current_platform_version()?; diff --git a/packages/rs-drive-abci/src/query/mod.rs b/packages/rs-drive-abci/src/query/mod.rs index 6be97cc1cfa..98bad2d269c 100644 --- a/packages/rs-drive-abci/src/query/mod.rs +++ b/packages/rs-drive-abci/src/query/mod.rs @@ -6,6 +6,7 @@ mod proofs; mod response_metadata; mod service; mod system; +mod token_queries; mod validator_queries; mod voting; diff --git a/packages/rs-drive-abci/src/query/token_queries/identities_token_balances/mod.rs b/packages/rs-drive-abci/src/query/token_queries/identities_token_balances/mod.rs new file mode 100644 index 00000000000..f600317ce6c --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/identities_token_balances/mod.rs @@ -0,0 +1,66 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_identities_token_balances_request::Version as RequestVersion; +use dapi_grpc::platform::v0::get_identities_token_balances_response::Version as ResponseVersion; +use dapi_grpc::platform::v0::{ + GetIdentitiesTokenBalancesRequest, GetIdentitiesTokenBalancesResponse, +}; +use dpp::version::PlatformVersion; +mod v0; + +impl Platform { + /// Querying of an identity's token balances by a public key hash + pub fn query_identities_token_balances( + &self, + GetIdentitiesTokenBalancesRequest { version }: GetIdentitiesTokenBalancesRequest, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let Some(version) = version else { + return Ok(QueryValidationResult::new_with_error( + QueryError::DecodingError( + "could not decode identity token balances query".to_string(), + ), + )); + }; + + let feature_version_bounds = &platform_version + .drive_abci + .query + .token_queries + .identities_token_balances; + + let feature_version = match &version { + RequestVersion::V0(_) => 0, + }; + if !feature_version_bounds.check_version(feature_version) { + return Ok(QueryValidationResult::new_with_error( + QueryError::UnsupportedQueryVersion( + "identities_token_balances".to_string(), + feature_version_bounds.min_version, + feature_version_bounds.max_version, + platform_version.protocol_version, + feature_version, + ), + )); + } + + match version { + RequestVersion::V0(request_v0) => { + let result = self.query_identities_token_balances_v0( + request_v0, + platform_state, + platform_version, + )?; + Ok( + result.map(|response_v0| GetIdentitiesTokenBalancesResponse { + version: Some(ResponseVersion::V0(response_v0)), + }), + ) + } + } + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/identities_token_balances/v0/mod.rs b/packages/rs-drive-abci/src/query/token_queries/identities_token_balances/v0/mod.rs new file mode 100644 index 00000000000..b655fdd99f0 --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/identities_token_balances/v0/mod.rs @@ -0,0 +1,88 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_identities_token_balances_request::GetIdentitiesTokenBalancesRequestV0; +use dapi_grpc::platform::v0::get_identities_token_balances_response::{get_identities_token_balances_response_v0, GetIdentitiesTokenBalancesResponseV0}; +use dapi_grpc::platform::v0::get_identities_token_balances_response::get_identities_token_balances_response_v0::{IdentityTokenBalanceEntry, IdentityTokenBalances}; +use dpp::check_validation_result_with_data; +use dpp::identifier::Identifier; +use dpp::validation::ValidationResult; +use dpp::version::PlatformVersion; + +impl Platform { + pub(super) fn query_identities_token_balances_v0( + &self, + GetIdentitiesTokenBalancesRequestV0 { + token_id, + identity_ids, + prove, + }: GetIdentitiesTokenBalancesRequestV0, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let token_id: Identifier = + check_validation_result_with_data!(token_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "token_id must be a valid identifier (32 bytes long)".to_string(), + ) + })); + + let identity_ids: Vec<[u8; 32]> = check_validation_result_with_data!(identity_ids + .into_iter() + .map(|identity_id| { + identity_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "identity_id must be a valid identifier (32 bytes long)".to_string(), + ) + }) + }) + .collect::, QueryError>>()); + + let response = if prove { + let proof = + check_validation_result_with_data!(self.drive.prove_identities_token_balances( + token_id.into_buffer(), + identity_ids.as_slice(), + None, + platform_version, + )); + + GetIdentitiesTokenBalancesResponseV0 { + result: Some(get_identities_token_balances_response_v0::Result::Proof( + self.response_proof_v0(platform_state, proof), + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + } else { + let identity_token_balances = self + .drive + .fetch_identities_token_balances( + token_id.into_buffer(), + identity_ids.as_slice(), + None, + platform_version, + )? + .into_iter() + .map(|(identity_id, amount)| IdentityTokenBalanceEntry { + identity_id: identity_id.to_vec(), + balance: amount, + }) + .collect(); + + GetIdentitiesTokenBalancesResponseV0 { + result: Some( + get_identities_token_balances_response_v0::Result::IdentityTokenBalances( + IdentityTokenBalances { + identity_token_balances, + }, + ), + ), + metadata: Some(self.response_metadata_v0(platform_state)), + } + }; + + Ok(QueryValidationResult::new_with_data(response)) + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/identity_token_balances/mod.rs b/packages/rs-drive-abci/src/query/token_queries/identity_token_balances/mod.rs new file mode 100644 index 00000000000..acc357d809a --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/identity_token_balances/mod.rs @@ -0,0 +1,62 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_identity_token_balances_request::Version as RequestVersion; +use dapi_grpc::platform::v0::get_identity_token_balances_response::Version as ResponseVersion; +use dapi_grpc::platform::v0::{GetIdentityTokenBalancesRequest, GetIdentityTokenBalancesResponse}; +use dpp::version::PlatformVersion; +mod v0; + +impl Platform { + /// Querying of an identity's token balances by a public key hash + pub fn query_identity_token_balances( + &self, + GetIdentityTokenBalancesRequest { version }: GetIdentityTokenBalancesRequest, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let Some(version) = version else { + return Ok(QueryValidationResult::new_with_error( + QueryError::DecodingError( + "could not decode identity token balances query".to_string(), + ), + )); + }; + + let feature_version_bounds = &platform_version + .drive_abci + .query + .token_queries + .identity_token_balances; + + let feature_version = match &version { + RequestVersion::V0(_) => 0, + }; + if !feature_version_bounds.check_version(feature_version) { + return Ok(QueryValidationResult::new_with_error( + QueryError::UnsupportedQueryVersion( + "identity_token_balances".to_string(), + feature_version_bounds.min_version, + feature_version_bounds.max_version, + platform_version.protocol_version, + feature_version, + ), + )); + } + + match version { + RequestVersion::V0(request_v0) => { + let result = self.query_identity_token_balances_v0( + request_v0, + platform_state, + platform_version, + )?; + Ok(result.map(|response_v0| GetIdentityTokenBalancesResponse { + version: Some(ResponseVersion::V0(response_v0)), + })) + } + } + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/identity_token_balances/v0/mod.rs b/packages/rs-drive-abci/src/query/token_queries/identity_token_balances/v0/mod.rs new file mode 100644 index 00000000000..45a54c731ca --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/identity_token_balances/v0/mod.rs @@ -0,0 +1,86 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_identity_token_balances_request::GetIdentityTokenBalancesRequestV0; +use dapi_grpc::platform::v0::get_identity_token_balances_response::{get_identity_token_balances_response_v0, GetIdentityTokenBalancesResponseV0}; +use dapi_grpc::platform::v0::get_identity_token_balances_response::get_identity_token_balances_response_v0::{TokenBalanceEntry, TokenBalances}; +use dpp::check_validation_result_with_data; +use dpp::identifier::Identifier; +use dpp::validation::ValidationResult; +use dpp::version::PlatformVersion; + +impl Platform { + pub(super) fn query_identity_token_balances_v0( + &self, + GetIdentityTokenBalancesRequestV0 { + identity_id, + token_ids, + prove, + }: GetIdentityTokenBalancesRequestV0, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let identity_id: Identifier = + check_validation_result_with_data!(identity_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "identity_id must be a valid identifier (32 bytes long)".to_string(), + ) + })); + + let token_ids: Vec<[u8; 32]> = check_validation_result_with_data!(token_ids + .into_iter() + .map(|token_id| { + token_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "token_id must be a valid identifier (32 bytes long)".to_string(), + ) + }) + }) + .collect::, QueryError>>()); + + let response = if prove { + let proof = + check_validation_result_with_data!(self.drive.prove_identity_token_balances( + token_ids.as_slice(), + identity_id.into_buffer(), + None, + platform_version, + )); + + GetIdentityTokenBalancesResponseV0 { + result: Some(get_identity_token_balances_response_v0::Result::Proof( + self.response_proof_v0(platform_state, proof), + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + } else { + let token_balances = self + .drive + .fetch_identity_token_balances( + token_ids.as_slice(), + identity_id.into_buffer(), + None, + platform_version, + )? + .into_iter() + .map(|(token_id, amount)| TokenBalanceEntry { + token_id: token_id.to_vec(), + balance: amount, + }) + .collect(); + + GetIdentityTokenBalancesResponseV0 { + result: Some( + get_identity_token_balances_response_v0::Result::TokenBalances(TokenBalances { + token_balances, + }), + ), + metadata: Some(self.response_metadata_v0(platform_state)), + } + }; + + Ok(QueryValidationResult::new_with_data(response)) + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/mod.rs b/packages/rs-drive-abci/src/query/token_queries/mod.rs new file mode 100644 index 00000000000..80ed054e11b --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/mod.rs @@ -0,0 +1,2 @@ +mod identities_token_balances; +mod identity_token_balances; 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 b2758a2f257..3684f2afc66 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 @@ -15,7 +15,9 @@ use dpp::version::PlatformVersion; use drive::drive::identity::key::fetch::IdentityKeysRequest; use drive::drive::Drive; use drive::query::{SingleDocumentDriveQuery, SingleDocumentDriveQueryContestedStatus}; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::{ + BatchedTransitionAction, DocumentTransitionAction, +}; use drive::state_transition_action::StateTransitionAction; use drive_abci::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; use drive_abci::platform_types::platform::PlatformRef; @@ -209,59 +211,57 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( ); } } - StateTransitionAction::DocumentsBatchAction(documents_batch_transition) => { - documents_batch_transition + StateTransitionAction::BatchAction(batch_transition) => { + batch_transition .transitions() .iter() - .for_each(|transition| { - let document_contested_status = - if let DocumentTransitionAction::CreateAction(create_action) = - transition - { - if create_action.prefunded_voting_balance().is_some() { - SingleDocumentDriveQueryContestedStatus::Contested as u8 + .for_each(|transition| match transition { + BatchedTransitionAction::DocumentAction(document_transition_action) => { + let document_contested_status = + if let DocumentTransitionAction::CreateAction(create_action) = + document_transition_action + { + if create_action.prefunded_voting_balance().is_some() { + SingleDocumentDriveQueryContestedStatus::Contested as u8 + } else { + SingleDocumentDriveQueryContestedStatus::NotContested + as u8 + } } else { SingleDocumentDriveQueryContestedStatus::NotContested as u8 - } - } else { - SingleDocumentDriveQueryContestedStatus::NotContested as u8 - }; - proofs_request - .documents - .push(get_proofs_request_v0::DocumentRequest { - contract_id: transition - .base() - .expect("expected a base for the document transition") - .data_contract_id() - .to_vec(), - document_type: transition - .base() - .expect("expected a base for the document transition") - .document_type_name() - .clone(), - document_type_keeps_history: transition - .base() - .expect("expected a base for the document transition") - .data_contract_fetch_info() - .contract - .document_type_for_name( - transition - .base() - .expect( - "expected a base for the document transition", - ) - .document_type_name() - .as_str(), - ) - .expect("get document type") - .documents_keep_history(), - document_id: transition - .base() - .expect("expected a base for the document transition") - .id() - .to_vec(), - document_contested_status: document_contested_status as i32, - }); + }; + proofs_request.documents.push( + get_proofs_request_v0::DocumentRequest { + contract_id: document_transition_action + .base() + .data_contract_id() + .to_vec(), + document_type: document_transition_action + .base() + .document_type_name() + .clone(), + document_type_keeps_history: document_transition_action + .base() + .data_contract_fetch_info() + .contract + .document_type_for_name( + document_transition_action + .base() + .document_type_name() + .as_str(), + ) + .expect("get document type") + .documents_keep_history(), + document_id: document_transition_action + .base() + .id() + .to_vec(), + document_contested_status: document_contested_status as i32, + }, + ); + } + BatchedTransitionAction::TokenAction(_) => {} + BatchedTransitionAction::BumpIdentityDataContractNonce(_) => {} }); let versioned_request = GetProofsRequest { version: Some(get_proofs_request::Version::V0(proofs_request)), @@ -274,210 +274,206 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( let response_proof = response.proof_owned().expect("proof should be present"); - for document_transition_action in - documents_batch_transition.transitions().iter() - { - let contract_fetch_info = document_transition_action - .base() - .expect("expected a base for the document transition") - .data_contract_fetch_info(); - - let document_type = contract_fetch_info - .contract - .document_type_for_name( - document_transition_action - .base() - .expect("expected a base for the document transition") - .document_type_name() - .as_str(), - ) - .expect("get document type"); - let contested_status = - if let DocumentTransitionAction::CreateAction(create_action) = - document_transition_action - { - if create_action.prefunded_voting_balance().is_some() { - SingleDocumentDriveQueryContestedStatus::Contested - } else { - SingleDocumentDriveQueryContestedStatus::NotContested - } - } else { - SingleDocumentDriveQueryContestedStatus::NotContested - }; - - let query = SingleDocumentDriveQuery { - contract_id: document_transition_action - .base() - .expect("expected a base for the document transition") - .data_contract_id() - .into_buffer(), - document_type_name: document_transition_action - .base() - .expect("expected a base for the document transition") - .document_type_name() - .clone(), - document_type_keeps_history: document_type.documents_keep_history(), - document_id: document_transition_action - .base() - .expect("expected a base for the document transition") - .id() - .into_buffer(), - block_time_ms: None, //None because we want latest - contested_status, - }; - - // dbg!( - // platform.state.height(), - // document_transition_action.action_type(), - // document_transition_action - // .base() - // .id() - // .to_string(Encoding::Base58) - // ); - - let (root_hash, document) = query - .verify_proof( - false, - &response_proof.grovedb_proof, - document_type, - platform_version, - ) - .expect("expected to verify a document"); + for transition_action in batch_transition.transitions().iter() { + match transition_action { + BatchedTransitionAction::DocumentAction(document_action) => { + let contract_fetch_info = + document_action.base().data_contract_fetch_info(); + + let document_type = contract_fetch_info + .contract + .document_type_for_name( + document_action.base().document_type_name().as_str(), + ) + .expect("get document type"); + let contested_status = + if let DocumentTransitionAction::CreateAction(create_action) = + document_action + { + if create_action.prefunded_voting_balance().is_some() { + SingleDocumentDriveQueryContestedStatus::Contested + } else { + SingleDocumentDriveQueryContestedStatus::NotContested + } + } else { + SingleDocumentDriveQueryContestedStatus::NotContested + }; - assert_eq!( - &root_hash, - expected_root_hash, - "state last block info {:?}", - platform.state.last_committed_block_info() - ); + let query = SingleDocumentDriveQuery { + contract_id: document_action + .base() + .data_contract_id() + .into_buffer(), + document_type_name: document_action + .base() + .document_type_name() + .clone(), + document_type_keeps_history: document_type + .documents_keep_history(), + document_id: document_action.base().id().into_buffer(), + block_time_ms: None, //None because we want latest + contested_status, + }; - match document_transition_action { - DocumentTransitionAction::CreateAction(creation_action) => { - if *was_executed { - let document = document.unwrap_or_else(|| { - panic!( - "expected a document on block {}", - platform.state.last_committed_block_height() - ) - }); - // dbg!( - // &document, - // Document::try_from_create_transition( - // creation_action, - // documents_batch_transition.owner_id(), - // platform_version, - // ) - // .expect("expected to get document") - // ); - assert_eq!( - document, - Document::try_from_create_transition_action( - creation_action, - documents_batch_transition.owner_id(), - platform_version, - ) - .expect("expected to get document") - ); - } else { - //there is the possibility that the state transition was not executed because it already existed, - // we can discount that for now in tests - assert!(document.is_none()); - } - } - DocumentTransitionAction::ReplaceAction(replace_action) => { - if *was_executed { - // it's also possible we deleted something we replaced - if let Some(document) = document { - assert_eq!( - document, - Document::try_from_replace_transition_action( - replace_action, - documents_batch_transition.owner_id(), - platform_version, - ) - .expect("expected to get document") - ); + // dbg!( + // platform.state.height(), + // document_transition_action.action_type(), + // document_transition_action + // .base() + // .id() + // .to_string(Encoding::Base58) + // ); + + let (root_hash, document) = query + .verify_proof( + false, + &response_proof.grovedb_proof, + document_type, + platform_version, + ) + .expect("expected to verify a document"); + + assert_eq!( + &root_hash, + expected_root_hash, + "state last block info {:?}", + platform.state.last_committed_block_info() + ); + + match document_action { + DocumentTransitionAction::CreateAction(creation_action) => { + if *was_executed { + let document = document.unwrap_or_else(|| { + panic!( + "expected a document on block {}", + platform.state.last_committed_block_height() + ) + }); + // dbg!( + // &document, + // Document::try_from_create_transition( + // creation_action, + // documents_batch_transition.owner_id(), + // platform_version, + // ) + // .expect("expected to get document") + // ); + assert_eq!( + document, + Document::try_from_create_transition_action( + creation_action, + batch_transition.owner_id(), + platform_version, + ) + .expect("expected to get document") + ); + } else { + //there is the possibility that the state transition was not executed because it already existed, + // we can discount that for now in tests + assert!(document.is_none()); + } } - } else { - //there is the possibility that the state transition was not executed and the state is equal to the previous - // state, aka there would have been no change anyways, we can discount that for now - if let Some(document) = document { - assert_ne!( - document, - Document::try_from_replace_transition_action( - replace_action, - documents_batch_transition.owner_id(), - platform_version, - ) - .expect("expected to get document") - ); + DocumentTransitionAction::ReplaceAction(replace_action) => { + if *was_executed { + // it's also possible we deleted something we replaced + if let Some(document) = document { + assert_eq!( + document, + Document::try_from_replace_transition_action( + replace_action, + batch_transition.owner_id(), + platform_version, + ) + .expect("expected to get document") + ); + } + } else { + //there is the possibility that the state transition was not executed and the state is equal to the previous + // state, aka there would have been no change anyways, we can discount that for now + if let Some(document) = document { + assert_ne!( + document, + Document::try_from_replace_transition_action( + replace_action, + batch_transition.owner_id(), + platform_version, + ) + .expect("expected to get document") + ); + } + } } - } - } - DocumentTransitionAction::DeleteAction(_) => { - // we expect no document - assert!(document.is_none()); - } - DocumentTransitionAction::BumpIdentityDataContractNonce(_) => { - panic!("we should not have a bump identity data contract nonce"); - } - DocumentTransitionAction::TransferAction(transfer_action) => { - if *was_executed { - // it's also possible we deleted something we replaced - if let Some(document) = document { - assert_eq!( - document.owner_id(), - transfer_action.document().owner_id() - ); + DocumentTransitionAction::DeleteAction(_) => { + // we expect no document + assert!(document.is_none()); } - } else { - //there is the possibility that the state transition was not executed and the state is equal to the previous - // state, aka there would have been no change anyways, we can discount that for now - if let Some(document) = document { - assert_ne!( - document.owner_id(), - transfer_action.document().owner_id() - ); + DocumentTransitionAction::TransferAction(transfer_action) => { + if *was_executed { + // it's also possible we deleted something we replaced + if let Some(document) = document { + assert_eq!( + document.owner_id(), + transfer_action.document().owner_id() + ); + } + } else { + //there is the possibility that the state transition was not executed and the state is equal to the previous + // state, aka there would have been no change anyways, we can discount that for now + if let Some(document) = document { + assert_ne!( + document.owner_id(), + transfer_action.document().owner_id() + ); + } + } } - } - } - DocumentTransitionAction::PurchaseAction(purchase_action) => { - if *was_executed { - if let Some(document) = document { - assert_eq!( - document.owner_id(), - purchase_action.document().owner_id() - ); + DocumentTransitionAction::PurchaseAction(purchase_action) => { + if *was_executed { + if let Some(document) = document { + assert_eq!( + document.owner_id(), + purchase_action.document().owner_id() + ); + } + } else { + //there is the possibility that the state transition was not executed and the state is equal to the previous + // state, aka there would have been no change anyways, we can discount that for now + if let Some(document) = document { + assert_ne!( + document.owner_id(), + purchase_action.document().owner_id() + ); + } + } } - } else { - //there is the possibility that the state transition was not executed and the state is equal to the previous - // state, aka there would have been no change anyways, we can discount that for now - if let Some(document) = document { - assert_ne!( - document.owner_id(), - purchase_action.document().owner_id() - ); + DocumentTransitionAction::UpdatePriceAction( + update_price_action, + ) => { + if *was_executed { + if let Some(document) = document { + assert_eq!( + document.get(PRICE), + update_price_action.document().get(PRICE) + ); + } + } else { + //there is the possibility that the state transition was not executed and the state is equal to the previous + // state, aka there would have been no change anyways, we can discount that for now + if let Some(document) = document { + assert_ne!( + document.get(PRICE), + update_price_action.document().get(PRICE) + ); + } + } } } } - DocumentTransitionAction::UpdatePriceAction(update_price_action) => { - if *was_executed { - if let Some(document) = document { - assert_eq!( - document.get(PRICE), - update_price_action.document().get(PRICE) - ); - } - } else { - //there is the possibility that the state transition was not executed and the state is equal to the previous - // state, aka there would have been no change anyways, we can discount that for now - if let Some(document) = document { - assert_ne!( - document.get(PRICE), - update_price_action.document().get(PRICE) - ); - } - } + BatchedTransitionAction::TokenAction(_) => { + todo!(); + } + BatchedTransitionAction::BumpIdentityDataContractNonce(_) => { + panic!("we should not have a bump identity data contract nonce"); } } } diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs index dd79be761a4..6f52a71afcc 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs @@ -34,7 +34,13 @@ impl Drive { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { - match platform_version.drive.methods.token.fetch.balance { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_balance + { 0 => self.fetch_identity_token_balance_v0( token_id, identity_id, @@ -106,7 +112,13 @@ impl Drive { drive_operations: &mut Vec, platform_version: &PlatformVersion, ) -> Result, Error> { - match platform_version.drive.methods.token.fetch.balance { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_balance + { 0 => self.fetch_identity_token_balance_operations_v0( token_id, identity_id, diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs new file mode 100644 index 00000000000..aca14dbbac5 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs @@ -0,0 +1,151 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::balances::credits::TokenAmount; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; +use std::collections::BTreeMap; + +impl Drive { + /// Fetches the token balances of an identity from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose balances are to be fetched. + /// * `identity_id` - The ID of the identity whose token balances are being queried. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding balances, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identities_token_balances( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_balances + { + 0 => self.fetch_identities_token_balances_v0( + token_id, + identity_ids, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_balances".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the identity's token balances with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to fetch the balances for. + /// * `identity_id` - The identity's ID whose balances are being queried. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result<((BTreeMap<[u8; 32], Option>), FeeResult), Error>` - A tuple containing a map of token balances and the associated fee result. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identities_token_balances_with_costs( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(BTreeMap<[u8; 32], Option>, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_identities_token_balances_operations( + token_id, + identity_ids, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to fetch the identity's token balances from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the balances for. + /// * `identity_id` - The ID of the identity whose token balances are being queried. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding balances, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identities_token_balances_operations( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_balances + { + 0 => self.fetch_identities_token_balances_operations_v0( + token_id, + identity_ids, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identities_token_balances_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs new file mode 100644 index 00000000000..c548c3f4d30 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs @@ -0,0 +1,74 @@ +use crate::drive::tokens::token_balances_path_vec; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::balances::credits::TokenAmount; +use dpp::version::PlatformVersion; +use grovedb::Element::SumItem; +use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; +use std::collections::BTreeMap; + +impl Drive { + pub(super) fn fetch_identities_token_balances_v0( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + self.fetch_identities_token_balances_operations_v0( + token_id, + identity_ids, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_identities_token_balances_operations_v0( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + let tokens_root = token_balances_path_vec(token_id); + + let mut query = Query::new(); + + for identity_id in identity_ids { + query.insert_key(identity_id.to_vec()); + } + + let path_query = PathQuery::new( + tokens_root, + SizedQuery::new(query, Some(identity_ids.len() as u16), None), + ); + + self.grove_get_raw_path_query_with_optional( + &path_query, + false, + transaction, + drive_operations, + &platform_version.drive, + )? + .into_iter() + .map(|(_, key, element)| { + let identity_id: [u8; 32] = key.try_into().map_err(|_| { + Error::Drive(DriveError::CorruptedDriveState( + "identity id not 32 bytes".to_string(), + )) + })?; + match element { + Some(SumItem(value, ..)) => Ok((identity_id, Some(value as TokenAmount))), + None => Ok((identity_id, None)), + _ => Err(Error::Drive(DriveError::CorruptedDriveState( + "token tree for balances should contain only sum items".to_string(), + ))), + } + }) + .collect() + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balances/mod.rs new file mode 100644 index 00000000000..fbe2b3aa43a --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balances/mod.rs @@ -0,0 +1,151 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::balances::credits::TokenAmount; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; +use std::collections::BTreeMap; + +impl Drive { + /// Fetches the token balances of an identity from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose balances are to be fetched. + /// * `identity_id` - The ID of the identity whose token balances are being queried. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding balances, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identity_token_balances( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_balances + { + 0 => self.fetch_identity_token_balances_v0( + token_ids, + identity_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_balances".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the identity's token balances with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to fetch the balances for. + /// * `identity_id` - The identity's ID whose balances are being queried. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result<((BTreeMap<[u8; 32], Option>), FeeResult), Error>` - A tuple containing a map of token balances and the associated fee result. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identity_token_balances_with_costs( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(BTreeMap<[u8; 32], Option>, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_identity_token_balances_operations( + token_ids, + identity_id, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to fetch the identity's token balances from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the balances for. + /// * `identity_id` - The ID of the identity whose token balances are being queried. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding balances, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identity_token_balances_operations( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_balances + { + 0 => self.fetch_identity_token_balances_operations_v0( + token_ids, + identity_id, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_balances_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balances/v0/mod.rs new file mode 100644 index 00000000000..782c357076c --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balances/v0/mod.rs @@ -0,0 +1,83 @@ +use crate::drive::tokens::{tokens_root_path_vec, TOKEN_BALANCES_KEY}; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::balances::credits::TokenAmount; +use dpp::version::PlatformVersion; +use grovedb::Element::SumItem; +use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; +use std::collections::BTreeMap; + +impl Drive { + pub(super) fn fetch_identity_token_balances_v0( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + self.fetch_identity_token_balances_operations_v0( + token_ids, + identity_id, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_identity_token_balances_operations_v0( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + let tokens_root = tokens_root_path_vec(); + + let mut query = Query::new(); + + for token_id in token_ids { + query.insert_key(token_id.to_vec()); + } + + query.set_subquery_path(vec![vec![TOKEN_BALANCES_KEY], identity_id.to_vec()]); + + let path_query = PathQuery::new( + tokens_root, + SizedQuery::new(query, Some(token_ids.len() as u16), None), + ); + + self.grove_get_raw_path_query_with_optional( + &path_query, + false, + transaction, + drive_operations, + &platform_version.drive, + )? + .into_iter() + .map(|(path, _, element)| { + let token_id: [u8; 32] = path + .get(1) + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "returned path item should always have a second part at index 1".to_string(), + )))? + .clone() + .try_into() + .map_err(|_| { + Error::Drive(DriveError::CorruptedDriveState( + "token id not 32 bytes".to_string(), + )) + })?; + match element { + Some(SumItem(value, ..)) => Ok((token_id, Some(value as TokenAmount))), + None => Ok((token_id, None)), + _ => Err(Error::Drive(DriveError::CorruptedDriveState( + "token tree for balances should contain only sum items".to_string(), + ))), + } + }) + .collect() + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/mod.rs index 7bc82048e39..8dbad4fc3d7 100644 --- a/packages/rs-drive/src/drive/tokens/balance/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/mod.rs @@ -3,7 +3,15 @@ mod add_to_previous_token_balance; #[cfg(feature = "server")] mod fetch; #[cfg(feature = "server")] +mod fetch_identities_token_balances; +#[cfg(feature = "server")] +mod fetch_identity_token_balances; +#[cfg(feature = "server")] mod prove; +#[cfg(feature = "server")] +mod prove_identities_token_balances; +#[cfg(feature = "server")] +mod prove_identity_token_balances; mod queries; #[cfg(feature = "server")] mod remove_from_identity_token_balance; diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/mod.rs new file mode 100644 index 00000000000..969fd63690b --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/mod.rs @@ -0,0 +1,149 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Proves the token balances of an identity from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose balances are to be proveed. + /// * `identity_id` - The ID of the identity whose token balances are being queried. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identities_token_balances( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .prove + .identity_token_balances + { + 0 => self.prove_identities_token_balances_v0( + token_id, + identity_ids, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_identity_token_balances".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Proves the identity's token balances with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to prove the balances for. + /// * `identity_id` - The identity's ID whose balances are being queried. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identities_token_balances_with_costs( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(Vec, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.prove_identities_token_balances_operations( + token_id, + identity_ids, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to prove the identity's token balances from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the balances for. + /// * `identity_id` - The ID of the identity whose token balances are being queried. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identities_token_balances_operations( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .prove + .identity_token_balances + { + 0 => self.prove_identities_token_balances_operations_v0( + token_id, + identity_ids, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_identities_token_balances_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs new file mode 100644 index 00000000000..58db6c0a537 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs @@ -0,0 +1,53 @@ +use crate::drive::tokens::token_balances_path_vec; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::version::PlatformVersion; +use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; + +impl Drive { + pub(super) fn prove_identities_token_balances_v0( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.prove_identities_token_balances_operations_v0( + token_id, + identity_ids, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn prove_identities_token_balances_operations_v0( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let tokens_root = token_balances_path_vec(token_id); + + let mut query = Query::new(); + + for identity_id in identity_ids { + query.insert_key(identity_id.to_vec()); + } + + let path_query = PathQuery::new( + tokens_root, + SizedQuery::new(query, Some(identity_ids.len() as u16), None), + ); + + self.grove_get_proved_path_query( + &path_query, + transaction, + drive_operations, + &platform_version.drive, + ) + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identity_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identity_token_balances/mod.rs new file mode 100644 index 00000000000..429bb599499 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identity_token_balances/mod.rs @@ -0,0 +1,149 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Fetches the token balances of an identity from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose balances are to be proveed. + /// * `identity_id` - The ID of the identity whose token balances are being queried. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identity_token_balances( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .prove + .identity_token_balances + { + 0 => self.prove_identity_token_balances_v0( + token_ids, + identity_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_identity_token_balances".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the identity's token balances with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to prove the balances for. + /// * `identity_id` - The identity's ID whose balances are being queried. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identity_token_balances_with_costs( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(Vec, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.prove_identity_token_balances_operations( + token_ids, + identity_id, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to prove the identity's token balances from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the balances for. + /// * `identity_id` - The ID of the identity whose token balances are being queried. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identity_token_balances_operations( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .prove + .identity_token_balances + { + 0 => self.prove_identity_token_balances_operations_v0( + token_ids, + identity_id, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_identity_token_balances_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identity_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identity_token_balances/v0/mod.rs new file mode 100644 index 00000000000..1185a9009a2 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identity_token_balances/v0/mod.rs @@ -0,0 +1,55 @@ +use crate::drive::tokens::{tokens_root_path_vec, TOKEN_BALANCES_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::version::PlatformVersion; +use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; + +impl Drive { + pub(super) fn prove_identity_token_balances_v0( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.prove_identity_token_balances_operations_v0( + token_ids, + identity_id, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn prove_identity_token_balances_operations_v0( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let tokens_root = tokens_root_path_vec(); + + let mut query = Query::new(); + + for token_id in token_ids { + query.insert_key(token_id.to_vec()); + } + + query.set_subquery_path(vec![vec![TOKEN_BALANCES_KEY], identity_id.to_vec()]); + + let path_query = PathQuery::new( + tokens_root, + SizedQuery::new(query, Some(token_ids.len() as u16), None), + ); + + self.grove_get_proved_path_query( + &path_query, + transaction, + drive_operations, + &platform_version.drive, + ) + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs index 8319da20122..3967e050f0f 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs @@ -1,6 +1,5 @@ use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; -use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/documents_batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/documents_batch_transition.rs index eb1371efc27..5630245ff14 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/documents_batch_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/documents_batch_transition.rs @@ -2,12 +2,12 @@ use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; -use crate::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; +use crate::state_transition_action::document::documents_batch::BatchTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::version::PlatformVersion; -impl DriveHighLevelOperationConverter for DocumentsBatchTransitionAction { +impl DriveHighLevelOperationConverter for BatchTransitionAction { fn into_high_level_drive_operations<'b>( self, epoch: &Epoch, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/mod.rs index bfc5b55e272..345b823df3e 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/mod.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/mod.rs @@ -39,7 +39,7 @@ impl DriveHighLevelOperationConverter for StateTransitionAction { data_contract_update_transition .into_high_level_drive_operations(epoch, platform_version) } - StateTransitionAction::DocumentsBatchAction(documents_batch_transition) => { + StateTransitionAction::BatchAction(documents_batch_transition) => { documents_batch_transition.into_high_level_drive_operations(epoch, platform_version) } StateTransitionAction::IdentityCreateAction(identity_create_transition) => { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index 2d9966e5367..0002aa0db2f 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -25,7 +25,8 @@ pub mod token_transfer_transition_action; pub use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; use derive_more::From; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use dpp::identifier::Identifier; +use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; @@ -33,8 +34,8 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; -use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::{BumpIdentityDataContractNonceAction, BumpIdentityDataContractNonceActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; @@ -126,3 +127,20 @@ pub enum BatchedTransitionAction { /// bump identity data contract nonce BumpIdentityDataContractNonce(BumpIdentityDataContractNonceAction), } + +impl BatchedTransitionAction { + /// Helper method to get the data contract id + pub fn data_contract_id(&self) -> Identifier { + match self { + BatchedTransitionAction::DocumentAction(document_action) => { + document_action.base().data_contract_id() + } + BatchedTransitionAction::TokenAction(token_action) => { + token_action.base().data_contract_id() + } + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action) => { + bump_action.data_contract_id() + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs index 7869450a1db..6ac929de511 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs @@ -17,74 +17,74 @@ pub mod v0; /// documents batch transition action #[derive(Debug, Clone, From)] -pub enum DocumentsBatchTransitionAction { +pub enum BatchTransitionAction { /// v0 V0(DocumentsBatchTransitionActionV0), } -impl DocumentsBatchTransitionAction { +impl BatchTransitionAction { /// owner id pub fn owner_id(&self) -> Identifier { match self { - DocumentsBatchTransitionAction::V0(v0) => v0.owner_id, + BatchTransitionAction::V0(v0) => v0.owner_id, } } /// transitions pub fn transitions(&self) -> &Vec { match self { - DocumentsBatchTransitionAction::V0(v0) => &v0.transitions, + BatchTransitionAction::V0(v0) => &v0.transitions, } } /// transitions pub fn transitions_mut(&mut self) -> &mut Vec { match self { - DocumentsBatchTransitionAction::V0(v0) => &mut v0.transitions, + BatchTransitionAction::V0(v0) => &mut v0.transitions, } } /// transitions pub fn transitions_take(&mut self) -> Vec { match self { - DocumentsBatchTransitionAction::V0(v0) => std::mem::take(&mut v0.transitions), + BatchTransitionAction::V0(v0) => std::mem::take(&mut v0.transitions), } } /// transitions owned pub fn transitions_owned(self) -> Vec { match self { - DocumentsBatchTransitionAction::V0(v0) => v0.transitions, + BatchTransitionAction::V0(v0) => v0.transitions, } } /// set transitions pub fn set_transitions(&mut self, transitions: Vec) { match self { - DocumentsBatchTransitionAction::V0(v0) => v0.transitions = transitions, + BatchTransitionAction::V0(v0) => v0.transitions = transitions, } } /// fee multiplier pub fn user_fee_increase(&self) -> UserFeeIncrease { match self { - DocumentsBatchTransitionAction::V0(transition) => transition.user_fee_increase, + BatchTransitionAction::V0(transition) => transition.user_fee_increase, } } } -impl DocumentsBatchTransitionAction { +impl BatchTransitionAction { /// The sum of all purchases amount and all conflicting index collateral voting funds pub fn all_used_balances(&self) -> Result, ProtocolError> { match self { - DocumentsBatchTransitionAction::V0(v0) => v0.all_used_balances(), + BatchTransitionAction::V0(v0) => v0.all_used_balances(), } } /// The sum of all purchases amounts for all purchase transitions in the batch pub fn all_purchases_amount(&self) -> Result, ProtocolError> { match self { - DocumentsBatchTransitionAction::V0(v0) => v0.all_purchases_amount(), + BatchTransitionAction::V0(v0) => v0.all_purchases_amount(), } } @@ -93,9 +93,7 @@ impl DocumentsBatchTransitionAction { &self, ) -> Result, ProtocolError> { match self { - DocumentsBatchTransitionAction::V0(v0) => { - v0.all_conflicting_index_collateral_voting_funds() - } + BatchTransitionAction::V0(v0) => v0.all_conflicting_index_collateral_voting_funds(), } } diff --git a/packages/rs-drive/src/state_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/mod.rs index c4e9d8477cf..987d90d87ba 100644 --- a/packages/rs-drive/src/state_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/mod.rs @@ -12,7 +12,7 @@ pub mod action_convert_to_operations; use crate::state_transition_action::contract::data_contract_create::DataContractCreateTransitionAction; use crate::state_transition_action::contract::data_contract_update::DataContractUpdateTransitionAction; -use crate::state_transition_action::document::documents_batch::DocumentsBatchTransitionAction; +use crate::state_transition_action::document::documents_batch::BatchTransitionAction; use crate::state_transition_action::identity::identity_create::IdentityCreateTransitionAction; use crate::state_transition_action::identity::identity_credit_transfer::IdentityCreditTransferTransitionAction; use crate::state_transition_action::identity::identity_credit_withdrawal::IdentityCreditWithdrawalTransitionAction; @@ -38,8 +38,8 @@ pub enum StateTransitionAction { DataContractCreateAction(DataContractCreateTransitionAction), /// data contract update DataContractUpdateAction(DataContractUpdateTransitionAction), - /// documents batch - DocumentsBatchAction(DocumentsBatchTransitionAction), + /// batch + BatchAction(BatchTransitionAction), /// identity create IdentityCreateAction(IdentityCreateTransitionAction), /// identity topup @@ -71,7 +71,7 @@ impl StateTransitionAction { match self { StateTransitionAction::DataContractCreateAction(action) => action.user_fee_increase(), StateTransitionAction::DataContractUpdateAction(action) => action.user_fee_increase(), - StateTransitionAction::DocumentsBatchAction(action) => action.user_fee_increase(), + StateTransitionAction::BatchAction(action) => action.user_fee_increase(), StateTransitionAction::IdentityCreateAction(action) => action.user_fee_increase(), StateTransitionAction::IdentityTopUpAction(action) => action.user_fee_increase(), StateTransitionAction::IdentityCreditWithdrawalAction(action) => { diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs index 8b010c9c3de..9597fc72b25 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs @@ -10,6 +10,7 @@ pub struct DriveAbciQueryVersions { pub document_query: FeatureVersionBounds, pub prefunded_specialized_balances: DriveAbciQueryPrefundedSpecializedBalancesVersions, pub identity_based_queries: DriveAbciQueryIdentityVersions, + pub token_queries: DriveAbciQueryTokenVersions, pub validator_queries: DriveAbciQueryValidatorVersions, pub data_contract_based_queries: DriveAbciQueryDataContractVersions, pub voting_based_queries: DriveAbciQueryVotingVersions, @@ -21,6 +22,12 @@ pub struct DriveAbciQueryPrefundedSpecializedBalancesVersions { pub balance: FeatureVersionBounds, } +#[derive(Clone, Debug, Default)] +pub struct DriveAbciQueryTokenVersions { + pub identity_token_balances: FeatureVersionBounds, + pub identities_token_balances: FeatureVersionBounds, +} + #[derive(Clone, Debug, Default)] pub struct DriveAbciQueryIdentityVersions { pub identity: FeatureVersionBounds, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs index b6af08405cf..69a05a0ae7e 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs @@ -1,7 +1,8 @@ use crate::version::drive_abci_versions::drive_abci_query_versions::{ DriveAbciQueryDataContractVersions, DriveAbciQueryIdentityVersions, DriveAbciQueryPrefundedSpecializedBalancesVersions, DriveAbciQuerySystemVersions, - DriveAbciQueryValidatorVersions, DriveAbciQueryVersions, DriveAbciQueryVotingVersions, + DriveAbciQueryTokenVersions, DriveAbciQueryValidatorVersions, DriveAbciQueryVersions, + DriveAbciQueryVotingVersions, }; use versioned_feature_core::FeatureVersionBounds; @@ -72,6 +73,18 @@ pub const DRIVE_ABCI_QUERY_VERSIONS_V1: DriveAbciQueryVersions = DriveAbciQueryV default_current_version: 0, }, }, + token_queries: DriveAbciQueryTokenVersions { + identity_token_balances: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identities_token_balances: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, validator_queries: DriveAbciQueryValidatorVersions { proposed_block_counts_by_evonode_ids: FeatureVersionBounds { min_version: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 830d594c99b..66817c52fcd 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -11,11 +11,15 @@ pub struct DriveTokenMethodVersions { #[derive(Clone, Debug, Default)] pub struct DriveTokenFetchMethodVersions { - pub balance: FeatureVersion, + pub identity_token_balance: FeatureVersion, + pub identity_token_balances: FeatureVersion, } #[derive(Clone, Debug, Default)] -pub struct DriveTokenProveMethodVersions {} +pub struct DriveTokenProveMethodVersions { + pub identity_token_balance: FeatureVersion, + pub identity_token_balances: FeatureVersion, +} #[derive(Clone, Debug, Default)] pub struct DriveTokenUpdateMethodVersions { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index 0eee66aa507..43c1311c620 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -4,8 +4,14 @@ use crate::version::drive_versions::drive_token_method_versions::{ }; pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenMethodVersions { - fetch: DriveTokenFetchMethodVersions { balance: 0 }, - prove: DriveTokenProveMethodVersions {}, + fetch: DriveTokenFetchMethodVersions { + identity_token_balance: 0, + identity_token_balances: 0, + }, + prove: DriveTokenProveMethodVersions { + identity_token_balance: 0, + identity_token_balances: 0, + }, update: DriveTokenUpdateMethodVersions { create_token_root_tree: 0, burn: 0, 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 6d0fe5e47a1..66f624b692d 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -17,7 +17,8 @@ use crate::version::drive_abci_versions::drive_abci_method_versions::v1::DRIVE_A use crate::version::drive_abci_versions::drive_abci_query_versions::{ DriveAbciQueryDataContractVersions, DriveAbciQueryIdentityVersions, DriveAbciQueryPrefundedSpecializedBalancesVersions, DriveAbciQuerySystemVersions, - DriveAbciQueryValidatorVersions, DriveAbciQueryVersions, DriveAbciQueryVotingVersions, + DriveAbciQueryTokenVersions, DriveAbciQueryValidatorVersions, DriveAbciQueryVersions, + DriveAbciQueryVotingVersions, }; use crate::version::drive_abci_versions::drive_abci_structure_versions::v1::DRIVE_ABCI_STRUCTURE_VERSIONS_V1; use crate::version::drive_abci_versions::drive_abci_validation_versions::v1::DRIVE_ABCI_VALIDATION_VERSIONS_V1; @@ -206,6 +207,18 @@ pub const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { default_current_version: 0, }, }, + token_queries: DriveAbciQueryTokenVersions { + identity_token_balances: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identities_token_balances: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, validator_queries: DriveAbciQueryValidatorVersions { proposed_block_counts_by_evonode_ids: FeatureVersionBounds { min_version: 0, diff --git a/packages/rs-platform-version/src/version/v8.rs b/packages/rs-platform-version/src/version/v8.rs index 8c60e65ef34..2cd6f0772e2 100644 --- a/packages/rs-platform-version/src/version/v8.rs +++ b/packages/rs-platform-version/src/version/v8.rs @@ -8,7 +8,6 @@ use crate::version::dpp_versions::dpp_identity_versions::v1::IDENTITY_VERSIONS_V use crate::version::dpp_versions::dpp_method_versions::v1::DPP_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2::STATE_TRANSITION_CONVERSION_VERSIONS_V2; use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; -use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v2::STATE_TRANSITION_SERIALIZATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANSITION_VERSIONS_V2; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; From 40316c072691355853bff3a00cda42bc28bdd669 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 27 Dec 2024 09:06:48 +0700 Subject: [PATCH 24/61] compiling --- Cargo.lock | 11 + Cargo.toml | 3 +- package.json | 3 +- packages/data-contracts/Cargo.toml | 1 + packages/data-contracts/src/error.rs | 18 ++ packages/data-contracts/src/lib.rs | 10 + .../rs-dpp/src/data_contract/accessors/mod.rs | 7 + .../src/data_contract/accessors/v1/mod.rs | 4 + .../token_configuration/mod.rs | 2 +- .../token_configuration/v0/mod.rs | 50 ++++ .../data_contract/change_control_rules/mod.rs | 5 +- .../change_control_rules/v0/mod.rs | 8 +- packages/rs-dpp/src/data_contract/mod.rs | 2 +- .../src/data_contract/v1/accessors/mod.rs | 11 + .../src/data_contract/v1/methods/schema.rs | 2 +- .../src/state_transition/serialization.rs | 4 +- .../batch_transition/json_conversion.rs | 9 + .../batch_transition/v1/value_conversion.rs | 4 +- .../batch_transition/value_conversion.rs | 29 ++- .../v0/mod.rs | 41 ++++ .../contract/insert/insert_contract/mod.rs | 16 +- .../contract/insert/insert_contract/v0/mod.rs | 2 +- .../contract/insert/insert_contract/v1/mod.rs | 187 +++++++++++++++ .../contract/update/update_contract/mod.rs | 34 ++- .../contract/update/update_contract/v0/mod.rs | 2 +- .../contract/update/update_contract/v1/mod.rs | 225 ++++++++++++++++++ .../rs-drive/src/drive/initialization/mod.rs | 4 +- .../src/drive/initialization/v0/mod.rs | 32 ++- .../src/drive/initialization/v1/mod.rs | 67 ++++++ .../fetch_identities_token_balances/v0/mod.rs | 16 +- .../rs-drive/src/drive/tokens/balance/mod.rs | 2 - .../src/drive/tokens/balance/prove.rs | 165 ------------- .../prove_identities_token_balances/v0/mod.rs | 225 ++++++++++++++++-- .../src/drive/tokens/balance/queries.rs | 2 +- packages/rs-drive/src/drive/tokens/mod.rs | 6 +- .../mod.rs | 30 ++- .../v0/mod.rs | 74 +++++- .../rs-drive/src/drive/tokens/system/mod.rs | 2 +- packages/rs-drive/src/fees/op.rs | 16 ++ .../batch_insert_empty_sum_tree/mod.rs | 46 ++++ .../batch_insert_empty_sum_tree/v0/mod.rs | 51 ++++ .../rs-drive/src/util/grove_operations/mod.rs | 3 + packages/rs-drive/src/verify/mod.rs | 1 + packages/rs-drive/src/verify/tokens/mod.rs | 1 + .../mod.rs | 81 +++++++ .../v0/mod.rs | 72 ++++++ .../drive_contract_method_versions/mod.rs | 1 + .../drive_contract_method_versions/v2.rs | 33 +++ .../drive_grove_method_versions/mod.rs | 1 + .../drive_grove_method_versions/v1.rs | 1 + .../drive_token_method_versions/mod.rs | 2 +- .../drive_token_method_versions/v1.rs | 2 +- .../drive_verify_method_versions/mod.rs | 7 + .../drive_verify_method_versions/v1.rs | 11 +- .../src/version/drive_versions/mod.rs | 1 + .../src/version/drive_versions/v3.rs | 102 ++++++++ .../rs-platform-version/src/version/mod.rs | 4 +- .../src/version/protocol_version.rs | 1 + .../rs-platform-version/src/version/v8.rs | 4 +- packages/token-history-contract/Cargo.toml | 4 +- .../wasm-dpp/src/document/document_facade.rs | 4 +- packages/wasm-dpp/src/document/factory.rs | 4 +- .../batched_transition/mod.rs | 18 ++ .../document_create_transition.rs | 0 .../document_delete_transition.rs | 0 .../document_replace_transition.rs | 0 .../document_transition/mod.rs | 0 .../mod.rs | 10 +- .../batch_transition/token_transition/mod.rs | 18 ++ .../validation/basic/find_duplicates_by_id.rs | 0 .../basic/find_duplicates_by_indices.rs | 0 .../validation/basic/mod.rs | 0 ...lidate_documents_batch_transition_basic.rs | 0 .../validate_partial_compound_indices.rs | 0 .../validation/mod.rs | 0 .../state/fetch_extended_documents.rs | 0 .../validation/state/mod.rs | 0 ...idate_documents_batch_transitions_state.rs | 0 ...alidate_documents_uniqueness_by_indices.rs | 0 .../src/document/state_transition/mod.rs | 2 +- .../src/errors/consensus/consensus_error.rs | 9 +- .../state_transition_factory.rs | 4 +- 82 files changed, 1550 insertions(+), 279 deletions(-) create mode 100644 packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs create mode 100644 packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs create mode 100644 packages/rs-drive/src/drive/initialization/v1/mod.rs delete mode 100644 packages/rs-drive/src/drive/tokens/balance/prove.rs rename packages/rs-drive/src/drive/tokens/system/{create_token_root_tree => create_token_trees}/mod.rs (78%) rename packages/rs-drive/src/drive/tokens/system/{create_token_root_tree => create_token_trees}/v0/mod.rs (63%) create mode 100644 packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs create mode 100644 packages/rs-drive/src/verify/tokens/mod.rs create mode 100644 packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs create mode 100644 packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs create mode 100644 packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs create mode 100644 packages/rs-platform-version/src/version/drive_versions/v3.rs create mode 100644 packages/wasm-dpp/src/document/state_transition/batch_transition/batched_transition/mod.rs rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/document_transition/document_create_transition.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/document_transition/document_delete_transition.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/document_transition/document_replace_transition.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/document_transition/mod.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/mod.rs (97%) create mode 100644 packages/wasm-dpp/src/document/state_transition/batch_transition/token_transition/mod.rs rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/basic/find_duplicates_by_id.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/basic/find_duplicates_by_indices.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/basic/mod.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/basic/validate_documents_batch_transition_basic.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/basic/validate_partial_compound_indices.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/mod.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/state/fetch_extended_documents.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/state/mod.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/state/validate_documents_batch_transitions_state.rs (100%) rename packages/wasm-dpp/src/document/state_transition/{document_batch_transition => batch_transition}/validation/state/validate_documents_uniqueness_by_indices.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index d249acda8f8..9faea6603cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1234,6 +1234,7 @@ dependencies = [ "platform-version", "serde_json", "thiserror 1.0.69", + "token-history-contract", "wallet-utils-contract", "withdrawals-contract", ] @@ -4894,6 +4895,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "token-history-contract" +version = "1.6.2" +dependencies = [ + "platform-value", + "platform-version", + "serde_json", + "thiserror 1.0.69", +] + [[package]] name = "tokio" version = "1.41.1" diff --git a/Cargo.toml b/Cargo.toml index 3b7b503758f..30f5e9d4f48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,8 @@ members = [ "packages/simple-signer", "packages/rs-json-schema-compatibility-validator", "packages/check-features", - "packages/wallet-utils-contract" + "packages/wallet-utils-contract", + "packages/token-history-contract" ] [workspace.package] diff --git a/package.json b/package.json index 16a30ea3df1..5471364e5f9 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,8 @@ "packages/masternode-reward-shares-contract", "packages/dash-spv", "packages/wasm-dpp", - "packages/withdrawals-contract" + "packages/withdrawals-contract", + "packages/token-history-contract" ], "resolutions": { "elliptic": "6.5.7", diff --git a/packages/data-contracts/Cargo.toml b/packages/data-contracts/Cargo.toml index 1c011e3d109..74a5cb70d51 100644 --- a/packages/data-contracts/Cargo.toml +++ b/packages/data-contracts/Cargo.toml @@ -17,3 +17,4 @@ dashpay-contract = { path = "../dashpay-contract" } feature-flags-contract = { path = "../feature-flags-contract" } platform-value = { path = "../rs-platform-value" } wallet-utils-contract = { path = "../wallet-utils-contract" } +token-history-contract = { path = "../token-history-contract" } diff --git a/packages/data-contracts/src/error.rs b/packages/data-contracts/src/error.rs index 0550873b012..d2f33d32250 100644 --- a/packages/data-contracts/src/error.rs +++ b/packages/data-contracts/src/error.rs @@ -119,3 +119,21 @@ impl From for Error { } } } + +impl From for Error { + fn from(e: token_history_contract::Error) -> Self { + match e { + token_history_contract::Error::UnknownVersionMismatch { + method, + known_versions, + received, + } => Error::UnknownVersionMismatch { + method, + known_versions, + received, + }, + token_history_contract::Error::InvalidSchemaJson(e) => Error::InvalidSchemaJson(e), + } + } +} + diff --git a/packages/data-contracts/src/lib.rs b/packages/data-contracts/src/lib.rs index 65f324137fd..cf82480300f 100644 --- a/packages/data-contracts/src/lib.rs +++ b/packages/data-contracts/src/lib.rs @@ -11,6 +11,7 @@ use platform_value::Identifier; use platform_version::version::PlatformVersion; pub use wallet_utils_contract; pub use withdrawals_contract; +pub use token_history_contract; #[repr(u8)] #[derive(PartialEq, Eq, Clone, Copy, Debug, Ord, PartialOrd, Hash)] @@ -21,6 +22,7 @@ pub enum SystemDataContract { DPNS = 3, Dashpay = 4, WalletUtils = 5, + TokenHistory = 6, } pub struct DataContractSource { @@ -40,6 +42,7 @@ impl SystemDataContract { SystemDataContract::DPNS => dpns_contract::ID_BYTES, SystemDataContract::Dashpay => dashpay_contract::ID_BYTES, SystemDataContract::WalletUtils => wallet_utils_contract::ID_BYTES, + SystemDataContract::TokenHistory => token_history_contract::ID_BYTES, }; Identifier::new(bytes) } @@ -92,6 +95,13 @@ impl SystemDataContract { definitions: wallet_utils_contract::load_definitions(platform_version)?, document_schemas: wallet_utils_contract::load_documents_schemas(platform_version)?, }, + SystemDataContract::TokenHistory => DataContractSource { + id_bytes: token_history_contract::ID_BYTES, + owner_id_bytes: token_history_contract::OWNER_ID_BYTES, + version: platform_version.system_data_contracts.wallet as u32, + definitions: token_history_contract::load_definitions(platform_version)?, + document_schemas: token_history_contract::load_documents_schemas(platform_version)?, + }, }; Ok(data) diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index 52b1076c3a9..4d320e7a001 100644 --- a/packages/rs-dpp/src/data_contract/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/mod.rs @@ -219,6 +219,13 @@ impl DataContractV1Getters for DataContract { DataContract::V1(v1) => Some(&mut v1.tokens), } } + + fn token_id(&self, position: TokenContractPosition) -> Option { + match self { + DataContract::V0(_) => None, + DataContract::V1(v1) => v1.token_id(position), + } + } } impl DataContractV1Setters for DataContract { diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs index 9d23a0e8374..57a3212cef2 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -3,6 +3,7 @@ use crate::data_contract::associated_token::token_configuration::TokenConfigurat use crate::data_contract::group::{Group, GroupName}; use crate::data_contract::TokenContractPosition; use std::collections::BTreeMap; +use platform_value::Identifier; pub trait DataContractV1Getters: DataContractV0Getters { /// Returns a reference to the groups map. @@ -16,6 +17,9 @@ pub trait DataContractV1Getters: DataContractV0Getters { /// Returns a mutable reference to the tokens map. fn tokens_mut(&mut self) -> Option<&mut BTreeMap>; + + /// Returns the token id at a certain position + fn token_id(&self, position: TokenContractPosition) -> Option; } pub trait DataContractV1Setters: DataContractV0Setters { diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs index 899fe85b0da..fa82163d4cc 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs @@ -7,7 +7,7 @@ use std::fmt; pub mod accessors; mod methods; -mod v0; +pub mod v0; #[derive(Serialize, Deserialize, Encode, Decode, Debug, Clone, PartialEq, Eq, From)] #[serde(tag = "$format_version")] diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 55f8699692c..af7b3052212 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -8,6 +8,7 @@ use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet}; use std::fmt; +use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] @@ -66,3 +67,52 @@ impl fmt::Display for TokenConfigurationV0 { ) } } + +impl TokenConfigurationV0 { + pub fn default_most_restrictive() -> Self { + Self { + conventions: TokenConfigurationConventionV0 { localizations: Default::default(), decimals: 8 }, + base_supply: 100000, + max_supply: None, + max_supply_change_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }.into(), + new_tokens_destination_identity: None, + new_tokens_destination_identity_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }.into(), + manual_minting_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }.into(), + manual_burning_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }.into(), + freeze_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }.into(), + unfreeze_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }.into(), + main_control_group: None, + main_control_group_can_be_modified: AuthorizedActionTakers::NoOne, + } + } +} diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs index efa7304690a..756c507014f 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs @@ -1,14 +1,15 @@ pub mod authorized_action_takers; -mod v0; +pub mod v0; use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; use crate::data_contract::group::Group; use crate::multi_identity_events::ActionTaker; use bincode::{Decode, Encode}; +use derive_more::From; use platform_value::Identifier; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, From)] pub enum ChangeControlRules { V0(ChangeControlRulesV0), } diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs index 2e4b3439b11..db59f7d7e63 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs @@ -8,13 +8,13 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] pub struct ChangeControlRulesV0 { /// This is who is authorized to make such a change - authorized_to_make_change: AuthorizedActionTakers, + pub authorized_to_make_change: AuthorizedActionTakers, /// This is who is authorized to make such a change to the people authorized to make a change - authorized_to_change_authorized_action_takers: AuthorizedActionTakers, + pub authorized_to_change_authorized_action_takers: AuthorizedActionTakers, /// Are we allowed to change to None in the future - changing_authorized_action_takers_to_no_one_allowed: bool, + pub changing_authorized_action_takers_to_no_one_allowed: bool, /// Are we allowed to change to None in the future - changing_authorized_action_takers_to_contract_owner_allowed: bool, + pub changing_authorized_action_takers_to_contract_owner_allowed: bool, } impl ChangeControlRulesV0 { diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index d609e535e34..b58bd46cce9 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -36,7 +36,7 @@ pub mod serialized_version; pub use methods::*; pub mod accessors; pub mod associated_token; -mod change_control_rules; +pub mod change_control_rules; pub mod config; mod group; pub mod storage_requirements; diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs index 23d1be1113e..b84eefccf4f 100644 --- a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -13,6 +13,7 @@ use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::group::{Group, GroupName}; use platform_value::Identifier; use std::collections::BTreeMap; +use crate::util::hash::hash_double; impl DataContractV0Getters for DataContractV1 { fn id(&self) -> Identifier { @@ -158,6 +159,16 @@ impl DataContractV1Getters for DataContractV1 { fn tokens_mut(&mut self) -> Option<&mut BTreeMap> { Some(&mut self.tokens) } + + /// Returns the token id if a token exists at that position + fn token_id(&self, position: TokenContractPosition) -> Option { + self.tokens.get(&position).map(|_| { + let mut bytes = b"dash_token".to_vec(); + bytes.extend_from_slice(self.id().as_bytes()); + bytes.extend_from_slice(&position.to_be_bytes()); + hash_double(bytes).into() + }) + } } impl DataContractV1Setters for DataContractV1 { diff --git a/packages/rs-dpp/src/data_contract/v1/methods/schema.rs b/packages/rs-dpp/src/data_contract/v1/methods/schema.rs index 8173352e8fa..3b88cc59142 100644 --- a/packages/rs-dpp/src/data_contract/v1/methods/schema.rs +++ b/packages/rs-dpp/src/data_contract/v1/methods/schema.rs @@ -103,7 +103,7 @@ mod test { use super::*; use crate::data_contract::config::DataContractConfig; use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; - use crate::data_contract::v0::DataContractV1; + use crate::data_contract::v1::DataContractV1; use platform_value::{platform_value, Identifier}; #[test] diff --git a/packages/rs-dpp/src/state_transition/serialization.rs b/packages/rs-dpp/src/state_transition/serialization.rs index bea1ab72cfd..ff55d2653ab 100644 --- a/packages/rs-dpp/src/state_transition/serialization.rs +++ b/packages/rs-dpp/src/state_transition/serialization.rs @@ -29,7 +29,7 @@ mod tests { }; use crate::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; use crate::state_transition::batch_transition::{ - BatchTransition, BatchTransitionV0, + BatchTransition, BatchTransitionV1, }; use crate::state_transition::identity_create_transition::v0::IdentityCreateTransitionV0; use crate::state_transition::identity_create_transition::IdentityCreateTransition; @@ -342,7 +342,7 @@ mod tests { [(DocumentTransitionActionType::Create, documents)], &mut nonces, ); - let documents_batch_transition: BatchTransition = BatchTransitionV0 { + let documents_batch_transition: BatchTransition = BatchTransitionV1 { owner_id: data_contract.owner_id(), transitions, ..Default::default() diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/json_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/json_conversion.rs index f74b93740a6..80d5c5c7911 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/json_conversion.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/json_conversion.rs @@ -22,6 +22,15 @@ impl<'a> StateTransitionJsonConvert<'a> for BatchTransition { ); Ok(value) } + BatchTransition::V1(transition) => { + let mut value = transition.to_json(options)?; + let map_value = value.as_object_mut().expect("expected an object"); + map_value.insert( + STATE_TRANSITION_PROTOCOL_VERSION.to_string(), + JsonValue::Number(Number::from(1)), + ); + Ok(value) + } } } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/value_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/value_conversion.rs index 5438c1e2d09..53a75f0a890 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/value_conversion.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/value_conversion.rs @@ -1,4 +1,4 @@ -use crate::state_transition::batch_transition::BatchTransitionV0; +use crate::state_transition::batch_transition::BatchTransitionV1; use crate::state_transition::StateTransitionValueConvert; -impl<'a> StateTransitionValueConvert<'a> for BatchTransitionV0 {} +impl<'a> StateTransitionValueConvert<'a> for BatchTransitionV1 {} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs index 9df007a4e85..a53a64ff534 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs @@ -4,7 +4,7 @@ use platform_value::Value; use crate::ProtocolError; -use crate::state_transition::batch_transition::{BatchTransition, BatchTransitionV0}; +use crate::state_transition::batch_transition::{BatchTransition, BatchTransitionV0, BatchTransitionV1}; use crate::state_transition::state_transitions::batch_transition::fields::*; use crate::state_transition::StateTransitionValueConvert; @@ -19,6 +19,11 @@ impl<'a> StateTransitionValueConvert<'a> for BatchTransition { value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(0))?; Ok(value) } + BatchTransition::V1(transition) => { + let mut value = transition.to_object(skip_signature)?; + value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(1))?; + Ok(value) + } } } @@ -29,6 +34,11 @@ impl<'a> StateTransitionValueConvert<'a> for BatchTransition { value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(0))?; Ok(value) } + BatchTransition::V1(transition) => { + let mut value = transition.to_canonical_object(skip_signature)?; + value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(1))?; + Ok(value) + } } } @@ -39,6 +49,11 @@ impl<'a> StateTransitionValueConvert<'a> for BatchTransition { value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(0))?; Ok(value) } + BatchTransition::V1(transition) => { + let mut value = transition.to_canonical_cleaned_object(skip_signature)?; + value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(1))?; + Ok(value) + } } } @@ -49,6 +64,11 @@ impl<'a> StateTransitionValueConvert<'a> for BatchTransition { value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(0))?; Ok(value) } + BatchTransition::V1(transition) => { + let mut value = transition.to_cleaned_object(skip_signature)?; + value.insert(STATE_TRANSITION_PROTOCOL_VERSION.to_string(), Value::U16(1))?; + Ok(value) + } } } @@ -69,8 +89,9 @@ impl<'a> StateTransitionValueConvert<'a> for BatchTransition { match version { 0 => Ok(BatchTransitionV0::from_object(raw_object, platform_version)?.into()), + 1 => Ok(BatchTransitionV1::from_object(raw_object, platform_version)?.into()), n => Err(ProtocolError::UnknownVersionError(format!( - "Unknown DataContractCreateTransition version {n}" + "Unknown contract_create_state_transition default_current_version {n}" ))), } } @@ -92,8 +113,9 @@ impl<'a> StateTransitionValueConvert<'a> for BatchTransition { match version { 0 => Ok(BatchTransitionV0::from_value_map(raw_value_map, platform_version)?.into()), + 1 => Ok(BatchTransitionV1::from_value_map(raw_value_map, platform_version)?.into()), n => Err(ProtocolError::UnknownVersionError(format!( - "Unknown DataContractCreateTransition version {n}" + "Unknown contract_create_state_transition default_current_version {n}" ))), } } @@ -105,6 +127,7 @@ impl<'a> StateTransitionValueConvert<'a> for BatchTransition { match version { 0 => BatchTransitionV0::clean_value(value), + 1 => BatchTransitionV1::clean_value(value), n => Err(ProtocolError::UnknownVersionError(format!( "Unknown DataContractCreateTransition version {n}" ))), diff --git a/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs index d36250ea3e7..8bf290565d1 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs @@ -8,6 +8,7 @@ use dpp::data_contracts::SystemDataContract; use dpp::system_data_contracts::load_system_data_contract; use dpp::version::PlatformVersion; use dpp::version::ProtocolVersion; +use drive::drive::balances::TOTAL_TOKEN_SUPPLIES_STORAGE_KEY; use drive::drive::identity::key::fetch::{ IdentityKeysRequest, KeyIDIdentityPublicKeyPairBTreeMap, KeyRequestType, }; @@ -15,6 +16,7 @@ use drive::drive::identity::withdrawals::paths::{ get_withdrawal_root_path, WITHDRAWAL_TRANSACTIONS_BROADCASTED_KEY, WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY, }; +use drive::drive::system::misc_path; use drive::grovedb::{Element, Transaction}; impl Platform { @@ -58,6 +60,10 @@ impl Platform { self.transition_to_version_6(block_info, transaction, platform_version)?; } + if previous_protocol_version < 8 && platform_version.protocol_version >= 8 { + self.transition_to_version_8(block_info, transaction, platform_version)?; + } + Ok(()) } @@ -86,6 +92,41 @@ impl Platform { Ok(()) } + /// Adds all trees needed for tokens, also adds the token history system data contract + /// + /// This function is called during the transition from protocol version 5 to protocol version 6 + /// and higher to set up the wallet contract in the platform. + fn transition_to_version_8( + &self, + block_info: &BlockInfo, + transaction: &Transaction, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let path = misc_path(); + self.drive.grove_insert_if_not_exists( + (&path).into(), + TOTAL_TOKEN_SUPPLIES_STORAGE_KEY.as_slice(), + Element::empty_tree(), + Some(transaction), + None, + &platform_version.drive, + )?; + + let contract = + load_system_data_contract(SystemDataContract::TokenHistory, platform_version)?; + + self.drive.insert_contract( + &contract, + *block_info, + true, + Some(transaction), + platform_version, + )?; + + Ok(()) + } + + /// Initializes an empty sum tree for withdrawal transactions required for protocol version 4. /// /// This function is called during the transition to protocol version 4 to set up diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/mod.rs index 8b39715cbb7..cfae17fd1c2 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/mod.rs @@ -1,4 +1,5 @@ mod v0; +mod v1; use crate::drive::Drive; use crate::error::drive::DriveError; @@ -51,9 +52,12 @@ impl Drive { 0 => { self.insert_contract_v0(contract, block_info, apply, transaction, platform_version) } + 1 => { + self.insert_contract_v1(contract, block_info, apply, transaction, platform_version) + } version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "insert_contract".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), } @@ -103,9 +107,17 @@ impl Drive { drive_operations, platform_version, ), + 1 => self.insert_contract_add_operations_v1( + contract_element, + contract, + block_info, + estimated_costs_only_with_layer_info, + drive_operations, + platform_version, + ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "insert_contract_add_operations".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), } diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rs index 207626f0641..635e315e86e 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v0/mod.rs @@ -145,7 +145,7 @@ impl Drive { /// The operations for adding a contract. /// These operations add a contract to storage using `add_contract_to_storage` /// and insert the empty trees which will be necessary to later insert documents. - fn insert_contract_operations_v0( + pub(in crate::drive::contract::insert::insert_contract) fn insert_contract_operations_v0( &self, contract_element: Element, contract: &DataContract, diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs new file mode 100644 index 00000000000..37d4ebd9fc3 --- /dev/null +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs @@ -0,0 +1,187 @@ +use crate::drive::Drive; +use crate::util::storage_flags::StorageFlags; + +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::config::v0::DataContractConfigGettersV0; +use dpp::data_contract::DataContract; +use dpp::fee::fee_result::FeeResult; + +use dpp::serialization::PlatformSerializableWithPlatformVersion; +use crate::error::contract::DataContractError; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use crate::drive::balances::total_tokens_root_supply_path; +use crate::drive::tokens::{TOKEN_BALANCES_KEY, token_path, tokens_root_path}; +use crate::util::grove_operations::BatchInsertTreeApplyType; +use crate::util::object_size_info::DriveKeyInfo; + +impl Drive { + /// Insert a contract. + #[inline(always)] + pub(super) fn insert_contract_v1( + &self, + contract: &DataContract, + block_info: BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations: Vec = vec![]; + + let storage_flags = if contract.config().can_be_deleted() || !contract.config().readonly() { + Some(StorageFlags::new_single_epoch( + block_info.epoch.index, + Some(contract.owner_id().to_buffer()), + )) + } else { + None + }; + + let serialized_contract = + contract.serialize_to_bytes_with_platform_version(platform_version)?; + + if serialized_contract.len() as u64 > u32::MAX as u64 + || serialized_contract.len() as u32 + > platform_version.dpp.contract_versions.max_serialized_size + { + // This should normally be caught by DPP, but there is a rare possibility that the + // re-serialized size is bigger than the original serialized data contract. + return Err(Error::DataContract(DataContractError::ContractTooBig(format!("Trying to insert a data contract of size {} that is over the max allowed insertion size {}", serialized_contract.len(), platform_version.dpp.contract_versions.max_serialized_size)))); + } + + let contract_element = Element::Item( + serialized_contract, + StorageFlags::map_to_some_element_flags(storage_flags.as_ref()), + ); + + self.insert_contract_element_v1( + contract_element, + contract, + &block_info, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + ) + } + + /// Adds a contract to storage using `add_contract_to_storage` + /// and inserts the empty trees which will be necessary to later insert documents. + fn insert_contract_element_v1( + &self, + contract_element: Element, + contract: &DataContract, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = if apply { + None::> + } else { + Some(HashMap::new()) + }; + let batch_operations = self.insert_contract_operations_v1( + contract_element, + contract, + block_info, + &mut estimated_costs_only_with_layer_info, + platform_version, + )?; + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + /// The operations for adding a contract. + /// These operations add a contract to storage using `add_contract_to_storage` + /// and insert the empty trees which will be necessary to later insert documents. + #[inline(always)] + pub(super) fn insert_contract_add_operations_v1( + &self, + contract_element: Element, + contract: &DataContract, + block_info: &BlockInfo, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let batch_operations = self.insert_contract_operations_v1( + contract_element, + contract, + block_info, + estimated_costs_only_with_layer_info, + platform_version, + )?; + drive_operations.extend(batch_operations); + Ok(()) + } + + /// The operations for adding a contract. + /// These operations add a contract to storage using `add_contract_to_storage` + /// and insert the empty trees which will be necessary to later insert documents. + fn insert_contract_operations_v1( + &self, + contract_element: Element, + contract: &DataContract, + block_info: &BlockInfo, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut batch_operations: Vec = self.insert_contract_operations_v0(contract_element, contract, block_info, estimated_costs_only_with_layer_info, platform_version)?; + + for token_pos in contract.tokens().keys() { + let token_id = contract.token_id(*token_pos).ok_or(Error::DataContract(DataContractError::CorruptedDataContract(format!("data contract has a token at position {}, but can not find it", token_pos))))?; + + self.batch_insert_empty_tree( + tokens_root_path(), + DriveKeyInfo::KeyRef(token_id.as_bytes()), + None, + &mut batch_operations, + &platform_version.drive, + )?; + + self.batch_insert_empty_tree( + token_path(token_id.as_bytes()), + DriveKeyInfo::Key(vec![TOKEN_BALANCES_KEY]), + None, + &mut batch_operations, + &platform_version.drive, + )?; + + self.batch_insert_empty_tree( + total_tokens_root_supply_path(), + DriveKeyInfo::KeyRef(token_id.as_bytes()), + None, + &mut batch_operations, + &platform_version.drive, + )?; + } + + Ok(batch_operations) + } +} diff --git a/packages/rs-drive/src/drive/contract/update/update_contract/mod.rs b/packages/rs-drive/src/drive/contract/update/update_contract/mod.rs index 8d22fc40435..f9f682d74ac 100644 --- a/packages/rs-drive/src/drive/contract/update/update_contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/update/update_contract/mod.rs @@ -1,4 +1,5 @@ mod v0; +mod v1; use crate::drive::Drive; use crate::error::drive::DriveError; @@ -64,9 +65,17 @@ impl Drive { platform_version, previous_fee_versions, ), + 1 => self.update_contract_v1( + contract, + block_info, + apply, + transaction, + platform_version, + previous_fee_versions, + ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "update_contract".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), } @@ -125,9 +134,18 @@ impl Drive { drive_operations, platform_version, ), + 1 => self.update_contract_element_v1( + contract_element, + contract, + original_contract, + block_info, + transaction, + drive_operations, + platform_version, + ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "update_contract_element".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), } @@ -192,9 +210,19 @@ impl Drive { drive_operations, platform_version, ), + 1 => self.update_contract_add_operations_v1( + contract_element, + contract, + original_contract, + block_info, + estimated_costs_only_with_layer_info, + transaction, + drive_operations, + platform_version, + ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "update_contract_add_operations".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), } diff --git a/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs b/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs index d95decc3f96..ddec35b2bae 100644 --- a/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs @@ -198,7 +198,7 @@ impl Drive { } /// operations for updating a contract. - fn update_contract_operations_v0( + pub(in crate::drive::contract::update::update_contract) fn update_contract_operations_v0( &self, contract_element: Element, contract: &DataContract, diff --git a/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs new file mode 100644 index 00000000000..fadf485b670 --- /dev/null +++ b/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs @@ -0,0 +1,225 @@ +use crate::drive::{contract_documents_path, Drive}; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::BatchInsertTreeApplyType; +use crate::util::object_size_info::DriveKeyInfo::KeyRef; +use crate::util::object_size_info::PathKeyInfo::{PathFixedSizeKey, PathFixedSizeKeyRef}; +use crate::util::storage_flags::StorageFlags; +use dpp::block::block_info::BlockInfo; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::config::v0::DataContractConfigGettersV0; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::data_contract::DataContract; +use dpp::fee::fee_result::FeeResult; + +use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; +use dpp::serialization::PlatformSerializableWithPlatformVersion; + +use dpp::fee::default_costs::CachedEpochIndexFeeVersions; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use std::collections::{HashMap, HashSet}; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use crate::drive::tokens::{TOKEN_BALANCES_KEY, token_path, tokens_root_path}; +use crate::error::contract::DataContractError; + +impl Drive { + /// Updates a data contract. + /// + /// This function updates a given data contract in the storage. The fee for updating + /// the contract is also calculated and returned. + /// + /// # Arguments + /// + /// * `contract` - A reference to the `DataContract` to be updated. + /// * `block_info` - A `BlockInfo` object containing information about the block where + /// the contract is being updated. + /// * `apply` - A boolean indicating whether the contract update should be applied (`true`) or not (`false`). Passing `false` would only tell the fees but won't interact with the state. + /// * `transaction` - A `TransactionArg` object representing the transaction to be used + /// for updating the contract. + /// + /// # Returns + /// + /// * `Result` - If successful, returns a `FeeResult` representing the fee + /// for updating the contract. If an error occurs during the contract update or fee calculation, + /// returns an `Error`. + /// + /// # Errors + /// + /// This function returns an error if the contract update or fee calculation fails. + #[inline(always)] + pub(super) fn update_contract_v1( + &self, + contract: &DataContract, + block_info: BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + previous_fee_versions: Option<&CachedEpochIndexFeeVersions>, + ) -> Result { + if !apply { + return self.insert_contract( + contract, + block_info, + false, + transaction, + platform_version, + ); + } + + let mut drive_operations: Vec = vec![]; + + let contract_bytes = contract.serialize_to_bytes_with_platform_version(platform_version)?; + + // Since we can update the contract by definition it already has storage flags + let storage_flags = Some(StorageFlags::new_single_epoch( + block_info.epoch.index, + Some(contract.owner_id().to_buffer()), + )); + + let contract_element = Element::Item( + contract_bytes, + StorageFlags::map_to_some_element_flags(storage_flags.as_ref()), + ); + + let original_contract_fetch_info = self + .get_contract_with_fetch_info_and_add_to_operations( + contract.id().to_buffer(), + Some(&block_info.epoch), + true, + transaction, + &mut drive_operations, + platform_version, + )? + .ok_or(Error::Drive(DriveError::CorruptedCodeExecution( + "contract should exist", + )))?; + + if original_contract_fetch_info.contract.config().readonly() { + return Err(Error::Drive(DriveError::UpdatingReadOnlyImmutableContract( + "original contract is readonly", + ))); + } + + self.update_contract_element_v1( + contract_element, + contract, + &original_contract_fetch_info.contract, + &block_info, + transaction, + &mut drive_operations, + platform_version, + )?; + + // Update DataContracts cache with the new contract + let updated_contract_fetch_info = self + .fetch_contract_and_add_operations( + contract.id().to_buffer(), + Some(&block_info.epoch), + transaction, + &mut drive_operations, + platform_version, + )? + .ok_or(Error::Drive(DriveError::CorruptedCodeExecution( + "contract should exist", + )))?; + + self.cache + .data_contracts + .insert(updated_contract_fetch_info, transaction.is_some()); + + Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + previous_fee_versions, + ) + } + + /// Updates a contract. + #[inline(always)] + pub(super) fn update_contract_element_v1( + &self, + contract_element: Element, + contract: &DataContract, + original_contract: &DataContract, + block_info: &BlockInfo, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + None::>; + let batch_operations = self.update_contract_operations_v1( + contract_element, + contract, + original_contract, + block_info, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + /// Updates a contract. + #[inline(always)] + pub(super) fn update_contract_add_operations_v1( + &self, + contract_element: Element, + contract: &DataContract, + original_contract: &DataContract, + block_info: &BlockInfo, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let batch_operations = self.update_contract_operations_v1( + contract_element, + contract, + original_contract, + block_info, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + drive_operations.extend(batch_operations); + Ok(()) + } + + /// operations for updating a contract. + fn update_contract_operations_v1( + &self, + contract_element: Element, + contract: &DataContract, + original_contract: &DataContract, + block_info: &BlockInfo, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut batch_operations: Vec = self.update_contract_operations_v0(contract_element, contract, original_contract, block_info, estimated_costs_only_with_layer_info, transaction, platform_version)?; + + for token_pos in contract.tokens().keys() { + let token_id = contract.token_id(*token_pos).ok_or(Error::DataContract(DataContractError::CorruptedDataContract(format!("data contract has a token at position {}, but can not find it", token_pos))))?; + + batch_operations.extend(self.create_token_trees_operations(token_id.to_buffer(), true, &mut None, estimated_costs_only_with_layer_info, transaction, platform_version)?); + } + Ok(batch_operations) + } +} diff --git a/packages/rs-drive/src/drive/initialization/mod.rs b/packages/rs-drive/src/drive/initialization/mod.rs index 97159a53ba9..2c673b90243 100644 --- a/packages/rs-drive/src/drive/initialization/mod.rs +++ b/packages/rs-drive/src/drive/initialization/mod.rs @@ -2,6 +2,7 @@ mod genesis_core_height; mod v0; +mod v1; use crate::drive::Drive; use crate::error::drive::DriveError; @@ -24,9 +25,10 @@ impl Drive { .create_initial_state_structure { 0 => self.create_initial_state_structure_0(transaction, platform_version), + 1 => self.create_initial_state_structure_1(transaction, platform_version), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "create_initial_state_structure".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), } diff --git a/packages/rs-drive/src/drive/initialization/v0/mod.rs b/packages/rs-drive/src/drive/initialization/v0/mod.rs index b612aad5a2e..8736d42d25b 100644 --- a/packages/rs-drive/src/drive/initialization/v0/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v0/mod.rs @@ -20,6 +20,24 @@ impl Drive { &self, transaction: TransactionArg, platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let drive_version = &platform_version.drive; + self.create_initial_state_structure_top_level_0(transaction, platform_version)?; + + // On lower layers we can use batching + + let batch = self.create_initial_state_structure_lower_layers_operations_0(platform_version)?; + + self.grove_apply_batch(batch, false, transaction, drive_version)?; + + Ok(()) + } + + /// Creates the initial state structure. + pub(in crate::drive::initialization) fn create_initial_state_structure_top_level_0( + &self, + transaction: TransactionArg, + platform_version: &PlatformVersion, ) -> Result<(), Error> { let drive_version = &platform_version.drive; // We can not use batching to insert the root tree structure @@ -151,6 +169,14 @@ impl Drive { drive_version, )?; + Ok(()) + } + + /// Creates the initial state structure. + pub(in crate::drive::initialization) fn create_initial_state_structure_lower_layers_operations_0( + &self, + platform_version: &PlatformVersion, + ) -> Result { // On lower layers we can use batching let mut batch = GroveDbOpBatch::new(); @@ -180,10 +206,8 @@ impl Drive { // For the votes tree structure Drive::add_initial_vote_tree_main_structure_operations(&mut batch, platform_version)?; - - self.grove_apply_batch(batch, false, transaction, drive_version)?; - - Ok(()) + + Ok(batch) } } diff --git a/packages/rs-drive/src/drive/initialization/v1/mod.rs b/packages/rs-drive/src/drive/initialization/v1/mod.rs new file mode 100644 index 00000000000..d0d16a7962e --- /dev/null +++ b/packages/rs-drive/src/drive/initialization/v1/mod.rs @@ -0,0 +1,67 @@ +//! Drive Initialization + +use crate::drive::balances::TOTAL_TOKEN_SUPPLIES_STORAGE_KEY; +use crate::util::batch::GroveDbOpBatch; + +use crate::drive::system::misc_path_vec; +use crate::drive::Drive; +use crate::error::Error; +use crate::util::batch::grovedb_op_batch::GroveDbOpBatchV0Methods; + +use dpp::version::PlatformVersion; +use grovedb::{Element, TransactionArg}; +use crate::drive::identity::withdrawals::paths::{get_withdrawal_root_path_vec, WITHDRAWAL_TRANSACTIONS_BROADCASTED_KEY, WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY}; + +impl Drive { + /// Creates the initial state structure. + pub(super) fn create_initial_state_structure_1( + &self, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let drive_version = &platform_version.drive; + self.create_initial_state_structure_top_level_0(transaction, platform_version)?; + + // On lower layers we can use batching + + let mut batch = self.create_initial_state_structure_lower_layers_operations_0(platform_version)?; + + self.initial_state_structure_lower_layers_add_operations_1(&mut batch, platform_version)?; + + self.grove_apply_batch(batch, false, transaction, drive_version)?; + + Ok(()) + } + + /// Creates the initial state structure. + pub(in crate::drive::initialization) fn initial_state_structure_lower_layers_add_operations_1( + &self, + batch: &mut GroveDbOpBatch, + _platform_version: &PlatformVersion, + ) -> Result<(), Error> { + + // In Misc + batch.add_insert( + misc_path_vec(), + TOTAL_TOKEN_SUPPLIES_STORAGE_KEY.to_vec(), + Element::empty_tree(), + ); + + // We are adding the withdrawal transactions sum amount tree + let path = get_withdrawal_root_path_vec(); + + batch.add_insert( + path.clone(), + WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY.to_vec(), + Element::empty_sum_tree(), + ); + + batch.add_insert( + path, + WITHDRAWAL_TRANSACTIONS_BROADCASTED_KEY.to_vec(), + Element::empty_tree(), + ); + + Ok(()) + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs index c548c3f4d30..fd884c1eba1 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs @@ -1,4 +1,3 @@ -use crate::drive::tokens::token_balances_path_vec; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; @@ -6,7 +5,7 @@ use crate::fees::op::LowLevelDriveOperation; use dpp::balances::credits::TokenAmount; use dpp::version::PlatformVersion; use grovedb::Element::SumItem; -use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; +use grovedb::TransactionArg; use std::collections::BTreeMap; impl Drive { @@ -34,18 +33,7 @@ impl Drive { drive_operations: &mut Vec, platform_version: &PlatformVersion, ) -> Result>, Error> { - let tokens_root = token_balances_path_vec(token_id); - - let mut query = Query::new(); - - for identity_id in identity_ids { - query.insert_key(identity_id.to_vec()); - } - - let path_query = PathQuery::new( - tokens_root, - SizedQuery::new(query, Some(identity_ids.len() as u16), None), - ); + let path_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids); self.grove_get_raw_path_query_with_optional( &path_query, diff --git a/packages/rs-drive/src/drive/tokens/balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/mod.rs index 8dbad4fc3d7..bc7bfa588f0 100644 --- a/packages/rs-drive/src/drive/tokens/balance/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/mod.rs @@ -7,8 +7,6 @@ mod fetch_identities_token_balances; #[cfg(feature = "server")] mod fetch_identity_token_balances; #[cfg(feature = "server")] -mod prove; -#[cfg(feature = "server")] mod prove_identities_token_balances; #[cfg(feature = "server")] mod prove_identity_token_balances; diff --git a/packages/rs-drive/src/drive/tokens/balance/prove.rs b/packages/rs-drive/src/drive/tokens/balance/prove.rs deleted file mode 100644 index f2ce692e6a7..00000000000 --- a/packages/rs-drive/src/drive/tokens/balance/prove.rs +++ /dev/null @@ -1,165 +0,0 @@ -use crate::drive::Drive; -use crate::error::Error; - -use dpp::version::drive_versions::DriveVersion; - -use grovedb::TransactionArg; - -impl Drive { - /// Proves an Identity's token balance from the backing store - pub fn prove_identity_token_balance( - &self, - token_id: [u8; 32], - identity_id: [u8; 32], - transaction: TransactionArg, - drive_version: &DriveVersion, - ) -> Result, Error> { - let balance_query = Self::token_balance_for_identity_id_query(token_id, identity_id); - self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) - } - - /// Proves multiple Identity token balances from the backing store - pub fn prove_many_identity_token_balances( - &self, - token_id: [u8; 32], - identity_ids: &[[u8; 32]], - transaction: TransactionArg, - drive_version: &DriveVersion, - ) -> Result, Error> { - let balance_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids); - self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) - } - - /// Proves multiple Identity balances from the backing store by range - pub fn prove_many_identity_token_balances_by_range( - &self, - token_id: [u8; 32], - start_at: Option<([u8; 32], bool)>, - ascending: bool, - limit: u16, - transaction: TransactionArg, - drive_version: &DriveVersion, - ) -> Result, Error> { - let balance_query = - Self::token_balances_for_range_query(token_id, start_at, ascending, limit); - self.grove_get_proved_path_query(&balance_query, transaction, &mut vec![], drive_version) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; - use dpp::block::block_info::BlockInfo; - use dpp::identity::Identity; - - mod prove_identity_token_balance { - use super::*; - use dpp::identity::accessors::IdentityGettersV0; - use dpp::version::PlatformVersion; - - #[test] - fn should_prove_a_single_identity_token_balance() { - let drive = setup_drive_with_initial_state_structure(None); - - let platform_version = PlatformVersion::first(); - - let identity = Identity::random_identity(3, Some(14), platform_version) - .expect("expected a platform identity"); - - let identity_id = identity.id().to_buffer(); - drive - .add_new_identity( - identity.clone(), - false, - &BlockInfo::default(), - true, - None, - platform_version, - ) - .expect("expected to add an identity"); - let proof = drive - .prove_identity_token_balance( - identity.id().to_buffer(), - None, - &platform_version.drive, - ) - .expect("should not error when proving an identity"); - - let (_, proved_identity_balance) = - Drive::verify_identity_token_balance_for_identity_id( - proof.as_slice(), - identity_id, - false, - platform_version, - ) - .expect("expect that this be verified"); - - assert_eq!(proved_identity_balance, Some(identity.balance())); - } - } - - mod prove_many_identity_token_balances { - use super::*; - use dpp::fee::Credits; - use dpp::identity::accessors::IdentityGettersV0; - use platform_version::version::PlatformVersion; - use rand::rngs::StdRng; - use rand::{Rng, SeedableRng}; - use std::collections::BTreeMap; - - #[test] - fn should_prove_multiple_identity_single_token_balances() { - let drive = setup_drive_with_initial_state_structure(None); - let platform_version = PlatformVersion::latest(); - let identities: BTreeMap<[u8; 32], Identity> = - Identity::random_identities(10, 3, Some(14), platform_version) - .expect("expected to get random identities") - .into_iter() - .map(|identity| (identity.id().to_buffer(), identity)) - .collect(); - - let mut rng = StdRng::seed_from_u64(293); - - let token_id: [u8; 32] = rng.gen(); - - drive.add_new_token(token_id); - - for identity in identities.values() { - drive - .add_new_identity( - identity.clone(), - false, - &BlockInfo::default(), - true, - None, - platform_version, - ) - .expect("expected to add an identity"); - } - let identity_ids = identities.keys().copied().collect::>(); - let identity_balances = identities - .into_iter() - .map(|(id, identity)| (id, Some(identity.balance()))) - .collect::>>(); - let proof = drive - .prove_many_identity_token_balances( - identity_ids.as_slice(), - None, - &platform_version.drive, - ) - .expect("should not error when proving an identity"); - - let (_, proved_identity_balances): ([u8; 32], BTreeMap<[u8; 32], Option>) = - Drive::verify_identity_balances_for_identity_ids( - proof.as_slice(), - false, - identity_ids.as_slice(), - platform_version, - ) - .expect("expect that this be verified"); - - assert_eq!(proved_identity_balances, identity_balances); - } - } -} diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs index 58db6c0a537..b81eea97b95 100644 --- a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs @@ -1,9 +1,8 @@ -use crate::drive::tokens::token_balances_path_vec; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use dpp::version::PlatformVersion; -use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; +use grovedb::TransactionArg; impl Drive { pub(super) fn prove_identities_token_balances_v0( @@ -30,18 +29,7 @@ impl Drive { drive_operations: &mut Vec, platform_version: &PlatformVersion, ) -> Result, Error> { - let tokens_root = token_balances_path_vec(token_id); - - let mut query = Query::new(); - - for identity_id in identity_ids { - query.insert_key(identity_id.to_vec()); - } - - let path_query = PathQuery::new( - tokens_root, - SizedQuery::new(query, Some(identity_ids.len() as u16), None), - ); + let path_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids); self.grove_get_proved_path_query( &path_query, @@ -51,3 +39,212 @@ impl Drive { ) } } + + +#[cfg(test)] +mod tests { + use std::collections::BTreeMap; + use dpp::balances::credits::TokenAmount; + use super::*; + use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; + use dpp::block::block_info::BlockInfo; + use dpp::data_contract::accessors::v1::DataContractV1Getters; + use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; + use dpp::data_contract::associated_token::token_configuration::v0::{TokenConfigurationConventionV0, TokenConfigurationV0}; + use dpp::data_contract::config::DataContractConfig; + use dpp::data_contract::config::v0::DataContractConfigV0; + use dpp::data_contract::v1::DataContractV1; + use dpp::identity::Identity; + + use dpp::identity::accessors::IdentityGettersV0; + use dpp::prelude::DataContract; + use dpp::version::PlatformVersion; + + #[test] + fn should_prove_a_single_identity_token_balance() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = Identity::random_identity(3, Some(14), platform_version) + .expect("expected a platform identity"); + + let identity_id = identity.id().to_buffer(); + + let contract = DataContract::V1(DataContractV1 { + id: Default::default(), + version: 0, + owner_id: Default::default(), + document_types: Default::default(), + metadata: None, + config: DataContractConfig::V0(DataContractConfigV0 { + can_be_deleted: false, + readonly: false, + keeps_history: false, + documents_keep_history_contract_default: false, + documents_mutable_contract_default: false, + documents_can_be_deleted_contract_default: false, + requires_identity_encryption_bounded_key: None, + requires_identity_decryption_bounded_key: None, + }), + schema_defs: None, + groups: Default::default(), + tokens: BTreeMap::from([(0, TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()))]), + }); + let token_id = contract.token_id(0).expect("expected token at position 0"); + drive + .add_new_identity( + identity.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + + drive.insert_contract(&contract, BlockInfo::default(), true, None, platform_version).expect("expected to insert contract"); + + drive.token_mint(token_id.to_buffer(), identity.id().to_buffer(), 10000, true, &BlockInfo::default(), true, None, platform_version).expect("expected to mint token"); + let proof = drive + .prove_identities_token_balances_v0( + token_id.to_buffer(), + &vec![identity.id().to_buffer()], + None, + platform_version, + ) + .expect("should not error when proving an identity"); + + let proved_identity_balance: BTreeMap<[u8;32], Option> = + Drive::verify_token_balances_for_identity_ids( + proof.as_slice(), + token_id.to_buffer(), + &vec![identity.id().to_buffer()], + false, + platform_version, + ) + .expect("expect that this be verified").1; + + assert_eq!(proved_identity_balance, BTreeMap::from([(identity_id, Some(10000))])); + } + + #[test] + fn should_prove_a_single_identity_token_balance_does_not_exist() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = Identity::random_identity(3, Some(14), platform_version) + .expect("expected a platform identity"); + + let identity_id = identity.id().to_buffer(); + + let contract = DataContract::V1(DataContractV1 { + id: Default::default(), + version: 0, + owner_id: Default::default(), + document_types: Default::default(), + metadata: None, + config: DataContractConfig::V0(DataContractConfigV0 { + can_be_deleted: false, + readonly: false, + keeps_history: false, + documents_keep_history_contract_default: false, + documents_mutable_contract_default: false, + documents_can_be_deleted_contract_default: false, + requires_identity_encryption_bounded_key: None, + requires_identity_decryption_bounded_key: None, + }), + schema_defs: None, + groups: Default::default(), + tokens: BTreeMap::from([(0, TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()))]), + }); + let token_id = contract.token_id(0).expect("expected token at position 0"); + drive + .add_new_identity( + identity.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + + drive.insert_contract(&contract, BlockInfo::default(), true, None, platform_version).expect("expected to insert contract"); + let proof = drive + .prove_identities_token_balances_v0( + token_id.to_buffer(), + &vec![identity.id().to_buffer()], + None, + platform_version, + ) + .expect("should not error when proving an identity"); + + let proved_identity_balance: BTreeMap<[u8;32], Option> = + Drive::verify_token_balances_for_identity_ids( + proof.as_slice(), + token_id.to_buffer(), + &vec![identity.id().to_buffer()], + false, + platform_version, + ) + .expect("expect that this be verified").1; + + assert_eq!(proved_identity_balance, BTreeMap::from([(identity_id, None)])); + } + + // #[test] + // fn should_prove_multiple_identity_single_token_balances() { + // let drive = setup_drive_with_initial_state_structure(None); + // let platform_version = PlatformVersion::latest(); + // let identities: BTreeMap<[u8; 32], Identity> = + // Identity::random_identities(10, 3, Some(14), platform_version) + // .expect("expected to get random identities") + // .into_iter() + // .map(|identity| (identity.id().to_buffer(), identity)) + // .collect(); + // + // let mut rng = StdRng::seed_from_u64(293); + // + // let token_id: [u8; 32] = rng.gen(); + // + // drive.add_new_token(token_id); + // + // for identity in identities.values() { + // drive + // .add_new_identity( + // identity.clone(), + // false, + // &BlockInfo::default(), + // true, + // None, + // platform_version, + // ) + // .expect("expected to add an identity"); + // } + // let identity_ids = identities.keys().copied().collect::>(); + // let identity_balances = identities + // .into_iter() + // .map(|(id, identity)| (id, Some(identity.balance()))) + // .collect::>>(); + // let proof = drive + // .prove_many_identity_token_balances( + // identity_ids.as_slice(), + // None, + // &platform_version.drive, + // ) + // .expect("should not error when proving an identity"); + // + // let (_, proved_identity_balances): ([u8; 32], BTreeMap<[u8; 32], Option>) = + // Drive::verify_identity_balances_for_identity_ids( + // proof.as_slice(), + // false, + // identity_ids.as_slice(), + // platform_version, + // ) + // .expect("expect that this be verified"); + // + // assert_eq!(proved_identity_balances, identity_balances); + // } +} \ No newline at end of file diff --git a/packages/rs-drive/src/drive/tokens/balance/queries.rs b/packages/rs-drive/src/drive/tokens/balance/queries.rs index fc32d25e6a8..b02b5bb52a2 100644 --- a/packages/rs-drive/src/drive/tokens/balance/queries.rs +++ b/packages/rs-drive/src/drive/tokens/balance/queries.rs @@ -26,7 +26,7 @@ impl Drive { path: balance_path, query: SizedQuery { query, - limit: None, + limit: Some(identity_ids.len() as u16), offset: None, }, } diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index f19f64aad80..6b4a9f0b572 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -27,7 +27,7 @@ pub(crate) fn tokens_root_path_vec() -> Vec> { #[cfg(any(feature = "server", feature = "verify"))] pub(crate) fn token_path(token_id: &[u8; 32]) -> [&[u8]; 2] { [ - Into::<&[u8; 1]>::into(RootTree::DataContractDocuments), + Into::<&[u8; 1]>::into(RootTree::Tokens), token_id, ] } @@ -42,7 +42,7 @@ pub(crate) fn token_path_vec(token_id: [u8; 32]) -> Vec> { #[cfg(any(feature = "server", feature = "verify"))] pub(crate) fn token_balances_path(token_id: &[u8; 32]) -> [&[u8]; 3] { [ - Into::<&[u8; 1]>::into(RootTree::DataContractDocuments), + Into::<&[u8; 1]>::into(RootTree::Tokens), token_id, &[TOKEN_BALANCES_KEY], ] @@ -62,7 +62,7 @@ pub(crate) fn token_balances_path_vec(token_id: [u8; 32]) -> Vec> { #[cfg(any(feature = "server", feature = "verify"))] pub(crate) fn token_identity_infos_path(token_id: &[u8; 32]) -> [&[u8]; 3] { [ - Into::<&[u8; 1]>::into(RootTree::DataContractDocuments), + Into::<&[u8; 1]>::into(RootTree::Tokens), token_id, &[TOKEN_IDENTITY_INFO_KEY], ] diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs similarity index 78% rename from packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs rename to packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs index 4833f51e092..4f2f6b1575e 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs @@ -14,9 +14,10 @@ use std::collections::HashMap; impl Drive { /// Adds a identity by inserting a new identity subtree structure to the `Identities` subtree. - pub fn create_token_root_tree( + pub fn create_token_trees( &self, token_id: [u8; 32], + allow_already_exists: bool, block_info: &BlockInfo, apply: bool, transaction: TransactionArg, @@ -27,17 +28,18 @@ impl Drive { .methods .token .update - .create_token_root_tree + .create_token_trees { - 0 => self.create_token_root_tree_v0( + 0 => self.create_token_trees_v0( token_id, + allow_already_exists, block_info, apply, transaction, platform_version, ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { - method: "create_token_root_tree".to_string(), + method: "create_token_trees".to_string(), known_versions: vec![0], received: version, })), @@ -45,9 +47,10 @@ impl Drive { } /// Adds identity creation operations to drive operations - pub fn create_token_root_tree_add_to_operations( + pub fn create_token_trees_add_to_operations( &self, token_id: [u8; 32], + allow_already_exists: bool, apply: bool, previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, @@ -59,10 +62,11 @@ impl Drive { .methods .token .update - .create_token_root_tree + .create_token_trees { - 0 => self.create_token_root_tree_add_to_operations_v0( + 0 => self.create_token_trees_add_to_operations_v0( token_id, + allow_already_exists, apply, previous_batch_operations, transaction, @@ -70,7 +74,7 @@ impl Drive { platform_version, ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { - method: "create_token_root_tree_add_to_operations".to_string(), + method: "create_token_trees_add_to_operations".to_string(), known_versions: vec![0], received: version, })), @@ -78,9 +82,10 @@ impl Drive { } /// The operations needed to create an identity - pub fn create_token_root_tree_operations( + pub fn create_token_trees_operations( &self, token_id: [u8; 32], + allow_already_exists: bool, previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, @@ -93,17 +98,18 @@ impl Drive { .methods .token .update - .create_token_root_tree + .create_token_trees { - 0 => self.create_token_root_tree_operations_v0( + 0 => self.create_token_trees_operations_v0( token_id, + allow_already_exists, previous_batch_operations, estimated_costs_only_with_layer_info, transaction, platform_version, ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { - method: "create_token_root_tree_operations".to_string(), + method: "create_token_trees_operations".to_string(), known_versions: vec![0], received: version, })), diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs similarity index 63% rename from packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs rename to packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs index 2be68ed7350..2a16720d3e0 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_root_tree/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs @@ -1,4 +1,4 @@ -use crate::drive::tokens::tokens_root_path; +use crate::drive::tokens::{TOKEN_BALANCES_KEY, token_path, tokens_root_path}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; @@ -11,13 +11,15 @@ use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::HashMap; +use crate::drive::balances::total_tokens_root_supply_path; impl Drive { /// Creates a new token root subtree at `TokenBalances` keyed by `token_id`. /// This function applies the operations directly, calculates fees, and returns the fee result. - pub(super) fn create_token_root_tree_v0( + pub(super) fn create_token_trees_v0( &self, token_id: [u8; 32], + allow_already_exists: bool, block_info: &BlockInfo, apply: bool, transaction: TransactionArg, @@ -26,8 +28,9 @@ impl Drive { let mut drive_operations: Vec = vec![]; // Add operations to create the token root tree - self.create_token_root_tree_add_to_operations_v0( + self.create_token_trees_add_to_operations_v0( token_id, + allow_already_exists, apply, &mut None, transaction, @@ -50,9 +53,10 @@ impl Drive { /// Adds the token root creation operations to the provided `drive_operations` vector without /// calculating or returning fees. If `apply` is false, it will only estimate costs. - pub(super) fn create_token_root_tree_add_to_operations_v0( + pub(super) fn create_token_trees_add_to_operations_v0( &self, token_id: [u8; 32], + allow_already_exists: bool, apply: bool, previous_batch_operations: &mut Option<&mut Vec>, transaction: TransactionArg, @@ -66,8 +70,9 @@ impl Drive { }; // Get the operations required to create the token tree - let batch_operations = self.create_token_root_tree_operations_v0( + let batch_operations = self.create_token_trees_operations_v0( token_id, + allow_already_exists, previous_batch_operations, &mut estimated_costs_only_with_layer_info, transaction, @@ -86,9 +91,10 @@ impl Drive { /// Gathers the operations needed to create the token root subtree. If `apply` is false, it /// populates `estimated_costs_only_with_layer_info` instead of applying. - pub(super) fn create_token_root_tree_operations_v0( + pub(super) fn create_token_trees_operations_v0( &self, token_id: [u8; 32], + allow_already_exists: bool, previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< HashMap, @@ -99,35 +105,81 @@ impl Drive { let mut batch_operations: Vec = vec![]; // Decide if we're doing a stateful or stateless insert for cost estimation - let apply_type = if estimated_costs_only_with_layer_info.is_none() { + let non_sum_tree_apply_type = if estimated_costs_only_with_layer_info.is_none() { + BatchInsertTreeApplyType::StatefulBatchInsertTree + } else { + BatchInsertTreeApplyType::StatelessBatchInsertTree { + in_tree_using_sums: false, + is_sum_tree: false, + flags_len: 0, + } + }; + + let token_balance_tree_apply_type = if estimated_costs_only_with_layer_info.is_none() { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { in_tree_using_sums: false, is_sum_tree: true, - flags_len: 0, // No additional storage flags here + flags_len: 0, } }; // Insert an empty tree for this token if it doesn't exist let inserted = self.batch_insert_empty_tree_if_not_exists( PathFixedSizeKey((tokens_root_path(), token_id.to_vec())), - true, + false, None, // No storage flags - apply_type, + non_sum_tree_apply_type, transaction, previous_batch_operations, &mut batch_operations, &platform_version.drive, )?; - if !inserted { + if !inserted && !allow_already_exists { // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. return Err(Error::Drive(DriveError::CorruptedDriveState( "token root tree already exists".to_string(), ))); } + let inserted = self.batch_insert_empty_tree_if_not_exists( + PathFixedSizeKey((token_path(&token_id), vec![TOKEN_BALANCES_KEY])), + true, + None, + token_balance_tree_apply_type, + transaction, + &mut None, + &mut batch_operations, + &platform_version.drive, + )?; + + if !inserted && !allow_already_exists { + // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. + return Err(Error::Drive(DriveError::CorruptedDriveState( + "token balance tree already exists".to_string(), + ))); + } + + let inserted = self.batch_insert_empty_tree_if_not_exists( + PathFixedSizeKey((total_tokens_root_supply_path(), token_id.to_vec())), + false, + None, + non_sum_tree_apply_type, + transaction, + &mut None, + &mut batch_operations, + &platform_version.drive, + )?; + + if !inserted && !allow_already_exists { + // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. + return Err(Error::Drive(DriveError::CorruptedDriveState( + "sum tree tree already exists".to_string(), + ))); + } + Ok(batch_operations) } } diff --git a/packages/rs-drive/src/drive/tokens/system/mod.rs b/packages/rs-drive/src/drive/tokens/system/mod.rs index 7f760fc3cf3..8d0f456d613 100644 --- a/packages/rs-drive/src/drive/tokens/system/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/mod.rs @@ -1,3 +1,3 @@ mod add_to_token_total_supply; -mod create_token_root_tree; +mod create_token_trees; mod remove_from_token_total_supply; diff --git a/packages/rs-drive/src/fees/op.rs b/packages/rs-drive/src/fees/op.rs index c28ea60caa2..ecd1c605311 100644 --- a/packages/rs-drive/src/fees/op.rs +++ b/packages/rs-drive/src/fees/op.rs @@ -398,6 +398,22 @@ impl LowLevelDriveOperation { LowLevelDriveOperation::insert_for_estimated_path_key_element(path, key, tree) } + /// Sets `GroveOperation` for inserting an empty sum tree at the given path and key + pub fn for_estimated_path_key_empty_sum_tree( + path: KeyInfoPath, + key: KeyInfo, + storage_flags: Option<&StorageFlags>, + ) -> Self { + let tree = match storage_flags { + Some(storage_flags) => { + Element::empty_sum_tree_with_flags(storage_flags.to_some_element_flags()) + } + None => Element::empty_sum_tree(), + }; + + LowLevelDriveOperation::insert_for_estimated_path_key_element(path, key, tree) + } + /// Sets `GroveOperation` for inserting an element at the given path and key pub fn insert_for_known_path_key_element( path: Vec>, diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/mod.rs new file mode 100644 index 00000000000..113e8f40f10 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/mod.rs @@ -0,0 +1,46 @@ +mod v0; + +use crate::util::object_size_info::DriveKeyInfo; +use crate::util::storage_flags::StorageFlags; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::version::drive_versions::DriveVersion; + +impl Drive { + /// Pushes an "insert empty tree" operation to `drive_operations`. + /// + /// # Parameters + /// * `path`: The path to insert an empty tree. + /// * `key_info`: The key information of the document. + /// * `storage_flags`: Storage options for the operation. + /// * `drive_operations`: The vector containing low-level drive operations. + /// * `drive_version`: The drive version to select the correct function version to run. + /// + /// # Returns + /// * `Ok(())` if the operation was successful. + /// * `Err(DriveError::UnknownVersionMismatch)` if the drive version does not match known versions. + pub fn batch_insert_empty_sum_tree<'a, 'c, P>( + &'a self, + path: P, + key_info: DriveKeyInfo<'c>, + storage_flags: Option<&StorageFlags>, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result<(), Error> + where + P: IntoIterator, +

::IntoIter: ExactSizeIterator + DoubleEndedIterator + Clone, + { + match drive_version.grove_methods.batch.batch_insert_empty_sum_tree { + 0 => self.batch_insert_empty_sum_tree_v0(path, key_info, storage_flags, drive_operations), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "batch_insert_empty_sum_tree".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs new file mode 100644 index 00000000000..7753b9f6729 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs @@ -0,0 +1,51 @@ +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::object_size_info::DriveKeyInfo; +use crate::util::object_size_info::DriveKeyInfo::{Key, KeyRef, KeySize}; +use crate::util::storage_flags::StorageFlags; +use grovedb::batch::KeyInfoPath; + +impl Drive { + /// Pushes an "insert empty tree" operation to `drive_operations`. + pub(crate) fn batch_insert_empty_sum_tree_v0<'a, 'c, P>( + &'a self, + path: P, + key_info: DriveKeyInfo<'c>, + storage_flags: Option<&StorageFlags>, + drive_operations: &mut Vec, + ) -> Result<(), Error> + where + P: IntoIterator, +

::IntoIter: ExactSizeIterator + DoubleEndedIterator + Clone, + { + match key_info { + KeyRef(key) => { + let path_items: Vec> = path.into_iter().map(Vec::from).collect(); + drive_operations.push(LowLevelDriveOperation::for_known_path_key_empty_sum_tree( + path_items, + key.to_vec(), + storage_flags, + )); + Ok(()) + } + KeySize(key) => { + drive_operations.push(LowLevelDriveOperation::for_estimated_path_key_empty_sum_tree( + KeyInfoPath::from_known_path(path), + key, + storage_flags, + )); + Ok(()) + } + Key(key) => { + let path_items: Vec> = path.into_iter().map(Vec::from).collect(); + drive_operations.push(LowLevelDriveOperation::for_known_path_key_empty_sum_tree( + path_items, + key, + storage_flags, + )); + Ok(()) + } + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/mod.rs b/packages/rs-drive/src/util/grove_operations/mod.rs index 41736ed442e..33f563a9304 100644 --- a/packages/rs-drive/src/util/grove_operations/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/mod.rs @@ -57,6 +57,9 @@ pub mod grove_has_raw; /// Batch insert operation into empty tree pub mod batch_insert_empty_tree; +/// Batch insert operation into empty sum tree +pub mod batch_insert_empty_sum_tree; + /// Batch insert operation into empty tree, but only if it doesn't already exist pub mod batch_insert_empty_tree_if_not_exists; diff --git a/packages/rs-drive/src/verify/mod.rs b/packages/rs-drive/src/verify/mod.rs index b4c627718e2..f0a4dc388ba 100644 --- a/packages/rs-drive/src/verify/mod.rs +++ b/packages/rs-drive/src/verify/mod.rs @@ -13,6 +13,7 @@ pub mod system; /// Verifies that a state transition contents exist in the proof pub mod state_transition; pub mod voting; +mod tokens; /// Represents the root hash of the grovedb tree pub type RootHash = [u8; 32]; diff --git a/packages/rs-drive/src/verify/tokens/mod.rs b/packages/rs-drive/src/verify/tokens/mod.rs new file mode 100644 index 00000000000..1a9a9421a46 --- /dev/null +++ b/packages/rs-drive/src/verify/tokens/mod.rs @@ -0,0 +1 @@ +mod verify_token_balances_for_identity_ids; \ No newline at end of file diff --git a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs new file mode 100644 index 00000000000..4303bf196a3 --- /dev/null +++ b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs @@ -0,0 +1,81 @@ +mod v0; + +use std::collections::BTreeMap; +use dpp::balances::credits::TokenAmount; +use crate::drive::Drive; + +use crate::error::drive::DriveError; + +use crate::error::Error; + +use crate::verify::RootHash; + +use dpp::version::PlatformVersion; + +impl Drive { + /// Verifies the token balances for a set of identity IDs. + /// + /// This function checks the token balances of multiple identities by verifying the provided + /// proof against the specified token ID and identity IDs. It also supports verifying a subset + /// of a larger proof if necessary. + /// + /// # Parameters + /// + /// - `proof`: A byte slice representing the proof of authentication from the user. This is used + /// to verify the validity of the identity and its associated balance. + /// - `token_id`: A 32-byte array representing the unique identifier for the token whose balance + /// is being verified. + /// - `identity_ids`: A slice of 32-byte arrays, each representing a unique identity ID. These + /// are the identities whose token balances are being verified. + /// - `verify_subset_of_proof`: A boolean flag indicating whether the proof being verified is a + /// subset of a larger proof. If `true`, the verification will consider only a part of the proof. + /// - `platform_version`: The version of the platform against which the identity token balances are + /// being verified. This ensures compatibility with the correct API version. + /// + /// # Returns + /// + /// - `Result<(RootHash, BTreeMap<[u8; 32], Option>), Error>`: If the verification is successful: + /// - `RootHash`: The root hash of the GroveDB, representing the state of the database. + /// - `BTreeMap<[u8; 32], Option>`: A map of identity IDs to their associated token balances. + /// The `Option` can be `Some(TokenAmount)` if a balance exists or `None` if no balance is found. + /// + /// # Errors + /// + /// The function will return an `Error` if any of the following occur: + /// + /// - The provided authentication proof is invalid. + /// - The provided identity ID does not correspond to a valid balance. + /// - The provided platform version is unknown or unsupported. + /// + pub fn verify_token_balances_for_identity_ids< + T: FromIterator<(I, Option)>, + I: From<[u8; 32]>, + >( + proof: &[u8], + token_id: [u8;32], + identity_ids: &[[u8; 32]], + verify_subset_of_proof: bool, + platform_version: &PlatformVersion, + ) -> Result<(RootHash, T), Error> { + match platform_version + .drive + .methods + .verify + .token + .verify_token_balances_for_identity_ids + { + 0 => Self::verify_token_balances_for_identity_ids_v0( + proof, + token_id, + identity_ids, + verify_subset_of_proof, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "verify_token_balances_for_identity_ids".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs new file mode 100644 index 00000000000..c6e152e6413 --- /dev/null +++ b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs @@ -0,0 +1,72 @@ +use crate::drive::Drive; + +use crate::error::proof::ProofError; +use crate::error::Error; + +use crate::verify::RootHash; + +use grovedb::GroveDb; +use dpp::balances::credits::TokenAmount; +use dpp::fee::Credits; +use platform_version::version::PlatformVersion; + +impl Drive { + pub(super) fn verify_token_balances_for_identity_ids_v0< + T: FromIterator<(I, Option)>, + I: From<[u8; 32]>, + >( + proof: &[u8], + token_id: [u8;32], + identity_ids: &[[u8; 32]], + verify_subset_of_proof: bool, + platform_version: &PlatformVersion, + ) -> Result<(RootHash, T), Error> { + let path_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids); + let (root_hash, mut proved_key_values) = if verify_subset_of_proof { + GroveDb::verify_subset_query_with_absence_proof( + proof, + &path_query, + &platform_version.drive.grove_version, + )? + } else { + GroveDb::verify_query_with_absence_proof( + proof, + &path_query, + &platform_version.drive.grove_version, + )? + }; + if proved_key_values.len() == identity_ids.len() { + let values = proved_key_values + .into_iter() + .map(|proved_key_value| { + let key: [u8; 32] = proved_key_value + .1 + .try_into() + .map_err(|_| Error::Proof(ProofError::IncorrectValueSize("value size")))?; + let maybe_element = proved_key_value.2; + match maybe_element { + None => Ok((key.into(), None)), + Some(element) => { + let balance: Credits = element + .as_sum_item_value() + .map_err(Error::GroveDB)? + .try_into() + .map_err(|_| { + Error::Proof(ProofError::IncorrectValueSize( + "balance was negative", + )) + })?; + Ok((key.into(), Some(balance))) + } + } + }) + .collect::>()?; + Ok((root_hash, values)) + } else { + Err(Error::Proof(ProofError::WrongElementCount { + expected: identity_ids.len(), + got: proved_key_values.len(), + })) + } + } +} diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/mod.rs index 18cf2d3a4f6..a216992f698 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/mod.rs @@ -1,6 +1,7 @@ use versioned_feature_core::FeatureVersion; pub mod v1; +pub mod v2; #[derive(Clone, Debug, Default)] pub struct DriveContractMethodVersions { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs b/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs new file mode 100644 index 00000000000..5197624ade2 --- /dev/null +++ b/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs @@ -0,0 +1,33 @@ +use crate::version::drive_versions::drive_contract_method_versions::{ + DriveContractApplyMethodVersions, DriveContractCostsMethodVersions, + DriveContractGetMethodVersions, DriveContractInsertMethodVersions, DriveContractMethodVersions, + DriveContractProveMethodVersions, DriveContractUpdateMethodVersions, +}; + +pub const DRIVE_CONTRACT_METHOD_VERSIONS_V2: DriveContractMethodVersions = + DriveContractMethodVersions { + prove: DriveContractProveMethodVersions { + prove_contract: 0, + prove_contract_history: 0, + prove_contracts: 0, + }, + apply: DriveContractApplyMethodVersions { + apply_contract: 0, + apply_contract_with_serialization: 0, + }, + insert: DriveContractInsertMethodVersions { + add_contract_to_storage: 0, + insert_contract: 1, // <--- changed to v1 (for token insertion + }, + update: DriveContractUpdateMethodVersions { update_contract: 1 }, // <--- changed to v1 (for token insertion) + costs: DriveContractCostsMethodVersions { + add_estimation_costs_for_contract_insertion: 0, + }, + get: DriveContractGetMethodVersions { + fetch_contract: 0, + fetch_contract_with_history: 0, + get_cached_contract_with_fetch_info: 0, + get_contract_with_fetch_info: 0, + get_contracts_with_fetch_info: 0, + }, + }; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs index c61b52f2504..5118c9093c4 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs @@ -51,6 +51,7 @@ pub struct DriveGroveBatchMethodVersions { pub batch_remove_raw: FeatureVersion, pub batch_delete_up_tree_while_empty: FeatureVersion, pub batch_refresh_reference: FeatureVersion, + pub batch_insert_empty_sum_tree: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs index 6dc9b44503c..900a65673dd 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs @@ -42,6 +42,7 @@ pub const DRIVE_GROVE_METHOD_VERSIONS_V1: DriveGroveMethodVersions = DriveGroveM batch_remove_raw: 0, batch_delete_up_tree_while_empty: 0, batch_refresh_reference: 0, + batch_insert_empty_sum_tree: 0, }, apply: DriveGroveApplyMethodVersions { grove_apply_operation: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 66817c52fcd..8f47a00183c 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -23,7 +23,7 @@ pub struct DriveTokenProveMethodVersions { #[derive(Clone, Debug, Default)] pub struct DriveTokenUpdateMethodVersions { - pub create_token_root_tree: FeatureVersion, + pub create_token_trees: FeatureVersion, pub burn: FeatureVersion, pub mint: FeatureVersion, pub transfer: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index 43c1311c620..f021ede2b3b 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -13,7 +13,7 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM identity_token_balances: 0, }, update: DriveTokenUpdateMethodVersions { - create_token_root_tree: 0, + create_token_trees: 0, burn: 0, mint: 0, transfer: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs index 39d42551360..f42756e4d5e 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs @@ -7,6 +7,7 @@ pub struct DriveVerifyMethodVersions { pub contract: DriveVerifyContractMethodVersions, pub document: DriveVerifyDocumentMethodVersions, pub identity: DriveVerifyIdentityMethodVersions, + pub token: DriveVerifyTokenMethodVersions, pub single_document: DriveVerifySingleDocumentMethodVersions, pub system: DriveVerifySystemMethodVersions, pub voting: DriveVerifyVoteMethodVersions, @@ -42,6 +43,12 @@ pub struct DriveVerifyIdentityMethodVersions { pub verify_identity_revision_for_identity_id: FeatureVersion, } +#[derive(Clone, Debug, Default)] +pub struct DriveVerifyTokenMethodVersions { + pub verify_token_balances_for_identity_ids: FeatureVersion, + pub verify_token_balances_for_identity_id: FeatureVersion, +} + #[derive(Clone, Debug, Default)] pub struct DriveVerifyVoteMethodVersions { pub verify_masternode_vote: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs index 4c40371f83d..9604882fe69 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs @@ -1,9 +1,4 @@ -use crate::version::drive_versions::drive_verify_method_versions::{ - DriveVerifyContractMethodVersions, DriveVerifyDocumentMethodVersions, - DriveVerifyIdentityMethodVersions, DriveVerifyMethodVersions, - DriveVerifySingleDocumentMethodVersions, DriveVerifyStateTransitionMethodVersions, - DriveVerifySystemMethodVersions, DriveVerifyVoteMethodVersions, -}; +use crate::version::drive_versions::drive_verify_method_versions::{DriveVerifyContractMethodVersions, DriveVerifyDocumentMethodVersions, DriveVerifyIdentityMethodVersions, DriveVerifyMethodVersions, DriveVerifySingleDocumentMethodVersions, DriveVerifyStateTransitionMethodVersions, DriveVerifySystemMethodVersions, DriveVerifyTokenMethodVersions, DriveVerifyVoteMethodVersions}; pub const DRIVE_VERIFY_METHOD_VERSIONS_V1: DriveVerifyMethodVersions = DriveVerifyMethodVersions { contract: DriveVerifyContractMethodVersions { @@ -29,6 +24,10 @@ pub const DRIVE_VERIFY_METHOD_VERSIONS_V1: DriveVerifyMethodVersions = DriveVeri verify_identities_contract_keys: 0, verify_identity_revision_for_identity_id: 0, }, + token: DriveVerifyTokenMethodVersions { + verify_token_balances_for_identity_ids: 0, + verify_token_balances_for_identity_id: 0, + }, single_document: DriveVerifySingleDocumentMethodVersions { verify_proof: 0, verify_proof_keep_serialized: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/mod.rs index 2cadffa64f5..a1e68142678 100644 --- a/packages/rs-platform-version/src/version/drive_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/mod.rs @@ -23,6 +23,7 @@ pub mod drive_verify_method_versions; pub mod drive_vote_method_versions; pub mod v1; pub mod v2; +pub mod v3; #[derive(Clone, Debug, Default)] pub struct DriveVersion { diff --git a/packages/rs-platform-version/src/version/drive_versions/v3.rs b/packages/rs-platform-version/src/version/drive_versions/v3.rs new file mode 100644 index 00000000000..30d67ebfd7d --- /dev/null +++ b/packages/rs-platform-version/src/version/drive_versions/v3.rs @@ -0,0 +1,102 @@ +use crate::version::drive_versions::drive_contract_method_versions::v2::DRIVE_CONTRACT_METHOD_VERSIONS_V2; +use crate::version::drive_versions::drive_credit_pool_method_versions::v1::CREDIT_POOL_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_document_method_versions::v1::DRIVE_DOCUMENT_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_grove_method_versions::v1::DRIVE_GROVE_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_identity_method_versions::v1::DRIVE_IDENTITY_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_state_transition_method_versions::v1::DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_structure_version::v1::DRIVE_STRUCTURE_V1; +use crate::version::drive_versions::drive_token_method_versions::v1::DRIVE_TOKEN_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_verify_method_versions::v1::DRIVE_VERIFY_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_vote_method_versions::v2::DRIVE_VOTE_METHOD_VERSIONS_V2; +use crate::version::drive_versions::{ + DriveAssetLockMethodVersions, DriveBalancesMethodVersions, DriveBatchOperationsMethodVersion, + DriveEstimatedCostsMethodVersions, DriveFeesMethodVersions, DriveFetchMethodVersions, + DriveInitializationMethodVersions, DriveMethodVersions, DriveOperationsMethodVersion, + DrivePlatformStateMethodVersions, DrivePlatformSystemMethodVersions, + DrivePrefundedSpecializedMethodVersions, DriveProtocolUpgradeVersions, + DriveProveMethodVersions, DriveSystemEstimationCostsMethodVersions, DriveVersion, +}; +use grovedb_version::version::v1::GROVE_V1; + +pub const DRIVE_VERSION_V3: DriveVersion = DriveVersion { + structure: DRIVE_STRUCTURE_V1, + methods: DriveMethodVersions { + initialization: DriveInitializationMethodVersions { + create_initial_state_structure: 1, // changed here to 1 to add token sum trees + }, + credit_pools: CREDIT_POOL_METHOD_VERSIONS_V1, + protocol_upgrade: DriveProtocolUpgradeVersions { + clear_version_information: 0, + fetch_versions_with_counter: 0, + fetch_proved_versions_with_counter: 0, + fetch_validator_version_votes: 0, + fetch_proved_validator_version_votes: 0, + remove_validators_proposed_app_versions: 0, + update_validator_proposed_app_version: 0, + }, + prove: DriveProveMethodVersions { + prove_elements: 0, + prove_multiple_state_transition_results: 0, + }, + balances: DriveBalancesMethodVersions { + add_to_system_credits: 0, + add_to_system_credits_operations: 0, + remove_from_system_credits: 0, + remove_from_system_credits_operations: 0, + calculate_total_credits_balance: 0, + }, + document: DRIVE_DOCUMENT_METHOD_VERSIONS_V1, + vote: DRIVE_VOTE_METHOD_VERSIONS_V2, + contract: DRIVE_CONTRACT_METHOD_VERSIONS_V2, // changed here to v2 + fees: DriveFeesMethodVersions { calculate_fee: 0 }, + estimated_costs: DriveEstimatedCostsMethodVersions { + add_estimation_costs_for_levels_up_to_contract: 0, + add_estimation_costs_for_levels_up_to_contract_document_type_excluded: 0, + add_estimation_costs_for_contested_document_tree_levels_up_to_contract: 0, + add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded: 0, + }, + asset_lock: DriveAssetLockMethodVersions { + add_asset_lock_outpoint: 0, + add_estimation_costs_for_adding_asset_lock: 0, + fetch_asset_lock_outpoint_info: 0, + }, + verify: DRIVE_VERIFY_METHOD_VERSIONS_V1, + identity: DRIVE_IDENTITY_METHOD_VERSIONS_V1, + token: DRIVE_TOKEN_METHOD_VERSIONS_V1, + platform_system: DrivePlatformSystemMethodVersions { + estimation_costs: DriveSystemEstimationCostsMethodVersions { + for_total_system_credits_update: 0, + }, + }, + operations: DriveOperationsMethodVersion { + rollback_transaction: 0, + drop_cache: 0, + commit_transaction: 0, + apply_partial_batch_low_level_drive_operations: 0, + apply_partial_batch_grovedb_operations: 0, + apply_batch_low_level_drive_operations: 0, + apply_batch_grovedb_operations: 0, + }, + state_transitions: DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1, + batch_operations: DriveBatchOperationsMethodVersion { + convert_drive_operations_to_grove_operations: 0, + apply_drive_operations: 0, + }, + platform_state: DrivePlatformStateMethodVersions { + fetch_platform_state_bytes: 0, + store_platform_state_bytes: 0, + }, + fetch: DriveFetchMethodVersions { fetch_elements: 0 }, + prefunded_specialized_balances: DrivePrefundedSpecializedMethodVersions { + fetch_single: 0, + prove_single: 0, + add_prefunded_specialized_balance: 0, + add_prefunded_specialized_balance_operations: 0, + deduct_from_prefunded_specialized_balance: 0, + deduct_from_prefunded_specialized_balance_operations: 0, + estimated_cost_for_prefunded_specialized_balance_update: 0, + }, + }, + grove_methods: DRIVE_GROVE_METHOD_VERSIONS_V1, + grove_version: GROVE_V1, +}; diff --git a/packages/rs-platform-version/src/version/mod.rs b/packages/rs-platform-version/src/version/mod.rs index 49d59ca80c4..f060faae78c 100644 --- a/packages/rs-platform-version/src/version/mod.rs +++ b/packages/rs-platform-version/src/version/mod.rs @@ -1,6 +1,6 @@ mod protocol_version; -use crate::version::v7::PROTOCOL_VERSION_7; pub use protocol_version::*; +use crate::version::v8::PROTOCOL_VERSION_8; mod consensus_versions; pub mod dpp_versions; @@ -23,5 +23,5 @@ mod v8; pub type ProtocolVersion = u32; -pub const LATEST_VERSION: ProtocolVersion = PROTOCOL_VERSION_7; +pub const LATEST_VERSION: ProtocolVersion = PROTOCOL_VERSION_8; pub const INITIAL_PROTOCOL_VERSION: ProtocolVersion = 1; diff --git a/packages/rs-platform-version/src/version/protocol_version.rs b/packages/rs-platform-version/src/version/protocol_version.rs index d14f75c8bcf..520ceef97ad 100644 --- a/packages/rs-platform-version/src/version/protocol_version.rs +++ b/packages/rs-platform-version/src/version/protocol_version.rs @@ -46,6 +46,7 @@ pub const PLATFORM_VERSIONS: &[PlatformVersion] = &[ PLATFORM_V5, PLATFORM_V6, PLATFORM_V7, + PLATFORM_V8, ]; #[cfg(feature = "mock-versions")] diff --git a/packages/rs-platform-version/src/version/v8.rs b/packages/rs-platform-version/src/version/v8.rs index 2cd6f0772e2..3eb5de2b5dc 100644 --- a/packages/rs-platform-version/src/version/v8.rs +++ b/packages/rs-platform-version/src/version/v8.rs @@ -19,7 +19,7 @@ use crate::version::drive_abci_versions::drive_abci_structure_versions::v1::DRIV use crate::version::drive_abci_versions::drive_abci_validation_versions::v4::DRIVE_ABCI_VALIDATION_VERSIONS_V4; use crate::version::drive_abci_versions::drive_abci_withdrawal_constants::v2::DRIVE_ABCI_WITHDRAWAL_CONSTANTS_V2; use crate::version::drive_abci_versions::DriveAbciVersion; -use crate::version::drive_versions::v2::DRIVE_VERSION_V2; +use crate::version::drive_versions::v3::DRIVE_VERSION_V3; use crate::version::fee::v1::FEE_VERSION1; use crate::version::protocol_version::PlatformVersion; use crate::version::system_data_contract_versions::v1::SYSTEM_DATA_CONTRACT_VERSIONS_V1; @@ -32,7 +32,7 @@ pub const PROTOCOL_VERSION_8: ProtocolVersion = 8; //todo: make changes pub const PLATFORM_V8: PlatformVersion = PlatformVersion { protocol_version: PROTOCOL_VERSION_8, - drive: DRIVE_VERSION_V2, + drive: DRIVE_VERSION_V3, // changed (for data contract insert) drive_abci: DriveAbciVersion { structs: DRIVE_ABCI_STRUCTURE_VERSIONS_V1, methods: DRIVE_ABCI_METHOD_VERSIONS_V4, diff --git a/packages/token-history-contract/Cargo.toml b/packages/token-history-contract/Cargo.toml index b5ea373f76f..3625f97a47e 100644 --- a/packages/token-history-contract/Cargo.toml +++ b/packages/token-history-contract/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "wallet-utils-contract" -description = "Wallet data contract schema and tools" +name = "token-history-contract" +description = "Token history data contract schema and tools" version = "1.6.2" edition = "2021" rust-version.workspace = true diff --git a/packages/wasm-dpp/src/document/document_facade.rs b/packages/wasm-dpp/src/document/document_facade.rs index 609794eaa99..6255dfe2df9 100644 --- a/packages/wasm-dpp/src/document/document_facade.rs +++ b/packages/wasm-dpp/src/document/document_facade.rs @@ -4,7 +4,7 @@ use wasm_bindgen::{prelude::*, JsValue}; use crate::document::factory::DocumentFactoryWASM; use crate::{DataContractWasm, ExtendedDocumentWasm}; -use crate::document::state_transition::document_batch_transition::DocumentsBatchTransitionWasm; +use crate::document::state_transition::batch_transition::BatchTransitionWasm; #[derive(Clone)] #[wasm_bindgen(js_name=DocumentFacade)] @@ -96,7 +96,7 @@ impl DocumentFacadeWasm { &self, documents: &JsValue, nonce_counter_value: &js_sys::Object, //IdentityID/ContractID -> nonce - ) -> Result { + ) -> Result { self.factory .create_state_transition(documents, nonce_counter_value) } diff --git a/packages/wasm-dpp/src/document/factory.rs b/packages/wasm-dpp/src/document/factory.rs index 769b47c7ce5..639aaa2324a 100644 --- a/packages/wasm-dpp/src/document/factory.rs +++ b/packages/wasm-dpp/src/document/factory.rs @@ -18,7 +18,7 @@ use dpp::state_transition::batch_transition::batched_transition::document_transi use dpp::version::PlatformVersion; use std::convert::TryFrom; -use crate::document_batch_transition::DocumentsBatchTransitionWasm; +use crate::batch_transition::BatchTransitionWasm; use crate::entropy_generator::ExternalEntropyGenerator; use crate::{ identifier::identifier_from_js_value, @@ -109,7 +109,7 @@ impl DocumentFactoryWASM { &self, documents: &JsValue, nonce_counter_value: &js_sys::Object, //IdentityID/ContractID -> nonce - ) -> Result { + ) -> Result { let mut nonce_counter = BTreeMap::new(); let mut contract_ids_to_check = HashSet::<&Identifier>::new(); diff --git a/packages/wasm-dpp/src/document/state_transition/batch_transition/batched_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/batched_transition/mod.rs new file mode 100644 index 00000000000..c7c58b54719 --- /dev/null +++ b/packages/wasm-dpp/src/document/state_transition/batch_transition/batched_transition/mod.rs @@ -0,0 +1,18 @@ +use wasm_bindgen::prelude::wasm_bindgen; +use dpp::state_transition::batch_transition::batched_transition::BatchedTransition; + +#[wasm_bindgen(js_name=BatchedTransition)] +#[derive(Debug, Clone)] +pub struct BatchedTransitionWasm(BatchedTransition); + +impl From for BatchedTransitionWasm { + fn from(t: BatchedTransition) -> Self { + BatchedTransitionWasm(t) + } +} + +impl From for BatchedTransition { + fn from(t: BatchedTransitionWasm) -> Self { + t.0 + } +} diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/document_create_transition.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_create_transition.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/document_create_transition.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/document_delete_transition.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_delete_transition.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/document_delete_transition.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/document_replace_transition.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/document_replace_transition.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/document_replace_transition.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/mod.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/document_transition/mod.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/mod.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs similarity index 97% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs index 402c5aa61cc..f0fc312bcbc 100644 --- a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs @@ -32,8 +32,11 @@ use dpp::state_transition::batch_transition::batched_transition::BatchedTransiti use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; use dpp::state_transition::StateTransitionIdentitySigned; +use crate::batch_transition::batched_transition::BatchedTransitionWasm; pub mod document_transition; +mod token_transition; +mod batched_transition; // pub mod validation; #[derive(Clone, Debug)] @@ -103,10 +106,9 @@ impl BatchTransitionWasm { #[wasm_bindgen(js_name=getTransitions)] pub fn get_transitions(&self) -> js_sys::Array { let array = js_sys::Array::new(); - let transitions = self.0.document_transitions(); - for tr in transitions.iter().cloned() { - let transition: BatchTransitionWasm = tr.into(); + for tr in self.0.transitions_iter() { + let transition: BatchedTransitionWasm = tr.to_owned_transition().into(); array.push(&transition.into()); } @@ -118,7 +120,7 @@ impl BatchTransitionWasm { let mut transitions = vec![]; for js_transition in js_transitions.iter() { let transition: BatchedTransition = js_transition - .to_wasm::("BatchedTransition")? + .to_wasm::("BatchedTransition")? .to_owned() .into(); transitions.push(transition) diff --git a/packages/wasm-dpp/src/document/state_transition/batch_transition/token_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/token_transition/mod.rs new file mode 100644 index 00000000000..67b4b4bd885 --- /dev/null +++ b/packages/wasm-dpp/src/document/state_transition/batch_transition/token_transition/mod.rs @@ -0,0 +1,18 @@ +use wasm_bindgen::prelude::wasm_bindgen; +use dpp::state_transition::batch_transition::batched_transition::token_transition::TokenTransition; + +#[wasm_bindgen(js_name=TokenTransition)] +#[derive(Debug, Clone)] +pub struct TokenTransitionWasm(TokenTransition); + +impl From for TokenTransitionWasm { + fn from(t: TokenTransition) -> Self { + TokenTransitionWasm(t) + } +} + +impl From for TokenTransition { + fn from(t: TokenTransitionWasm) -> Self { + t.0 + } +} diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/find_duplicates_by_id.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_id.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/find_duplicates_by_id.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/find_duplicates_by_indices.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/find_duplicates_by_indices.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/find_duplicates_by_indices.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/mod.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/mod.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/mod.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/validate_documents_batch_transition_basic.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_documents_batch_transition_basic.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/validate_documents_batch_transition_basic.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/validate_partial_compound_indices.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/basic/validate_partial_compound_indices.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/basic/validate_partial_compound_indices.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/mod.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/mod.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/mod.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/state/fetch_extended_documents.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/fetch_extended_documents.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/state/fetch_extended_documents.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/state/mod.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/mod.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/state/mod.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/validate_documents_batch_transitions_state.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/state/validate_documents_batch_transitions_state.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/validate_documents_batch_transitions_state.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/state/validate_documents_batch_transitions_state.rs diff --git a/packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs similarity index 100% rename from packages/wasm-dpp/src/document/state_transition/document_batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs rename to packages/wasm-dpp/src/document/state_transition/batch_transition/validation/state/validate_documents_uniqueness_by_indices.rs diff --git a/packages/wasm-dpp/src/document/state_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/mod.rs index 7db6d118e0a..03238bee69e 100644 --- a/packages/wasm-dpp/src/document/state_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/mod.rs @@ -1 +1 @@ -pub mod document_batch_transition; +pub mod batch_transition; diff --git a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs index 627b65a2674..85bbbc4e6b2 100644 --- a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs @@ -61,7 +61,7 @@ use dpp::consensus::state::data_trigger::DataTriggerError::{ DataTriggerConditionError, DataTriggerExecutionError, DataTriggerInvalidResultError, }; use wasm_bindgen::{JsError, JsValue}; -use dpp::consensus::basic::data_contract::{ContestedUniqueIndexOnMutableDocumentTypeError, ContestedUniqueIndexWithUniqueIndexError, InvalidDocumentTypeRequiredSecurityLevelError, UnknownDocumentCreationRestrictionModeError, UnknownSecurityLevelError, UnknownStorageKeyRequirementsError, UnknownTradeModeError, UnknownTransferableTypeError}; +use dpp::consensus::basic::data_contract::{ContestedUniqueIndexOnMutableDocumentTypeError, ContestedUniqueIndexWithUniqueIndexError, DataContractTokenConfigurationUpdateError, InvalidDocumentTypeRequiredSecurityLevelError, UnknownDocumentCreationRestrictionModeError, UnknownSecurityLevelError, UnknownStorageKeyRequirementsError, UnknownTradeModeError, UnknownTransferableTypeError}; use dpp::consensus::basic::document::{ContestedDocumentsTemporarilyNotAllowedError, DocumentCreationNotAllowedError, DocumentFieldMaxSizeExceededError, MaxDocumentsTransitionsExceededError, MissingPositionsInDocumentTypePropertiesError}; use dpp::consensus::basic::identity::{DataContractBoundsNotPresentError, DisablingKeyIdAlsoBeingAddedInSameTransitionError, InvalidIdentityCreditWithdrawalTransitionAmountError, InvalidIdentityUpdateTransitionDisableKeysError, InvalidIdentityUpdateTransitionEmptyError, TooManyMasterPublicKeyError, WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError}; use dpp::consensus::basic::overflow_error::OverflowError; @@ -571,6 +571,13 @@ fn from_basic_error(basic_error: &BasicError) -> JsValue { ) .into() } + BasicError::DataContractTokenConfigurationUpdateError(e) => { + generic_consensus_error!( + DataContractTokenConfigurationUpdateError, + e + ) + .into() + } } } diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index f0ba5cde672..d57903a8dcb 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -1,5 +1,5 @@ use crate::data_contract::{DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm}; -use crate::document_batch_transition::DocumentsBatchTransitionWasm; +use crate::batch_transition::BatchTransitionWasm; use crate::errors::from_dpp_err; use crate::identity::state_transition::{ IdentityCreateTransitionWasm, IdentityCreditTransferTransitionWasm, @@ -56,7 +56,7 @@ impl StateTransitionFactoryWasm { StateTransition::IdentityCreditWithdrawal(st) => { Ok(IdentityCreditWithdrawalTransitionWasm::from(st).into()) } - StateTransition::Batch(st) => Ok(DocumentsBatchTransitionWasm::from(st).into()), + StateTransition::Batch(st) => Ok(BatchTransitionWasm::from(st).into()), StateTransition::MasternodeVote(st) => { Ok(MasternodeVoteTransitionWasm::from(st).into()) } From e23bcdafc6e82bfc3d1ae12b48c62ff34a7c9bcf Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 28 Dec 2024 19:00:51 +0700 Subject: [PATCH 25/61] a lot more work --- packages/data-contracts/src/error.rs | 1 - packages/data-contracts/src/lib.rs | 2 +- .../src/data_contract/accessors/v1/mod.rs | 4 +- .../token_configuration/accessors/mod.rs | 7 + .../token_configuration/accessors/v0/mod.rs | 3 + .../token_configuration/v0/accessors.rs | 5 + .../token_configuration/v0/mod.rs | 28 ++- .../src/data_contract/v1/accessors/mod.rs | 2 +- .../src/document/generate_document_id.rs | 1 + packages/rs-dpp/src/lib.rs | 9 + .../token_burn_transition/v0/mod.rs | 11 +- .../token_burn_transition/v0/v0_methods.rs | 21 ++ .../token_burn_transition/v0_methods.rs | 18 ++ .../token_issuance_transition/v0/mod.rs | 11 +- .../v0/v0_methods.rs | 35 +++ .../token_issuance_transition/v0_methods.rs | 31 +++ .../token_transfer_transition/v0/mod.rs | 30 ++- .../v0/v0_methods.rs | 149 +++++++++++- .../token_transfer_transition/v0_methods.rs | 99 ++++++++ .../batch_transition/value_conversion.rs | 4 +- packages/rs-dpp/src/tokens/mod.rs | 1 + packages/rs-dpp/src/tokens/token_event.rs | 26 +++ .../v0/mod.rs | 3 +- .../rs-drive/src/cache/system_contracts.rs | 11 + .../contract/insert/insert_contract/v1/mod.rs | 32 ++- .../contract/update/update_contract/v1/mod.rs | 35 ++- .../src/drive/initialization/v0/mod.rs | 5 +- .../src/drive/initialization/v1/mod.rs | 13 +- .../tokens/add_transaction_history/mod.rs | 1 - .../tokens/add_transaction_history/v0/mod.rs | 1 - .../add_transaction_history_operations/mod.rs | 56 +++++ .../v0/mod.rs | 213 ++++++++++++++++++ .../prove_identities_token_balances/v0/mod.rs | 192 ++++++++++------ packages/rs-drive/src/drive/tokens/mod.rs | 7 +- .../system/create_token_trees/v0/mod.rs | 4 +- .../document/token_burn_transition.rs | 12 + .../document/token_issuance_transition.rs | 14 +- .../document/token_transfer_transition.rs | 35 ++- .../document_transition/mod.rs | 3 +- .../token_burn_transition_action/mod.rs | 64 ++---- .../token_burn_transition_action/v0/mod.rs | 60 ++++- .../v0/transformer.rs | 14 +- .../token_mint_transition_action/mod.rs | 26 ++- .../token_mint_transition_action/v0/mod.rs | 37 ++- .../v0/transformer.rs | 8 +- .../token_transfer_transition_action/mod.rs | 130 +++++++---- .../v0/mod.rs | 162 ++++++++++++- .../v0/transformer.rs | 12 + .../src/util/batch/drive_op_batch/token.rs | 33 ++- .../batch_insert_empty_sum_tree/mod.rs | 10 +- .../batch_insert_empty_sum_tree/v0/mod.rs | 12 +- packages/rs-drive/src/verify/mod.rs | 2 +- packages/rs-drive/src/verify/tokens/mod.rs | 2 +- .../mod.rs | 10 +- .../v0/mod.rs | 4 +- .../drive_token_method_versions/mod.rs | 1 + .../drive_token_method_versions/v1.rs | 1 + .../drive_verify_method_versions/v1.rs | 7 +- .../rs-platform-version/src/version/mod.rs | 2 +- .../v1/token-history-contract-documents.json | 48 +++- .../batched_transition/mod.rs | 2 +- .../state_transition/batch_transition/mod.rs | 4 +- .../batch_transition/token_transition/mod.rs | 2 +- .../src/errors/consensus/consensus_error.rs | 6 +- .../state_transition_factory.rs | 2 +- 65 files changed, 1526 insertions(+), 270 deletions(-) create mode 100644 packages/rs-dpp/src/tokens/token_event.rs delete mode 100644 packages/rs-drive/src/drive/tokens/add_transaction_history/mod.rs delete mode 100644 packages/rs-drive/src/drive/tokens/add_transaction_history/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/add_transaction_history_operations/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs diff --git a/packages/data-contracts/src/error.rs b/packages/data-contracts/src/error.rs index d2f33d32250..7c0c802b71e 100644 --- a/packages/data-contracts/src/error.rs +++ b/packages/data-contracts/src/error.rs @@ -136,4 +136,3 @@ impl From for Error { } } } - diff --git a/packages/data-contracts/src/lib.rs b/packages/data-contracts/src/lib.rs index cf82480300f..a78ffefc373 100644 --- a/packages/data-contracts/src/lib.rs +++ b/packages/data-contracts/src/lib.rs @@ -9,9 +9,9 @@ pub use feature_flags_contract; pub use masternode_reward_shares_contract; use platform_value::Identifier; use platform_version::version::PlatformVersion; +pub use token_history_contract; pub use wallet_utils_contract; pub use withdrawals_contract; -pub use token_history_contract; #[repr(u8)] #[derive(PartialEq, Eq, Clone, Copy, Debug, Ord, PartialOrd, Hash)] diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs index 57a3212cef2..78a0df7a9b7 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -2,8 +2,8 @@ use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0S use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::group::{Group, GroupName}; use crate::data_contract::TokenContractPosition; -use std::collections::BTreeMap; use platform_value::Identifier; +use std::collections::BTreeMap; pub trait DataContractV1Getters: DataContractV0Getters { /// Returns a reference to the groups map. @@ -17,7 +17,7 @@ pub trait DataContractV1Getters: DataContractV0Getters { /// Returns a mutable reference to the tokens map. fn tokens_mut(&mut self) -> Option<&mut BTreeMap>; - + /// Returns the token id at a certain position fn token_id(&self, position: TokenContractPosition) -> Option; } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs index 8c51014c0a6..580288845c6 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs @@ -34,6 +34,13 @@ impl TokenConfigurationV0Getters for TokenConfiguration { } } + /// Returns if we keep history. + fn keeps_history(&self) -> bool { + match self { + TokenConfiguration::V0(v0) => v0.keeps_history(), + } + } + /// Returns the maximum supply. fn max_supply(&self) -> Option { match self { diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs index 866a400658b..a08b4590185 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -1,4 +1,5 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationConventionV0; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::group::RequiredSigners; @@ -15,6 +16,8 @@ pub trait TokenConfigurationV0Getters { /// Returns the base supply. fn base_supply(&self) -> u64; + /// Returns the base supply. + fn keeps_history(&self) -> bool; /// Returns the maximum supply. fn max_supply(&self) -> Option; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs index 538297c5782..c93436316f2 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs @@ -27,6 +27,11 @@ impl TokenConfigurationV0Getters for TokenConfigurationV0 { self.base_supply } + /// Returns if we keep history. + fn keeps_history(&self) -> bool { + self.keeps_history + } + /// Returns the maximum supply. fn max_supply(&self) -> Option { self.max_supply diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index af7b3052212..d6f32abdf25 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -1,6 +1,7 @@ mod accessors; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; +use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::group::RequiredSigners; use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; @@ -8,7 +9,6 @@ use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet}; use std::fmt; -use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] @@ -33,6 +33,8 @@ pub struct TokenConfigurationV0 { pub base_supply: u64, /// The maximum supply the token can ever have pub max_supply: Option, + /// Do we keep history, default is true. + pub keeps_history: bool, /// Who can change the max supply /// Even if set no one can ever change this under the base supply pub max_supply_change_rules: ChangeControlRules, @@ -71,46 +73,56 @@ impl fmt::Display for TokenConfigurationV0 { impl TokenConfigurationV0 { pub fn default_most_restrictive() -> Self { Self { - conventions: TokenConfigurationConventionV0 { localizations: Default::default(), decimals: 8 }, + conventions: TokenConfigurationConventionV0 { + localizations: Default::default(), + decimals: 8, + }, base_supply: 100000, max_supply: None, + keeps_history: true, max_supply_change_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, changing_authorized_action_takers_to_no_one_allowed: false, changing_authorized_action_takers_to_contract_owner_allowed: false, - }.into(), + } + .into(), new_tokens_destination_identity: None, new_tokens_destination_identity_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, changing_authorized_action_takers_to_no_one_allowed: false, changing_authorized_action_takers_to_contract_owner_allowed: false, - }.into(), + } + .into(), manual_minting_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, changing_authorized_action_takers_to_no_one_allowed: false, changing_authorized_action_takers_to_contract_owner_allowed: false, - }.into(), + } + .into(), manual_burning_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, changing_authorized_action_takers_to_no_one_allowed: false, changing_authorized_action_takers_to_contract_owner_allowed: false, - }.into(), + } + .into(), freeze_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, changing_authorized_action_takers_to_no_one_allowed: false, changing_authorized_action_takers_to_contract_owner_allowed: false, - }.into(), + } + .into(), unfreeze_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, changing_authorized_action_takers_to_no_one_allowed: false, changing_authorized_action_takers_to_contract_owner_allowed: false, - }.into(), + } + .into(), main_control_group: None, main_control_group_can_be_modified: AuthorizedActionTakers::NoOne, } diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs index b84eefccf4f..07e0e597aa3 100644 --- a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -11,9 +11,9 @@ use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1S use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::group::{Group, GroupName}; +use crate::util::hash::hash_double; use platform_value::Identifier; use std::collections::BTreeMap; -use crate::util::hash::hash_double; impl DataContractV0Getters for DataContractV1 { fn id(&self) -> Identifier { diff --git a/packages/rs-dpp/src/document/generate_document_id.rs b/packages/rs-dpp/src/document/generate_document_id.rs index b14fc599a44..96d4af68c17 100644 --- a/packages/rs-dpp/src/document/generate_document_id.rs +++ b/packages/rs-dpp/src/document/generate_document_id.rs @@ -1,4 +1,5 @@ use crate::document::Document; +use crate::prelude::IdentityNonce; use crate::{prelude::Identifier, util::hash::hash_double_to_vec}; impl Document { diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 302a6d10047..de0c10f6c47 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -88,6 +88,15 @@ pub mod prelude { pub type Revision = u64; pub type IdentityNonce = u64; + pub type SenderKeyIndex = u32; + pub type RecipientKeyIndex = u32; + + /// The index of the user's key that is used to derive keys that will be used to encrypt the contact's user id in encToUserId and the private data. + pub type RootEncryptionKeyIndex = u32; + + /// The index at which to derive the root encryption key. + pub type DerivationEncryptionKeyIndex = u32; + /// UserFeeIncrease is the additional percentage of the processing fee. /// A 1 here means we pay 1% more in processing fees. A 100 means we pay 100% more. pub type UserFeeIncrease = u16; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs index dfdb4d57269..dc07a538271 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/mod.rs @@ -23,7 +23,16 @@ pub struct TokenBurnTransitionV0 { /// Document Base Transition #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] pub base: TokenBaseTransition, - + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "burnAmount") + )] /// How much should we burn pub burn_amount: u64, + /// The public note + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "publicNote") + )] + pub public_note: Option, } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs index 7f9f99fbfa4..dcf6d104a22 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs @@ -20,6 +20,15 @@ pub trait TokenBurnTransitionV0Methods: TokenBaseTransitionAccessors { fn burn_amount(&self) -> u64; fn set_burn_amount(&mut self, amount: u64); + + /// Returns the `public_note` field of the `TokenBurnTransitionV0`. + fn public_note(&self) -> Option<&String>; + + /// Returns the owned `public_note` field of the `TokenBurnTransitionV0`. + fn public_note_owned(self) -> Option; + + /// Sets the `public_note` field in the `TokenBurnTransitionV0`. + fn set_public_note(&mut self, public_note: Option); } impl TokenBurnTransitionV0Methods for TokenBurnTransitionV0 { @@ -30,4 +39,16 @@ impl TokenBurnTransitionV0Methods for TokenBurnTransitionV0 { fn set_burn_amount(&mut self, amount: u64) { self.burn_amount = amount; } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs index a34139c10e6..4c83f78232f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs @@ -35,4 +35,22 @@ impl TokenBurnTransitionV0Methods for TokenBurnTransition { TokenBurnTransition::V0(v0) => v0.set_burn_amount(burn_amount), } } + + fn public_note(&self) -> Option<&String> { + match self { + TokenBurnTransition::V0(v0) => v0.public_note(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenBurnTransition::V0(v0) => v0.public_note_owned(), + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenBurnTransition::V0(v0) => v0.set_public_note(public_note), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs index fe20c85bb72..2e4d17a6ebf 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs @@ -24,13 +24,22 @@ pub struct TokenIssuanceTransitionV0 { /// Document Base Transition #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] pub base: TokenBaseTransition, - + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "issuedToIdentityId") + )] /// Who should we issue the token to? If this is not set then we issue to the identity set in /// contract settings. If such an operation is allowed. pub issued_to_identity_id: Option, /// How much should we issue pub amount: u64, + /// The public note + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "publicNote") + )] + pub public_note: Option, } impl fmt::Display for TokenIssuanceTransitionV0 { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs index f8c21f9b18e..5f24acc145b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs @@ -1,3 +1,4 @@ +use platform_value::Identifier; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; @@ -20,6 +21,21 @@ pub trait TokenIssuanceTransitionV0Methods: TokenBaseTransitionAccessors { fn amount(&self) -> u64; fn set_amount(&mut self, amount: u64); + + /// Returns the `public_note` field of the `TokenIssuanceTransitionV0`. + fn public_note(&self) -> Option<&String>; + + /// Returns the owned `public_note` field of the `TokenIssuanceTransitionV0`. + fn public_note_owned(self) -> Option; + + /// Sets the value of the `public_note` field in the `TokenIssuanceTransitionV0`. + fn set_public_note(&mut self, public_note: Option); + + /// Returns the `issued_to_identity_id` field of the `TokenIssuanceTransitionV0`. + fn issued_to_identity_id(&self) -> Option; + + /// Sets the value of the `issued_to_identity_id` field in the `TokenIssuanceTransitionV0`. + fn set_issued_to_identity_id(&mut self, issued_to_identity_id: Option); } impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransitionV0 { @@ -30,4 +46,23 @@ impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransitionV0 { fn set_amount(&mut self, amount: u64) { self.amount = amount; } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } + + fn issued_to_identity_id(&self) -> Option { + self.issued_to_identity_id + } + fn set_issued_to_identity_id(&mut self, issued_to_identity_id: Option) { + self.issued_to_identity_id = issued_to_identity_id; + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs index fa3137f0222..71b228a35ae 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs @@ -1,3 +1,4 @@ +use platform_value::Identifier; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransition; @@ -35,4 +36,34 @@ impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransition { TokenIssuanceTransition::V0(v0) => v0.set_amount(amount), } } + + fn public_note(&self) -> Option<&String> { + match self { + TokenIssuanceTransition::V0(v0) => v0.public_note(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenIssuanceTransition::V0(v0) => v0.public_note_owned(), + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenIssuanceTransition::V0(v0) => v0.set_public_note(public_note), + } + } + + fn issued_to_identity_id(&self) -> Option { + match self { + TokenIssuanceTransition::V0(v0) => v0.issued_to_identity_id(), + } + } + + fn set_issued_to_identity_id(&mut self, issued_to_identity_id: Option) { + match self { + TokenIssuanceTransition::V0(v0) => v0.set_issued_to_identity_id(issued_to_identity_id), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs index b2e140b8122..f3d3d00a52e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs @@ -3,13 +3,15 @@ pub mod v0_methods; use bincode::{Decode, Encode}; use derive_more::Display; +pub use super::super::token_base_transition::IDENTIFIER_FIELDS; +use crate::prelude::{ + DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex, +}; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use platform_value::Identifier; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; -pub use super::super::token_base_transition::IDENTIFIER_FIELDS; -use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; - mod property_names { pub const AMOUNT: &str = "$amount"; pub const RECIPIENT_OWNER_ID: &str = "recipientOwnerId"; @@ -40,4 +42,26 @@ pub struct TokenTransferTransitionV0 { serde(rename = "recipientOwnerId") )] pub recipient_owner_id: Identifier, + /// The public note + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "publicNote") + )] + pub public_note: Option, + /// An optional shared encrypted note + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "sharedEncryptedNote") + )] + pub shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + /// An optional private encrypted note + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "privateEncryptedNote") + )] + pub private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs index afa066cea39..22762c4bbda 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs @@ -1,5 +1,5 @@ use platform_value::Identifier; - +use crate::prelude::{DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; use crate::state_transition::batch_transition::batched_transition::token_transfer_transition::TokenTransferTransitionV0; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; @@ -19,20 +19,82 @@ impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { } pub trait TokenTransferTransitionV0Methods: TokenBaseTransitionAccessors { - /// Returns a reference to the `revision` field of the `DocumentReplaceTransitionV0`. + /// Returns the `amount` field of the `TokenTransferTransitionV0`. fn amount(&self) -> u64; - /// Sets the value of the `revision` field in the `DocumentReplaceTransitionV0`. + /// Sets the value of the `amount` field in the `TokenTransferTransitionV0`. fn set_amount(&mut self, amount: u64); - /// Returns the `recipient_owner_id` field of the `DocumentReplaceTransitionV0`. + /// Returns the `recipient_owner_id` field of the `TokenTransferTransitionV0`. fn recipient_owner_id(&self) -> Identifier; - /// Returns a reference to the `recipient_owner_id` field of the `DocumentReplaceTransitionV0`. + /// Returns a reference to the `recipient_owner_id` field of the `TokenTransferTransitionV0`. fn recipient_owner_id_ref(&self) -> &Identifier; - /// Sets the value of the `recipient_owner_id` field in the `DocumentReplaceTransitionV0`. + /// Sets the value of the `recipient_owner_id` field in the `TokenTransferTransitionV0`. fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier); + + /// Returns the `public_note` field of the `TokenTransferTransitionV0`. + fn public_note(&self) -> Option<&String>; + + /// Returns the owned `public_note` field of the `TokenTransferTransitionV0`. + fn public_note_owned(self) -> Option; + + /// Sets the value of the `public_note` field in the `TokenTransferTransitionV0`. + fn set_public_note(&mut self, public_note: Option); + + /// Returns the `shared_encrypted_note` field of the `TokenTransferTransitionV0`. + fn shared_encrypted_note(&self) -> Option<&(SenderKeyIndex, RecipientKeyIndex, Vec)>; + + /// Returns the owned `shared_encrypted_note` field of the `TokenTransferTransitionV0`. + fn shared_encrypted_note_owned(self) -> Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>; + + /// Sets the value of the `shared_encrypted_note` field in the `TokenTransferTransitionV0`. + fn set_shared_encrypted_note( + &mut self, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + ); + + /// Returns the `private_encrypted_note` field of the `TokenTransferTransitionV0`. + fn private_encrypted_note( + &self, + ) -> Option<&( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>; + + /// Returns the owned `private_encrypted_note` field of the `TokenTransferTransitionV0`. + fn private_encrypted_note_owned( + self, + ) -> Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>; + + /// Sets the value of the `private_encrypted_note` field in the `TokenTransferTransitionV0`. + fn set_private_encrypted_note( + &mut self, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ); + + /// Returns all notes (public, shared, and private) as owned values in a tuple. + fn notes_owned( + self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ); } impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { @@ -55,4 +117,79 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier) { self.recipient_owner_id = recipient_owner_id; } + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } + + fn shared_encrypted_note(&self) -> Option<&(SenderKeyIndex, RecipientKeyIndex, Vec)> { + self.shared_encrypted_note.as_ref() + } + + fn shared_encrypted_note_owned(self) -> Option<(SenderKeyIndex, RecipientKeyIndex, Vec)> { + self.shared_encrypted_note + } + + fn set_shared_encrypted_note( + &mut self, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + ) { + self.shared_encrypted_note = shared_encrypted_note; + } + + fn private_encrypted_note( + &self, + ) -> Option<&( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )> { + self.private_encrypted_note.as_ref() + } + + fn private_encrypted_note_owned( + self, + ) -> Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )> { + self.private_encrypted_note + } + + fn set_private_encrypted_note( + &mut self, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { + self.private_encrypted_note = private_encrypted_note; + } + + fn notes_owned( + self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { + ( + self.public_note, + self.shared_encrypted_note, + self.private_encrypted_note, + ) + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs index 9e0a0617d80..c6423015997 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs @@ -1,4 +1,5 @@ use platform_value::Identifier; +use crate::prelude::{DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; use crate::state_transition::batch_transition::batched_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::TokenTransferTransition; @@ -54,4 +55,102 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransition { TokenTransferTransition::V0(v0) => v0.recipient_owner_id = recipient_owner_id, } } + + // Methods for `public_note` + fn public_note(&self) -> Option<&String> { + match self { + TokenTransferTransition::V0(v0) => v0.public_note.as_ref(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenTransferTransition::V0(v0) => v0.public_note, + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenTransferTransition::V0(v0) => v0.public_note = public_note, + } + } + + fn shared_encrypted_note(&self) -> Option<&(SenderKeyIndex, RecipientKeyIndex, Vec)> { + match self { + TokenTransferTransition::V0(v0) => v0.shared_encrypted_note.as_ref(), + } + } + + fn shared_encrypted_note_owned(self) -> Option<(SenderKeyIndex, RecipientKeyIndex, Vec)> { + match self { + TokenTransferTransition::V0(v0) => v0.shared_encrypted_note, + } + } + + fn set_shared_encrypted_note( + &mut self, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + ) { + match self { + TokenTransferTransition::V0(v0) => v0.shared_encrypted_note = shared_encrypted_note, + } + } + + fn private_encrypted_note( + &self, + ) -> Option<&( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )> { + match self { + TokenTransferTransition::V0(v0) => v0.private_encrypted_note.as_ref(), + } + } + + fn private_encrypted_note_owned( + self, + ) -> Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )> { + match self { + TokenTransferTransition::V0(v0) => v0.private_encrypted_note, + } + } + + fn set_private_encrypted_note( + &mut self, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { + match self { + TokenTransferTransition::V0(v0) => v0.private_encrypted_note = private_encrypted_note, + } + } + + // Method to return all notes as owned values + fn notes_owned( + self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { + match self { + TokenTransferTransition::V0(v0) => ( + v0.public_note, + v0.shared_encrypted_note, + v0.private_encrypted_note, + ), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs index a53a64ff534..e9d975ea47b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/value_conversion.rs @@ -4,7 +4,9 @@ use platform_value::Value; use crate::ProtocolError; -use crate::state_transition::batch_transition::{BatchTransition, BatchTransitionV0, BatchTransitionV1}; +use crate::state_transition::batch_transition::{ + BatchTransition, BatchTransitionV0, BatchTransitionV1, +}; use crate::state_transition::state_transitions::batch_transition::fields::*; use crate::state_transition::StateTransitionValueConvert; diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs index 1980cdf712f..f5325ea4371 100644 --- a/packages/rs-dpp/src/tokens/mod.rs +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -1,2 +1,3 @@ pub mod allowed_currency; pub mod errors; +pub mod token_event; diff --git a/packages/rs-dpp/src/tokens/token_event.rs b/packages/rs-dpp/src/tokens/token_event.rs new file mode 100644 index 00000000000..8a3d3a6c0ff --- /dev/null +++ b/packages/rs-dpp/src/tokens/token_event.rs @@ -0,0 +1,26 @@ +use crate::balances::credits::TokenAmount; +use crate::prelude::{ + DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex, +}; +use platform_value::Identifier; + +pub type TokenEventPublicNote = Option; +pub type TokenEventSharedEncryptedNote = Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>; +pub type TokenEventPersonalEncryptedNote = Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, +)>; + +#[derive(Debug, PartialEq, PartialOrd, Clone, Eq)] +pub enum TokenEvent { + Mint(TokenAmount, TokenEventPublicNote), + Burn(TokenAmount, TokenEventPublicNote), + Transfer( + Identifier, + TokenEventPublicNote, + TokenEventSharedEncryptedNote, + TokenEventPersonalEncryptedNote, + TokenAmount, + ), +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs index 8bf290565d1..46a0590c01c 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs @@ -111,7 +111,7 @@ impl Platform { None, &platform_version.drive, )?; - + let contract = load_system_data_contract(SystemDataContract::TokenHistory, platform_version)?; @@ -126,7 +126,6 @@ impl Platform { Ok(()) } - /// Initializes an empty sum tree for withdrawal transactions required for protocol version 4. /// /// This function is called during the transition to protocol version 4 to set up diff --git a/packages/rs-drive/src/cache/system_contracts.rs b/packages/rs-drive/src/cache/system_contracts.rs index c1a2785c3c4..7de44da36bd 100644 --- a/packages/rs-drive/src/cache/system_contracts.rs +++ b/packages/rs-drive/src/cache/system_contracts.rs @@ -15,6 +15,8 @@ pub struct SystemDataContracts { dashpay: ArcSwap, /// Masternode reward shares contract masternode_reward_shares: ArcSwap, + /// Token history contract + token_history: ArcSwap, } impl SystemDataContracts { @@ -39,6 +41,10 @@ impl SystemDataContracts { SystemDataContract::MasternodeRewards, platform_version, )?), + token_history: ArcSwap::from_pointee(load_system_data_contract( + SystemDataContract::TokenHistory, + platform_version, + )?), }) } @@ -47,6 +53,11 @@ impl SystemDataContracts { self.withdrawals.load() } + /// Returns token history contract + pub fn load_token_history(&self) -> Guard> { + self.token_history.load() + } + /// Returns DPNS contract pub fn load_dpns(&self) -> Guard> { self.dpns.load() diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs index 37d4ebd9fc3..a413dc7ed28 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs @@ -9,17 +9,17 @@ use dpp::data_contract::config::v0::DataContractConfigGettersV0; use dpp::data_contract::DataContract; use dpp::fee::fee_result::FeeResult; -use dpp::serialization::PlatformSerializableWithPlatformVersion; +use crate::drive::balances::total_tokens_root_supply_path; +use crate::drive::tokens::{token_path, tokens_root_path, TOKEN_BALANCES_KEY}; use crate::error::contract::DataContractError; +use crate::util::grove_operations::BatchInsertTreeApplyType; +use crate::util::object_size_info::DriveKeyInfo; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::serialization::PlatformSerializableWithPlatformVersion; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; use std::collections::HashMap; -use dpp::data_contract::accessors::v1::DataContractV1Getters; -use crate::drive::balances::total_tokens_root_supply_path; -use crate::drive::tokens::{TOKEN_BALANCES_KEY, token_path, tokens_root_path}; -use crate::util::grove_operations::BatchInsertTreeApplyType; -use crate::util::object_size_info::DriveKeyInfo; impl Drive { /// Insert a contract. @@ -152,10 +152,22 @@ impl Drive { >, platform_version: &PlatformVersion, ) -> Result, Error> { - let mut batch_operations: Vec = self.insert_contract_operations_v0(contract_element, contract, block_info, estimated_costs_only_with_layer_info, platform_version)?; - + let mut batch_operations: Vec = self + .insert_contract_operations_v0( + contract_element, + contract, + block_info, + estimated_costs_only_with_layer_info, + platform_version, + )?; + for token_pos in contract.tokens().keys() { - let token_id = contract.token_id(*token_pos).ok_or(Error::DataContract(DataContractError::CorruptedDataContract(format!("data contract has a token at position {}, but can not find it", token_pos))))?; + let token_id = contract.token_id(*token_pos).ok_or(Error::DataContract( + DataContractError::CorruptedDataContract(format!( + "data contract has a token at position {}, but can not find it", + token_pos + )), + ))?; self.batch_insert_empty_tree( tokens_root_path(), @@ -181,7 +193,7 @@ impl Drive { &platform_version.drive, )?; } - + Ok(batch_operations) } } diff --git a/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs index fadf485b670..460055f9036 100644 --- a/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs @@ -16,14 +16,14 @@ use dpp::fee::fee_result::FeeResult; use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; use dpp::serialization::PlatformSerializableWithPlatformVersion; +use crate::drive::tokens::{token_path, tokens_root_path, TOKEN_BALANCES_KEY}; +use crate::error::contract::DataContractError; +use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; use std::collections::{HashMap, HashSet}; -use dpp::data_contract::accessors::v1::DataContractV1Getters; -use crate::drive::tokens::{TOKEN_BALANCES_KEY, token_path, tokens_root_path}; -use crate::error::contract::DataContractError; impl Drive { /// Updates a data contract. @@ -213,12 +213,33 @@ impl Drive { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { - let mut batch_operations: Vec = self.update_contract_operations_v0(contract_element, contract, original_contract, block_info, estimated_costs_only_with_layer_info, transaction, platform_version)?; + let mut batch_operations: Vec = self + .update_contract_operations_v0( + contract_element, + contract, + original_contract, + block_info, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; for token_pos in contract.tokens().keys() { - let token_id = contract.token_id(*token_pos).ok_or(Error::DataContract(DataContractError::CorruptedDataContract(format!("data contract has a token at position {}, but can not find it", token_pos))))?; - - batch_operations.extend(self.create_token_trees_operations(token_id.to_buffer(), true, &mut None, estimated_costs_only_with_layer_info, transaction, platform_version)?); + let token_id = contract.token_id(*token_pos).ok_or(Error::DataContract( + DataContractError::CorruptedDataContract(format!( + "data contract has a token at position {}, but can not find it", + token_pos + )), + ))?; + + batch_operations.extend(self.create_token_trees_operations( + token_id.to_buffer(), + true, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); } Ok(batch_operations) } diff --git a/packages/rs-drive/src/drive/initialization/v0/mod.rs b/packages/rs-drive/src/drive/initialization/v0/mod.rs index 8736d42d25b..daa41b1c243 100644 --- a/packages/rs-drive/src/drive/initialization/v0/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v0/mod.rs @@ -26,7 +26,8 @@ impl Drive { // On lower layers we can use batching - let batch = self.create_initial_state_structure_lower_layers_operations_0(platform_version)?; + let batch = + self.create_initial_state_structure_lower_layers_operations_0(platform_version)?; self.grove_apply_batch(batch, false, transaction, drive_version)?; @@ -206,7 +207,7 @@ impl Drive { // For the votes tree structure Drive::add_initial_vote_tree_main_structure_operations(&mut batch, platform_version)?; - + Ok(batch) } } diff --git a/packages/rs-drive/src/drive/initialization/v1/mod.rs b/packages/rs-drive/src/drive/initialization/v1/mod.rs index d0d16a7962e..80b893444ac 100644 --- a/packages/rs-drive/src/drive/initialization/v1/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v1/mod.rs @@ -8,9 +8,12 @@ use crate::drive::Drive; use crate::error::Error; use crate::util::batch::grovedb_op_batch::GroveDbOpBatchV0Methods; +use crate::drive::identity::withdrawals::paths::{ + get_withdrawal_root_path_vec, WITHDRAWAL_TRANSACTIONS_BROADCASTED_KEY, + WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY, +}; use dpp::version::PlatformVersion; use grovedb::{Element, TransactionArg}; -use crate::drive::identity::withdrawals::paths::{get_withdrawal_root_path_vec, WITHDRAWAL_TRANSACTIONS_BROADCASTED_KEY, WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY}; impl Drive { /// Creates the initial state structure. @@ -24,8 +27,9 @@ impl Drive { // On lower layers we can use batching - let mut batch = self.create_initial_state_structure_lower_layers_operations_0(platform_version)?; - + let mut batch = + self.create_initial_state_structure_lower_layers_operations_0(platform_version)?; + self.initial_state_structure_lower_layers_add_operations_1(&mut batch, platform_version)?; self.grove_apply_batch(batch, false, transaction, drive_version)?; @@ -39,7 +43,6 @@ impl Drive { batch: &mut GroveDbOpBatch, _platform_version: &PlatformVersion, ) -> Result<(), Error> { - // In Misc batch.add_insert( misc_path_vec(), @@ -61,7 +64,7 @@ impl Drive { WITHDRAWAL_TRANSACTIONS_BROADCASTED_KEY.to_vec(), Element::empty_tree(), ); - + Ok(()) } } diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history/mod.rs deleted file mode 100644 index e084dffc38f..00000000000 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history/mod.rs +++ /dev/null @@ -1 +0,0 @@ -mod v0; diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history/v0/mod.rs deleted file mode 100644 index 8b137891791..00000000000 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history/v0/mod.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/mod.rs new file mode 100644 index 00000000000..c7682b7dcde --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/mod.rs @@ -0,0 +1,56 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; +use dpp::tokens::token_event::TokenEvent; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::HashMap; + +mod v0; + +impl Drive { + /// Adds token transaction history + pub fn add_token_transaction_history_operations( + &self, + token_id: Identifier, + owner_id: Identifier, + owner_nonce: IdentityNonce, + event: TokenEvent, + block_info: &BlockInfo, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .update + .add_transaction_history_operations + { + 0 => self.add_token_transaction_history_operations_v0( + token_id, + owner_id, + owner_nonce, + event, + block_info, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_token_transaction_history_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs new file mode 100644 index 00000000000..3f5760b53db --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs @@ -0,0 +1,213 @@ +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; +use crate::util::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; +use dpp::block::block_info::BlockInfo; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::document::{Document, DocumentV0}; +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; +use dpp::tokens::token_event::TokenEvent; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::{BTreeMap, HashMap}; + +impl Drive { + /// Adds token transaction history + pub(super) fn add_token_transaction_history_operations_v0( + &self, + token_id: Identifier, + owner_id: Identifier, + owner_nonce: IdentityNonce, + event: TokenEvent, + block_info: &BlockInfo, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let operations; + + let contract = self.cache.system_data_contracts.load_token_history(); + + match event { + TokenEvent::Mint(mint_amount, public_note) => { + let document_type = contract.document_type_for_name("mint")?; + let document_id = Document::generate_document_id_v0( + &contract.id(), + &owner_id, + "mint", + owner_nonce.to_be_bytes().as_slice(), + ); + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("amount".to_string(), mint_amount.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + let document: Document = DocumentV0 { + id: document_id, + owner_id, + properties, + revision: None, + created_at: Some(block_info.time_ms), + updated_at: None, + transferred_at: None, + created_at_block_height: Some(block_info.height), + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: Some(block_info.core_height), + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + operations = self.add_document_for_contract_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentOwnedInfo((document, None)), + owner_id: Some(owner_id.to_buffer()), + }, + contract: &contract, + document_type, + }, + true, + block_info, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + } + TokenEvent::Burn(burn_amount, public_note) => { + let document_type = contract.document_type_for_name("mint")?; + let document_id = Document::generate_document_id_v0( + &contract.id(), + &owner_id, + "burn", + owner_nonce.to_be_bytes().as_slice(), + ); + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("amount".to_string(), burn_amount.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + let document: Document = DocumentV0 { + id: document_id, + owner_id, + properties, + revision: None, + created_at: Some(block_info.time_ms), + updated_at: None, + transferred_at: None, + created_at_block_height: Some(block_info.height), + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: Some(block_info.core_height), + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + operations = self.add_document_for_contract_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentOwnedInfo((document, None)), + owner_id: Some(owner_id.to_buffer()), + }, + contract: &contract, + document_type, + }, + true, + block_info, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + } + TokenEvent::Transfer( + to, + public_note, + token_event_shared_encrypted_note, + token_event_personal_encrypted_note, + amount, + ) => { + let document_type = contract.document_type_for_name("transfer")?; + let document_id = Document::generate_document_id_v0( + &contract.id(), + &owner_id, + "transfer", + owner_nonce.to_be_bytes().as_slice(), + ); + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("amount".to_string(), amount.into()), + ("toIdentityId".to_string(), to.into()), + ]); + if let Some(note) = public_note { + properties.insert("publicNote".to_string(), note.into()); + } + if let Some((sender_key_index, recipient_key_index, note)) = + token_event_shared_encrypted_note + { + properties.insert("encryptedSharedNote".to_string(), note.into()); + properties.insert("senderKeyIndex".to_string(), sender_key_index.into()); + properties.insert("recipientKeyIndex".to_string(), recipient_key_index.into()); + } + + if let Some((root_encryption_key_index, derivation_encryption_key_index, note)) = + token_event_personal_encrypted_note + { + properties.insert("encryptedPersonalNote".to_string(), note.into()); + properties.insert( + "rootEncryptionKeyIndex".to_string(), + root_encryption_key_index.into(), + ); + properties.insert( + "derivationEncryptionKeyIndex".to_string(), + derivation_encryption_key_index.into(), + ); + } + let document: Document = DocumentV0 { + id: document_id, + owner_id, + properties, + revision: None, + created_at: Some(block_info.time_ms), + updated_at: None, + transferred_at: None, + created_at_block_height: Some(block_info.height), + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: Some(block_info.core_height), + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + operations = self.add_document_for_contract_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentOwnedInfo((document, None)), + owner_id: Some(owner_id.to_buffer()), + }, + contract: &contract, + document_type, + }, + true, + block_info, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + } + } + + Ok(operations) + } +} diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs index b81eea97b95..98d5e667bbc 100644 --- a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs @@ -40,23 +40,24 @@ impl Drive { } } - #[cfg(test)] mod tests { - use std::collections::BTreeMap; - use dpp::balances::credits::TokenAmount; use super::*; use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; + use dpp::balances::credits::TokenAmount; use dpp::block::block_info::BlockInfo; use dpp::data_contract::accessors::v1::DataContractV1Getters; + use dpp::data_contract::associated_token::token_configuration::v0::{ + TokenConfigurationConventionV0, TokenConfigurationV0, + }; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; - use dpp::data_contract::associated_token::token_configuration::v0::{TokenConfigurationConventionV0, TokenConfigurationV0}; - use dpp::data_contract::config::DataContractConfig; use dpp::data_contract::config::v0::DataContractConfigV0; + use dpp::data_contract::config::DataContractConfig; use dpp::data_contract::v1::DataContractV1; use dpp::identity::Identity; - - use dpp::identity::accessors::IdentityGettersV0; + use std::collections::BTreeMap; + + use dpp::identity::accessors::IdentityGettersV0; use dpp::prelude::DataContract; use dpp::version::PlatformVersion; @@ -89,7 +90,10 @@ mod tests { }), schema_defs: None, groups: Default::default(), - tokens: BTreeMap::from([(0, TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()))]), + tokens: BTreeMap::from([( + 0, + TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()), + )]), }); let token_id = contract.token_id(0).expect("expected token at position 0"); drive @@ -103,9 +107,28 @@ mod tests { ) .expect("expected to add an identity"); - drive.insert_contract(&contract, BlockInfo::default(), true, None, platform_version).expect("expected to insert contract"); - - drive.token_mint(token_id.to_buffer(), identity.id().to_buffer(), 10000, true, &BlockInfo::default(), true, None, platform_version).expect("expected to mint token"); + drive + .insert_contract( + &contract, + BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert contract"); + + drive + .token_mint( + token_id.to_buffer(), + identity.id().to_buffer(), + 10000, + true, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to mint token"); let proof = drive .prove_identities_token_balances_v0( token_id.to_buffer(), @@ -115,7 +138,7 @@ mod tests { ) .expect("should not error when proving an identity"); - let proved_identity_balance: BTreeMap<[u8;32], Option> = + let proved_identity_balance: BTreeMap<[u8; 32], Option> = Drive::verify_token_balances_for_identity_ids( proof.as_slice(), token_id.to_buffer(), @@ -123,9 +146,13 @@ mod tests { false, platform_version, ) - .expect("expect that this be verified").1; + .expect("expect that this be verified") + .1; - assert_eq!(proved_identity_balance, BTreeMap::from([(identity_id, Some(10000))])); + assert_eq!( + proved_identity_balance, + BTreeMap::from([(identity_id, Some(10000))]) + ); } #[test] @@ -138,7 +165,7 @@ mod tests { .expect("expected a platform identity"); let identity_id = identity.id().to_buffer(); - + let contract = DataContract::V1(DataContractV1 { id: Default::default(), version: 0, @@ -157,7 +184,10 @@ mod tests { }), schema_defs: None, groups: Default::default(), - tokens: BTreeMap::from([(0, TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()))]), + tokens: BTreeMap::from([( + 0, + TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()), + )]), }); let token_id = contract.token_id(0).expect("expected token at position 0"); drive @@ -170,8 +200,16 @@ mod tests { platform_version, ) .expect("expected to add an identity"); - - drive.insert_contract(&contract, BlockInfo::default(), true, None, platform_version).expect("expected to insert contract"); + + drive + .insert_contract( + &contract, + BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert contract"); let proof = drive .prove_identities_token_balances_v0( token_id.to_buffer(), @@ -181,7 +219,7 @@ mod tests { ) .expect("should not error when proving an identity"); - let proved_identity_balance: BTreeMap<[u8;32], Option> = + let proved_identity_balance: BTreeMap<[u8; 32], Option> = Drive::verify_token_balances_for_identity_ids( proof.as_slice(), token_id.to_buffer(), @@ -189,62 +227,66 @@ mod tests { false, platform_version, ) - .expect("expect that this be verified").1; + .expect("expect that this be verified") + .1; - assert_eq!(proved_identity_balance, BTreeMap::from([(identity_id, None)])); + assert_eq!( + proved_identity_balance, + BTreeMap::from([(identity_id, None)]) + ); } - // #[test] - // fn should_prove_multiple_identity_single_token_balances() { - // let drive = setup_drive_with_initial_state_structure(None); - // let platform_version = PlatformVersion::latest(); - // let identities: BTreeMap<[u8; 32], Identity> = - // Identity::random_identities(10, 3, Some(14), platform_version) - // .expect("expected to get random identities") - // .into_iter() - // .map(|identity| (identity.id().to_buffer(), identity)) - // .collect(); - // - // let mut rng = StdRng::seed_from_u64(293); - // - // let token_id: [u8; 32] = rng.gen(); - // - // drive.add_new_token(token_id); - // - // for identity in identities.values() { - // drive - // .add_new_identity( - // identity.clone(), - // false, - // &BlockInfo::default(), - // true, - // None, - // platform_version, - // ) - // .expect("expected to add an identity"); - // } - // let identity_ids = identities.keys().copied().collect::>(); - // let identity_balances = identities - // .into_iter() - // .map(|(id, identity)| (id, Some(identity.balance()))) - // .collect::>>(); - // let proof = drive - // .prove_many_identity_token_balances( - // identity_ids.as_slice(), - // None, - // &platform_version.drive, - // ) - // .expect("should not error when proving an identity"); - // - // let (_, proved_identity_balances): ([u8; 32], BTreeMap<[u8; 32], Option>) = - // Drive::verify_identity_balances_for_identity_ids( - // proof.as_slice(), - // false, - // identity_ids.as_slice(), - // platform_version, - // ) - // .expect("expect that this be verified"); - // - // assert_eq!(proved_identity_balances, identity_balances); - // } -} \ No newline at end of file + // #[test] + // fn should_prove_multiple_identity_single_token_balances() { + // let drive = setup_drive_with_initial_state_structure(None); + // let platform_version = PlatformVersion::latest(); + // let identities: BTreeMap<[u8; 32], Identity> = + // Identity::random_identities(10, 3, Some(14), platform_version) + // .expect("expected to get random identities") + // .into_iter() + // .map(|identity| (identity.id().to_buffer(), identity)) + // .collect(); + // + // let mut rng = StdRng::seed_from_u64(293); + // + // let token_id: [u8; 32] = rng.gen(); + // + // drive.add_new_token(token_id); + // + // for identity in identities.values() { + // drive + // .add_new_identity( + // identity.clone(), + // false, + // &BlockInfo::default(), + // true, + // None, + // platform_version, + // ) + // .expect("expected to add an identity"); + // } + // let identity_ids = identities.keys().copied().collect::>(); + // let identity_balances = identities + // .into_iter() + // .map(|(id, identity)| (id, Some(identity.balance()))) + // .collect::>>(); + // let proof = drive + // .prove_many_identity_token_balances( + // identity_ids.as_slice(), + // None, + // &platform_version.drive, + // ) + // .expect("should not error when proving an identity"); + // + // let (_, proved_identity_balances): ([u8; 32], BTreeMap<[u8; 32], Option>) = + // Drive::verify_identity_balances_for_identity_ids( + // proof.as_slice(), + // false, + // identity_ids.as_slice(), + // platform_version, + // ) + // .expect("expect that this be verified"); + // + // assert_eq!(proved_identity_balances, identity_balances); + // } +} diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index 6b4a9f0b572..ea27741ade7 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -1,6 +1,6 @@ use crate::drive::RootTree; -mod add_transaction_history; +mod add_transaction_history_operations; pub mod balance; pub mod burn; pub mod estimated_costs; @@ -26,10 +26,7 @@ pub(crate) fn tokens_root_path_vec() -> Vec> { /// The path for the token tree #[cfg(any(feature = "server", feature = "verify"))] pub(crate) fn token_path(token_id: &[u8; 32]) -> [&[u8]; 2] { - [ - Into::<&[u8; 1]>::into(RootTree::Tokens), - token_id, - ] + [Into::<&[u8; 1]>::into(RootTree::Tokens), token_id] } /// The path for the token tree diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs index 2a16720d3e0..c307cba91dc 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs @@ -1,4 +1,5 @@ -use crate::drive::tokens::{TOKEN_BALANCES_KEY, token_path, tokens_root_path}; +use crate::drive::balances::total_tokens_root_supply_path; +use crate::drive::tokens::{token_path, tokens_root_path, TOKEN_BALANCES_KEY}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; @@ -11,7 +12,6 @@ use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::HashMap; -use crate::drive::balances::total_tokens_root_supply_path; impl Drive { /// Creates a new token root subtree at `TokenBalances` keyed by `token_id`. diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs index 82e08b7b9d6..b1b41e6795f 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs @@ -1,5 +1,7 @@ use dpp::block::epoch::Epoch; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::identifier::Identifier; +use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; @@ -43,6 +45,16 @@ impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { burn_amount: self.burn_amount(), })); + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Burn(self.burn_amount(), self.public_note_owned()), + })); + } + Ok(ops) } version => Err(Error::Drive(DriveError::UnknownVersionMismatch { diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs index ec3a48d1323..0ffc9c77d36 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs @@ -1,5 +1,7 @@ use dpp::block::epoch::Epoch; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::identifier::Identifier; +use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; @@ -40,10 +42,20 @@ impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { ops.push(TokenOperation(TokenOperationType::TokenMint { token_id: self.token_id(), identity_balance_holder_id: owner_id, - mint_amount: self.issuance_amount(), + mint_amount: self.mint_amount(), allow_first_mint: false, })); + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Mint(self.mint_amount(), self.public_note_owned()), + })); + } + Ok(ops) } version => Err(Error::Drive(DriveError::UnknownVersionMismatch { diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs index a00416e1799..61bd9db796b 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs @@ -1,11 +1,14 @@ use dpp::block::epoch::Epoch; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::identifier::Identifier; +use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::TokenOperationType; use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; @@ -29,6 +32,12 @@ impl DriveHighLevelDocumentOperationConverter for TokenTransferTransitionAction let identity_contract_nonce = self.base().identity_contract_nonce(); + let token_id = self.token_id(); + + let recipient_id = self.recipient_id(); + + let amount = self.amount(); + let mut ops = vec![IdentityOperation( IdentityOperationType::UpdateIdentityContractNonce { identity_id: owner_id.into_buffer(), @@ -38,12 +47,30 @@ impl DriveHighLevelDocumentOperationConverter for TokenTransferTransitionAction )]; ops.push(TokenOperation(TokenOperationType::TokenTransfer { - token_id: self.token_id(), + token_id, sender_id: owner_id, - recipient_id: self.recipient_id(), - amount: self.amount(), + recipient_id, + amount, })); + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + let (public_note, shared_encrypted_note, private_encrypted_note) = + self.notes_owned(); + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id, + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Transfer( + recipient_id, + public_note, + shared_encrypted_note, + private_encrypted_note, + amount, + ), + })); + } + Ok(ops) } version => Err(Error::Drive(DriveError::UnknownVersionMismatch { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index 0002aa0db2f..9c2f4c4fdeb 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -38,7 +38,8 @@ use crate::state_transition_action::system::bump_identity_data_contract_nonce_ac use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; /// version pub const DOCUMENT_TRANSITION_ACTION_VERSION: u32 = 0; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs index d99a0f88948..e93292f0522 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs @@ -22,64 +22,46 @@ pub enum TokenBurnTransitionAction { V0(TokenBurnTransitionActionV0), } -/// Accessors trait for TokenBurnTransitionAction for version 0 fields -pub trait TokenBurnTransitionActionAccessorsV0 { - /// Returns a reference to the base token transition action - fn base(&self) -> &TokenBaseTransitionAction; - - /// Returns the base token transition action - fn base_owned(self) -> TokenBaseTransitionAction; - - /// Returns the burn amount - fn burn_amount(&self) -> u64; - - /// Returns the token position in the contract - fn token_position(&self) -> u16 { - self.base().token_position() - } - - /// Returns the token ID - fn token_id(&self) -> Identifier { - self.base().token_id() - } - - /// Returns the data contract ID - fn data_contract_id(&self) -> Identifier { - self.base().data_contract_id() +impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenBurnTransitionAction::V0(v0) => &v0.base, + } } - /// Returns a reference to the data contract fetch info - fn data_contract_fetch_info_ref(&self) -> &Arc { - self.base().data_contract_fetch_info_ref() + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenBurnTransitionAction::V0(v0) => v0.base, + } } - /// Returns the data contract fetch info - fn data_contract_fetch_info(&self) -> Arc { - self.base().data_contract_fetch_info() + fn burn_amount(&self) -> u64 { + match self { + TokenBurnTransitionAction::V0(v0) => v0.burn_amount, + } } - /// Returns the identity contract nonce - fn identity_contract_nonce(&self) -> IdentityNonce { - self.base().identity_contract_nonce() + fn set_burn_amount(&mut self, amount: u64) { + match self { + TokenBurnTransitionAction::V0(v0) => v0.burn_amount = amount, + } } -} -impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionAction { - fn base(&self) -> &TokenBaseTransitionAction { + fn public_note(&self) -> Option<&String> { match self { - TokenBurnTransitionAction::V0(v0) => &v0.base, + TokenBurnTransitionAction::V0(v0) => v0.public_note.as_ref(), } } - fn base_owned(self) -> TokenBaseTransitionAction { + fn public_note_owned(self) -> Option { match self { - TokenBurnTransitionAction::V0(v0) => v0.base, + TokenBurnTransitionAction::V0(v0) => v0.public_note, } } - fn burn_amount(&self) -> u64 { + fn set_public_note(&mut self, public_note: Option) { match self { - TokenBurnTransitionAction::V0(v0) => v0.burn_amount, + TokenBurnTransitionAction::V0(v0) => v0.public_note = public_note, } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs index 7b63337dc96..84f239a832b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs @@ -1,5 +1,10 @@ mod transformer; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; + +use std::sync::Arc; +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; /// Token burn transition action v0 #[derive(Debug, Clone)] @@ -8,6 +13,8 @@ pub struct TokenBurnTransitionActionV0 { pub base: TokenBaseTransitionAction, /// The amount of tokens to burn pub burn_amount: u64, + /// A public note + pub public_note: Option, } /// Accessors for `TokenBurnTransitionActionV0` @@ -23,6 +30,45 @@ pub trait TokenBurnTransitionActionAccessorsV0 { /// Sets the amount of tokens to burn fn set_burn_amount(&mut self, amount: u64); + + /// Returns a reference to the `public_note` field of the `TokenBurnTransitionActionV0` + fn public_note(&self) -> Option<&String>; + + /// Returns the owned `public_note` field of the `TokenBurnTransitionActionV0` + fn public_note_owned(self) -> Option; + + /// Sets the value of the `public_note` field in the `TokenBurnTransitionActionV0` + fn set_public_note(&mut self, public_note: Option); + + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } + + /// Returns the token ID + fn token_id(&self) -> Identifier { + self.base().token_id() + } + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + /// Returns the identity contract nonce + fn identity_contract_nonce(&self) -> IdentityNonce { + self.base().identity_contract_nonce() + } } impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionActionV0 { @@ -41,4 +87,16 @@ impl TokenBurnTransitionActionAccessorsV0 for TokenBurnTransitionActionV0 { fn set_burn_amount(&mut self, amount: u64) { self.burn_amount = amount; } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index 96ac0ef533e..09bb907014b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -23,7 +23,11 @@ impl TokenBurnTransitionActionV0 { value: TokenBurnTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenBurnTransitionV0 { base, burn_amount } = value; + let TokenBurnTransitionV0 { + base, + burn_amount, + public_note, + } = value; let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( base, @@ -33,6 +37,7 @@ impl TokenBurnTransitionActionV0 { Ok(TokenBurnTransitionActionV0 { base: base_action, burn_amount, + public_note, }) } @@ -50,7 +55,11 @@ impl TokenBurnTransitionActionV0 { value: &TokenBurnTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenBurnTransitionV0 { base, burn_amount } = value; + let TokenBurnTransitionV0 { + base, + burn_amount, + public_note, + } = value; let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( @@ -61,6 +70,7 @@ impl TokenBurnTransitionActionV0 { Ok(TokenBurnTransitionActionV0 { base: base_action, burn_amount: *burn_amount, + public_note: public_note.clone(), }) } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs index 28868b09a7a..405337029c0 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs @@ -29,15 +29,15 @@ impl TokenMintTransitionActionAccessorsV0 for TokenMintTransitionAction { } } - fn issuance_amount(&self) -> u64 { + fn mint_amount(&self) -> u64 { match self { - TokenMintTransitionAction::V0(v0) => v0.issuance_amount, + TokenMintTransitionAction::V0(v0) => v0.mint_amount, } } - fn set_issuance_amount(&mut self, amount: u64) { + fn set_mint_amount(&mut self, amount: u64) { match self { - TokenMintTransitionAction::V0(v0) => v0.issuance_amount = amount, + TokenMintTransitionAction::V0(v0) => v0.mint_amount = amount, } } @@ -52,4 +52,22 @@ impl TokenMintTransitionActionAccessorsV0 for TokenMintTransitionAction { TokenMintTransitionAction::V0(v0) => v0.identity_balance_holder_id = id, } } + + fn public_note(&self) -> Option<&String> { + match self { + TokenMintTransitionAction::V0(v0) => v0.public_note.as_ref(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenMintTransitionAction::V0(v0) => v0.public_note, + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenMintTransitionAction::V0(v0) => v0.public_note = public_note, + } + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs index 54ccf11b25d..5d158482d68 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs @@ -11,9 +11,11 @@ pub struct TokenIssuanceTransitionActionV0 { /// Base token transition action pub base: TokenBaseTransitionAction, /// The amount of tokens to create - pub issuance_amount: u64, + pub mint_amount: u64, /// The identity to credit the token to pub identity_balance_holder_id: Identifier, + /// A public note + pub public_note: Option, } /// Accessors for `TokenIssuanceTransitionActionV0` @@ -25,10 +27,10 @@ pub trait TokenMintTransitionActionAccessorsV0 { fn base_owned(self) -> TokenBaseTransitionAction; /// Returns the amount of tokens to issuance - fn issuance_amount(&self) -> u64; + fn mint_amount(&self) -> u64; /// Sets the amount of tokens to issuance - fn set_issuance_amount(&mut self, amount: u64); + fn set_mint_amount(&mut self, amount: u64); /// Consumes self and returns the identity balance holder ID fn identity_balance_holder_id(&self) -> Identifier; @@ -60,6 +62,15 @@ pub trait TokenMintTransitionActionAccessorsV0 { fn data_contract_fetch_info(&self) -> Arc { self.base().data_contract_fetch_info() } + + /// Returns the public note (optional) + fn public_note(&self) -> Option<&String>; + + /// Returns the public note (owned) + fn public_note_owned(self) -> Option; + + /// Sets the public note + fn set_public_note(&mut self, public_note: Option); } impl TokenMintTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV0 { @@ -71,12 +82,12 @@ impl TokenMintTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV0 { self.base } - fn issuance_amount(&self) -> u64 { - self.issuance_amount + fn mint_amount(&self) -> u64 { + self.mint_amount } - fn set_issuance_amount(&mut self, amount: u64) { - self.issuance_amount = amount; + fn set_mint_amount(&mut self, amount: u64) { + self.mint_amount = amount; } fn identity_balance_holder_id(&self) -> Identifier { @@ -86,4 +97,16 @@ impl TokenMintTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV0 { fn set_identity_balance_holder_id(&mut self, id: Identifier) { self.identity_balance_holder_id = id; } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs index fb563fe6ad9..bedc0d48c7c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs @@ -30,6 +30,7 @@ impl TokenIssuanceTransitionActionV0 { base, issued_to_identity_id, amount, + public_note, } = value; let position = base.token_contract_position(); @@ -56,8 +57,9 @@ impl TokenIssuanceTransitionActionV0 { Ok(TokenIssuanceTransitionActionV0 { base: base_action, - issuance_amount: amount, + mint_amount: amount, identity_balance_holder_id, + public_note, }) } @@ -79,6 +81,7 @@ impl TokenIssuanceTransitionActionV0 { base, issued_to_identity_id, amount, + public_note, } = value; let base_action = @@ -104,8 +107,9 @@ impl TokenIssuanceTransitionActionV0 { Ok(TokenIssuanceTransitionActionV0 { base: base_action, - issuance_amount: *amount, + mint_amount: *amount, identity_balance_holder_id, + public_note: public_note.clone(), }) } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs index 060b7a408ae..6e0c82cf2cf 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs @@ -5,7 +5,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti }; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use dpp::identifier::Identifier; -use dpp::prelude::IdentityNonce; +use dpp::prelude::{DerivationEncryptionKeyIndex, IdentityNonce, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; use std::sync::Arc; use crate::drive::contract::DataContractFetchInfo; @@ -21,72 +21,124 @@ pub enum TokenTransferTransitionAction { V0(TokenTransferTransitionActionV0), } -/// Accessors trait for TokenTransferTransitionAction -pub trait TokenTransferTransitionActionAccessors { - /// Returns a reference to the base token transition action - fn base(&self) -> &TokenBaseTransitionAction; +impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenTransferTransitionAction::V0(v0) => v0.base(), + } + } - /// Returns a reference to the base token transition action - fn base_owned(self) -> TokenBaseTransitionAction; + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenTransferTransitionAction::V0(v0) => v0.base_owned(), + } + } - /// Returns the amount of tokens to transfer - fn amount(&self) -> u64; + fn amount(&self) -> u64 { + match self { + TokenTransferTransitionAction::V0(v0) => v0.amount(), + } + } - /// Returns the recipient ID - fn recipient_id(&self) -> Identifier; + fn recipient_id(&self) -> Identifier { + match self { + TokenTransferTransitionAction::V0(v0) => v0.recipient_id(), + } + } - /// Returns the token position in the contract - fn token_position(&self) -> u16 { - self.base().token_position() + fn public_note(&self) -> Option<&String> { + match self { + TokenTransferTransitionAction::V0(v0) => v0.public_note(), + } } - /// Returns the token ID - fn token_id(&self) -> Identifier { - self.base().token_id() + fn public_note_owned(self) -> Option { + match self { + TokenTransferTransitionAction::V0(v0) => v0.public_note_owned(), + } } - /// Returns the data contract ID - fn data_contract_id(&self) -> Identifier { - self.base().data_contract_id() + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenTransferTransitionAction::V0(v0) => v0.set_public_note(public_note), + } } - /// Returns a reference to the data contract fetch info - fn data_contract_fetch_info_ref(&self) -> &Arc { - self.base().data_contract_fetch_info_ref() + fn shared_encrypted_note(&self) -> Option<&(SenderKeyIndex, RecipientKeyIndex, Vec)> { + match self { + TokenTransferTransitionAction::V0(v0) => v0.shared_encrypted_note(), + } } - /// Returns the data contract fetch info - fn data_contract_fetch_info(&self) -> Arc { - self.base().data_contract_fetch_info() + fn shared_encrypted_note_owned(self) -> Option<(SenderKeyIndex, RecipientKeyIndex, Vec)> { + match self { + TokenTransferTransitionAction::V0(v0) => v0.shared_encrypted_note_owned(), + } } - /// Returns the identity contract nonce - fn identity_contract_nonce(&self) -> IdentityNonce { - self.base().identity_contract_nonce() + fn set_shared_encrypted_note( + &mut self, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + ) { + match self { + TokenTransferTransitionAction::V0(v0) => { + v0.set_shared_encrypted_note(shared_encrypted_note) + } + } } -} -impl TokenTransferTransitionActionAccessors for TokenTransferTransitionAction { - fn base(&self) -> &TokenBaseTransitionAction { + fn private_encrypted_note( + &self, + ) -> Option<&( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )> { match self { - TokenTransferTransitionAction::V0(v0) => v0.base(), + TokenTransferTransitionAction::V0(v0) => v0.private_encrypted_note(), } } - fn base_owned(self) -> TokenBaseTransitionAction { + + fn private_encrypted_note_owned( + self, + ) -> Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )> { match self { - TokenTransferTransitionAction::V0(v0) => v0.base_owned(), + TokenTransferTransitionAction::V0(v0) => v0.private_encrypted_note_owned(), } } - fn amount(&self) -> u64 { + fn set_private_encrypted_note( + &mut self, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { match self { - TokenTransferTransitionAction::V0(v0) => v0.amount(), + TokenTransferTransitionAction::V0(v0) => { + v0.set_private_encrypted_note(private_encrypted_note) + } } } - fn recipient_id(&self) -> Identifier { + fn notes_owned( + self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { match self { - TokenTransferTransitionAction::V0(v0) => v0.recipient_id(), + TokenTransferTransitionAction::V0(v0) => v0.notes_owned(), } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs index acebdbcf653..e1d318d219a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs @@ -3,7 +3,10 @@ mod transformer; use std::sync::Arc; use dpp::identifier::Identifier; -use dpp::prelude::IdentityNonce; +use dpp::prelude::{ + DerivationEncryptionKeyIndex, IdentityNonce, RecipientKeyIndex, RootEncryptionKeyIndex, + SenderKeyIndex, +}; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{ @@ -19,6 +22,16 @@ pub struct TokenTransferTransitionActionV0 { pub amount: u64, /// The recipient owner ID pub recipient_id: Identifier, + /// The public note + pub public_note: Option, + /// An optional shared encrypted note + pub shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + /// An optional private encrypted note + pub private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, } /// Accessors for `TokenTransferTransitionActionV0` @@ -35,11 +48,16 @@ pub trait TokenTransferTransitionActionAccessorsV0 { /// Returns the recipient owner ID fn recipient_id(&self) -> Identifier; - /// Returns the token ID from the base action - fn token_id(&self) -> u16 { + /// Returns the token position in the contract + fn token_position(&self) -> u16 { self.base().token_position() } + /// Returns the token ID + fn token_id(&self) -> Identifier { + self.base().token_id() + } + /// Returns the data contract ID from the base action fn data_contract_id(&self) -> Identifier { self.base().data_contract_id() @@ -59,6 +77,68 @@ pub trait TokenTransferTransitionActionAccessorsV0 { fn identity_contract_nonce(&self) -> IdentityNonce { self.base().identity_contract_nonce() } + + /// Returns the public note, if present + fn public_note(&self) -> Option<&String>; + + /// Consumes the `TokenTransferTransitionActionV0` and returns the public note, if present + fn public_note_owned(self) -> Option; + + /// Sets the public note + fn set_public_note(&mut self, public_note: Option); + + /// Returns the shared encrypted note, if present + fn shared_encrypted_note(&self) -> Option<&(SenderKeyIndex, RecipientKeyIndex, Vec)>; + + /// Consumes the `TokenTransferTransitionActionV0` and returns the shared encrypted note, if present + fn shared_encrypted_note_owned(self) -> Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>; + + /// Sets the shared encrypted note + fn set_shared_encrypted_note( + &mut self, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + ); + + /// Returns the private encrypted note, if present + fn private_encrypted_note( + &self, + ) -> Option<&( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>; + + /// Consumes the `TokenTransferTransitionActionV0` and returns the private encrypted note, if present + fn private_encrypted_note_owned( + self, + ) -> Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>; + + /// Sets the private encrypted note + fn set_private_encrypted_note( + &mut self, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ); + + /// All notes + fn notes_owned( + self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ); } impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionActionV0 { @@ -77,4 +157,80 @@ impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionActionV fn recipient_id(&self) -> Identifier { self.recipient_id } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } + + fn shared_encrypted_note(&self) -> Option<&(SenderKeyIndex, RecipientKeyIndex, Vec)> { + self.shared_encrypted_note.as_ref() + } + + fn shared_encrypted_note_owned(self) -> Option<(SenderKeyIndex, RecipientKeyIndex, Vec)> { + self.shared_encrypted_note + } + + fn set_shared_encrypted_note( + &mut self, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + ) { + self.shared_encrypted_note = shared_encrypted_note; + } + + fn private_encrypted_note( + &self, + ) -> Option<&( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )> { + self.private_encrypted_note.as_ref() + } + + fn private_encrypted_note_owned( + self, + ) -> Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )> { + self.private_encrypted_note + } + + fn set_private_encrypted_note( + &mut self, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { + self.private_encrypted_note = private_encrypted_note; + } + + fn notes_owned( + self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { + ( + self.public_note, + self.shared_encrypted_note, + self.private_encrypted_note, + ) + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index f543a19b219..dec31daefc3 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -18,6 +18,9 @@ impl TokenTransferTransitionActionV0 { base, amount, recipient_owner_id, + public_note, + shared_encrypted_note, + private_encrypted_note, } = value; let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( @@ -29,6 +32,9 @@ impl TokenTransferTransitionActionV0 { base: base_action, amount, recipient_id: recipient_owner_id, + public_note, + shared_encrypted_note, + private_encrypted_note, }) } @@ -41,6 +47,9 @@ impl TokenTransferTransitionActionV0 { base, amount, recipient_owner_id, + public_note, + shared_encrypted_note, + private_encrypted_note, } = value; let base_action = @@ -53,6 +62,9 @@ impl TokenTransferTransitionActionV0 { base: base_action.into(), amount: *amount, recipient_id: *recipient_owner_id, + public_note: public_note.clone(), + shared_encrypted_note: shared_encrypted_note.clone(), + private_encrypted_note: private_encrypted_note.clone(), }) } } diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index 527db6f1693..51efa60fbca 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -5,6 +5,8 @@ use crate::util::batch::drive_op_batch::DriveLowLevelOperationConverter; use dpp::balances::credits::TokenAmount; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; +use dpp::tokens::token_event::TokenEvent; use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; use platform_version::version::PlatformVersion; @@ -44,6 +46,17 @@ pub enum TokenOperationType { /// The amount to transfer amount: TokenAmount, }, + /// Adds a document to a contract matching the desired info. + TokenHistory { + /// The token id + token_id: Identifier, + /// The identity making the event + owner_id: Identifier, + /// The nonce + nonce: IdentityNonce, + /// The token event + event: TokenEvent, + }, } impl DriveLowLevelOperationConverter for TokenOperationType { @@ -53,7 +66,7 @@ impl DriveLowLevelOperationConverter for TokenOperationType { estimated_costs_only_with_layer_info: &mut Option< HashMap, >, - _block_info: &BlockInfo, + block_info: &BlockInfo, transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { @@ -115,6 +128,24 @@ impl DriveLowLevelOperationConverter for TokenOperationType { )?; Ok(batch_operations) } + TokenOperationType::TokenHistory { + token_id, + owner_id, + nonce, + event, + } => { + let batch_operations = drive.add_token_transaction_history_operations( + token_id, + owner_id, + nonce, + event, + block_info, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + Ok(batch_operations) + } } } } diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/mod.rs index 113e8f40f10..2a2a033ff46 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/mod.rs @@ -34,8 +34,14 @@ impl Drive { P: IntoIterator,

::IntoIter: ExactSizeIterator + DoubleEndedIterator + Clone, { - match drive_version.grove_methods.batch.batch_insert_empty_sum_tree { - 0 => self.batch_insert_empty_sum_tree_v0(path, key_info, storage_flags, drive_operations), + match drive_version + .grove_methods + .batch + .batch_insert_empty_sum_tree + { + 0 => { + self.batch_insert_empty_sum_tree_v0(path, key_info, storage_flags, drive_operations) + } version => Err(Error::Drive(DriveError::UnknownVersionMismatch { method: "batch_insert_empty_sum_tree".to_string(), known_versions: vec![0], diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs index 7753b9f6729..fb76aa3f18c 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_sum_tree/v0/mod.rs @@ -30,11 +30,13 @@ impl Drive { Ok(()) } KeySize(key) => { - drive_operations.push(LowLevelDriveOperation::for_estimated_path_key_empty_sum_tree( - KeyInfoPath::from_known_path(path), - key, - storage_flags, - )); + drive_operations.push( + LowLevelDriveOperation::for_estimated_path_key_empty_sum_tree( + KeyInfoPath::from_known_path(path), + key, + storage_flags, + ), + ); Ok(()) } Key(key) => { diff --git a/packages/rs-drive/src/verify/mod.rs b/packages/rs-drive/src/verify/mod.rs index f0a4dc388ba..18474b4bbb7 100644 --- a/packages/rs-drive/src/verify/mod.rs +++ b/packages/rs-drive/src/verify/mod.rs @@ -12,8 +12,8 @@ pub mod system; /// Verifies that a state transition contents exist in the proof pub mod state_transition; -pub mod voting; mod tokens; +pub mod voting; /// Represents the root hash of the grovedb tree pub type RootHash = [u8; 32]; diff --git a/packages/rs-drive/src/verify/tokens/mod.rs b/packages/rs-drive/src/verify/tokens/mod.rs index 1a9a9421a46..7f169cda4e2 100644 --- a/packages/rs-drive/src/verify/tokens/mod.rs +++ b/packages/rs-drive/src/verify/tokens/mod.rs @@ -1 +1 @@ -mod verify_token_balances_for_identity_ids; \ No newline at end of file +mod verify_token_balances_for_identity_ids; diff --git a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs index 4303bf196a3..078408d9924 100644 --- a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs +++ b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs @@ -1,8 +1,8 @@ mod v0; -use std::collections::BTreeMap; -use dpp::balances::credits::TokenAmount; use crate::drive::Drive; +use dpp::balances::credits::TokenAmount; +use std::collections::BTreeMap; use crate::error::drive::DriveError; @@ -16,7 +16,7 @@ impl Drive { /// Verifies the token balances for a set of identity IDs. /// /// This function checks the token balances of multiple identities by verifying the provided - /// proof against the specified token ID and identity IDs. It also supports verifying a subset + /// proof against the specified token ID and identity IDs. It also supports verifying a subset /// of a larger proof if necessary. /// /// # Parameters @@ -27,7 +27,7 @@ impl Drive { /// is being verified. /// - `identity_ids`: A slice of 32-byte arrays, each representing a unique identity ID. These /// are the identities whose token balances are being verified. - /// - `verify_subset_of_proof`: A boolean flag indicating whether the proof being verified is a + /// - `verify_subset_of_proof`: A boolean flag indicating whether the proof being verified is a /// subset of a larger proof. If `true`, the verification will consider only a part of the proof. /// - `platform_version`: The version of the platform against which the identity token balances are /// being verified. This ensures compatibility with the correct API version. @@ -52,7 +52,7 @@ impl Drive { I: From<[u8; 32]>, >( proof: &[u8], - token_id: [u8;32], + token_id: [u8; 32], identity_ids: &[[u8; 32]], verify_subset_of_proof: bool, platform_version: &PlatformVersion, diff --git a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs index c6e152e6413..be941cc5a58 100644 --- a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs +++ b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs @@ -5,9 +5,9 @@ use crate::error::Error; use crate::verify::RootHash; -use grovedb::GroveDb; use dpp::balances::credits::TokenAmount; use dpp::fee::Credits; +use grovedb::GroveDb; use platform_version::version::PlatformVersion; impl Drive { @@ -16,7 +16,7 @@ impl Drive { I: From<[u8; 32]>, >( proof: &[u8], - token_id: [u8;32], + token_id: [u8; 32], identity_ids: &[[u8; 32]], verify_subset_of_proof: bool, platform_version: &PlatformVersion, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 8f47a00183c..1daea28aeb3 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -31,4 +31,5 @@ pub struct DriveTokenUpdateMethodVersions { pub remove_from_token_total_supply: FeatureVersion, pub remove_from_identity_token_balance: FeatureVersion, pub add_to_identity_token_balance: FeatureVersion, + pub add_transaction_history_operations: FeatureVersion, } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index f021ede2b3b..c2afcae91e9 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -21,5 +21,6 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM remove_from_token_total_supply: 0, remove_from_identity_token_balance: 0, add_to_identity_token_balance: 0, + add_transaction_history_operations: 0, }, }; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs index 9604882fe69..d012f3e6acf 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs @@ -1,4 +1,9 @@ -use crate::version::drive_versions::drive_verify_method_versions::{DriveVerifyContractMethodVersions, DriveVerifyDocumentMethodVersions, DriveVerifyIdentityMethodVersions, DriveVerifyMethodVersions, DriveVerifySingleDocumentMethodVersions, DriveVerifyStateTransitionMethodVersions, DriveVerifySystemMethodVersions, DriveVerifyTokenMethodVersions, DriveVerifyVoteMethodVersions}; +use crate::version::drive_versions::drive_verify_method_versions::{ + DriveVerifyContractMethodVersions, DriveVerifyDocumentMethodVersions, + DriveVerifyIdentityMethodVersions, DriveVerifyMethodVersions, + DriveVerifySingleDocumentMethodVersions, DriveVerifyStateTransitionMethodVersions, + DriveVerifySystemMethodVersions, DriveVerifyTokenMethodVersions, DriveVerifyVoteMethodVersions, +}; pub const DRIVE_VERIFY_METHOD_VERSIONS_V1: DriveVerifyMethodVersions = DriveVerifyMethodVersions { contract: DriveVerifyContractMethodVersions { diff --git a/packages/rs-platform-version/src/version/mod.rs b/packages/rs-platform-version/src/version/mod.rs index f060faae78c..b0ae65471cb 100644 --- a/packages/rs-platform-version/src/version/mod.rs +++ b/packages/rs-platform-version/src/version/mod.rs @@ -1,6 +1,6 @@ mod protocol_version; -pub use protocol_version::*; use crate::version::v8::PROTOCOL_VERSION_8; +pub use protocol_version::*; mod consensus_versions; pub mod dpp_versions; diff --git a/packages/token-history-contract/schema/v1/token-history-contract-documents.json b/packages/token-history-contract/schema/v1/token-history-contract-documents.json index 1f71eb10ee5..a364d38776f 100644 --- a/packages/token-history-contract/schema/v1/token-history-contract-documents.json +++ b/packages/token-history-contract/schema/v1/token-history-contract-documents.json @@ -134,7 +134,7 @@ "note": { "type": "string", "maxLength": 2048, - "description": "An optional explanation of why this burn took place", + "description": "An optional explanation of why this mint took place", "position": 2 } }, @@ -226,6 +226,52 @@ "maxItems": 32, "description": "The identity or the group Id", "position": 2 + }, + "encryptedPersonalNote": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 2048, + "description": "An optional encrypted explanation of why this transfer took place only meant for the sender", + "position": 3 + }, + "encryptedSharedNote": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 2048, + "description": "An optional encrypted explanation of why this transfer took place shared between the sender and the receiver", + "position": 4 + }, + "publicNote": { + "type": "string", + "maxLength": 2048, + "description": "An optional public explanation of why this transfer took place", + "position": 5 + }, + "senderKeyIndex": { + "type": "integer", + "minimum": 0, + "description": "Used with the encrypted shared note", + "position": 6 + }, + "recipientKeyIndex": { + "type": "integer", + "minimum": 0, + "description": "Used with the encrypted shared note", + "position": 7 + }, + "rootEncryptionKeyIndex": { + "type": "integer", + "minimum": 0, + "description": "Used with the encrypted private note", + "position": 8 + }, + "derivationEncryptionKeyIndex": { + "type": "integer", + "minimum": 0, + "description": "Used with the encrypted private note", + "position": 9 } }, "required": [ diff --git a/packages/wasm-dpp/src/document/state_transition/batch_transition/batched_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/batched_transition/mod.rs index c7c58b54719..d83ae4d4735 100644 --- a/packages/wasm-dpp/src/document/state_transition/batch_transition/batched_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/batch_transition/batched_transition/mod.rs @@ -1,5 +1,5 @@ -use wasm_bindgen::prelude::wasm_bindgen; use dpp::state_transition::batch_transition::batched_transition::BatchedTransition; +use wasm_bindgen::prelude::wasm_bindgen; #[wasm_bindgen(js_name=BatchedTransition)] #[derive(Debug, Clone)] diff --git a/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs index f0fc312bcbc..30396e17fc9 100644 --- a/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs @@ -31,12 +31,12 @@ use dpp::ed25519_dalek::ed25519::signature::SignerMut; use dpp::state_transition::batch_transition::batched_transition::BatchedTransition; use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; -use dpp::state_transition::StateTransitionIdentitySigned; use crate::batch_transition::batched_transition::BatchedTransitionWasm; +use dpp::state_transition::StateTransitionIdentitySigned; +mod batched_transition; pub mod document_transition; mod token_transition; -mod batched_transition; // pub mod validation; #[derive(Clone, Debug)] diff --git a/packages/wasm-dpp/src/document/state_transition/batch_transition/token_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/token_transition/mod.rs index 67b4b4bd885..7b10fb55c14 100644 --- a/packages/wasm-dpp/src/document/state_transition/batch_transition/token_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/batch_transition/token_transition/mod.rs @@ -1,5 +1,5 @@ -use wasm_bindgen::prelude::wasm_bindgen; use dpp::state_transition::batch_transition::batched_transition::token_transition::TokenTransition; +use wasm_bindgen::prelude::wasm_bindgen; #[wasm_bindgen(js_name=TokenTransition)] #[derive(Debug, Clone)] diff --git a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs index 85bbbc4e6b2..496ab2fc6f3 100644 --- a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs @@ -572,11 +572,7 @@ fn from_basic_error(basic_error: &BasicError) -> JsValue { .into() } BasicError::DataContractTokenConfigurationUpdateError(e) => { - generic_consensus_error!( - DataContractTokenConfigurationUpdateError, - e - ) - .into() + generic_consensus_error!(DataContractTokenConfigurationUpdateError, e).into() } } } diff --git a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs index d57903a8dcb..2ba1a0e025c 100644 --- a/packages/wasm-dpp/src/state_transition/state_transition_factory.rs +++ b/packages/wasm-dpp/src/state_transition/state_transition_factory.rs @@ -1,5 +1,5 @@ -use crate::data_contract::{DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm}; use crate::batch_transition::BatchTransitionWasm; +use crate::data_contract::{DataContractCreateTransitionWasm, DataContractUpdateTransitionWasm}; use crate::errors::from_dpp_err; use crate::identity::state_transition::{ IdentityCreateTransitionWasm, IdentityCreditTransferTransitionWasm, From 4135031e385ec56e526facca2c9ec6df6a94d6d5 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 30 Dec 2024 10:29:47 +0700 Subject: [PATCH 26/61] work on group actions --- .../rs-dpp/src/data_contract/accessors/mod.rs | 16 +- .../src/data_contract/accessors/v1/mod.rs | 12 +- .../token_configuration/accessors/v0/mod.rs | 1 - .../token_configuration/mod.rs | 2 +- .../token_configuration/v0/mod.rs | 2 +- .../authorized_action_takers.rs | 2 +- .../document_type/restricted_creation/mod.rs | 2 +- .../rs-dpp/src/data_contract/group/mod.rs | 20 +- .../rs-dpp/src/data_contract/group/v0/mod.rs | 18 +- packages/rs-dpp/src/data_contract/mod.rs | 7 +- .../serialized_version/v0/mod.rs | 2 +- .../serialized_version/v1/mod.rs | 10 +- .../src/data_contract/v1/accessors/mod.rs | 14 +- .../src/data_contract/v1/data_contract.rs | 10 +- .../src/document/generate_document_id.rs | 1 - .../consensus/state/data_trigger/mod.rs | 2 +- packages/rs-dpp/src/group/action_event.rs | 12 + packages/rs-dpp/src/group/group_action/mod.rs | 14 + .../rs-dpp/src/group/group_action/v0/mod.rs | 12 + packages/rs-dpp/src/group/mod.rs | 29 ++ .../chain/chain_asset_lock_proof.rs | 1 - .../state_transition/asset_lock_proof/mod.rs | 2 +- packages/rs-dpp/src/lib.rs | 1 + .../batched_transition/document_transition.rs | 6 +- .../batched_transition/mod.rs | 1 + .../batched_transition/multi_party_action.rs | 5 + .../batched_transition/resolvers.rs | 6 +- .../token_base_transition/fields.rs | 2 + .../token_base_transition/v0/mod.rs | 40 ++- .../token_base_transition/v0/v0_methods.rs | 17 ++ .../token_base_transition/v0_methods.rs | 18 +- .../token_burn_transition/v0/v0_methods.rs | 24 +- .../token_burn_transition/v0_methods.rs | 10 + .../token_issuance_transition/mod.rs | 10 +- .../token_issuance_transition/v0/mod.rs | 4 +- .../v0/v0_methods.rs | 27 +- .../token_issuance_transition/v0_methods.rs | 37 ++- .../batched_transition/token_transition.rs | 8 +- .../document/batch_transition/mod.rs | 2 +- .../batch_transition/resolvers/v0/mod.rs | 4 +- packages/rs-dpp/src/tokens/errors.rs | 2 + packages/rs-dpp/src/tokens/token_event.rs | 8 +- .../contender_structs/contender/v0/mod.rs | 2 +- .../src/voting/contender_structs/mod.rs | 2 +- .../mod.rs | 2 +- .../mod.rs | 2 +- packages/rs-dpp/src/voting/vote_polls/mod.rs | 2 +- .../src/voting/votes/resource_vote/mod.rs | 2 +- .../v0/mod.rs | 11 + .../batch/transformer/v0/mod.rs | 34 ++- .../v0/mod.rs | 1 + .../contract/insert/insert_contract/mod.rs | 2 + .../contract/insert/insert_contract/v1/mod.rs | 15 +- .../contract/update/update_contract/v1/mod.rs | 21 +- .../group/insert/add_group_action/mod.rs | 121 +++++++++ .../group/insert/add_group_action/v0/mod.rs | 199 ++++++++++++++ .../drive/group/insert/add_new_groups/mod.rs | 99 +++++++ .../group/insert/add_new_groups/v0/mod.rs | 251 ++++++++++++++++++ .../rs-drive/src/drive/group/insert/mod.rs | 2 + packages/rs-drive/src/drive/group/mod.rs | 152 +++++++++++ .../src/drive/initialization/v1/mod.rs | 27 +- packages/rs-drive/src/drive/mod.rs | 13 +- .../prove_identities_token_balances/v0/mod.rs | 175 ++++++++---- .../token_base_transition_action/mod.rs | 14 + .../transformer.rs | 11 +- .../token_base_transition_action/v0/mod.rs | 23 ++ .../v0/transformer.rs | 31 ++- .../transformer.rs | 13 +- .../v0/transformer.rs | 13 +- .../token_mint_transition_action/mod.rs | 2 +- .../transformer.rs | 47 ++-- .../token_mint_transition_action/v0/mod.rs | 4 +- .../v0/transformer.rs | 45 ++-- .../transformer.rs | 11 +- .../v0/transformer.rs | 13 +- .../src/util/batch/grovedb_op_batch/mod.rs | 2 + .../mod.rs | 71 +++++ .../v0/mod.rs | 224 ++++++++++++++++ .../rs-drive/src/util/grove_operations/mod.rs | 2 + .../drive_contract_method_versions/v2.rs | 2 +- .../drive_group_method_versions/mod.rs | 26 ++ .../drive_group_method_versions/v1.rs | 14 + .../drive_grove_method_versions/mod.rs | 1 + .../drive_grove_method_versions/v1.rs | 1 + .../src/version/drive_versions/mod.rs | 5 +- .../src/version/drive_versions/v1.rs | 2 + .../src/version/drive_versions/v2.rs | 2 + .../src/version/drive_versions/v3.rs | 2 + .../src/version/mocks/v2_test.rs | 2 + 89 files changed, 1890 insertions(+), 251 deletions(-) create mode 100644 packages/rs-dpp/src/group/action_event.rs create mode 100644 packages/rs-dpp/src/group/group_action/mod.rs create mode 100644 packages/rs-dpp/src/group/group_action/v0/mod.rs create mode 100644 packages/rs-dpp/src/group/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/multi_party_action.rs create mode 100644 packages/rs-drive/src/drive/group/insert/add_group_action/mod.rs create mode 100644 packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/group/insert/add_new_groups/mod.rs create mode 100644 packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/group/insert/mod.rs create mode 100644 packages/rs-drive/src/drive/group/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs create mode 100644 packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs create mode 100644 packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index 4d320e7a001..4840054ef76 100644 --- a/packages/rs-dpp/src/data_contract/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/mod.rs @@ -1,7 +1,9 @@ use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use crate::data_contract::config::DataContractConfig; use crate::data_contract::document_type::{DocumentType, DocumentTypeRef}; -use crate::data_contract::{DocumentName, TokenContractPosition, EMPTY_GROUPS, EMPTY_TOKENS}; +use crate::data_contract::{ + DocumentName, GroupContractPosition, TokenContractPosition, EMPTY_GROUPS, EMPTY_TOKENS, +}; use crate::metadata::Metadata; use crate::prelude::DataContract; @@ -10,7 +12,7 @@ use platform_value::Identifier; use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1Setters}; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::errors::DataContractError; -use crate::data_contract::group::{Group, GroupName}; +use crate::data_contract::group::Group; use std::collections::BTreeMap; pub mod v0; @@ -187,7 +189,7 @@ impl DataContractV0Setters for DataContract { /// Implementing DataContractV1Getters for DataContract impl DataContractV1Getters for DataContract { /// Returns a reference to the groups map. - fn groups(&self) -> &BTreeMap { + fn groups(&self) -> &BTreeMap { match self { DataContract::V0(_) => &EMPTY_GROUPS, DataContract::V1(v1) => &v1.groups, @@ -196,7 +198,7 @@ impl DataContractV1Getters for DataContract { /// Returns a mutable reference to the groups map. /// Returns `None` for V0 since it doesn't have groups. - fn groups_mut(&mut self) -> Option<&mut BTreeMap> { + fn groups_mut(&mut self) -> Option<&mut BTreeMap> { match self { DataContract::V0(_) => None, DataContract::V1(v1) => Some(&mut v1.groups), @@ -230,7 +232,7 @@ impl DataContractV1Getters for DataContract { impl DataContractV1Setters for DataContract { /// Sets the groups map for the data contract. - fn set_groups(&mut self, groups: BTreeMap) { + fn set_groups(&mut self, groups: BTreeMap) { match self { DataContract::V0(_) => {} DataContract::V1(v1) => { @@ -250,11 +252,11 @@ impl DataContractV1Setters for DataContract { } /// Adds or updates a single group in the groups map. - fn add_group(&mut self, name: GroupName, group: Group) { + fn add_group(&mut self, position: GroupContractPosition, group: Group) { match self { DataContract::V0(_) => {} DataContract::V1(v1) => { - v1.groups.insert(name, group); + v1.groups.insert(position, group); } } } diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs index 78a0df7a9b7..489d45b5f18 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -1,16 +1,16 @@ use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; -use crate::data_contract::group::{Group, GroupName}; -use crate::data_contract::TokenContractPosition; +use crate::data_contract::group::Group; +use crate::data_contract::{GroupContractPosition, TokenContractPosition}; use platform_value::Identifier; use std::collections::BTreeMap; pub trait DataContractV1Getters: DataContractV0Getters { /// Returns a reference to the groups map. - fn groups(&self) -> &BTreeMap; + fn groups(&self) -> &BTreeMap; /// Returns a mutable reference to the groups map. - fn groups_mut(&mut self) -> Option<&mut BTreeMap>; + fn groups_mut(&mut self) -> Option<&mut BTreeMap>; /// Returns a reference to the tokens map. fn tokens(&self) -> &BTreeMap; @@ -24,13 +24,13 @@ pub trait DataContractV1Getters: DataContractV0Getters { pub trait DataContractV1Setters: DataContractV0Setters { /// Sets the groups map for the data contract. - fn set_groups(&mut self, groups: BTreeMap); + fn set_groups(&mut self, groups: BTreeMap); /// Sets the tokens map for the data contract. fn set_tokens(&mut self, tokens: BTreeMap); /// Adds or updates a single group in the groups map. - fn add_group(&mut self, name: GroupName, group: Group); + fn add_group(&mut self, pos: GroupContractPosition, group: Group); /// Adds or updates a single token configuration in the tokens map. fn add_token(&mut self, pos: TokenContractPosition, token: TokenConfiguration); diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs index a08b4590185..ff06d882bd5 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -1,5 +1,4 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationConventionV0; -use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::group::RequiredSigners; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs index fa82163d4cc..e5e34c66646 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/mod.rs @@ -1,5 +1,5 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use bincode::{Decode, Encode}; use derive_more::From; use serde::{Deserialize, Serialize}; use std::borrow::Cow; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index d6f32abdf25..ad86bc0d76b 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -4,7 +4,7 @@ use crate::data_contract::change_control_rules::authorized_action_takers::Author use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::group::RequiredSigners; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use bincode::{Decode, Encode}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, BTreeSet}; diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs b/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs index e099c8cbd9b..e669504cda4 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs @@ -1,7 +1,7 @@ use crate::data_contract::group::accessors::v0::GroupV0Getters; use crate::data_contract::group::{Group, GroupMemberPower}; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::multi_identity_events::ActionTaker; +use bincode::{Decode, Encode}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; diff --git a/packages/rs-dpp/src/data_contract/document_type/restricted_creation/mod.rs b/packages/rs-dpp/src/data_contract/document_type/restricted_creation/mod.rs index 81194382f46..e875a6fe2c4 100644 --- a/packages/rs-dpp/src/data_contract/document_type/restricted_creation/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/restricted_creation/mod.rs @@ -1,8 +1,8 @@ use crate::consensus::basic::data_contract::UnknownDocumentCreationRestrictionModeError; use crate::consensus::basic::BasicError; use crate::consensus::ConsensusError; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::ProtocolError; +use bincode::{Decode, Encode}; use std::fmt; use std::fmt::{Display, Formatter}; diff --git a/packages/rs-dpp/src/data_contract/group/mod.rs b/packages/rs-dpp/src/data_contract/group/mod.rs index c1762fad525..df3427ede35 100644 --- a/packages/rs-dpp/src/data_contract/group/mod.rs +++ b/packages/rs-dpp/src/data_contract/group/mod.rs @@ -1,19 +1,31 @@ use crate::data_contract::group::accessors::v0::{GroupV0Getters, GroupV0Setters}; use crate::data_contract::group::v0::GroupV0; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use crate::errors::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; pub mod accessors; mod v0; - -pub type GroupName = String; pub type RequiredSigners = u8; pub type GroupMemberPower = u32; pub type GroupRequiredPower = u32; -#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[derive( + Serialize, + Deserialize, + Decode, + Encode, + PlatformSerialize, + PlatformDeserialize, + Debug, + Clone, + PartialEq, + Eq, +)] +#[platform_serialize(unversioned)] pub enum Group { V0(GroupV0), } diff --git a/packages/rs-dpp/src/data_contract/group/v0/mod.rs b/packages/rs-dpp/src/data_contract/group/v0/mod.rs index ae8b64532a0..00dbb9bee63 100644 --- a/packages/rs-dpp/src/data_contract/group/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/group/v0/mod.rs @@ -1,11 +1,25 @@ use crate::data_contract::group::accessors::v0::{GroupV0Getters, GroupV0Setters}; use crate::data_contract::group::{GroupMemberPower, GroupRequiredPower}; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; -#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[derive( + Serialize, + Deserialize, + Decode, + Encode, + PlatformSerialize, + PlatformDeserialize, + Debug, + Clone, + PartialEq, + Eq, +)] +#[platform_serialize(unversioned)] pub struct GroupV0 { pub members: BTreeMap, pub required_power: GroupRequiredPower, diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index b58bd46cce9..0897fd20287 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -38,7 +38,7 @@ pub mod accessors; pub mod associated_token; pub mod change_control_rules; pub mod config; -mod group; +pub mod group; pub mod storage_requirements; use crate::data_contract::serialized_version::{ @@ -51,7 +51,7 @@ use crate::ProtocolError; use crate::ProtocolError::{PlatformDeserializationError, PlatformSerializationError}; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; -use crate::data_contract::group::{Group, GroupName}; +use crate::data_contract::group::Group; use crate::data_contract::v0::DataContractV0; use crate::data_contract::v1::DataContractV1; use platform_version::TryIntoPlatformVersioned; @@ -62,13 +62,14 @@ type JsonSchema = JsonValue; type DefinitionName = String; pub type DocumentName = String; pub type TokenName = String; +pub type GroupContractPosition = u16; pub type TokenContractPosition = u16; type PropertyPath = String; pub const INITIAL_DATA_CONTRACT_VERSION: u32 = 1; // Define static empty BTreeMaps -static EMPTY_GROUPS: Lazy> = Lazy::new(|| BTreeMap::new()); +static EMPTY_GROUPS: Lazy> = Lazy::new(|| BTreeMap::new()); static EMPTY_TOKENS: Lazy> = Lazy::new(|| BTreeMap::new()); diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs index 03591d44fea..6cd119e3bf0 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v0/mod.rs @@ -5,7 +5,7 @@ use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::v0::DataContractV0; use crate::data_contract::v1::DataContractV1; use crate::data_contract::{DataContract, DefinitionName, DocumentName}; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use bincode::{Decode, Encode}; use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index de7c8cbac79..176f06f57d1 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -3,11 +3,13 @@ use crate::data_contract::config::DataContractConfig; use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; -use crate::data_contract::group::{Group, GroupName}; +use crate::data_contract::group::Group; use crate::data_contract::v0::DataContractV0; use crate::data_contract::v1::DataContractV1; -use crate::data_contract::{DataContract, DefinitionName, DocumentName, TokenContractPosition}; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use crate::data_contract::{ + DataContract, DefinitionName, DocumentName, GroupContractPosition, TokenContractPosition, +}; +use bincode::{Decode, Encode}; use platform_value::{Identifier, Value}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -35,7 +37,7 @@ pub struct DataContractInSerializationFormatV1 { pub document_schemas: BTreeMap, /// Groups that allow for specific multiparty actions on the contract - pub groups: BTreeMap, + pub groups: BTreeMap, /// The tokens on the contract. pub tokens: BTreeMap, diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs index 07e0e597aa3..2dda757c4da 100644 --- a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -4,13 +4,13 @@ use crate::data_contract::document_type::{DocumentType, DocumentTypeRef}; use crate::data_contract::errors::DataContractError; use crate::data_contract::v1::DataContractV1; -use crate::data_contract::{DocumentName, TokenContractPosition}; +use crate::data_contract::{DocumentName, GroupContractPosition, TokenContractPosition}; use crate::metadata::Metadata; use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1Setters}; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; -use crate::data_contract::group::{Group, GroupName}; +use crate::data_contract::group::Group; use crate::util::hash::hash_double; use platform_value::Identifier; use std::collections::BTreeMap; @@ -144,11 +144,11 @@ impl DataContractV0Setters for DataContractV1 { } impl DataContractV1Getters for DataContractV1 { - fn groups(&self) -> &BTreeMap { + fn groups(&self) -> &BTreeMap { &self.groups } - fn groups_mut(&mut self) -> Option<&mut BTreeMap> { + fn groups_mut(&mut self) -> Option<&mut BTreeMap> { Some(&mut self.groups) } @@ -172,7 +172,7 @@ impl DataContractV1Getters for DataContractV1 { } impl DataContractV1Setters for DataContractV1 { - fn set_groups(&mut self, groups: BTreeMap) { + fn set_groups(&mut self, groups: BTreeMap) { self.groups = groups; } @@ -180,8 +180,8 @@ impl DataContractV1Setters for DataContractV1 { self.tokens = tokens; } - fn add_group(&mut self, name: GroupName, group: Group) { - self.groups.insert(name, group); + fn add_group(&mut self, group_position: GroupContractPosition, group: Group) { + self.groups.insert(group_position, group); } fn add_token(&mut self, name: TokenContractPosition, token: TokenConfiguration) { diff --git a/packages/rs-dpp/src/data_contract/v1/data_contract.rs b/packages/rs-dpp/src/data_contract/v1/data_contract.rs index 554d9ba475d..60a6527fd07 100644 --- a/packages/rs-dpp/src/data_contract/v1/data_contract.rs +++ b/packages/rs-dpp/src/data_contract/v1/data_contract.rs @@ -6,8 +6,10 @@ use platform_value::Value; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::config::DataContractConfig; use crate::data_contract::document_type::DocumentType; -use crate::data_contract::group::{Group, GroupName}; -use crate::data_contract::{DefinitionName, DocumentName, TokenContractPosition}; +use crate::data_contract::group::Group; +use crate::data_contract::{ + DefinitionName, DocumentName, GroupContractPosition, TokenContractPosition, +}; use crate::metadata::Metadata; /// `DataContractV1` represents a data contract in a decentralized platform. @@ -24,7 +26,7 @@ use crate::metadata::Metadata; /// In `DataContractV1`, two significant features were introduced to enhance contract governance /// and support token-related operations: /// -/// 1. **Groups** (`groups: BTreeMap`) +/// 1. **Groups** (`groups: BTreeMap`) /// - Groups allow for specific multiparty actions on the contract. Each group is defined with a /// set of members (`Identifier`) and their corresponding member power (`u32`). /// - Groups facilitate fine-grained access control and decision-making processes by enabling @@ -66,7 +68,7 @@ pub struct DataContractV1 { pub schema_defs: Option>, /// Groups that allow for specific multiparty actions on the contract - pub groups: BTreeMap, + pub groups: BTreeMap, /// The tokens on the contract. pub tokens: BTreeMap, diff --git a/packages/rs-dpp/src/document/generate_document_id.rs b/packages/rs-dpp/src/document/generate_document_id.rs index 96d4af68c17..b14fc599a44 100644 --- a/packages/rs-dpp/src/document/generate_document_id.rs +++ b/packages/rs-dpp/src/document/generate_document_id.rs @@ -1,5 +1,4 @@ use crate::document::Document; -use crate::prelude::IdentityNonce; use crate::{prelude::Identifier, util::hash::hash_double_to_vec}; impl Document { diff --git a/packages/rs-dpp/src/errors/consensus/state/data_trigger/mod.rs b/packages/rs-dpp/src/errors/consensus/state/data_trigger/mod.rs index a753c9ccd62..e43de444588 100644 --- a/packages/rs-dpp/src/errors/consensus/state/data_trigger/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/state/data_trigger/mod.rs @@ -4,7 +4,7 @@ use crate::consensus::state::data_trigger::data_trigger_invalid_result_error::Da use crate::consensus::state::state_error::StateError; use crate::consensus::ConsensusError; use crate::errors::ProtocolError; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use bincode::{Decode, Encode}; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use thiserror::Error; diff --git a/packages/rs-dpp/src/group/action_event.rs b/packages/rs-dpp/src/group/action_event.rs new file mode 100644 index 00000000000..54cb5a950f5 --- /dev/null +++ b/packages/rs-dpp/src/group/action_event.rs @@ -0,0 +1,12 @@ +use crate::tokens::token_event::TokenEvent; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; + +#[derive( + Debug, PartialEq, PartialOrd, Clone, Eq, Encode, Decode, PlatformDeserialize, PlatformSerialize, +)] +#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version +pub enum GroupActionEvent { + TokenEvent(TokenEvent), +} diff --git a/packages/rs-dpp/src/group/group_action/mod.rs b/packages/rs-dpp/src/group/group_action/mod.rs new file mode 100644 index 00000000000..5f6ac854939 --- /dev/null +++ b/packages/rs-dpp/src/group/group_action/mod.rs @@ -0,0 +1,14 @@ +mod v0; + +use crate::group::group_action::v0::GroupActionV0; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; + +#[derive( + Debug, PartialEq, PartialOrd, Clone, Eq, Encode, Decode, PlatformDeserialize, PlatformSerialize, +)] +#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version +pub enum GroupAction { + V0(GroupActionV0), +} diff --git a/packages/rs-dpp/src/group/group_action/v0/mod.rs b/packages/rs-dpp/src/group/group_action/v0/mod.rs new file mode 100644 index 00000000000..5f90ce0788b --- /dev/null +++ b/packages/rs-dpp/src/group/group_action/v0/mod.rs @@ -0,0 +1,12 @@ +use crate::group::action_event::GroupActionEvent; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; + +#[derive( + Debug, PartialEq, PartialOrd, Clone, Eq, Encode, Decode, PlatformDeserialize, PlatformSerialize, +)] +#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version +pub struct GroupActionV0 { + pub event: GroupActionEvent, +} diff --git a/packages/rs-dpp/src/group/mod.rs b/packages/rs-dpp/src/group/mod.rs new file mode 100644 index 00000000000..42dda497ca1 --- /dev/null +++ b/packages/rs-dpp/src/group/mod.rs @@ -0,0 +1,29 @@ +use crate::data_contract::GroupContractPosition; +use bincode::{Decode, Encode}; +use derive_more::Display; +use platform_value::Identifier; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +pub mod action_event; +pub mod group_action; + +#[derive(Debug, Clone, Encode, Decode, Default, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[display("ID: {}, Action ID: {}", "id", "action_id")] +pub struct GroupStateTransitionInfo { + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "$groupContractPosition") + )] + pub group_contract_position: GroupContractPosition, + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "$groupActionId") + )] + pub action_id: Identifier, +} diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs index 0a7b020cc1a..6829ea6eaf3 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/chain/chain_asset_lock_proof.rs @@ -4,7 +4,6 @@ use std::convert::TryFrom; use crate::util::hash::hash_double; use crate::{identifier::Identifier, ProtocolError}; -pub use bincode::{Decode, Encode}; use dashcore::OutPoint; /// Instant Asset Lock Proof is a part of Identity Create and Identity Topup diff --git a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs index 2e97ad74808..a25ded9547e 100644 --- a/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs +++ b/packages/rs-dpp/src/identity/state_transition/asset_lock_proof/mod.rs @@ -4,7 +4,7 @@ use dashcore::{OutPoint, Transaction}; use serde::{Deserialize, Deserializer, Serialize}; -pub use bincode::{Decode, Encode}; +use bincode::{Decode, Encode}; pub use instant::*; use platform_value::Value; diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index de0c10f6c47..e1dd2787b1d 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -60,6 +60,7 @@ pub mod voting; #[cfg(feature = "core-types")] pub mod core_types; +pub mod group; pub mod withdrawal; pub use async_trait; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs index eae1a4790f8..910c0795ce9 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs @@ -3,9 +3,9 @@ use std::collections::BTreeMap; use derive_more::{Display, From}; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use bincode::{Encode, Decode}; use crate::prelude::{IdentityNonce, Revision}; -use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition}; +use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenMintTransition, TokenTransferTransition}; use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition}; use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use crate::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; @@ -86,7 +86,7 @@ impl BatchTransitionResolversV0 for DocumentTransition { None } - fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { + fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition> { None } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs index f4ff1666aff..8cfa58e7e37 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs @@ -12,6 +12,7 @@ pub mod document_transfer_transition; pub mod document_transition; pub mod document_transition_action_type; pub mod document_update_price_transition; +pub mod multi_party_action; mod resolvers; pub mod token_base_transition; pub mod token_burn_transition; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/multi_party_action.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/multi_party_action.rs new file mode 100644 index 00000000000..9b648ea5f90 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/multi_party_action.rs @@ -0,0 +1,5 @@ +use platform_value::Identifier; + +pub trait AllowedAsMultiPartyAction { + fn action_id(&self, owner_id: Identifier) -> Identifier; +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs index fde56d9f9e9..22fdba19a57 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs @@ -4,7 +4,7 @@ use crate::state_transition::batch_transition::batched_transition::{ use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; use crate::state_transition::batch_transition::{ DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, - TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition, + TokenBurnTransition, TokenMintTransition, TokenTransferTransition, }; impl BatchTransitionResolversV0 for BatchedTransition { @@ -50,7 +50,7 @@ impl BatchTransitionResolversV0 for BatchedTransition { } } - fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { + fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition> { match self { BatchedTransition::Document(_) => None, BatchedTransition::Token(token) => token.as_transition_token_issuance(), @@ -108,7 +108,7 @@ impl<'a> BatchTransitionResolversV0 for BatchedTransitionRef<'a> { } } - fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { + fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition> { match self { BatchedTransitionRef::Document(_) => None, BatchedTransitionRef::Token(token) => token.as_transition_token_issuance(), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs index 2863c1718d9..98529f9e9e5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs @@ -2,6 +2,8 @@ pub(in crate::state_transition::state_transitions::document::batch_transition) m pub const DATA_CONTRACT_ID: &str = "$dataContractId"; pub const TOKEN_CONTRACT_POSITION: &str = "$tokenContractPosition"; pub const TOKEN_ID: &str = "$tokenId"; + pub const GROUP_CONTRACT_POSITION: &str = "$groupContractPosition"; + pub const GROUP_ACTION_ID: &str = "$groupActionId"; pub const ACTION: &str = "$action"; pub const IDENTITY_CONTRACT_NONCE: &str = "$identityContractNonce"; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs index 7a695e5040d..e685bccdbee 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs @@ -15,10 +15,15 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "state-transition-value-conversion")] use crate::data_contract::accessors::v0::DataContractV0Getters; +#[cfg(feature = "state-transition-value-conversion")] +use crate::data_contract::accessors::v1::DataContractV1Getters; +use crate::group::GroupStateTransitionInfo; use crate::identifier::Identifier; use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-value-conversion")] use crate::state_transition::batch_transition::token_base_transition::property_names; +#[cfg(feature = "state-transition-value-conversion")] +use crate::tokens::errors::TokenError; #[cfg(any( feature = "state-transition-json-conversion", feature = "state-transition-value-conversion" @@ -61,6 +66,9 @@ pub struct TokenBaseTransitionV0 { serde(rename = "$tokenId") )] pub token_id: Identifier, + /// Using group multi party rules for authentication + #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] + pub using_group: Option, } impl TokenBaseTransitionV0 { @@ -70,21 +78,37 @@ impl TokenBaseTransitionV0 { data_contract: DataContract, identity_contract_nonce: IdentityNonce, ) -> Result { + let token_contract_position = map + .remove_integer(property_names::TOKEN_CONTRACT_POSITION) + .map_err(ProtocolError::ValueError)?; Ok(TokenBaseTransitionV0 { identity_contract_nonce, - token_contract_position: map - .remove_integer(property_names::TOKEN_CONTRACT_POSITION) - .map_err(ProtocolError::ValueError)?, + token_contract_position, data_contract_id: Identifier::new( map.remove_optional_hash256_bytes(property_names::DATA_CONTRACT_ID) .map_err(ProtocolError::ValueError)? .unwrap_or(data_contract.id().to_buffer()), ), - token_id: Identifier::new( - map.remove_optional_hash256_bytes(property_names::TOKEN_ID) - .map_err(ProtocolError::ValueError)? - .unwrap_or(data_contract.id().to_buffer()), - ), + token_id: map + .remove_optional_hash256_bytes(property_names::TOKEN_ID) + .map_err(ProtocolError::ValueError)? + .map(Identifier::new) + .unwrap_or(data_contract.token_id(token_contract_position).ok_or( + ProtocolError::Token(TokenError::TokenNotFoundAtPositionError.into()), + )?), + using_group: map + .remove_optional_integer(property_names::GROUP_CONTRACT_POSITION) + .map_err(ProtocolError::ValueError)? + .map(|group_contract_position| { + Ok::(GroupStateTransitionInfo { + group_contract_position, + action_id: map + .remove_hash256_bytes(property_names::GROUP_ACTION_ID) + .map_err(ProtocolError::ValueError)? + .into(), + }) + }) + .transpose()?, }) } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs index 70297bddb50..9e0802ca875 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs @@ -1,3 +1,5 @@ +use crate::data_contract::GroupContractPosition; +use crate::group::GroupStateTransitionInfo; use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use platform_value::Identifier; @@ -20,6 +22,11 @@ pub trait TokenBaseTransitionV0Methods { fn set_token_id(&mut self, token_id: Identifier); + /// Returns the group ID. + fn group_position(&self) -> Option; + + fn set_group_info(&mut self, group_info: Option); + /// Sets the data contract ID. fn set_data_contract_id(&mut self, data_contract_id: Identifier); fn identity_contract_nonce(&self) -> IdentityNonce; @@ -66,4 +73,14 @@ impl TokenBaseTransitionV0Methods for TokenBaseTransitionV0 { fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce) { self.identity_contract_nonce = identity_contract_nonce; } + + fn group_position(&self) -> Option { + self.using_group + .as_ref() + .map(|info| info.group_contract_position) + } + + fn set_group_info(&mut self, group_info: Option) { + self.using_group = group_info; + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs index 53a3244db1d..2bc0f33dfcd 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs @@ -1,3 +1,5 @@ +use crate::data_contract::GroupContractPosition; +use crate::group::GroupStateTransitionInfo; use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; @@ -34,15 +36,27 @@ impl TokenBaseTransitionV0Methods for TokenBaseTransition { } } + fn token_id_ref(&self) -> &Identifier { + match self { + TokenBaseTransition::V0(v0) => v0.token_id_ref(), + } + } + fn set_token_id(&mut self, token_id: Identifier) { match self { TokenBaseTransition::V0(v0) => v0.set_token_id(token_id), } } - fn token_id_ref(&self) -> &Identifier { + fn group_position(&self) -> Option { match self { - TokenBaseTransition::V0(v0) => v0.token_id_ref(), + TokenBaseTransition::V0(v0) => v0.group_position(), + } + } + + fn set_group_info(&mut self, group_info: Option) { + match self { + TokenBaseTransition::V0(v0) => v0.set_group_info(group_info), } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs index dcf6d104a22..1da7aea51b3 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs @@ -1,6 +1,10 @@ +use platform_value::Identifier; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::batch_transition::token_burn_transition::TokenBurnTransitionV0; +use crate::util::hash::hash_double; impl TokenBaseTransitionAccessors for TokenBurnTransitionV0 { fn base(&self) -> &TokenBaseTransition { @@ -16,7 +20,9 @@ impl TokenBaseTransitionAccessors for TokenBurnTransitionV0 { } } -pub trait TokenBurnTransitionV0Methods: TokenBaseTransitionAccessors { +pub trait TokenBurnTransitionV0Methods: + TokenBaseTransitionAccessors + AllowedAsMultiPartyAction +{ fn burn_amount(&self) -> u64; fn set_burn_amount(&mut self, amount: u64); @@ -52,3 +58,19 @@ impl TokenBurnTransitionV0Methods for TokenBurnTransitionV0 { self.public_note = public_note; } } + +impl AllowedAsMultiPartyAction for TokenBurnTransitionV0 { + fn action_id(&self, owner_id: Identifier) -> Identifier { + let TokenBurnTransitionV0 { + base, burn_amount, .. + } = self; + + let mut bytes = b"action_burn".to_vec(); + bytes.extend_from_slice(base.token_id().as_bytes()); + bytes.extend_from_slice(owner_id.as_bytes()); + bytes.extend_from_slice(&base.identity_contract_nonce().to_be_bytes()); + bytes.extend_from_slice(&burn_amount.to_be_bytes()); + + hash_double(bytes).into() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs index 4c83f78232f..96b4b5ee969 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs @@ -1,3 +1,5 @@ +use platform_value::Identifier; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::batch_transition::token_burn_transition::TokenBurnTransition; @@ -54,3 +56,11 @@ impl TokenBurnTransitionV0Methods for TokenBurnTransition { } } } + +impl AllowedAsMultiPartyAction for TokenBurnTransition { + fn action_id(&self, owner_id: Identifier) -> Identifier { + match self { + TokenBurnTransition::V0(v0) => v0.action_id(owner_id), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/mod.rs index a82e5a3a6fe..a37fe199c3a 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/mod.rs @@ -5,20 +5,20 @@ use bincode::{Decode, Encode}; use derive_more::{Display, From}; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; -pub use v0::TokenIssuanceTransitionV0; +pub use v0::TokenMintTransitionV0; #[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] #[cfg_attr( feature = "state-transition-serde-conversion", derive(Serialize, Deserialize) )] -pub enum TokenIssuanceTransition { +pub enum TokenMintTransition { #[display("V0({})", "_0")] - V0(TokenIssuanceTransitionV0), + V0(TokenMintTransitionV0), } -impl Default for TokenIssuanceTransition { +impl Default for TokenMintTransition { fn default() -> Self { - TokenIssuanceTransition::V0(TokenIssuanceTransitionV0::default()) // since only v0 + TokenMintTransition::V0(TokenMintTransitionV0::default()) // since only v0 } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs index 2e4d17a6ebf..412111a65c7 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs @@ -20,7 +20,7 @@ pub use super::super::document_base_transition::IDENTIFIER_FIELDS; derive(Serialize, Deserialize), serde(rename_all = "camelCase") )] -pub struct TokenIssuanceTransitionV0 { +pub struct TokenMintTransitionV0 { /// Document Base Transition #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] pub base: TokenBaseTransition, @@ -42,7 +42,7 @@ pub struct TokenIssuanceTransitionV0 { pub public_note: Option, } -impl fmt::Display for TokenIssuanceTransitionV0 { +impl fmt::Display for TokenMintTransitionV0 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Format the base transition (assuming `TokenBaseTransition` implements Display) write!( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs index 5f24acc145b..9aa6948dfd2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs @@ -1,9 +1,12 @@ use platform_value::Identifier; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransitionV0; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::batch_transition::token_issuance_transition::TokenMintTransitionV0; +use crate::util::hash::hash_double; -impl TokenBaseTransitionAccessors for TokenIssuanceTransitionV0 { +impl TokenBaseTransitionAccessors for TokenMintTransitionV0 { fn base(&self) -> &TokenBaseTransition { &self.base } @@ -17,7 +20,9 @@ impl TokenBaseTransitionAccessors for TokenIssuanceTransitionV0 { } } -pub trait TokenIssuanceTransitionV0Methods: TokenBaseTransitionAccessors { +pub trait TokenMintTransitionV0Methods: + TokenBaseTransitionAccessors + AllowedAsMultiPartyAction +{ fn amount(&self) -> u64; fn set_amount(&mut self, amount: u64); @@ -38,7 +43,7 @@ pub trait TokenIssuanceTransitionV0Methods: TokenBaseTransitionAccessors { fn set_issued_to_identity_id(&mut self, issued_to_identity_id: Option); } -impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransitionV0 { +impl TokenMintTransitionV0Methods for TokenMintTransitionV0 { fn amount(&self) -> u64 { self.amount } @@ -66,3 +71,17 @@ impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransitionV0 { self.issued_to_identity_id = issued_to_identity_id; } } + +impl AllowedAsMultiPartyAction for TokenMintTransitionV0 { + fn action_id(&self, owner_id: Identifier) -> Identifier { + let TokenMintTransitionV0 { base, amount, .. } = self; + + let mut bytes = b"action_mint".to_vec(); + bytes.extend_from_slice(base.token_id().as_bytes()); + bytes.extend_from_slice(owner_id.as_bytes()); + bytes.extend_from_slice(&base.identity_contract_nonce().to_be_bytes()); + bytes.extend_from_slice(&amount.to_be_bytes()); + + hash_double(bytes).into() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs index 71b228a35ae..78726f5976d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs @@ -1,69 +1,78 @@ use platform_value::Identifier; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransition; -use crate::state_transition::batch_transition::token_issuance_transition::v0::v0_methods::TokenIssuanceTransitionV0Methods; +use crate::state_transition::batch_transition::token_issuance_transition::TokenMintTransition; +use crate::state_transition::batch_transition::token_issuance_transition::v0::v0_methods::TokenMintTransitionV0Methods; -impl TokenBaseTransitionAccessors for TokenIssuanceTransition { +impl TokenBaseTransitionAccessors for TokenMintTransition { fn base(&self) -> &TokenBaseTransition { match self { - TokenIssuanceTransition::V0(v0) => &v0.base, + TokenMintTransition::V0(v0) => &v0.base, } } fn base_mut(&mut self) -> &mut TokenBaseTransition { match self { - TokenIssuanceTransition::V0(v0) => &mut v0.base, + TokenMintTransition::V0(v0) => &mut v0.base, } } fn set_base(&mut self, base: TokenBaseTransition) { match self { - TokenIssuanceTransition::V0(v0) => v0.base = base, + TokenMintTransition::V0(v0) => v0.base = base, } } } -impl TokenIssuanceTransitionV0Methods for TokenIssuanceTransition { +impl TokenMintTransitionV0Methods for TokenMintTransition { fn amount(&self) -> u64 { match self { - TokenIssuanceTransition::V0(v0) => v0.amount(), + TokenMintTransition::V0(v0) => v0.amount(), } } fn set_amount(&mut self, amount: u64) { match self { - TokenIssuanceTransition::V0(v0) => v0.set_amount(amount), + TokenMintTransition::V0(v0) => v0.set_amount(amount), } } fn public_note(&self) -> Option<&String> { match self { - TokenIssuanceTransition::V0(v0) => v0.public_note(), + TokenMintTransition::V0(v0) => v0.public_note(), } } fn public_note_owned(self) -> Option { match self { - TokenIssuanceTransition::V0(v0) => v0.public_note_owned(), + TokenMintTransition::V0(v0) => v0.public_note_owned(), } } fn set_public_note(&mut self, public_note: Option) { match self { - TokenIssuanceTransition::V0(v0) => v0.set_public_note(public_note), + TokenMintTransition::V0(v0) => v0.set_public_note(public_note), } } fn issued_to_identity_id(&self) -> Option { match self { - TokenIssuanceTransition::V0(v0) => v0.issued_to_identity_id(), + TokenMintTransition::V0(v0) => v0.issued_to_identity_id(), } } fn set_issued_to_identity_id(&mut self, issued_to_identity_id: Option) { match self { - TokenIssuanceTransition::V0(v0) => v0.set_issued_to_identity_id(issued_to_identity_id), + TokenMintTransition::V0(v0) => v0.set_issued_to_identity_id(issued_to_identity_id), + } + } +} + +impl AllowedAsMultiPartyAction for TokenMintTransition { + fn action_id(&self, owner_id: Identifier) -> Identifier { + match self { + TokenMintTransition::V0(v0) => v0.action_id(owner_id), } } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs index 5a143fcd62b..5527b77e557 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs @@ -2,9 +2,9 @@ use derive_more::{Display, From}; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; use platform_value::Identifier; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; +use bincode::{Encode, Decode}; use crate::prelude::IdentityNonce; -use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition}; +use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenMintTransition, TokenTransferTransition}; use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition}; use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; @@ -21,7 +21,7 @@ pub enum TokenTransition { Burn(TokenBurnTransition), #[display("TokenIssuanceTransition({})", "_0")] - Mint(TokenIssuanceTransition), + Mint(TokenMintTransition), #[display("TokenTransferTransition({})", "_0")] Transfer(TokenTransferTransition), @@ -54,7 +54,7 @@ impl BatchTransitionResolversV0 for TokenTransition { None } } - fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition> { + fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition> { if let Self::Mint(ref t) = self { Some(t) } else { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs index 0ded71c1f97..11fc10aa5d2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs @@ -17,7 +17,7 @@ pub use self::batched_transition::{ document_delete_transition::DocumentDeleteTransition, document_replace_transition, document_replace_transition::DocumentReplaceTransition, token_base_transition, token_burn_transition, token_burn_transition::TokenBurnTransition, token_issuance_transition, - token_issuance_transition::TokenIssuanceTransition, token_transfer_transition, + token_issuance_transition::TokenMintTransition, token_transfer_transition, token_transfer_transition::TokenTransferTransition, }; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs index e1cf7a939c9..66f862789d2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs @@ -3,7 +3,7 @@ use crate::state_transition::batch_transition::batched_transition::{ }; use crate::state_transition::batch_transition::{ DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, - TokenBurnTransition, TokenIssuanceTransition, TokenTransferTransition, + TokenBurnTransition, TokenMintTransition, TokenTransferTransition, }; pub trait BatchTransitionResolversV0 { @@ -13,6 +13,6 @@ pub trait BatchTransitionResolversV0 { fn as_transition_transfer(&self) -> Option<&DocumentTransferTransition>; fn as_transition_purchase(&self) -> Option<&DocumentPurchaseTransition>; fn as_transition_token_burn(&self) -> Option<&TokenBurnTransition>; - fn as_transition_token_issuance(&self) -> Option<&TokenIssuanceTransition>; + fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition>; fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition>; } diff --git a/packages/rs-dpp/src/tokens/errors.rs b/packages/rs-dpp/src/tokens/errors.rs index 4a0fa2eb39b..823e1f577c2 100644 --- a/packages/rs-dpp/src/tokens/errors.rs +++ b/packages/rs-dpp/src/tokens/errors.rs @@ -4,4 +4,6 @@ use thiserror::Error; pub enum TokenError { #[error("There is no destination identity to put the token balance to")] DestinationIdentityForMintingNotSetError, + #[error("There is no token at this position")] + TokenNotFoundAtPositionError, } diff --git a/packages/rs-dpp/src/tokens/token_event.rs b/packages/rs-dpp/src/tokens/token_event.rs index 8a3d3a6c0ff..c79056872b2 100644 --- a/packages/rs-dpp/src/tokens/token_event.rs +++ b/packages/rs-dpp/src/tokens/token_event.rs @@ -2,6 +2,8 @@ use crate::balances::credits::TokenAmount; use crate::prelude::{ DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex, }; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use platform_value::Identifier; pub type TokenEventPublicNote = Option; @@ -11,8 +13,12 @@ pub type TokenEventPersonalEncryptedNote = Option<( DerivationEncryptionKeyIndex, Vec, )>; +use crate::ProtocolError; -#[derive(Debug, PartialEq, PartialOrd, Clone, Eq)] +#[derive( + Debug, PartialEq, PartialOrd, Clone, Eq, Encode, Decode, PlatformDeserialize, PlatformSerialize, +)] +#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version pub enum TokenEvent { Mint(TokenAmount, TokenEventPublicNote), Burn(TokenAmount, TokenEventPublicNote), diff --git a/packages/rs-dpp/src/voting/contender_structs/contender/v0/mod.rs b/packages/rs-dpp/src/voting/contender_structs/contender/v0/mod.rs index 7ff0929f612..ed4c0fc0797 100644 --- a/packages/rs-dpp/src/voting/contender_structs/contender/v0/mod.rs +++ b/packages/rs-dpp/src/voting/contender_structs/contender/v0/mod.rs @@ -1,8 +1,8 @@ use crate::data_contract::document_type::DocumentTypeRef; use crate::document::serialization_traits::DocumentPlatformConversionMethodsV0; use crate::document::Document; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::ProtocolError; +use bincode::{Decode, Encode}; use platform_value::Identifier; use platform_version::version::PlatformVersion; diff --git a/packages/rs-dpp/src/voting/contender_structs/mod.rs b/packages/rs-dpp/src/voting/contender_structs/mod.rs index 0e8d96c25fe..a71c77f19ab 100644 --- a/packages/rs-dpp/src/voting/contender_structs/mod.rs +++ b/packages/rs-dpp/src/voting/contender_structs/mod.rs @@ -3,9 +3,9 @@ mod contender; use crate::data_contract::document_type::DocumentTypeRef; use crate::document::serialization_traits::DocumentPlatformConversionMethodsV0; use crate::document::Document; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use crate::ProtocolError; +use bincode::{Decode, Encode}; use platform_value::Identifier; use platform_version::version::PlatformVersion; use std::fmt; diff --git a/packages/rs-dpp/src/voting/vote_info_storage/contested_document_vote_poll_stored_info/mod.rs b/packages/rs-dpp/src/voting/vote_info_storage/contested_document_vote_poll_stored_info/mod.rs index 12eb2b400cc..90a920fa78e 100644 --- a/packages/rs-dpp/src/voting/vote_info_storage/contested_document_vote_poll_stored_info/mod.rs +++ b/packages/rs-dpp/src/voting/vote_info_storage/contested_document_vote_poll_stored_info/mod.rs @@ -1,13 +1,13 @@ mod v0; use crate::block::block_info::BlockInfo; -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::voting::contender_structs::{ ContenderWithSerializedDocument, FinalizedResourceVoteChoicesWithVoterInfo, }; use crate::voting::vote_info_storage::contested_document_vote_poll_stored_info::v0::ContestedDocumentVotePollStoredInfoV0; use crate::voting::vote_info_storage::contested_document_vote_poll_winner_info::ContestedDocumentVotePollWinnerInfo; use crate::ProtocolError; +use bincode::{Decode, Encode}; use derive_more::From; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use platform_value::Identifier; diff --git a/packages/rs-dpp/src/voting/vote_polls/contested_document_resource_vote_poll/mod.rs b/packages/rs-dpp/src/voting/vote_polls/contested_document_resource_vote_poll/mod.rs index 21f953f844c..9342eae819a 100644 --- a/packages/rs-dpp/src/voting/vote_polls/contested_document_resource_vote_poll/mod.rs +++ b/packages/rs-dpp/src/voting/vote_polls/contested_document_resource_vote_poll/mod.rs @@ -1,7 +1,7 @@ -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::serialization::PlatformSerializable; use crate::util::hash::hash_double; use crate::ProtocolError; +use bincode::{Decode, Encode}; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use platform_value::{Identifier, Value}; #[cfg(feature = "vote-serde-conversion")] diff --git a/packages/rs-dpp/src/voting/vote_polls/mod.rs b/packages/rs-dpp/src/voting/vote_polls/mod.rs index 9186451e680..938a852ed4e 100644 --- a/packages/rs-dpp/src/voting/vote_polls/mod.rs +++ b/packages/rs-dpp/src/voting/vote_polls/mod.rs @@ -1,6 +1,6 @@ -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::voting::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePoll; use crate::ProtocolError; +use bincode::{Decode, Encode}; use derive_more::From; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use platform_value::Identifier; diff --git a/packages/rs-dpp/src/voting/votes/resource_vote/mod.rs b/packages/rs-dpp/src/voting/votes/resource_vote/mod.rs index 8ee89fe3714..15787e88d73 100644 --- a/packages/rs-dpp/src/voting/votes/resource_vote/mod.rs +++ b/packages/rs-dpp/src/voting/votes/resource_vote/mod.rs @@ -1,6 +1,6 @@ -use crate::identity::state_transition::asset_lock_proof::{Decode, Encode}; use crate::voting::votes::resource_vote::v0::ResourceVoteV0; use crate::ProtocolError; +use bincode::{Decode, Encode}; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; #[cfg(feature = "vote-serde-conversion")] use serde::{Deserialize, Serialize}; diff --git a/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs index 46a0590c01c..b3d9eae7f67 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs @@ -17,7 +17,9 @@ use drive::drive::identity::withdrawals::paths::{ WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY, }; use drive::drive::system::misc_path; +use drive::drive::RootTree; use drive::grovedb::{Element, Transaction}; +use drive::grovedb_path::SubtreePath; impl Platform { /// Executes protocol-specific events on the first block after a protocol version change. @@ -102,6 +104,15 @@ impl Platform { transaction: &Transaction, platform_version: &PlatformVersion, ) -> Result<(), Error> { + self.drive.grove_insert_empty_tree( + SubtreePath::empty(), + &[RootTree::GroupActions as u8], + Some(transaction), + None, + &mut vec![], + &platform_version.drive, + )?; + let path = misc_path(); self.drive.grove_insert_if_not_exists( (&path).into(), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index b0323b9821d..07aca1c1a5b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -97,8 +97,19 @@ trait BatchTransitionInternalTransformerV0 { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result>, Error>; - /// The data contract can be of multiple difference versions + fn transform_token_transitions_within_contract_v0( + platform: &PlatformStateRef, + data_contract_id: &Identifier, + validate_against_state: bool, + token_transitions: &Vec<&TokenTransition>, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error>; + /// Transfer token transition fn transform_token_transition_v0( + drive: &Drive, + transaction: TransactionArg, + full_validation: bool, data_contract_fetch_info: Arc, transition: &TokenTransition, ) -> Result, Error>; @@ -129,13 +140,6 @@ trait BatchTransitionInternalTransformerV0 { document_id: Identifier, original_document: &Document, ) -> SimpleConsensusValidationResult; - fn transform_token_transitions_within_contract_v0( - platform: &PlatformStateRef, - data_contract_id: &Identifier, - token_transitions: &Vec<&TokenTransition>, - transaction: TransactionArg, - platform_version: &PlatformVersion, - ) -> Result>, Error>; } impl BatchTransitionTransformerV0 for BatchTransition { @@ -221,6 +225,7 @@ impl BatchTransitionTransformerV0 for BatchTransition { Self::transform_token_transitions_within_contract_v0( platform, data_contract_id, + validate_against_state, token_transitions, transaction, platform_version, @@ -255,6 +260,7 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { fn transform_token_transitions_within_contract_v0( platform: &PlatformStateRef, data_contract_id: &Identifier, + validate_against_state: bool, token_transitions: &Vec<&TokenTransition>, transaction: TransactionArg, platform_version: &PlatformVersion, @@ -283,6 +289,9 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { .iter() .map(|token_transition| { Self::transform_token_transition_v0( + platform.drive, + transaction, + validate_against_state, data_contract_fetch_info.clone(), token_transition, ) @@ -447,13 +456,16 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { /// The data contract can be of multiple difference versions fn transform_token_transition_v0( + drive: &Drive, + transaction: TransactionArg, + validate_against_state: bool, data_contract_fetch_info: Arc, transition: &TokenTransition, ) -> Result, Error> { match transition { TokenTransition::Burn(token_burn_transition) => { let result = ConsensusValidationResult::::new(); - let token_burn_action = TokenBurnTransitionAction::try_from_borrowed_token_burn_transition_with_contract_lookup(token_burn_transition, |_identifier| { + let token_burn_action = TokenBurnTransitionAction::try_from_borrowed_token_burn_transition_with_contract_lookup(drive, transaction, token_burn_transition, |_identifier| { Ok(data_contract_fetch_info.clone()) })?; @@ -468,7 +480,7 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { } TokenTransition::Mint(token_mint_transition) => { let result = ConsensusValidationResult::::new(); - let token_mint_action = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(token_mint_transition, |_identifier| { + let token_mint_action = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(drive, transaction, token_mint_transition, |_identifier| { Ok(data_contract_fetch_info.clone()) })?; @@ -483,7 +495,7 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { } TokenTransition::Transfer(token_transfer_transition) => { let result = ConsensusValidationResult::::new(); - let token_transfer_action = TokenTransferTransitionAction::try_from_borrowed_token_transfer_transition_with_contract_lookup(token_transfer_transition, |_identifier| { + let token_transfer_action = TokenTransferTransitionAction::try_from_borrowed_token_transfer_transition_with_contract_lookup(drive, transaction, token_transfer_transition, |_identifier| { Ok(data_contract_fetch_info.clone()) })?; diff --git a/packages/rs-drive/src/drive/contract/apply/apply_contract_with_serialization/v0/mod.rs b/packages/rs-drive/src/drive/contract/apply/apply_contract_with_serialization/v0/mod.rs index 816b660e324..a7b41957bfc 100644 --- a/packages/rs-drive/src/drive/contract/apply/apply_contract_with_serialization/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/apply/apply_contract_with_serialization/v0/mod.rs @@ -208,6 +208,7 @@ impl Drive { block_info, estimated_costs_only_with_layer_info, &mut drive_operations, + transaction, platform_version, )?; } diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/mod.rs index cfae17fd1c2..9d6eac54379 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/mod.rs @@ -90,6 +90,7 @@ impl Drive { HashMap, >, drive_operations: &mut Vec, + transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result<(), Error> { match platform_version @@ -113,6 +114,7 @@ impl Drive { block_info, estimated_costs_only_with_layer_info, drive_operations, + transaction, platform_version, ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs index a413dc7ed28..b28f13f4811 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs @@ -12,7 +12,6 @@ use dpp::fee::fee_result::FeeResult; use crate::drive::balances::total_tokens_root_supply_path; use crate::drive::tokens::{token_path, tokens_root_path, TOKEN_BALANCES_KEY}; use crate::error::contract::DataContractError; -use crate::util::grove_operations::BatchInsertTreeApplyType; use crate::util::object_size_info::DriveKeyInfo; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::serialization::PlatformSerializableWithPlatformVersion; @@ -102,6 +101,7 @@ impl Drive { contract, block_info, &mut estimated_costs_only_with_layer_info, + transaction, platform_version, )?; self.apply_batch_low_level_drive_operations( @@ -126,6 +126,7 @@ impl Drive { HashMap, >, drive_operations: &mut Vec, + transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result<(), Error> { let batch_operations = self.insert_contract_operations_v1( @@ -133,6 +134,7 @@ impl Drive { contract, block_info, estimated_costs_only_with_layer_info, + transaction, platform_version, )?; drive_operations.extend(batch_operations); @@ -150,6 +152,7 @@ impl Drive { estimated_costs_only_with_layer_info: &mut Option< HashMap, >, + transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { let mut batch_operations: Vec = self @@ -194,6 +197,16 @@ impl Drive { )?; } + if !contract.groups().is_empty() { + batch_operations.extend(self.add_new_groups_operations( + contract.id(), + contract.groups(), + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); + } + Ok(batch_operations) } } diff --git a/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs index 460055f9036..75d236e331b 100644 --- a/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs @@ -1,29 +1,23 @@ -use crate::drive::{contract_documents_path, Drive}; +use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; -use crate::util::grove_operations::BatchInsertTreeApplyType; -use crate::util::object_size_info::DriveKeyInfo::KeyRef; -use crate::util::object_size_info::PathKeyInfo::{PathFixedSizeKey, PathFixedSizeKeyRef}; use crate::util::storage_flags::StorageFlags; use dpp::block::block_info::BlockInfo; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::config::v0::DataContractConfigGettersV0; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::data_contract::DataContract; use dpp::fee::fee_result::FeeResult; -use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; use dpp::serialization::PlatformSerializableWithPlatformVersion; -use crate::drive::tokens::{token_path, tokens_root_path, TOKEN_BALANCES_KEY}; use crate::error::contract::DataContractError; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; impl Drive { /// Updates a data contract. @@ -241,6 +235,17 @@ impl Drive { platform_version, )?); } + + if !contract.groups().is_empty() { + batch_operations.extend(self.add_new_groups_operations( + contract.id(), + contract.groups(), + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?); + } + Ok(batch_operations) } } diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/mod.rs new file mode 100644 index 00000000000..c255a565566 --- /dev/null +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/mod.rs @@ -0,0 +1,121 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; + +use dpp::data_contract::group::GroupMemberPower; +use dpp::data_contract::GroupContractPosition; +use dpp::prelude::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +mod v0; + +impl Drive { + /// Adds an action to the state + pub fn add_group_action( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + signer_identity_id: Identifier, + signer_power: GroupMemberPower, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version.drive.methods.group.insert.add_group_action { + 0 => self.add_group_action_v0( + contract_id, + group_contract_position, + action_id, + signer_identity_id, + signer_power, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_group_action".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds action creation operations to drive operations + pub fn add_group_action_add_to_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + signer_identity_id: Identifier, + signer_power: GroupMemberPower, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version.drive.methods.group.insert.add_group_action { + 0 => self.add_group_action_add_to_operations_v0( + contract_id, + group_contract_position, + action_id, + signer_identity_id, + signer_power, + block_info, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_group_action_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// The operations needed to create a new group action + pub fn add_group_action_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + signer_identity_id: Identifier, + signer_power: GroupMemberPower, + block_info: &BlockInfo, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.insert.add_new_groups { + 0 => self.add_group_action_operations_v0( + contract_id, + group_contract_position, + action_id, + signer_identity_id, + signer_power, + block_info, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_new_group_action_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs new file mode 100644 index 00000000000..71c991d9f40 --- /dev/null +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -0,0 +1,199 @@ +use crate::drive::group::{ + group_action_path, group_action_root_path, group_action_signers_path_vec, ACTION_SIGNERS_KEY, +}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::{BatchInsertApplyType, BatchInsertTreeApplyType, QueryTarget}; +use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKeyRef; +use crate::util::object_size_info::{DriveKeyInfo, PathKeyElementInfo}; +use dpp::block::block_info::BlockInfo; +use dpp::data_contract::group::GroupMemberPower; +use dpp::data_contract::GroupContractPosition; +use dpp::fee::fee_result::FeeResult; +use dpp::identifier::Identifier; +use dpp::serialization::PlatformSerializable; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::element::SumValue; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb_epoch_based_storage_flags::StorageFlags; +use std::collections::HashMap; + +impl Drive { + pub(super) fn add_group_action_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + signer_identity_id: Identifier, + signer_power: GroupMemberPower, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations: Vec = vec![]; + self.add_group_action_add_to_operations_v0( + contract_id, + group_contract_position, + action_id, + signer_identity_id, + signer_power, + block_info, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + Ok(fees) + } + + /// Adds group creation operations to drive operations + pub(super) fn add_group_action_add_to_operations_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + signer_identity_id: Identifier, + signer_power: GroupMemberPower, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = if apply { + None::> + } else { + Some(HashMap::new()) + }; + + let batch_operations = self.add_new_group_action_operations( + contract_id, + group_contract_position, + action_id, + signer_identity_id, + signer_power, + block_info, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + /// The operations needed to create a group + pub(super) fn add_group_action_operations_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + signer_identity_id: Identifier, + signer_power: GroupMemberPower, + block_info: &BlockInfo, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut batch_operations: Vec = vec![]; + + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + let group_action_root_path = group_action_root_path( + contract_id.as_slice(), + group_contract_position_bytes.as_slice(), + ); + let apply_type = if estimated_costs_only_with_layer_info.is_none() { + BatchInsertTreeApplyType::StatefulBatchInsertTree + } else { + BatchInsertTreeApplyType::StatelessBatchInsertTree { + in_tree_using_sums: false, + is_sum_tree: false, + flags_len: 0, + } + }; + + // We insert the contract root into the group tree + let inserted_root_action = self.batch_insert_empty_tree_if_not_exists( + PathFixedSizeKeyRef((group_action_root_path, action_id.as_slice())), + false, + None, + apply_type, + transaction, + &mut None, + &mut batch_operations, + &platform_version.drive, + )?; + + if !inserted_root_action { + let group_action_path = group_action_path( + contract_id.as_slice(), + group_contract_position_bytes.as_slice(), + action_id.as_slice(), + ); + + self.batch_insert_empty_sum_tree( + group_action_path, + DriveKeyInfo::KeyRef(ACTION_SIGNERS_KEY), + None, + &mut batch_operations, + &platform_version.drive, + )?; + } + + let signers_path = group_action_signers_path_vec( + contract_id.as_slice(), + *group_contract_position, + action_id.as_slice(), + ); + + let storage_flags = Some(StorageFlags::new_single_epoch( + block_info.epoch.index, + Some(signer_identity_id.to_buffer()), + )); + + let signer_apply_type = if estimated_costs_only_with_layer_info.is_none() { + BatchInsertApplyType::StatefulBatchInsert + } else { + BatchInsertApplyType::StatelessBatchInsert { + in_tree_using_sums: true, + target: QueryTarget::QueryTargetValue(8), + } + }; + + self.batch_insert_sum_item_if_not_exists( + PathKeyElementInfo::PathKeyElement(( + signers_path, + signer_identity_id.to_vec(), + Element::SumItem( + signer_power as SumValue, + StorageFlags::map_to_some_element_flags(storage_flags.as_ref()), + ), + )), + true, + signer_apply_type, + transaction, + &mut batch_operations, + &platform_version.drive, + )?; + + Ok(batch_operations) + } +} diff --git a/packages/rs-drive/src/drive/group/insert/add_new_groups/mod.rs b/packages/rs-drive/src/drive/group/insert/add_new_groups/mod.rs new file mode 100644 index 00000000000..a5fe50e5458 --- /dev/null +++ b/packages/rs-drive/src/drive/group/insert/add_new_groups/mod.rs @@ -0,0 +1,99 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; + +use dpp::data_contract::group::Group; +use dpp::data_contract::GroupContractPosition; +use dpp::prelude::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use std::collections::{BTreeMap, HashMap}; + +mod v0; + +impl Drive { + /// Adds groups to the state. + pub fn add_new_groups( + &self, + contract_id: Identifier, + groups: &BTreeMap, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version.drive.methods.group.insert.add_new_groups { + 0 => self.add_new_groups_v0( + contract_id, + groups, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_new_groups".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds groups creation operations to drive operations + pub fn add_new_groups_add_to_operations( + &self, + contract_id: Identifier, + groups: &BTreeMap, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version.drive.methods.group.insert.add_new_groups { + 0 => self.add_new_groups_add_to_operations_v0( + contract_id, + groups, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_new_groups_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// The operations needed to create groups + pub fn add_new_groups_operations( + &self, + contract_id: Identifier, + groups: &BTreeMap, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.insert.add_new_groups { + 0 => self.add_new_groups_operations_v0( + contract_id, + groups, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_new_groups_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs new file mode 100644 index 00000000000..c8de9a1432d --- /dev/null +++ b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs @@ -0,0 +1,251 @@ +use crate::drive::group::{group_contract_path, group_path_vec, group_root_path, GROUP_INFO_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::BatchInsertTreeApplyType; +use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKey; +use crate::util::object_size_info::{DriveKeyInfo, PathKeyElementInfo}; +use dpp::block::block_info::BlockInfo; +use dpp::data_contract::group::Group; +use dpp::data_contract::GroupContractPosition; +use dpp::fee::fee_result::FeeResult; +use dpp::identifier::Identifier; +use dpp::serialization::PlatformSerializable; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use std::collections::{BTreeMap, HashMap}; + +impl Drive { + /// Adds a group by inserting a new group subtree structure to the `Identities` subtree. + pub(super) fn add_new_groups_v0( + &self, + contract_id: Identifier, + groups: &BTreeMap, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations: Vec = vec![]; + self.add_new_groups_add_to_operations_v0( + contract_id, + groups, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + Ok(fees) + } + + /// Adds group creation operations to drive operations + pub(super) fn add_new_groups_add_to_operations_v0( + &self, + contract_id: Identifier, + groups: &BTreeMap, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = if apply { + None::> + } else { + Some(HashMap::new()) + }; + + let batch_operations = self.add_new_groups_operations( + contract_id, + groups, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + /// The operations needed to create a group + pub(super) fn add_new_groups_operations_v0( + &self, + contract_id: Identifier, + groups: &BTreeMap, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut batch_operations: Vec = vec![]; + + let group_tree_path = group_root_path(); + + let apply_type = if estimated_costs_only_with_layer_info.is_none() { + BatchInsertTreeApplyType::StatefulBatchInsertTree + } else { + BatchInsertTreeApplyType::StatelessBatchInsertTree { + in_tree_using_sums: false, + is_sum_tree: false, + flags_len: 0, + } + }; + + // We insert the contract root into the group tree + let inserted = self.batch_insert_empty_tree_if_not_exists( + PathFixedSizeKey((group_tree_path, contract_id.to_vec())), + false, + None, + apply_type, + transaction, + &mut None, + &mut batch_operations, + &platform_version.drive, + )?; + + if inserted { + for (group_pos, group) in groups { + let group_pos_bytes = group_pos.to_be_bytes().to_vec(); + let path = group_contract_path(contract_id.as_slice()); + self.batch_insert_empty_tree( + path, + DriveKeyInfo::Key(group_pos_bytes.clone()), + None, + &mut batch_operations, + &platform_version.drive, + )?; + let group_path = group_path_vec(contract_id.as_slice(), *group_pos); + + let serialized_group_info = group.serialize_to_bytes()?; + let info_item = Element::Item(serialized_group_info, None); + self.batch_insert( + PathKeyElementInfo::PathKeyElement::<0>(( + group_path, + GROUP_INFO_KEY.to_vec(), + info_item, + )), + &mut batch_operations, + &platform_version.drive, + )?; + } + } else { + for (group_pos, group) in groups { + let group_pos_bytes = group_pos.to_be_bytes().to_vec(); + let path = group_contract_path(contract_id.as_slice()); + let inserted = self.batch_insert_empty_tree_if_not_exists( + PathFixedSizeKey((path, group_pos_bytes)), + false, + None, + apply_type, + transaction, + &mut None, + &mut batch_operations, + &platform_version.drive, + )?; + + if inserted { + let group_path = group_path_vec(contract_id.as_slice(), *group_pos); + + let serialized_group_info = group.serialize_to_bytes()?; + let info_item = Element::Item(serialized_group_info, None); + self.batch_insert( + PathKeyElementInfo::PathKeyElement::<0>(( + group_path, + GROUP_INFO_KEY.to_vec(), + info_item, + )), + &mut batch_operations, + &platform_version.drive, + )?; + } + } + } + + Ok(batch_operations) + } +} + +#[cfg(test)] +mod tests { + use crate::util::test_helpers::setup::{setup_drive, setup_drive_with_initial_state_structure}; + + use dpp::block::block_info::BlockInfo; + + use dpp::version::PlatformVersion; + + #[test] + fn test_insert_and_fetch_group_v0() { + let drive = setup_drive(None); + let platform_version = PlatformVersion::first(); + + let transaction = drive.grove.start_transaction(); + + drive + .create_initial_state_structure(Some(&transaction), platform_version) + .expect("expected to create root tree successfully"); + + let group = Identity::random_group(5, Some(12345), platform_version) + .expect("expected a random group"); + + drive + .add_new_groups_v0( + group.clone(), + false, + &BlockInfo::default(), + true, + Some(&transaction), + platform_version, + ) + .expect("expected to insert group"); + + let fetched_group = drive + .fetch_full_group(group.id().to_buffer(), Some(&transaction), platform_version) + .expect("should fetch an group") + .expect("should have an group"); + + assert_eq!(group, fetched_group); + } + + #[test] + fn test_insert_group_v0() { + let drive = setup_drive_with_initial_state_structure(None); + + let db_transaction = drive.grove.start_transaction(); + + let platform_version = PlatformVersion::latest(); + + let group = Identity::random_group(5, Some(12345), platform_version) + .expect("expected a random group"); + + drive + .add_new_groups_v0( + group, + false, + &BlockInfo::default(), + true, + Some(&db_transaction), + platform_version, + ) + .expect("expected to insert group"); + + drive + .grove + .commit_transaction(db_transaction) + .unwrap() + .expect("expected to be able to commit a transaction"); + } +} diff --git a/packages/rs-drive/src/drive/group/insert/mod.rs b/packages/rs-drive/src/drive/group/insert/mod.rs new file mode 100644 index 00000000000..344133883d6 --- /dev/null +++ b/packages/rs-drive/src/drive/group/insert/mod.rs @@ -0,0 +1,2 @@ +mod add_group_action; +mod add_new_groups; diff --git a/packages/rs-drive/src/drive/group/mod.rs b/packages/rs-drive/src/drive/group/mod.rs new file mode 100644 index 00000000000..b65a51ee37f --- /dev/null +++ b/packages/rs-drive/src/drive/group/mod.rs @@ -0,0 +1,152 @@ +use crate::drive::RootTree; +use dpp::data_contract::GroupContractPosition; + +mod insert; +pub const GROUP_INFO_KEY: &[u8; 1] = b"I"; +pub const GROUP_ACTIONS_KEY: &[u8; 1] = b"M"; +pub const ACTION_INFO_KEY: &[u8; 1] = b"I"; +pub const ACTION_SIGNERS_KEY: &[u8; 1] = b"S"; + +/// Group root path +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_root_path() -> [&'static [u8]; 1] { + [Into::<&[u8; 1]>::into(RootTree::GroupActions)] +} + +/// Group root path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_root_path_vec() -> Vec> { + vec![vec![RootTree::GroupActions as u8]] +} + +/// Group path +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_contract_path(contract_id: &[u8]) -> [&[u8]; 2] { + [Into::<&[u8; 1]>::into(RootTree::GroupActions), contract_id] +} + +/// Group path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_contract_path_vec(contract_id: &[u8]) -> Vec> { + vec![vec![RootTree::GroupActions as u8], contract_id.to_vec()] +} + +/// Group path +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_path<'a>( + contract_id: &'a [u8], + group_contract_position_bytes: &'a [u8], +) -> [&'a [u8]; 3] { + [ + Into::<&[u8; 1]>::into(RootTree::GroupActions), + contract_id, + group_contract_position_bytes, + ] +} + +/// Group path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_path_vec( + contract_id: &[u8], + group_contract_position: GroupContractPosition, +) -> Vec> { + vec![ + vec![RootTree::GroupActions as u8], + contract_id.to_vec(), + group_contract_position.to_be_bytes().to_vec(), + ] +} + +/// Group action path +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_action_root_path<'a>( + contract_id: &'a [u8], + group_contract_position_bytes: &'a [u8], +) -> [&'a [u8]; 4] { + [ + Into::<&[u8; 1]>::into(RootTree::GroupActions), + contract_id, + group_contract_position_bytes, + GROUP_ACTIONS_KEY, + ] +} + +/// Group action path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_action_root_path_vec( + contract_id: &[u8], + group_contract_position: GroupContractPosition, +) -> Vec> { + vec![ + vec![RootTree::GroupActions as u8], + contract_id.to_vec(), + group_contract_position.to_be_bytes().to_vec(), + GROUP_ACTIONS_KEY.to_vec(), + ] +} + +/// Group path +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_action_path<'a>( + contract_id: &'a [u8], + group_contract_position_bytes: &'a [u8], + action_id: &'a [u8], +) -> [&'a [u8]; 5] { + [ + Into::<&[u8; 1]>::into(RootTree::GroupActions), + contract_id, + group_contract_position_bytes, + GROUP_ACTIONS_KEY, + action_id, + ] +} + +/// Group path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_action_path_vec( + contract_id: &[u8], + group_contract_position: GroupContractPosition, + action_id: &[u8], +) -> Vec> { + vec![ + vec![RootTree::GroupActions as u8], + contract_id.to_vec(), + group_contract_position.to_be_bytes().to_vec(), + GROUP_ACTIONS_KEY.to_vec(), + action_id.to_vec(), + ] +} + +/// Group path +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_action_signers_path<'a>( + contract_id: &'a [u8], + group_contract_position_bytes: &'a [u8], + action_id: &'a [u8], +) -> [&'a [u8]; 6] { + [ + Into::<&[u8; 1]>::into(RootTree::GroupActions), + contract_id, + group_contract_position_bytes, + GROUP_ACTIONS_KEY, + action_id, + ACTION_SIGNERS_KEY, + ] +} + +/// Group path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub(crate) fn group_action_signers_path_vec( + contract_id: &[u8], + group_contract_position: GroupContractPosition, + action_id: &[u8], +) -> Vec> { + vec![ + vec![RootTree::GroupActions as u8], + contract_id.to_vec(), + group_contract_position.to_be_bytes().to_vec(), + GROUP_ACTIONS_KEY.to_vec(), + action_id.to_vec(), + ACTION_SIGNERS_KEY.to_vec(), + ] +} diff --git a/packages/rs-drive/src/drive/initialization/v1/mod.rs b/packages/rs-drive/src/drive/initialization/v1/mod.rs index 80b893444ac..0e0db5c11bc 100644 --- a/packages/rs-drive/src/drive/initialization/v1/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v1/mod.rs @@ -4,7 +4,7 @@ use crate::drive::balances::TOTAL_TOKEN_SUPPLIES_STORAGE_KEY; use crate::util::batch::GroveDbOpBatch; use crate::drive::system::misc_path_vec; -use crate::drive::Drive; +use crate::drive::{Drive, RootTree}; use crate::error::Error; use crate::util::batch::grovedb_op_batch::GroveDbOpBatchV0Methods; @@ -14,6 +14,7 @@ use crate::drive::identity::withdrawals::paths::{ }; use dpp::version::PlatformVersion; use grovedb::{Element, TransactionArg}; +use grovedb_path::SubtreePath; impl Drive { /// Creates the initial state structure. @@ -25,6 +26,15 @@ impl Drive { let drive_version = &platform_version.drive; self.create_initial_state_structure_top_level_0(transaction, platform_version)?; + self.grove_insert_empty_tree( + SubtreePath::empty(), + &[RootTree::GroupActions as u8], + transaction, + None, + &mut vec![], + drive_version, + )?; + // On lower layers we can use batching let mut batch = @@ -50,21 +60,6 @@ impl Drive { Element::empty_tree(), ); - // We are adding the withdrawal transactions sum amount tree - let path = get_withdrawal_root_path_vec(); - - batch.add_insert( - path.clone(), - WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY.to_vec(), - Element::empty_sum_tree(), - ); - - batch.add_insert( - path, - WITHDRAWAL_TRANSACTIONS_BROADCASTED_KEY.to_vec(), - Element::empty_tree(), - ); - Ok(()) } } diff --git a/packages/rs-drive/src/drive/mod.rs b/packages/rs-drive/src/drive/mod.rs index f23dbdf2d90..4a303c4e695 100644 --- a/packages/rs-drive/src/drive/mod.rs +++ b/packages/rs-drive/src/drive/mod.rs @@ -48,6 +48,7 @@ pub(crate) mod prefunded_specialized_balances; #[cfg(any(feature = "server", feature = "verify"))] pub mod votes; +pub mod group; #[cfg(feature = "server")] mod shared; mod tokens; @@ -79,10 +80,10 @@ pub struct Drive { // DataContract_Documents 64 // / \ // Identities 32 Balances 96 -// / \ / \ -// Token_Balances 16 Pools 48 WithdrawalTransactions 80 Votes 112 -// / \ / \ / / \ -// NUPKH->I 8 UPKH->I 24 PreFundedSpecializedBalances 40 Masternode Lists 56 (reserved) SpentAssetLockTransactions 72 Misc 104 Versions 120 +// / \ / \ +// Token_Balances 16 Pools 48 WithdrawalTransactions 80 Votes 112 +// / \ / \ / \ / \ +// NUPKH->I 8 UPKH->I 24 PreFundedSpecializedBalances 40 Masternode Lists 56 (reserved) SpentAssetLockTransactions 72 GroupActions 88 Misc 104 Versions 120 /// Keys for the root tree. #[cfg(any(feature = "server", feature = "verify"))] @@ -119,6 +120,8 @@ pub enum RootTree { Versions = 120, /// Registered votes Votes = 112, + /// Group actions + GroupActions = 88, } #[cfg(any(feature = "server", feature = "verify"))] @@ -141,6 +144,7 @@ impl fmt::Display for RootTree { RootTree::Tokens => "TokenBalances", RootTree::Versions => "Versions", RootTree::Votes => "Votes", + RootTree::GroupActions => "GroupActions", }; write!(f, "{}", variant_name) } @@ -209,6 +213,7 @@ impl From for &'static [u8; 1] { RootTree::NonUniquePublicKeyKeyHashesToIdentities => &[8], RootTree::Versions => &[120], RootTree::Votes => &[112], + RootTree::GroupActions => &[88], } } } diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs index 98d5e667bbc..86d2103a4ea 100644 --- a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs @@ -236,57 +236,126 @@ mod tests { ); } - // #[test] - // fn should_prove_multiple_identity_single_token_balances() { - // let drive = setup_drive_with_initial_state_structure(None); - // let platform_version = PlatformVersion::latest(); - // let identities: BTreeMap<[u8; 32], Identity> = - // Identity::random_identities(10, 3, Some(14), platform_version) - // .expect("expected to get random identities") - // .into_iter() - // .map(|identity| (identity.id().to_buffer(), identity)) - // .collect(); - // - // let mut rng = StdRng::seed_from_u64(293); - // - // let token_id: [u8; 32] = rng.gen(); - // - // drive.add_new_token(token_id); - // - // for identity in identities.values() { - // drive - // .add_new_identity( - // identity.clone(), - // false, - // &BlockInfo::default(), - // true, - // None, - // platform_version, - // ) - // .expect("expected to add an identity"); - // } - // let identity_ids = identities.keys().copied().collect::>(); - // let identity_balances = identities - // .into_iter() - // .map(|(id, identity)| (id, Some(identity.balance()))) - // .collect::>>(); - // let proof = drive - // .prove_many_identity_token_balances( - // identity_ids.as_slice(), - // None, - // &platform_version.drive, - // ) - // .expect("should not error when proving an identity"); - // - // let (_, proved_identity_balances): ([u8; 32], BTreeMap<[u8; 32], Option>) = - // Drive::verify_identity_balances_for_identity_ids( - // proof.as_slice(), - // false, - // identity_ids.as_slice(), - // platform_version, - // ) - // .expect("expect that this be verified"); - // - // assert_eq!(proved_identity_balances, identity_balances); - // } + #[test] + fn should_prove_multiple_identity_single_token_balances_after_transfer() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity_1 = Identity::random_identity(3, Some(14), platform_version) + .expect("expected a platform identity"); + + let identity_1_id = identity_1.id().to_buffer(); + + let identity_2 = Identity::random_identity(3, Some(15), platform_version) + .expect("expected a platform identity"); + + let identity_2_id = identity_2.id().to_buffer(); + + let contract = DataContract::V1(DataContractV1 { + id: Default::default(), + version: 0, + owner_id: Default::default(), + document_types: Default::default(), + metadata: None, + config: DataContractConfig::V0(DataContractConfigV0 { + can_be_deleted: false, + readonly: false, + keeps_history: false, + documents_keep_history_contract_default: false, + documents_mutable_contract_default: false, + documents_can_be_deleted_contract_default: false, + requires_identity_encryption_bounded_key: None, + requires_identity_decryption_bounded_key: None, + }), + schema_defs: None, + groups: Default::default(), + tokens: BTreeMap::from([( + 0, + TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()), + )]), + }); + let token_id = contract.token_id(0).expect("expected token at position 0"); + drive + .add_new_identity( + identity_1.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + + drive + .add_new_identity( + identity_2.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + + drive + .insert_contract( + &contract, + BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert contract"); + + drive + .token_mint( + token_id.to_buffer(), + identity_1.id().to_buffer(), + 100000, + true, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to mint token"); + + drive + .token_transfer( + token_id.to_buffer(), + identity_1.id().to_buffer(), + identity_2.id().to_buffer(), + 30000, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to transfer token"); + let proof = drive + .prove_identities_token_balances_v0( + token_id.to_buffer(), + &vec![identity_1.id().to_buffer(), identity_2.id().to_buffer()], + None, + platform_version, + ) + .expect("should not error when proving an identity"); + + let proved_identity_balance: BTreeMap<[u8; 32], Option> = + Drive::verify_token_balances_for_identity_ids( + proof.as_slice(), + token_id.to_buffer(), + &vec![identity_1.id().to_buffer(), identity_2.id().to_buffer()], + false, + platform_version, + ) + .expect("expect that this be verified") + .1; + + assert_eq!( + proved_identity_balance, + BTreeMap::from([(identity_1_id, Some(70000)), (identity_2_id, Some(30000))]) + ); + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs index 33447ccc016..8af281a02bf 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs @@ -1,5 +1,7 @@ use derive_more::From; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; +use dpp::data_contract::GroupContractPosition; +use dpp::group::GroupStateTransitionInfo; use dpp::platform_value::Identifier; use dpp::prelude::IdentityNonce; use std::sync::Arc; @@ -62,4 +64,16 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionAction { TokenBaseTransitionAction::V0(v0) => v0.identity_contract_nonce(), } } + + fn store_in_group(&self) -> Option { + match self { + TokenBaseTransitionAction::V0(v0) => v0.store_in_group(), + } + } + + fn perform_action(&self) -> bool { + match self { + TokenBaseTransitionAction::V0(v0) => v0.perform_action(), + } + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs index 46939f2f56e..4143ca11a86 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs @@ -1,20 +1,25 @@ use dpp::platform_value::Identifier; use std::sync::Arc; - +use grovedb::TransactionArg; use dpp::ProtocolError; use dpp::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::drive::contract::DataContractFetchInfo; +use crate::drive::Drive; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; impl TokenBaseTransitionAction { /// from base transition with contract lookup pub fn try_from_base_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: TokenBaseTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { match value { TokenBaseTransition::V0(v0) => Ok( TokenBaseTransitionActionV0::try_from_base_transition_with_contract_lookup( + drive, + transaction, v0, get_data_contract, )? @@ -25,11 +30,13 @@ impl TokenBaseTransitionAction { /// from borrowed base transition with contract lookup pub fn try_from_borrowed_base_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: &TokenBaseTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { match value { - TokenBaseTransition::V0(v0) => Ok(TokenBaseTransitionActionV0::try_from_borrowed_base_transition_with_contract_lookup(v0, get_data_contract)?.into()), + TokenBaseTransition::V0(v0) => Ok(TokenBaseTransitionActionV0::try_from_borrowed_base_transition_with_contract_lookup(drive, transaction, v0, get_data_contract)?.into()), } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs index b6c63703c56..1ec510b4037 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs @@ -3,6 +3,8 @@ use crate::error::Error; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; +use dpp::data_contract::GroupContractPosition; +use dpp::group::GroupStateTransitionInfo; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; use dpp::ProtocolError; @@ -22,6 +24,13 @@ pub struct TokenBaseTransitionActionV0 { pub token_contract_position: u16, /// A potential data contract pub data_contract: Arc, + /// Using group multi party rules for authentication + /// If this is set we should store in group + pub store_in_group: Option, + /// Should the action be performed. + /// This is true if we don't store in group. + /// And also true if we store in group and with this have enough signatures to perform the action + pub perform_action: bool, } /// Token base transition action accessors v0 @@ -46,6 +55,12 @@ pub trait TokenBaseTransitionActionAccessorsV0 { /// Gets the token configuration associated to the action fn token_configuration(&self) -> Result<&TokenConfiguration, Error>; + + /// Gets the store_in_group field (optional) + fn store_in_group(&self) -> Option; + + /// Gets the perform_action field + fn perform_action(&self) -> bool; } impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { @@ -86,4 +101,12 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { ), ))) } + + fn store_in_group(&self) -> Option { + self.store_in_group + } + + fn perform_action(&self) -> bool { + self.perform_action + } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index 1b4efe5527c..ffd5ad44c01 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -1,15 +1,20 @@ -use std::sync::Arc; - +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::group::GroupStateTransitionInfo; use dpp::platform_value::Identifier; +use grovedb::TransactionArg; +use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use crate::drive::contract::DataContractFetchInfo; +use crate::drive::Drive; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; impl TokenBaseTransitionActionV0 { /// try from base transition with contract lookup pub fn try_from_base_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: TokenBaseTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -18,17 +23,34 @@ impl TokenBaseTransitionActionV0 { data_contract_id, identity_contract_nonce, token_id, + using_group, } = value; + + let data_contract = get_data_contract(data_contract_id)?; + + let (store_in_group, perform_action) = match using_group { + None => (None, true), + Some(GroupStateTransitionInfo { + group_contract_position, + action_id, + }) => { + drive.fetch_action_id_signers(data_contract_id, group_contract_position, action_id) + } + }; Ok(TokenBaseTransitionActionV0 { token_id, identity_contract_nonce, token_contract_position, - data_contract: get_data_contract(data_contract_id)?, + data_contract, + store_in_group, + perform_action, }) } /// try from borrowed base transition with contract lookup pub fn try_from_borrowed_base_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: &TokenBaseTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -37,12 +59,15 @@ impl TokenBaseTransitionActionV0 { data_contract_id, identity_contract_nonce, token_id, + using_group, } = value; Ok(TokenBaseTransitionActionV0 { token_id: *token_id, identity_contract_nonce: *identity_contract_nonce, token_contract_position: *token_contract_position, data_contract: get_data_contract(*data_contract_id)?, + store_in_group: None, + perform_action: false, }) } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs index 9e7c757a102..8413eb68813 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs @@ -1,13 +1,14 @@ -use std::sync::Arc; - use dpp::platform_value::Identifier; use dpp::ProtocolError; +use grovedb::TransactionArg; +use std::sync::Arc; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{ TokenBurnTransitionAction, TokenBurnTransitionActionV0, }; use dpp::state_transition::batch_transition::token_burn_transition::TokenBurnTransition; +use crate::drive::Drive; /// Implement methods to transform a `TokenBurnTransition` into a `TokenBurnTransitionAction`. impl TokenBurnTransitionAction { @@ -22,6 +23,8 @@ impl TokenBurnTransitionAction { /// /// * `Result` - A `TokenBurnTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_token_burn_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: TokenBurnTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -29,6 +32,8 @@ impl TokenBurnTransitionAction { TokenBurnTransition::V0(v0) => { let v0_action = TokenBurnTransitionActionV0::try_from_token_burn_transition_with_contract_lookup( + drive, + transaction, v0, get_data_contract, )?; @@ -48,12 +53,16 @@ impl TokenBurnTransitionAction { /// /// * `Result` - A `TokenBurnTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_borrowed_token_burn_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: &TokenBurnTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { match value { TokenBurnTransition::V0(v0) => { let v0_action = TokenBurnTransitionActionV0::try_from_borrowed_token_burn_transition_with_contract_lookup( + drive, + transaction, v0, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index 09bb907014b..9c71c39315c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -1,10 +1,11 @@ -use std::sync::Arc; - use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_burn_transition::v0::TokenBurnTransitionV0; use dpp::ProtocolError; +use grovedb::TransactionArg; +use std::sync::Arc; use crate::drive::contract::DataContractFetchInfo; +use crate::drive::Drive; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; @@ -20,6 +21,8 @@ impl TokenBurnTransitionActionV0 { /// /// * `Result` - A `TokenBurnTransitionActionV0` if successful, else `ProtocolError`. pub fn try_from_token_burn_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: TokenBurnTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -30,6 +33,8 @@ impl TokenBurnTransitionActionV0 { } = value; let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( + drive, + transaction, base, get_data_contract, )?; @@ -52,6 +57,8 @@ impl TokenBurnTransitionActionV0 { /// /// * `Result` - A `TokenBurnTransitionActionV0` if successful, else `ProtocolError`. pub fn try_from_borrowed_token_burn_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: &TokenBurnTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -63,6 +70,8 @@ impl TokenBurnTransitionActionV0 { let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + transaction, base, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs index 405337029c0..10262ce08b8 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs @@ -13,7 +13,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti #[derive(Debug, Clone, From)] pub enum TokenMintTransitionAction { /// v0 - V0(TokenIssuanceTransitionActionV0), + V0(TokenMintTransitionActionV0), } impl TokenMintTransitionActionAccessorsV0 for TokenMintTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs index 1ad37b14bed..03db3c62813 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs @@ -1,34 +1,37 @@ -use std::sync::Arc; - use dpp::platform_value::Identifier; use dpp::ProtocolError; +use grovedb::TransactionArg; +use std::sync::Arc; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{ - TokenMintTransitionAction, TokenIssuanceTransitionActionV0, -}; -use dpp::state_transition::batch_transition::token_issuance_transition::TokenIssuanceTransition; +use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionActionV0, TokenMintTransitionAction}; +use dpp::state_transition::batch_transition::token_issuance_transition::TokenMintTransition; +use crate::drive::Drive; -/// Implement methods to transform a `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction`. +/// Implement methods to transform a `TokenMintTransition` into a `TokenMintTransitionAction`. impl TokenMintTransitionAction { - /// Transform a `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction` using the provided data contract lookup. + /// Transform a `TokenMintTransition` into a `TokenMintTransitionAction` using the provided data contract lookup. /// /// # Arguments /// - /// * `value` - A `TokenIssuanceTransition` instance. + /// * `value` - A `TokenMintTransition` instance. /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. /// /// # Returns /// - /// * `Result` - A `TokenIssuanceTransitionAction` if successful, otherwise `ProtocolError`. - pub fn from_token_issuance_transition_with_contract_lookup( - value: TokenIssuanceTransition, + /// * `Result` - A `TokenMintTransitionAction` if successful, otherwise `ProtocolError`. + pub fn from_token_mint_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, + value: TokenMintTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { match value { - TokenIssuanceTransition::V0(v0) => { + TokenMintTransition::V0(v0) => { let v0_action = - TokenIssuanceTransitionActionV0::try_from_token_issuance_transition_with_contract_lookup( + TokenMintTransitionActionV0::try_from_token_mint_transition_with_contract_lookup( + drive, + transaction, v0, get_data_contract, )?; @@ -37,23 +40,27 @@ impl TokenMintTransitionAction { } } - /// Transform a borrowed `TokenIssuanceTransition` into a `TokenIssuanceTransitionAction` using the provided data contract lookup. + /// Transform a borrowed `TokenMintTransition` into a `TokenMintTransitionAction` using the provided data contract lookup. /// /// # Arguments /// - /// * `value` - A reference to a `TokenIssuanceTransition`. + /// * `value` - A reference to a `TokenMintTransition`. /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. /// /// # Returns /// - /// * `Result` - A `TokenIssuanceTransitionAction` if successful, otherwise `ProtocolError`. + /// * `Result` - A `TokenMintTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_borrowed_token_mint_transition_with_contract_lookup( - value: &TokenIssuanceTransition, + drive: &Drive, + transaction: TransactionArg, + value: &TokenMintTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { match value { - TokenIssuanceTransition::V0(v0) => { - let v0_action = TokenIssuanceTransitionActionV0::try_from_borrowed_token_issuance_transition_with_contract_lookup( + TokenMintTransition::V0(v0) => { + let v0_action = TokenMintTransitionActionV0::try_from_borrowed_token_mint_transition_with_contract_lookup( + drive, + transaction, v0, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs index 5d158482d68..5af141cff4a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs @@ -7,7 +7,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti /// Token issuance transition action v0 #[derive(Debug, Clone)] -pub struct TokenIssuanceTransitionActionV0 { +pub struct TokenMintTransitionActionV0 { /// Base token transition action pub base: TokenBaseTransitionAction, /// The amount of tokens to create @@ -73,7 +73,7 @@ pub trait TokenMintTransitionActionAccessorsV0 { fn set_public_note(&mut self, public_note: Option); } -impl TokenMintTransitionActionAccessorsV0 for TokenIssuanceTransitionActionV0 { +impl TokenMintTransitionActionAccessorsV0 for TokenMintTransitionActionV0 { fn base(&self) -> &TokenBaseTransitionAction { &self.base } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs index bedc0d48c7c..4e3fca8997d 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs @@ -1,32 +1,35 @@ use std::sync::Arc; - +use grovedb::TransactionArg; use dpp::identifier::Identifier; -use dpp::state_transition::batch_transition::token_issuance_transition::v0::TokenIssuanceTransitionV0; +use dpp::state_transition::batch_transition::token_issuance_transition::v0::TokenMintTransitionV0; use dpp::ProtocolError; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use dpp::tokens::errors::TokenError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::v0::TokenIssuanceTransitionActionV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::v0::TokenMintTransitionActionV0; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use crate::drive::Drive; -impl TokenIssuanceTransitionActionV0 { - /// Attempt to convert a `TokenIssuanceTransitionV0` into a `TokenIssuanceTransitionActionV0` using a data contract lookup function. +impl TokenMintTransitionActionV0 { + /// Attempt to convert a `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using a data contract lookup function. /// /// # Arguments /// - /// * `value` - A `TokenIssuanceTransitionV0` from which to derive the action + /// * `value` - A `TokenMintTransitionV0` from which to derive the action /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` /// /// # Returns /// - /// * `Result` - A `TokenIssuanceTransitionActionV0` if successful, else `ProtocolError`. - pub fn try_from_token_issuance_transition_with_contract_lookup( - value: TokenIssuanceTransitionV0, + /// * `Result` - A `TokenMintTransitionActionV0` if successful, else `ProtocolError`. + pub fn try_from_token_mint_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, + value: TokenMintTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenIssuanceTransitionV0 { + let TokenMintTransitionV0 { base, issued_to_identity_id, amount, @@ -36,6 +39,8 @@ impl TokenIssuanceTransitionActionV0 { let position = base.token_contract_position(); let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( + drive, + transaction, base, get_data_contract, )?; @@ -55,7 +60,7 @@ impl TokenIssuanceTransitionActionV0 { TokenError::DestinationIdentityForMintingNotSetError.into(), ))?; - Ok(TokenIssuanceTransitionActionV0 { + Ok(TokenMintTransitionActionV0 { base: base_action, mint_amount: amount, identity_balance_holder_id, @@ -63,21 +68,23 @@ impl TokenIssuanceTransitionActionV0 { }) } - /// Attempt to convert a borrowed `TokenIssuanceTransitionV0` into a `TokenIssuanceTransitionActionV0` using a data contract lookup function. + /// Attempt to convert a borrowed `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using a data contract lookup function. /// /// # Arguments /// - /// * `value` - A reference to a `TokenIssuanceTransitionV0` from which to derive the action + /// * `value` - A reference to a `TokenMintTransitionV0` from which to derive the action /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` /// /// # Returns /// - /// * `Result` - A `TokenIssuanceTransitionActionV0` if successful, else `ProtocolError`. - pub fn try_from_borrowed_token_issuance_transition_with_contract_lookup( - value: &TokenIssuanceTransitionV0, + /// * `Result` - A `TokenMintTransitionActionV0` if successful, else `ProtocolError`. + pub fn try_from_borrowed_token_mint_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, + value: &TokenMintTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { - let TokenIssuanceTransitionV0 { + let TokenMintTransitionV0 { base, issued_to_identity_id, amount, @@ -86,6 +93,8 @@ impl TokenIssuanceTransitionActionV0 { let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + transaction, base, get_data_contract, )?; @@ -105,7 +114,7 @@ impl TokenIssuanceTransitionActionV0 { TokenError::DestinationIdentityForMintingNotSetError.into(), ))?; - Ok(TokenIssuanceTransitionActionV0 { + Ok(TokenMintTransitionActionV0 { base: base_action, mint_amount: *amount, identity_balance_holder_id, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs index 708eb7004b7..99a2af6f1d2 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs @@ -1,9 +1,10 @@ use std::sync::Arc; - +use grovedb::TransactionArg; use dpp::platform_value::Identifier; use dpp::ProtocolError; use dpp::state_transition::batch_transition::TokenTransferTransition; use crate::drive::contract::DataContractFetchInfo; +use crate::drive::Drive; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionV0; @@ -20,6 +21,8 @@ impl TokenTransferTransitionAction { /// /// * `Result` - A `TokenTransferTransitionAction` if successful, otherwise `ProtocolError`. pub fn from_token_transfer_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: TokenTransferTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -27,6 +30,8 @@ impl TokenTransferTransitionAction { TokenTransferTransition::V0(v0) => { let v0_action = TokenTransferTransitionActionV0::try_from_token_transfer_transition_with_contract_lookup( + drive, + transaction, v0, get_data_contract, )?; @@ -46,12 +51,16 @@ impl TokenTransferTransitionAction { /// /// * `Result` - A `TokenTransferTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_borrowed_token_transfer_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: &TokenTransferTransition, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { match value { TokenTransferTransition::V0(v0) => { let v0_action = TokenTransferTransitionActionV0::try_from_borrowed_token_transfer_transition_with_contract_lookup( + drive, + transaction, v0, get_data_contract, )?; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index dec31daefc3..2c27cde2acf 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -1,16 +1,19 @@ -use std::sync::Arc; - use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_transfer_transition::v0::TokenTransferTransitionV0; use dpp::ProtocolError; +use grovedb::TransactionArg; +use std::sync::Arc; use crate::drive::contract::DataContractFetchInfo; +use crate::drive::Drive; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionActionV0; impl TokenTransferTransitionActionV0 { /// Convert a `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using contract lookup pub fn try_from_token_transfer_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: TokenTransferTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -24,6 +27,8 @@ impl TokenTransferTransitionActionV0 { } = value; let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( + drive, + transaction, base, get_data_contract, )?; @@ -40,6 +45,8 @@ impl TokenTransferTransitionActionV0 { /// Convert a borrowed `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using contract lookup pub fn try_from_borrowed_token_transfer_transition_with_contract_lookup( + drive: &Drive, + transaction: TransactionArg, value: &TokenTransferTransitionV0, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { @@ -54,6 +61,8 @@ impl TokenTransferTransitionActionV0 { let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + transaction, &base, get_data_contract, )?; diff --git a/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs b/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs index 8fba7f7970e..68bac3502d1 100644 --- a/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs @@ -52,6 +52,7 @@ enum KnownPath { TokenBalancesRoot, //Level 1 VersionsRoot, //Level 1 VotesRoot, //Level 1 + GroupActionsRoot, //Level 1 } impl From for KnownPath { @@ -74,6 +75,7 @@ impl From for KnownPath { RootTree::Tokens => KnownPath::TokenBalancesRoot, RootTree::Versions => KnownPath::VersionsRoot, RootTree::Votes => KnownPath::VotesRoot, + RootTree::GroupActions => KnownPath::GroupActionsRoot, } } } diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/mod.rs new file mode 100644 index 00000000000..943dac0b8e0 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/mod.rs @@ -0,0 +1,71 @@ +mod v0; + +use crate::util::grove_operations::BatchInsertApplyType; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::object_size_info::PathKeyElementInfo; + +use dpp::version::drive_versions::DriveVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Attempts to batch insert a sum item at the specified path and key if it doesn't already exist. + /// This method dispatches to the appropriate version of the `batch_insert_sum_item_if_not_exists` function + /// based on the version of the drive. Currently, version `0` is supported. + /// + /// # Parameters + /// * `path_key_element_info`: Contains the path, key, and element information to be inserted. + /// * `error_if_exists`: A flag that determines whether an error is returned if a sum item already exists at the given path and key. + /// * `apply_type`: Defines the batch insert type, such as stateless or stateful insertion. + /// * `transaction`: The transaction argument used for the operation. + /// * `drive_operations`: A mutable reference to a vector that collects low-level drive operations to be executed. + /// * `drive_version`: The version of the drive that influences the behavior of the batch insert operation. + /// + /// # Returns + /// * `Ok(())` if the batch insert is successful. + /// * `Err(Error)` if the operation fails, including an error for unknown version mismatches. + /// + /// # Description + /// This function checks the version of the drive's batch methods and dispatches the operation to the appropriate version of + /// `batch_insert_sum_item_if_not_exists`. Currently, only version `0` is supported, which delegates to the function + /// `batch_insert_sum_item_if_not_exists_v0`. If the drive version is not supported, an error is returned. + /// + /// In version `0`, the function performs the following: + /// - Checks if a sum item exists at the specified path and key. + /// - If the sum item exists and `error_if_exists` is true, an error is returned. + /// - If no sum item exists, a new sum item is inserted at the path and key. + /// + /// This method allows flexibility for future versions of the drive to implement different behaviors for batch insertion. + pub fn batch_insert_sum_item_if_not_exists( + &self, + path_key_element_info: PathKeyElementInfo, + error_if_exists: bool, + apply_type: BatchInsertApplyType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result<(), Error> { + match drive_version + .grove_methods + .batch + .batch_insert_sum_item_if_not_exists + { + 0 => self.batch_insert_sum_item_if_not_exists_v0( + path_key_element_info, + error_if_exists, + apply_type, + transaction, + drive_operations, + drive_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "batch_insert_sum_item_if_not_exists".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs new file mode 100644 index 00000000000..13e88ba1ca9 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs @@ -0,0 +1,224 @@ +use crate::util::grove_operations::BatchInsertApplyType; +use crate::util::object_size_info::PathKeyElementInfo::{ + PathFixedSizeKeyRefElement, PathKeyElement, PathKeyElementSize, PathKeyRefElement, + PathKeyUnknownElementSize, +}; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::fees::op::LowLevelDriveOperation::CalculatedCostOperation; +use crate::util::object_size_info::PathKeyElementInfo; +use dpp::version::drive_versions::DriveVersion; +use grovedb::{Element, GroveDb, TransactionArg}; + +impl Drive { + /// Inserts a sum item at the specified path and key if it doesn't already exist. + /// If a sum item exists at the specified location and `error_if_exists` is true, an error is returned. + /// If a sum item exists and `error_if_exists` is false, no changes are made. + /// If no sum item exists, a new sum item is inserted at the specified path and key. + /// + /// # Parameters + /// * `path_key_element_info`: Contains information about the path, key, and element to be processed. + /// * `error_if_exists`: A flag that determines whether to return an error if the sum item already exists. + /// * `apply_type`: Defines the type of batch insert to be performed (stateful or stateless). + /// * `transaction`: The transaction argument for the operation. + /// * `drive_operations`: A mutable reference to a vector of low-level drive operations to which new operations will be appended. + /// * `drive_version`: The version of the drive to ensure compatibility with the operation. + /// + /// # Returns + /// * `Ok(())` if the operation is successful. + /// * `Err(Error)` if the operation fails for any reason, such as corrupted state or unsupported operation. + /// + /// # Description + /// This function checks whether an existing sum item exists at the given path and key: + /// - If a sum item is found and `error_if_exists` is true, an error is returned. + /// - If a sum item is found and `error_if_exists` is false, no changes are made. + /// - If no sum item exists, a new sum item is inserted at the specified path and key. + /// + /// This function supports several types of paths and keys, including: + /// - `PathKeyRefElement`: A path with a reference to a key and element. + /// - `PathKeyElement`: A path with a direct key and element. + /// - `PathFixedSizeKeyRefElement`: A fixed-size key reference. + /// - `PathKeyElementSize`: An element with an associated size. + /// - `PathKeyUnknownElementSize`: An unknown element size type. + /// + /// Depending on the element type (`SumItem` in this case), the appropriate operations will be applied. + /// + /// **Note**: Stateful batch insertions of document sizes are not supported. + pub(super) fn batch_insert_sum_item_if_not_exists_v0( + &self, + path_key_element_info: PathKeyElementInfo, + error_if_exists: bool, + apply_type: BatchInsertApplyType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result<(), Error> { + match path_key_element_info { + PathKeyRefElement((path, key, element)) => { + if let Element::SumItem(new_value, _) = element { + // Check if the sum item already exists + let existing_element = self.grove_get_raw_optional( + path.as_slice().into(), + key, + apply_type.to_direct_query_type(), + transaction, + drive_operations, + drive_version, + )?; + + if let Some(Element::SumItem(..)) = existing_element { + if error_if_exists { + return Err(Error::Drive(DriveError::CorruptedDriveState( + "expected no sum item".to_string(), + ))); + } + // Else do nothing + } else if existing_element.is_some() { + return Err(Error::Drive(DriveError::CorruptedElementType( + "expected sum item element type", + ))); + } else { + // Insert as a new sum item + drive_operations.push( + LowLevelDriveOperation::insert_for_known_path_key_element( + path, + key.to_vec(), + Element::new_sum_item(new_value), + ), + ); + } + } else { + return Err(Error::Drive(DriveError::CorruptedCodeExecution( + "expected sum item element type", + ))); + } + Ok(()) + } + PathKeyElement((path, key, element)) => { + if let Element::SumItem(new_value, _) = element { + // Check if the sum item already exists + let existing_element = self.grove_get_raw_optional( + path.as_slice().into(), + key.as_slice(), + apply_type.to_direct_query_type(), + transaction, + drive_operations, + drive_version, + )?; + + if let Some(Element::SumItem(existing_value, _)) = existing_element { + if error_if_exists { + return Err(Error::Drive(DriveError::CorruptedDriveState( + "expected no sum item".to_string(), + ))); + } + // Else do nothing + } else if existing_element.is_some() { + return Err(Error::Drive(DriveError::CorruptedElementType( + "expected sum item element type", + ))); + } else { + // Insert as a new sum item + drive_operations.push( + LowLevelDriveOperation::insert_for_known_path_key_element( + path, + key, + Element::new_sum_item(new_value), + ), + ); + } + } else { + return Err(Error::Drive(DriveError::CorruptedCodeExecution( + "expected sum item element type", + ))); + } + Ok(()) + } + PathFixedSizeKeyRefElement((path, key, element)) => { + if let Element::SumItem(new_value, _) = element { + // Check if the sum item already exists + let existing_element = self.grove_get_raw_optional( + path.as_slice().into(), + key, + apply_type.to_direct_query_type(), + transaction, + drive_operations, + drive_version, + )?; + + if let Some(Element::SumItem(existing_value, _)) = existing_element { + if error_if_exists { + return Err(Error::Drive(DriveError::CorruptedDriveState( + "expected no sum item".to_string(), + ))); + } + // Else do nothing + } else if existing_element.is_some() { + return Err(Error::Drive(DriveError::CorruptedElementType( + "expected sum item element type", + ))); + } else { + // Insert as a new sum item + let path_items: Vec> = path.into_iter().map(Vec::from).collect(); + drive_operations.push( + LowLevelDriveOperation::insert_for_known_path_key_element( + path_items, + key.to_vec(), + Element::new_sum_item(new_value), + ), + ); + } + } else { + return Err(Error::Drive(DriveError::CorruptedCodeExecution( + "expected sum item element type", + ))); + } + Ok(()) + } + PathKeyElementSize((key_info_path, key_info, element)) => { + if let Element::SumItem(new_value, _) = element { + match apply_type { + BatchInsertApplyType::StatelessBatchInsert { + in_tree_using_sums, .. + } => { + // Estimate if the sum item with the given size already exists + drive_operations.push(CalculatedCostOperation( + GroveDb::average_case_for_has_raw( + &key_info_path, + &key_info, + element.serialized_size(&drive_version.grove_version)? as u32, + in_tree_using_sums, + &drive_version.grove_version, + )?, + )); + + drive_operations.push( + LowLevelDriveOperation::insert_for_estimated_path_key_element( + key_info_path, + key_info, + Element::new_sum_item(new_value), + ), + ); + Ok(()) + } + BatchInsertApplyType::StatefulBatchInsert => { + Err(Error::Drive(DriveError::NotSupportedPrivate( + "document sizes for stateful insert in batch operations not supported", + ))) + } + } + } else { + Err(Error::Drive(DriveError::CorruptedCodeExecution( + "expected sum item element type", + ))) + } + } + PathKeyUnknownElementSize(_) => Err(Error::Drive(DriveError::NotSupportedPrivate( + "document sizes in batch operations not supported", + ))), + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/mod.rs b/packages/rs-drive/src/util/grove_operations/mod.rs index 33f563a9304..119f2d83792 100644 --- a/packages/rs-drive/src/util/grove_operations/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/mod.rs @@ -129,6 +129,8 @@ pub mod grove_get_proved_path_query_with_conditional; /// Inserts an element if it does not exist and returns the existing element if it does in GroveDB. pub mod grove_insert_if_not_exists_return_existing_element; +/// Batch inserts sum items if not already existing +pub mod batch_insert_sum_item_if_not_exists; /// Moved items that are found in a path query to a new path. pub mod batch_move_items_in_path_query; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs b/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs index 5197624ade2..ea5387a78b4 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs @@ -12,7 +12,7 @@ pub const DRIVE_CONTRACT_METHOD_VERSIONS_V2: DriveContractMethodVersions = prove_contracts: 0, }, apply: DriveContractApplyMethodVersions { - apply_contract: 0, + apply_contract: 1, // <--- changed to v1 for inserting groups apply_contract_with_serialization: 0, }, insert: DriveContractInsertMethodVersions { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs new file mode 100644 index 00000000000..4f05d816a12 --- /dev/null +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs @@ -0,0 +1,26 @@ +use grovedb_version::version::FeatureVersion; + +pub mod v1; + +#[derive(Clone, Debug, Default)] +pub struct DriveGroupMethodVersions { + pub fetch: DriveGroupFetchMethodVersions, + pub prove: DriveGroupProveMethodVersions, + pub insert: DriveGroupInsertMethodVersions, + pub cost_estimation: DriveGroupCostEstimationMethodVersions, +} + +#[derive(Clone, Debug, Default)] +pub struct DriveGroupFetchMethodVersions {} + +#[derive(Clone, Debug, Default)] +pub struct DriveGroupProveMethodVersions {} + +#[derive(Clone, Debug, Default)] +pub struct DriveGroupInsertMethodVersions { + pub add_new_groups: FeatureVersion, + pub add_group_action: FeatureVersion, +} + +#[derive(Clone, Debug, Default)] +pub struct DriveGroupCostEstimationMethodVersions {} diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs new file mode 100644 index 00000000000..6b1624dbc4b --- /dev/null +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs @@ -0,0 +1,14 @@ +use crate::version::drive_versions::drive_group_method_versions::{ + DriveGroupCostEstimationMethodVersions, DriveGroupFetchMethodVersions, + DriveGroupInsertMethodVersions, DriveGroupMethodVersions, DriveGroupProveMethodVersions, +}; + +pub const DRIVE_GROUP_METHOD_VERSIONS_V1: DriveGroupMethodVersions = DriveGroupMethodVersions { + fetch: DriveGroupFetchMethodVersions {}, + prove: DriveGroupProveMethodVersions {}, + insert: DriveGroupInsertMethodVersions { + add_new_groups: 0, + add_group_action: 0, + }, + cost_estimation: DriveGroupCostEstimationMethodVersions {}, +}; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs index 5118c9093c4..209e0c5d816 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs @@ -40,6 +40,7 @@ pub struct DriveGroveBatchMethodVersions { pub batch_insert_empty_tree: FeatureVersion, pub batch_insert_empty_tree_if_not_exists: FeatureVersion, pub batch_insert_empty_tree_if_not_exists_check_existing_operations: FeatureVersion, + pub batch_insert_sum_item_if_not_exists: FeatureVersion, pub batch_insert_sum_item_or_add_to_if_already_exists: FeatureVersion, pub batch_insert: FeatureVersion, pub batch_insert_if_not_exists: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs index 900a65673dd..7d29de08a6b 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs @@ -31,6 +31,7 @@ pub const DRIVE_GROVE_METHOD_VERSIONS_V1: DriveGroveMethodVersions = DriveGroveM batch_insert_empty_tree: 0, batch_insert_empty_tree_if_not_exists: 0, batch_insert_empty_tree_if_not_exists_check_existing_operations: 0, + batch_insert_sum_item_if_not_exists: 0, batch_insert_sum_item_or_add_to_if_already_exists: 0, batch_insert: 0, batch_insert_if_not_exists: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/mod.rs index a1e68142678..130aa64f5a1 100644 --- a/packages/rs-platform-version/src/version/drive_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/mod.rs @@ -1,12 +1,13 @@ -use crate::version::drive_versions::drive_token_method_versions::DriveTokenMethodVersions; use crate::version::FeatureVersion; use drive_contract_method_versions::DriveContractMethodVersions; use drive_credit_pool_method_versions::DriveCreditPoolMethodVersions; use drive_document_method_versions::DriveDocumentMethodVersions; +use drive_group_method_versions::DriveGroupMethodVersions; use drive_grove_method_versions::DriveGroveMethodVersions; use drive_identity_method_versions::DriveIdentityMethodVersions; use drive_state_transition_method_versions::DriveStateTransitionMethodVersions; use drive_structure_version::DriveStructureVersion; +use drive_token_method_versions::DriveTokenMethodVersions; use drive_verify_method_versions::DriveVerifyMethodVersions; use drive_vote_method_versions::DriveVoteMethodVersions; use grovedb_version::version::GroveVersion; @@ -14,6 +15,7 @@ use grovedb_version::version::GroveVersion; pub mod drive_contract_method_versions; pub mod drive_credit_pool_method_versions; pub mod drive_document_method_versions; +pub mod drive_group_method_versions; pub mod drive_grove_method_versions; pub mod drive_identity_method_versions; pub mod drive_state_transition_method_versions; @@ -56,6 +58,7 @@ pub struct DriveMethodVersions { pub prove: DriveProveMethodVersions, pub state_transitions: DriveStateTransitionMethodVersions, pub platform_state: DrivePlatformStateMethodVersions, + pub group: DriveGroupMethodVersions, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/v1.rs index b058e036701..6fd8d42f987 100644 --- a/packages/rs-platform-version/src/version/drive_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/v1.rs @@ -1,6 +1,7 @@ use crate::version::drive_versions::drive_contract_method_versions::v1::DRIVE_CONTRACT_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_credit_pool_method_versions::v1::CREDIT_POOL_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_document_method_versions::v1::DRIVE_DOCUMENT_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_group_method_versions::v1::DRIVE_GROUP_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_grove_method_versions::v1::DRIVE_GROVE_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_identity_method_versions::v1::DRIVE_IDENTITY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_state_transition_method_versions::v1::DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1; @@ -96,6 +97,7 @@ pub const DRIVE_VERSION_V1: DriveVersion = DriveVersion { deduct_from_prefunded_specialized_balance_operations: 0, estimated_cost_for_prefunded_specialized_balance_update: 0, }, + group: DRIVE_GROUP_METHOD_VERSIONS_V1, }, grove_methods: DRIVE_GROVE_METHOD_VERSIONS_V1, grove_version: GROVE_V1, diff --git a/packages/rs-platform-version/src/version/drive_versions/v2.rs b/packages/rs-platform-version/src/version/drive_versions/v2.rs index 9ffd2082845..62cd996763d 100644 --- a/packages/rs-platform-version/src/version/drive_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_versions/v2.rs @@ -1,6 +1,7 @@ use crate::version::drive_versions::drive_contract_method_versions::v1::DRIVE_CONTRACT_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_credit_pool_method_versions::v1::CREDIT_POOL_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_document_method_versions::v1::DRIVE_DOCUMENT_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_group_method_versions::v1::DRIVE_GROUP_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_grove_method_versions::v1::DRIVE_GROVE_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_identity_method_versions::v1::DRIVE_IDENTITY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_state_transition_method_versions::v1::DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1; @@ -96,6 +97,7 @@ pub const DRIVE_VERSION_V2: DriveVersion = DriveVersion { deduct_from_prefunded_specialized_balance_operations: 0, estimated_cost_for_prefunded_specialized_balance_update: 0, }, + group: DRIVE_GROUP_METHOD_VERSIONS_V1, }, grove_methods: DRIVE_GROVE_METHOD_VERSIONS_V1, grove_version: GROVE_V1, diff --git a/packages/rs-platform-version/src/version/drive_versions/v3.rs b/packages/rs-platform-version/src/version/drive_versions/v3.rs index 30d67ebfd7d..f7e8b1b1e78 100644 --- a/packages/rs-platform-version/src/version/drive_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_versions/v3.rs @@ -1,6 +1,7 @@ use crate::version::drive_versions::drive_contract_method_versions::v2::DRIVE_CONTRACT_METHOD_VERSIONS_V2; use crate::version::drive_versions::drive_credit_pool_method_versions::v1::CREDIT_POOL_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_document_method_versions::v1::DRIVE_DOCUMENT_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_group_method_versions::v1::DRIVE_GROUP_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_grove_method_versions::v1::DRIVE_GROVE_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_identity_method_versions::v1::DRIVE_IDENTITY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_state_transition_method_versions::v1::DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1; @@ -96,6 +97,7 @@ pub const DRIVE_VERSION_V3: DriveVersion = DriveVersion { deduct_from_prefunded_specialized_balance_operations: 0, estimated_cost_for_prefunded_specialized_balance_update: 0, }, + group: DRIVE_GROUP_METHOD_VERSIONS_V1, }, grove_methods: DRIVE_GROVE_METHOD_VERSIONS_V1, grove_version: GROVE_V1, 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 66f624b692d..88f8ad14365 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -27,6 +27,7 @@ use crate::version::drive_abci_versions::DriveAbciVersion; use crate::version::drive_versions::drive_contract_method_versions::v1::DRIVE_CONTRACT_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_credit_pool_method_versions::v1::CREDIT_POOL_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_document_method_versions::v1::DRIVE_DOCUMENT_METHOD_VERSIONS_V1; +use crate::version::drive_versions::drive_group_method_versions::v1::DRIVE_GROUP_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_grove_method_versions::v1::DRIVE_GROVE_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_identity_method_versions::v1::DRIVE_IDENTITY_METHOD_VERSIONS_V1; use crate::version::drive_versions::drive_state_transition_method_versions::v1::DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1; @@ -131,6 +132,7 @@ pub const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { deduct_from_prefunded_specialized_balance_operations: 0, estimated_cost_for_prefunded_specialized_balance_update: 0, }, + group: DRIVE_GROUP_METHOD_VERSIONS_V1, }, grove_methods: DRIVE_GROVE_METHOD_VERSIONS_V1, grove_version: GROVE_V1, From bd541b629aefc4d415ccbb955c3f0276d216010a Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 30 Dec 2024 12:54:35 +0700 Subject: [PATCH 27/61] more work on groups --- .../rs-dpp/src/data_contract/accessors/mod.rs | 11 ++ .../src/data_contract/accessors/v1/mod.rs | 3 + .../data_contract/group/accessors/v0/mod.rs | 3 + .../rs-dpp/src/data_contract/group/mod.rs | 6 + .../rs-dpp/src/data_contract/group/v0/mod.rs | 10 ++ .../src/data_contract/v1/accessors/mod.rs | 11 ++ packages/rs-dpp/src/errors/protocol_error.rs | 6 + packages/rs-dpp/src/group/mod.rs | 2 +- .../fetch_action_id_signers_power/mod.rs | 82 +++++++++++ .../fetch_action_id_signers_power/v0/mod.rs | 134 ++++++++++++++++++ .../rs-drive/src/drive/group/fetch/mod.rs | 1 + .../group/insert/add_group_action/v0/mod.rs | 4 +- packages/rs-drive/src/drive/group/mod.rs | 2 + .../src/drive/initialization/v1/mod.rs | 5 - .../add_transaction_history_operations/mod.rs | 1 - .../prove_identities_token_balances/v0/mod.rs | 4 +- packages/rs-drive/src/query/mod.rs | 4 +- .../token_base_transition_action/mod.rs | 1 - .../token_base_transition_action/v0/mod.rs | 2 +- .../v0/transformer.rs | 44 ++++-- .../drive_group_method_versions/mod.rs | 4 +- .../drive_group_method_versions/v1.rs | 4 +- 22 files changed, 316 insertions(+), 28 deletions(-) create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/mod.rs diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index 4840054ef76..b47f1d7efa6 100644 --- a/packages/rs-dpp/src/data_contract/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/mod.rs @@ -13,6 +13,7 @@ use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1S use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::errors::DataContractError; use crate::data_contract::group::Group; +use crate::ProtocolError; use std::collections::BTreeMap; pub mod v0; @@ -188,6 +189,16 @@ impl DataContractV0Setters for DataContract { /// Implementing DataContractV1Getters for DataContract impl DataContractV1Getters for DataContract { + /// Returns a reference to the groups map. + fn group(&self, position: GroupContractPosition) -> Result<&Group, ProtocolError> { + match self { + DataContract::V0(_) => Err(ProtocolError::GroupNotFound( + "There can not be a group in v0 data contracts".to_string(), + )), + DataContract::V1(v1) => v1.group(position), + } + } + /// Returns a reference to the groups map. fn groups(&self) -> &BTreeMap { match self { diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs index 489d45b5f18..5f43439f635 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -2,10 +2,13 @@ use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0S use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::group::Group; use crate::data_contract::{GroupContractPosition, TokenContractPosition}; +use crate::ProtocolError; use platform_value::Identifier; use std::collections::BTreeMap; pub trait DataContractV1Getters: DataContractV0Getters { + /// Gets a group at a certain position + fn group(&self, position: GroupContractPosition) -> Result<&Group, ProtocolError>; /// Returns a reference to the groups map. fn groups(&self) -> &BTreeMap; diff --git a/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs index ed082f3d5ef..55353dd047b 100644 --- a/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/group/accessors/v0/mod.rs @@ -1,9 +1,12 @@ use crate::data_contract::group::GroupRequiredPower; +use crate::ProtocolError; use platform_value::Identifier; use std::collections::BTreeMap; /// Getters for GroupV0 pub trait GroupV0Getters { + /// Returns the member power + fn member_power(&self, member_id: Identifier) -> Result; /// Returns the members map of the group fn members(&self) -> &BTreeMap; diff --git a/packages/rs-dpp/src/data_contract/group/mod.rs b/packages/rs-dpp/src/data_contract/group/mod.rs index df3427ede35..01919b161a4 100644 --- a/packages/rs-dpp/src/data_contract/group/mod.rs +++ b/packages/rs-dpp/src/data_contract/group/mod.rs @@ -12,6 +12,7 @@ mod v0; pub type RequiredSigners = u8; pub type GroupMemberPower = u32; +pub type GroupSumPower = u32; pub type GroupRequiredPower = u32; #[derive( Serialize, @@ -31,6 +32,11 @@ pub enum Group { } impl GroupV0Getters for Group { + fn member_power(&self, member_id: Identifier) -> Result { + match self { + Group::V0(group_v0) => group_v0.member_power(member_id), + } + } fn members(&self) -> &BTreeMap { match self { Group::V0(group_v0) => group_v0.members(), diff --git a/packages/rs-dpp/src/data_contract/group/v0/mod.rs b/packages/rs-dpp/src/data_contract/group/v0/mod.rs index 00dbb9bee63..c53696e9b25 100644 --- a/packages/rs-dpp/src/data_contract/group/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/group/v0/mod.rs @@ -26,6 +26,16 @@ pub struct GroupV0 { } impl GroupV0Getters for GroupV0 { + fn member_power(&self, member_id: Identifier) -> Result { + self.members + .get(&member_id) + .cloned() + .ok_or(ProtocolError::GroupMemberNotFound(format!( + "Group member {} not found", + member_id + ))) + } + fn members(&self) -> &BTreeMap { &self.members } diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs index 2dda757c4da..a1987129762 100644 --- a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -12,6 +12,7 @@ use crate::data_contract::associated_token::token_configuration::TokenConfigurat use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::group::Group; use crate::util::hash::hash_double; +use crate::ProtocolError; use platform_value::Identifier; use std::collections::BTreeMap; @@ -144,6 +145,16 @@ impl DataContractV0Setters for DataContractV1 { } impl DataContractV1Getters for DataContractV1 { + fn group(&self, position: GroupContractPosition) -> Result<&Group, ProtocolError> { + self.groups + .get(&position) + .ok_or(ProtocolError::GroupNotFound(format!( + "Group not found in contract {} at position {}", + self.id(), + position + ))) + } + fn groups(&self) -> &BTreeMap { &self.groups } diff --git a/packages/rs-dpp/src/errors/protocol_error.rs b/packages/rs-dpp/src/errors/protocol_error.rs index e9fa0a7a0a2..a179ae93e7f 100644 --- a/packages/rs-dpp/src/errors/protocol_error.rs +++ b/packages/rs-dpp/src/errors/protocol_error.rs @@ -236,6 +236,12 @@ pub enum ProtocolError { #[error("Public key generation error {0}")] PublicKeyGenerationError(String), + #[error("group member not found in contract: {0}")] + GroupMemberNotFound(String), + + #[error("group not found in contract: {0}")] + GroupNotFound(String), + #[error("corrupted code execution: {0}")] CorruptedCodeExecution(String), diff --git a/packages/rs-dpp/src/group/mod.rs b/packages/rs-dpp/src/group/mod.rs index 42dda497ca1..d1069d494c5 100644 --- a/packages/rs-dpp/src/group/mod.rs +++ b/packages/rs-dpp/src/group/mod.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; pub mod action_event; pub mod group_action; -#[derive(Debug, Clone, Encode, Decode, Default, PartialEq, Display)] +#[derive(Debug, Clone, Copy, Encode, Decode, Default, PartialEq, Display)] #[cfg_attr( feature = "state-transition-serde-conversion", derive(Serialize, Deserialize), diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs new file mode 100644 index 00000000000..9b9ac635fa8 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs @@ -0,0 +1,82 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::group::GroupSumPower; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::HashMap; + +mod v0; + +impl Drive { + /// Fetches the action id signers power + pub fn fetch_action_id_signers_power( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_signers_power + { + 0 => self.fetch_action_id_signers_power_v0( + contract_id, + group_contract_position, + action_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_signers_power".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + pub(crate) fn fetch_action_id_signers_power_and_add_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_signers_power + { + 0 => self.fetch_action_id_signers_power_and_add_operations_v0( + contract_id, + group_contract_position, + action_id, + estimated_costs_only_with_layer_info, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_signers_and_add_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs new file mode 100644 index 00000000000..d6b6531c96f --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs @@ -0,0 +1,134 @@ +use std::collections::HashMap; + +use crate::drive::group::{group_action_path, group_action_signers_path, ACTION_SIGNERS_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::DirectQueryType::StatefulDirectQuery; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::data_contract::group::GroupSumPower; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; + +impl Drive { + /// v0 implementation of fetching the signers' power for a given action ID within a group contract. + /// + /// This function retrieves the signers' power associated with a specific action ID in a group contract. + /// It constructs the appropriate GroveDB path, fetches the relevant data, deserializes it, and + /// calculates any applicable fees based on the provided epoch. + /// + /// # Parameters + /// * `contract_id` - The identifier of the contract. + /// * `group_contract_position` - The position of the group contract within the data contract. + /// * `action_id` - The identifier of the action whose signers' power is to be fetched. + /// * `apply` - A boolean flag indicating whether to apply certain operations during the fetch. + /// * `transaction` - The GroveDB transaction argument for executing the fetch operation. + /// * `platform_version` - The current platform version, used to ensure compatibility. + /// + /// # Returns + /// * `Ok(Some(Arc))` if the signers' power is successfully fetched. + /// * `Ok(None)` if the signers' power does not exist. + /// * `Err(Error)` if an error occurs during the fetch operation. + /// + /// # Errors + /// * `Error::Drive(DriveError::CorruptedContractPath)` if the fetched path does not refer to a valid sum item. + /// * `Error::Drive(DriveError::CorruptedCodeExecution)` if the element type is unexpected. + /// * `Error::GroveDB` for any underlying GroveDB errors. + pub(super) fn fetch_action_id_signers_power_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_action_path( + contract_id.as_ref(), + &group_contract_position_bytes, + action_id.as_ref(), + ); + + let value = self.grove_get_sum_tree_total_value( + (&path).into(), + ACTION_SIGNERS_KEY, + StatefulDirectQuery, + transaction, + &mut vec![], + &platform_version.drive, + )?; + + Ok(value as GroupSumPower) + } + + /// v0 implementation of fetching the signers' power for a given action ID within a group contract and adding related operations. + /// + /// This function not only fetches the signers' power but also appends necessary low-level drive operations based on the provided epoch. + /// It ensures that fees are calculated and added to the `drive_operations` vector when applicable. + /// + /// # Parameters + /// * `contract_id` - The identifier of the contract. + /// * `group_contract_position` - The position of the group contract within the data contract. + /// * `action_id` - The identifier of the action whose signers' power is to be fetched. + /// * `epoch` - An optional reference to an `Epoch` object. If provided, fees will be calculated based on the epoch. + /// * `transaction` - The GroveDB transaction argument for executing the fetch operation. + /// * `drive_operations` - A mutable reference to a vector where low-level drive operations and fees will be appended. + /// * `platform_version` - The current platform version, used to ensure compatibility. + /// + /// # Returns + /// * `Ok(Some(Arc))` if the signers' power is successfully fetched. + /// * `Ok(None)` if the signers' power does not exist. + /// * `Err(Error)` if an error occurs during the fetch operation. + /// + /// # Errors + /// * `Error::Drive(DriveError::CorruptedContractPath)` if the fetched path does not refer to a valid sum item. + /// * `Error::Drive(DriveError::CorruptedCodeExecution)` if the element type is unexpected. + /// * `Error::Drive(DriveError::NotSupportedPrivate)` if stateful batch insertions are attempted. + /// * `Error::GroveDB` for any underlying GroveDB errors. + pub(super) fn fetch_action_id_signers_power_and_add_operations_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_action_path( + contract_id.as_ref(), + &group_contract_position_bytes, + action_id.as_ref(), + ); + + // no estimated_costs_only_with_layer_info, means we want to apply to state + let direct_query_type = if estimated_costs_only_with_layer_info.is_none() { + DirectQueryType::StatefulDirectQuery + } else { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums: false, + query_target: QueryTargetValue(8), + } + }; + + let value = self.grove_get_sum_tree_total_value( + (&path).into(), + ACTION_SIGNERS_KEY, + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + )?; + + Ok(value as GroupSumPower) + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/mod.rs b/packages/rs-drive/src/drive/group/fetch/mod.rs new file mode 100644 index 00000000000..7954f4ad501 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/mod.rs @@ -0,0 +1 @@ +mod fetch_action_id_signers_power; diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs index 71c991d9f40..34ccdd1e182 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -77,7 +77,7 @@ impl Drive { Some(HashMap::new()) }; - let batch_operations = self.add_new_group_action_operations( + let batch_operations = self.add_group_action_operations( contract_id, group_contract_position, action_id, @@ -160,7 +160,7 @@ impl Drive { let signers_path = group_action_signers_path_vec( contract_id.as_slice(), - *group_contract_position, + group_contract_position, action_id.as_slice(), ); diff --git a/packages/rs-drive/src/drive/group/mod.rs b/packages/rs-drive/src/drive/group/mod.rs index b65a51ee37f..83799023d9f 100644 --- a/packages/rs-drive/src/drive/group/mod.rs +++ b/packages/rs-drive/src/drive/group/mod.rs @@ -1,7 +1,9 @@ use crate::drive::RootTree; use dpp::data_contract::GroupContractPosition; +mod fetch; mod insert; + pub const GROUP_INFO_KEY: &[u8; 1] = b"I"; pub const GROUP_ACTIONS_KEY: &[u8; 1] = b"M"; pub const ACTION_INFO_KEY: &[u8; 1] = b"I"; diff --git a/packages/rs-drive/src/drive/initialization/v1/mod.rs b/packages/rs-drive/src/drive/initialization/v1/mod.rs index 0e0db5c11bc..4fbf480d0bc 100644 --- a/packages/rs-drive/src/drive/initialization/v1/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v1/mod.rs @@ -7,11 +7,6 @@ use crate::drive::system::misc_path_vec; use crate::drive::{Drive, RootTree}; use crate::error::Error; use crate::util::batch::grovedb_op_batch::GroveDbOpBatchV0Methods; - -use crate::drive::identity::withdrawals::paths::{ - get_withdrawal_root_path_vec, WITHDRAWAL_TRANSACTIONS_BROADCASTED_KEY, - WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY, -}; use dpp::version::PlatformVersion; use grovedb::{Element, TransactionArg}; use grovedb_path::SubtreePath; diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/mod.rs index c7682b7dcde..53acbd61852 100644 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/mod.rs +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/mod.rs @@ -3,7 +3,6 @@ use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use dpp::block::block_info::BlockInfo; -use dpp::fee::fee_result::FeeResult; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; use dpp::tokens::token_event::TokenEvent; diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs index 86d2103a4ea..d25dc8fe165 100644 --- a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/v0/mod.rs @@ -47,9 +47,7 @@ mod tests { use dpp::balances::credits::TokenAmount; use dpp::block::block_info::BlockInfo; use dpp::data_contract::accessors::v1::DataContractV1Getters; - use dpp::data_contract::associated_token::token_configuration::v0::{ - TokenConfigurationConventionV0, TokenConfigurationV0, - }; + use dpp::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; use dpp::data_contract::config::v0::DataContractConfigV0; use dpp::data_contract::config::DataContractConfig; diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index f6aa81deb21..03a568103f0 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -2292,9 +2292,7 @@ mod tests { use serde_json::Value::Null; use crate::config::DriveConfig; - use crate::util::test_helpers::setup::{ - setup_drive_with_initial_state_structure, setup_system_data_contract, - }; + use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; use dpp::block::block_info::BlockInfo; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contracts::SystemDataContract; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs index 8af281a02bf..ecbcfac66c8 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs @@ -1,6 +1,5 @@ use derive_more::From; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; -use dpp::data_contract::GroupContractPosition; use dpp::group::GroupStateTransitionInfo; use dpp::platform_value::Identifier; use dpp::prelude::IdentityNonce; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs index 1ec510b4037..d698831c213 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs @@ -57,7 +57,7 @@ pub trait TokenBaseTransitionActionAccessorsV0 { fn token_configuration(&self) -> Result<&TokenConfiguration, Error>; /// Gets the store_in_group field (optional) - fn store_in_group(&self) -> Option; + fn store_in_group(&self) -> Option; /// Gets the perform_action field fn perform_action(&self) -> bool; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index ffd5ad44c01..767451179ea 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -1,22 +1,32 @@ -use dpp::data_contract::accessors::v1::DataContractV1Getters; +use std::collections::HashMap; use dpp::group::GroupStateTransitionInfo; use dpp::platform_value::Identifier; -use grovedb::TransactionArg; +use grovedb::{EstimatedLayerInformation, TransactionArg}; use std::sync::Arc; - +use grovedb::batch::KeyInfoPath; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::group::accessors::v0::GroupV0Getters; use dpp::ProtocolError; use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; +use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; impl TokenBaseTransitionActionV0 { /// try from base transition with contract lookup pub fn try_from_base_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: TokenBaseTransitionV0, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, ) -> Result { let TokenBaseTransitionV0 { token_contract_position, @@ -28,13 +38,25 @@ impl TokenBaseTransitionActionV0 { let data_contract = get_data_contract(data_contract_id)?; - let (store_in_group, perform_action) = match using_group { - None => (None, true), + let perform_action = match &using_group { + None => true, Some(GroupStateTransitionInfo { group_contract_position, action_id, }) => { - drive.fetch_action_id_signers(data_contract_id, group_contract_position, action_id) + let group = data_contract.contract.group(*group_contract_position)?; + let signer_power = group.member_power(owner_id)?; + let required_power = group.required_power(); + let current_power = drive.fetch_action_id_signers_power_and_add_operations( + data_contract_id, + *group_contract_position, + *action_id, + estimated_costs_only_with_layer_info, + transaction, + drive_operations, + platform_version, + )?; + current_power + signer_power >= required_power } }; Ok(TokenBaseTransitionActionV0 { @@ -42,7 +64,7 @@ impl TokenBaseTransitionActionV0 { identity_contract_nonce, token_contract_position, data_contract, - store_in_group, + store_in_group: using_group, perform_action, }) } @@ -50,8 +72,12 @@ impl TokenBaseTransitionActionV0 { /// try from borrowed base transition with contract lookup pub fn try_from_borrowed_base_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, value: &TokenBaseTransitionV0, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, ) -> Result { let TokenBaseTransitionV0 { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs index 4f05d816a12..2fd64eedbdd 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs @@ -11,7 +11,9 @@ pub struct DriveGroupMethodVersions { } #[derive(Clone, Debug, Default)] -pub struct DriveGroupFetchMethodVersions {} +pub struct DriveGroupFetchMethodVersions { + pub fetch_action_id_signers_power: FeatureVersion, +} #[derive(Clone, Debug, Default)] pub struct DriveGroupProveMethodVersions {} diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs index 6b1624dbc4b..e47d8645819 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs @@ -4,7 +4,9 @@ use crate::version::drive_versions::drive_group_method_versions::{ }; pub const DRIVE_GROUP_METHOD_VERSIONS_V1: DriveGroupMethodVersions = DriveGroupMethodVersions { - fetch: DriveGroupFetchMethodVersions {}, + fetch: DriveGroupFetchMethodVersions { + fetch_action_id_signers_power: 0, + }, prove: DriveGroupProveMethodVersions {}, insert: DriveGroupInsertMethodVersions { add_new_groups: 0, From 712396bcba0baf9212f0bd240c0c8bc4c57241af Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 30 Dec 2024 20:35:57 +0700 Subject: [PATCH 28/61] basic validation of tokens --- .../src/errors/consensus/basic/basic_error.rs | 13 ++++++ .../rs-dpp/src/errors/consensus/basic/mod.rs | 1 + .../basic/token/invalid_action_id_error.rs | 39 ++++++++++++++++++ .../token/invalid_group_position_error.rs | 40 ++++++++++++++++++ .../basic/token/invalid_token_id_error.rs | 39 ++++++++++++++++++ .../token/invalid_token_position_error.rs | 40 ++++++++++++++++++ .../src/errors/consensus/basic/token/mod.rs | 9 ++++ packages/rs-dpp/src/errors/consensus/codes.rs | 8 +++- packages/rs-dpp/src/group/mod.rs | 6 +++ .../batched_transition/document_transition.rs | 2 +- .../batched_transition/mod.rs | 2 +- .../batched_transition/multi_party_action.rs | 2 +- .../batched_transition/resolvers.rs | 8 ++-- .../token_base_transition/v0/mod.rs | 4 +- .../token_base_transition/v0/v0_methods.rs | 23 +++++++++-- .../token_base_transition/v0_methods.rs | 10 ++++- .../token_burn_transition/v0/v0_methods.rs | 4 +- .../token_burn_transition/v0_methods.rs | 4 +- .../mod.rs | 0 .../v0/mod.rs | 0 .../v0/v0_methods.rs | 6 +-- .../v0_methods.rs | 8 ++-- .../v0/v0_methods.rs | 21 +++++++++- .../token_transfer_transition/v0_methods.rs | 9 ++++ .../batched_transition/token_transition.rs | 13 +++++- .../document/batch_transition/mod.rs | 4 +- .../batch_transition/resolvers/v0/mod.rs | 2 +- .../validate_basic_structure/v0/mod.rs | 26 ++++++++++++ .../group/insert/add_group_action/v0/mod.rs | 2 +- .../v0/transformer.rs | 41 +++++++++++++++---- .../transformer.rs | 2 +- .../v0/transformer.rs | 2 +- .../v0/mod.rs | 2 +- 33 files changed, 349 insertions(+), 43 deletions(-) create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/invalid_action_id_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/invalid_group_position_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_id_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/mod.rs rename packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/{token_issuance_transition => token_mint_transition}/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/{token_issuance_transition => token_mint_transition}/v0/mod.rs (100%) rename packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/{token_issuance_transition => token_mint_transition}/v0/v0_methods.rs (92%) rename packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/{token_issuance_transition => token_mint_transition}/v0_methods.rs (85%) diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index bb6ed170f8b..065c3510761 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -72,6 +72,7 @@ use crate::consensus::basic::value_error::ValueError; use crate::consensus::basic::{ json_schema_compilation_error::JsonSchemaCompilationError, json_schema_error::JsonSchemaError, }; +use crate::consensus::basic::token::{InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, InvalidTokenPositionError}; use crate::consensus::state::identity::master_public_key_update_error::MasterPublicKeyUpdateError; use crate::data_contract::errors::DataContractError; @@ -406,6 +407,18 @@ pub enum BasicError { #[error(transparent)] ContestedDocumentsTemporarilyNotAllowedError(ContestedDocumentsTemporarilyNotAllowedError), + + #[error(transparent)] + InvalidTokenIdError(InvalidTokenIdError), + + #[error(transparent)] + InvalidTokenPositionError(InvalidTokenPositionError), + + #[error(transparent)] + InvalidGroupPositionError(InvalidGroupPositionError), + + #[error(transparent)] + InvalidActionIdError(InvalidActionIdError), } impl From for ConsensusError { diff --git a/packages/rs-dpp/src/errors/consensus/basic/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/mod.rs index b96be4629b0..3d3f1ac9d40 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/mod.rs @@ -7,6 +7,7 @@ pub use unsupported_version_error::*; pub mod data_contract; pub mod decode; pub mod document; +pub mod token; pub mod identity; pub mod incompatible_protocol_version_error; pub mod unsupported_protocol_version_error; diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_action_id_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_action_id_error.rs new file mode 100644 index 00000000000..cb16b1851bb --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_action_id_error.rs @@ -0,0 +1,39 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use crate::prelude::Identifier; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Invalid action id {}, expected {}", invalid_action_id, expected_action_id)] +#[platform_serialize(unversioned)] +pub struct InvalidActionIdError { + expected_action_id: Identifier, + invalid_action_id: Identifier, +} + +impl InvalidActionIdError { + pub fn new(expected_action_id: Identifier, invalid_action_id: Identifier) -> Self { + Self { + expected_action_id, + invalid_action_id, + } + } + + pub fn expected_action_id(&self) -> Identifier { + self.expected_action_id + } + + pub fn invalid_action_id(&self) -> Identifier { + self.invalid_action_id + } +} + +impl From for ConsensusError { + fn from(err: InvalidActionIdError) -> Self { + Self::BasicError(BasicError::InvalidActionIdError(err)) + } +} \ No newline at end of file diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_group_position_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_group_position_error.rs new file mode 100644 index 00000000000..7eab6464cbc --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_group_position_error.rs @@ -0,0 +1,40 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use thiserror::Error; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use bincode::{Decode, Encode}; +use crate::data_contract::GroupContractPosition; +use crate::ProtocolError; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Invalid group position {}, expected {}", invalid_group_position, expected_group_position)] +#[platform_serialize(unversioned)] +pub struct InvalidGroupPositionError { + expected_group_position: GroupContractPosition, + invalid_group_position: GroupContractPosition, +} + +impl InvalidGroupPositionError { + pub fn new(expected_group_position: GroupContractPosition, invalid_group_position: GroupContractPosition) -> Self { + Self { + expected_group_position, + invalid_group_position, + } + } + + pub fn expected_group_position(&self) -> GroupContractPosition { + self.expected_group_position + } + + pub fn invalid_group_position(&self) -> GroupContractPosition { + self.invalid_group_position + } +} + +impl From for ConsensusError { + fn from(err: InvalidGroupPositionError) -> Self { + Self::BasicError(BasicError::InvalidGroupPositionError(err)) + } +} \ No newline at end of file diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_id_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_id_error.rs new file mode 100644 index 00000000000..d11856ff0ca --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_id_error.rs @@ -0,0 +1,39 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use crate::prelude::Identifier; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Invalid token id {}, expected {}", invalid_token_id, expected_token_id)] +#[platform_serialize(unversioned)] +pub struct InvalidTokenIdError { + expected_token_id: Identifier, + invalid_token_id: Identifier, +} + +impl InvalidTokenIdError { + pub fn new(expected_token_id: Identifier, invalid_token_id: Identifier) -> Self { + Self { + expected_token_id, + invalid_token_id, + } + } + + pub fn expected_token_id(&self) -> Identifier { + self.expected_token_id + } + + pub fn invalid_token_id(&self) -> Identifier { + self.invalid_token_id + } +} + +impl From for ConsensusError { + fn from(err: InvalidTokenIdError) -> Self { + Self::BasicError(BasicError::InvalidTokenIdError(err)) + } +} \ No newline at end of file diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs new file mode 100644 index 00000000000..fb1b79ae60b --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs @@ -0,0 +1,40 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use thiserror::Error; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use bincode::{Decode, Encode}; +use crate::data_contract::TokenContractPosition; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Invalid token position {}, expected {}", invalid_token_position, expected_token_position)] +#[platform_serialize(unversioned)] +pub struct InvalidTokenPositionError { + expected_token_position: TokenContractPosition, + invalid_token_position: TokenContractPosition, +} + +impl InvalidTokenPositionError { + pub fn new(expected_token_position: TokenContractPosition, invalid_token_position: TokenContractPosition) -> Self { + Self { + expected_token_position, + invalid_token_position, + } + } + + pub fn expected_token_position(&self) -> TokenContractPosition { + self.expected_token_position + } + + pub fn invalid_token_position(&self) -> TokenContractPosition { + self.invalid_token_position + } +} + +impl From for ConsensusError { + fn from(err: InvalidTokenPositionError) -> Self { + Self::BasicError(BasicError::InvalidTokenPositionError(err)) + } +} \ No newline at end of file diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs new file mode 100644 index 00000000000..9e2c4bce5ad --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs @@ -0,0 +1,9 @@ +pub mod invalid_token_id_error; +pub mod invalid_token_position_error; +pub mod invalid_group_position_error; +pub mod invalid_action_id_error; + +pub use invalid_token_id_error::*; +pub use invalid_token_position_error::*; +pub use invalid_group_position_error::*; +pub use invalid_action_id_error::*; \ No newline at end of file diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index aff0563c53d..748cd1648c0 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -100,7 +100,7 @@ impl ErrorWithCode for BasicError { Self::ContestedUniqueIndexWithUniqueIndexError(_) => 10249, Self::DataContractTokenConfigurationUpdateError { .. } => 10250, - // Document Errors: 10400-10499 + // Document Errors: 10400-10449 Self::DataContractNotPresentError { .. } => 10400, Self::DuplicateDocumentTransitionsWithIdsError { .. } => 10401, Self::DuplicateDocumentTransitionsWithIndicesError { .. } => 10402, @@ -121,6 +121,12 @@ impl ErrorWithCode for BasicError { Self::DocumentFieldMaxSizeExceededError(_) => 10417, Self::ContestedDocumentsTemporarilyNotAllowedError(_) => 10418, + // Token Errors: 10450-10499 + Self::InvalidTokenIdError(_) => 10450, + Self::InvalidTokenPositionError(_) => 10451, + Self::InvalidGroupPositionError(_) => 10452, + Self::InvalidActionIdError(_) => 10453, + // Identity Errors: 10500-10599 Self::DuplicatedIdentityPublicKeyBasicError(_) => 10500, Self::DuplicatedIdentityPublicKeyIdBasicError(_) => 10501, diff --git a/packages/rs-dpp/src/group/mod.rs b/packages/rs-dpp/src/group/mod.rs index d1069d494c5..081ea63a1f3 100644 --- a/packages/rs-dpp/src/group/mod.rs +++ b/packages/rs-dpp/src/group/mod.rs @@ -26,4 +26,10 @@ pub struct GroupStateTransitionInfo { serde(rename = "$groupActionId") )] pub action_id: Identifier, + /// This is true if we are the proposer, otherwise we are just voting on a previous action. + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "$groupActionIsProposer") + )] + pub action_is_proposer: bool, } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs index 910c0795ce9..a9f5f1ecdb2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs @@ -86,7 +86,7 @@ impl BatchTransitionResolversV0 for DocumentTransition { None } - fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition> { + fn as_transition_token_mint(&self) -> Option<&TokenMintTransition> { None } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs index 8cfa58e7e37..f89836c8c9a 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs @@ -16,7 +16,7 @@ pub mod multi_party_action; mod resolvers; pub mod token_base_transition; pub mod token_burn_transition; -pub mod token_issuance_transition; +pub mod token_mint_transition; pub mod token_transfer_transition; pub mod token_transition; pub mod token_transition_action_type; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/multi_party_action.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/multi_party_action.rs index 9b648ea5f90..52f7cf4e7f4 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/multi_party_action.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/multi_party_action.rs @@ -1,5 +1,5 @@ use platform_value::Identifier; pub trait AllowedAsMultiPartyAction { - fn action_id(&self, owner_id: Identifier) -> Identifier; + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs index 22fdba19a57..4939084539c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs @@ -50,10 +50,10 @@ impl BatchTransitionResolversV0 for BatchedTransition { } } - fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition> { + fn as_transition_token_mint(&self) -> Option<&TokenMintTransition> { match self { BatchedTransition::Document(_) => None, - BatchedTransition::Token(token) => token.as_transition_token_issuance(), + BatchedTransition::Token(token) => token.as_transition_token_mint(), } } @@ -108,10 +108,10 @@ impl<'a> BatchTransitionResolversV0 for BatchedTransitionRef<'a> { } } - fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition> { + fn as_transition_token_mint(&self) -> Option<&TokenMintTransition> { match self { BatchedTransitionRef::Document(_) => None, - BatchedTransitionRef::Token(token) => token.as_transition_token_issuance(), + BatchedTransitionRef::Token(token) => token.as_transition_token_mint(), } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs index e685bccdbee..4034cdc1706 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs @@ -68,7 +68,7 @@ pub struct TokenBaseTransitionV0 { pub token_id: Identifier, /// Using group multi party rules for authentication #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] - pub using_group: Option, + pub using_group_info: Option, } impl TokenBaseTransitionV0 { @@ -96,7 +96,7 @@ impl TokenBaseTransitionV0 { .unwrap_or(data_contract.token_id(token_contract_position).ok_or( ProtocolError::Token(TokenError::TokenNotFoundAtPositionError.into()), )?), - using_group: map + using_group_info: map .remove_optional_integer(property_names::GROUP_CONTRACT_POSITION) .map_err(ProtocolError::ValueError)? .map(|group_contract_position| { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs index 9e0802ca875..07330e0192a 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs @@ -3,6 +3,7 @@ use crate::group::GroupStateTransitionInfo; use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use platform_value::Identifier; +use crate::util::hash::hash_double; /// A trait that contains getter and setter methods for `TokenBaseTransitionV0` pub trait TokenBaseTransitionV0Methods { @@ -16,6 +17,14 @@ pub trait TokenBaseTransitionV0Methods { fn data_contract_id(&self) -> Identifier; fn data_contract_id_ref(&self) -> &Identifier; + /// Calculates the token ID. + fn calculate_token_id(&self) -> Identifier { + let mut bytes = b"token".to_vec(); + bytes.extend_from_slice(self.data_contract_id().as_bytes()); + bytes.extend_from_slice(&self.token_contract_position().to_be_bytes()); + hash_double(bytes).into() + } + /// Returns the token ID. fn token_id(&self) -> Identifier; fn token_id_ref(&self) -> &Identifier; @@ -25,7 +34,9 @@ pub trait TokenBaseTransitionV0Methods { /// Returns the group ID. fn group_position(&self) -> Option; - fn set_group_info(&mut self, group_info: Option); + fn using_group_info(&self) -> Option; + + fn set_using_group_info(&mut self, group_info: Option); /// Sets the data contract ID. fn set_data_contract_id(&mut self, data_contract_id: Identifier); @@ -75,12 +86,16 @@ impl TokenBaseTransitionV0Methods for TokenBaseTransitionV0 { } fn group_position(&self) -> Option { - self.using_group + self.using_group_info .as_ref() .map(|info| info.group_contract_position) } - fn set_group_info(&mut self, group_info: Option) { - self.using_group = group_info; + fn set_using_group_info(&mut self, group_info: Option) { + self.using_group_info = group_info; + } + + fn using_group_info(&self) -> Option { + self.using_group_info } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs index 2bc0f33dfcd..5eeffbf6ff0 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0_methods.rs @@ -54,9 +54,15 @@ impl TokenBaseTransitionV0Methods for TokenBaseTransition { } } - fn set_group_info(&mut self, group_info: Option) { + fn using_group_info(&self) -> Option { match self { - TokenBaseTransition::V0(v0) => v0.set_group_info(group_info), + TokenBaseTransition::V0(v0) => v0.using_group_info(), + } + } + + fn set_using_group_info(&mut self, group_info: Option) { + match self { + TokenBaseTransition::V0(v0) => v0.set_using_group_info(group_info), } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs index 1da7aea51b3..8cdcd6e153f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0/v0_methods.rs @@ -60,12 +60,12 @@ impl TokenBurnTransitionV0Methods for TokenBurnTransitionV0 { } impl AllowedAsMultiPartyAction for TokenBurnTransitionV0 { - fn action_id(&self, owner_id: Identifier) -> Identifier { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { let TokenBurnTransitionV0 { base, burn_amount, .. } = self; - let mut bytes = b"action_burn".to_vec(); + let mut bytes = b"action_token_burn".to_vec(); bytes.extend_from_slice(base.token_id().as_bytes()); bytes.extend_from_slice(owner_id.as_bytes()); bytes.extend_from_slice(&base.identity_contract_nonce().to_be_bytes()); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs index 96b4b5ee969..060ac9c70ba 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_burn_transition/v0_methods.rs @@ -58,9 +58,9 @@ impl TokenBurnTransitionV0Methods for TokenBurnTransition { } impl AllowedAsMultiPartyAction for TokenBurnTransition { - fn action_id(&self, owner_id: Identifier) -> Identifier { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { match self { - TokenBurnTransition::V0(v0) => v0.action_id(owner_id), + TokenBurnTransition::V0(v0) => v0.calculate_action_id(owner_id), } } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/mod.rs similarity index 100% rename from packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/mod.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/mod.rs diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs similarity index 92% rename from packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs index 9aa6948dfd2..f82156f1317 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs @@ -3,7 +3,7 @@ use crate::state_transition::batch_transition::batched_transition::multi_party_a use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; -use crate::state_transition::batch_transition::token_issuance_transition::TokenMintTransitionV0; +use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; use crate::util::hash::hash_double; impl TokenBaseTransitionAccessors for TokenMintTransitionV0 { @@ -73,10 +73,10 @@ impl TokenMintTransitionV0Methods for TokenMintTransitionV0 { } impl AllowedAsMultiPartyAction for TokenMintTransitionV0 { - fn action_id(&self, owner_id: Identifier) -> Identifier { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { let TokenMintTransitionV0 { base, amount, .. } = self; - let mut bytes = b"action_mint".to_vec(); + let mut bytes = b"action_token_mint".to_vec(); bytes.extend_from_slice(base.token_id().as_bytes()); bytes.extend_from_slice(owner_id.as_bytes()); bytes.extend_from_slice(&base.identity_contract_nonce().to_be_bytes()); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0_methods.rs similarity index 85% rename from packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs rename to packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0_methods.rs index 78726f5976d..9af7d32aac2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_issuance_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0_methods.rs @@ -2,8 +2,8 @@ use platform_value::Identifier; use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::batch_transition::token_issuance_transition::TokenMintTransition; -use crate::state_transition::batch_transition::token_issuance_transition::v0::v0_methods::TokenMintTransitionV0Methods; +use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransition; +use crate::state_transition::batch_transition::token_mint_transition::v0::v0_methods::TokenMintTransitionV0Methods; impl TokenBaseTransitionAccessors for TokenMintTransition { fn base(&self) -> &TokenBaseTransition { @@ -70,9 +70,9 @@ impl TokenMintTransitionV0Methods for TokenMintTransition { } impl AllowedAsMultiPartyAction for TokenMintTransition { - fn action_id(&self, owner_id: Identifier) -> Identifier { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { match self { - TokenMintTransition::V0(v0) => v0.action_id(owner_id), + TokenMintTransition::V0(v0) => v0.calculate_action_id(owner_id), } } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs index 22762c4bbda..346df2e2284 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs @@ -1,8 +1,12 @@ use platform_value::Identifier; use crate::prelude::{DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::batched_transition::token_transfer_transition::TokenTransferTransitionV0; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; +use crate::util::hash::hash_double; impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { fn base(&self) -> &TokenBaseTransition { @@ -18,7 +22,7 @@ impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { } } -pub trait TokenTransferTransitionV0Methods: TokenBaseTransitionAccessors { +pub trait TokenTransferTransitionV0Methods: TokenBaseTransitionAccessors + AllowedAsMultiPartyAction { /// Returns the `amount` field of the `TokenTransferTransitionV0`. fn amount(&self) -> u64; @@ -193,3 +197,18 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { ) } } + +impl AllowedAsMultiPartyAction for TokenTransferTransitionV0 { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + let TokenTransferTransitionV0 { base, amount, recipient_owner_id, .. } = self; + + let mut bytes = b"action_token_transfer".to_vec(); + bytes.extend_from_slice(base.token_id().as_bytes()); + bytes.extend_from_slice(owner_id.as_bytes()); + bytes.extend_from_slice(recipient_owner_id.as_bytes()); + bytes.extend_from_slice(&base.identity_contract_nonce().to_be_bytes()); + bytes.extend_from_slice(&amount.to_be_bytes()); + + hash_double(bytes).into() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs index c6423015997..b849bb7aef6 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs @@ -1,5 +1,6 @@ use platform_value::Identifier; use crate::prelude::{DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::batched_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::TokenTransferTransition; @@ -154,3 +155,11 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransition { } } } + +impl AllowedAsMultiPartyAction for TokenTransferTransition { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + match self { + TokenTransferTransition::V0(v0) => v0.calculate_action_id(owner_id), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs index 5527b77e557..9eee0c41536 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs @@ -6,6 +6,7 @@ use bincode::{Encode, Decode}; use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenMintTransition, TokenTransferTransition}; use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition}; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; @@ -54,7 +55,7 @@ impl BatchTransitionResolversV0 for TokenTransition { None } } - fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition> { + fn as_transition_token_mint(&self) -> Option<&TokenMintTransition> { if let Self::Mint(ref t) = self { Some(t) } else { @@ -89,6 +90,8 @@ pub trait TokenTransitionV0Methods { fn identity_contract_nonce(&self) -> IdentityNonce; /// sets identity contract nonce fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce); + + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier; } impl TokenTransitionV0Methods for TokenTransition { @@ -112,6 +115,14 @@ impl TokenTransitionV0Methods for TokenTransition { self.base().data_contract_id() } + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + match self { + TokenTransition::Burn(t) => t.calculate_action_id(owner_id), + TokenTransition::Mint(t) => t.calculate_action_id(owner_id), + TokenTransition::Transfer(t) => t.calculate_action_id(owner_id), + } + } + fn set_data_contract_id(&mut self, id: Identifier) { self.base_mut().set_data_contract_id(id); } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs index 11fc10aa5d2..fe45ab58c3d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs @@ -16,8 +16,8 @@ pub use self::batched_transition::{ document_create_transition::DocumentCreateTransition, document_delete_transition, document_delete_transition::DocumentDeleteTransition, document_replace_transition, document_replace_transition::DocumentReplaceTransition, token_base_transition, - token_burn_transition, token_burn_transition::TokenBurnTransition, token_issuance_transition, - token_issuance_transition::TokenMintTransition, token_transfer_transition, + token_burn_transition, token_burn_transition::TokenBurnTransition, token_mint_transition, + token_mint_transition::TokenMintTransition, token_transfer_transition, token_transfer_transition::TokenTransferTransition, }; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs index 66f862789d2..87015c97fcd 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs @@ -13,6 +13,6 @@ pub trait BatchTransitionResolversV0 { fn as_transition_transfer(&self) -> Option<&DocumentTransferTransition>; fn as_transition_purchase(&self) -> Option<&DocumentPurchaseTransition>; fn as_transition_token_burn(&self) -> Option<&TokenBurnTransition>; - fn as_transition_token_issuance(&self) -> Option<&TokenMintTransition>; + fn as_transition_token_mint(&self) -> Option<&TokenMintTransition>; fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition>; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs index 68d07f70476..c955ea84fd6 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs @@ -15,9 +15,12 @@ use platform_value::Identifier; use platform_version::version::PlatformVersion; use std::collections::btree_map::Entry; use std::collections::BTreeMap; +use crate::consensus::basic::token::{InvalidActionIdError, InvalidTokenIdError}; use crate::state_transition::batch_transition::batched_transition::BatchedTransitionRef; use crate::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; +use crate::state_transition::StateTransitionLike; impl BatchTransition { #[inline(always)] @@ -116,6 +119,29 @@ impl BatchTransition { NonceOutOfBoundsError::new(transition.identity_contract_nonce()), )); } + + let transition_token_id = transition.base().token_id(); + let calculated_token_id = transition.base().calculate_token_id(); + + // We need to verify that the token id is correct + if transition_token_id != calculated_token_id { + result.add_error(BasicError::InvalidTokenIdError( + InvalidTokenIdError::new(calculated_token_id, transition_token_id), + )); + } + + // We need to verify that the action id given matches the expected action id + // But only if we are the proposer + if let Some(group_state_transition_info) = transition.base().using_group_info() { + if group_state_transition_info.action_is_proposer { + let calculated_action_id = transition.calculate_action_id(self.owner_id()); + if group_state_transition_info.action_id != calculated_action_id { + result.add_error(BasicError::InvalidActionIdError( + InvalidActionIdError::new(calculated_action_id, group_state_transition_info.action_id), + )); + } + } + } } Ok(result) diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs index 34ccdd1e182..a0c96f1c0f5 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -142,7 +142,7 @@ impl Drive { &platform_version.drive, )?; - if !inserted_root_action { + if inserted_root_action { let group_action_path = group_action_path( contract_id.as_slice(), group_contract_position_bytes.as_slice(), diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index 767451179ea..e98b83edf10 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -11,6 +11,7 @@ use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBas use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; +use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; @@ -27,13 +28,13 @@ impl TokenBaseTransitionActionV0 { drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result { let TokenBaseTransitionV0 { token_contract_position, data_contract_id, identity_contract_nonce, token_id, - using_group, + using_group_info: using_group, } = value; let data_contract = get_data_contract(data_contract_id)?; @@ -72,6 +73,7 @@ impl TokenBaseTransitionActionV0 { /// try from borrowed base transition with contract lookup pub fn try_from_borrowed_base_transition_with_contract_lookup( drive: &Drive, + owner_id: Identifier, value: &TokenBaseTransitionV0, estimated_costs_only_with_layer_info: &mut Option< HashMap, @@ -79,21 +81,46 @@ impl TokenBaseTransitionActionV0 { transaction: TransactionArg, drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { let TokenBaseTransitionV0 { token_contract_position, data_contract_id, identity_contract_nonce, token_id, - using_group, + using_group_info: using_group, } = value; + + let data_contract = get_data_contract(*data_contract_id)?; + + let perform_action = match &using_group { + None => true, + Some(GroupStateTransitionInfo { + group_contract_position, + action_id, + }) => { + let group = data_contract.contract.group(*group_contract_position)?; + let signer_power = group.member_power(owner_id)?; + let required_power = group.required_power(); + let current_power = drive.fetch_action_id_signers_power_and_add_operations( + *data_contract_id, + *group_contract_position, + *action_id, + estimated_costs_only_with_layer_info, + transaction, + drive_operations, + platform_version, + )?; + current_power + signer_power >= required_power + } + }; Ok(TokenBaseTransitionActionV0 { token_id: *token_id, identity_contract_nonce: *identity_contract_nonce, token_contract_position: *token_contract_position, - data_contract: get_data_contract(*data_contract_id)?, - store_in_group: None, - perform_action: false, + data_contract, + store_in_group: *using_group, + perform_action, }) } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs index 03db3c62813..b808b9e3d66 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionActionV0, TokenMintTransitionAction}; -use dpp::state_transition::batch_transition::token_issuance_transition::TokenMintTransition; +use dpp::state_transition::batch_transition::token_mint_transition::TokenMintTransition; use crate::drive::Drive; /// Implement methods to transform a `TokenMintTransition` into a `TokenMintTransitionAction`. diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs index 4e3fca8997d..fb88935b143 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use grovedb::TransactionArg; use dpp::identifier::Identifier; -use dpp::state_transition::batch_transition::token_issuance_transition::v0::TokenMintTransitionV0; +use dpp::state_transition::batch_transition::token_mint_transition::v0::TokenMintTransitionV0; use dpp::ProtocolError; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; diff --git a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs index be941cc5a58..96d3f2ecabe 100644 --- a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs +++ b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs @@ -22,7 +22,7 @@ impl Drive { platform_version: &PlatformVersion, ) -> Result<(RootHash, T), Error> { let path_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids); - let (root_hash, mut proved_key_values) = if verify_subset_of_proof { + let (root_hash, proved_key_values) = if verify_subset_of_proof { GroveDb::verify_subset_query_with_absence_proof( proof, &path_query, From d3c026075f938fe66826f8a6e1501eee3ba5bcea Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 Jan 2025 00:11:50 +0700 Subject: [PATCH 29/61] more work --- .../src/errors/consensus/basic/basic_error.rs | 8 +- .../rs-dpp/src/errors/consensus/basic/mod.rs | 2 +- .../token/contract_has_no_tokens_error.rs | 31 +++++ .../basic/token/invalid_action_id_error.rs | 10 +- .../token/invalid_group_position_error.rs | 19 ++- .../basic/token/invalid_token_id_error.rs | 10 +- .../token/invalid_token_position_error.rs | 27 ++-- .../src/errors/consensus/basic/token/mod.rs | 9 +- packages/rs-dpp/src/group/group_action/mod.rs | 2 +- packages/rs-dpp/src/group/mod.rs | 11 ++ .../token_base_transition/v0/v0_methods.rs | 2 +- .../v0/v0_methods.rs | 11 +- .../validate_basic_structure/v0/mod.rs | 16 ++- .../batch/action_validation/mod.rs | 1 + .../token_base_transition_action/mod.rs | 86 ++++++++++++ .../state_v0/mod.rs | 52 ++++++++ .../structure_v0/mod.rs | 50 +++++++ .../token_burn_transition_action/mod.rs | 2 +- .../structure_v0/mod.rs | 1 + .../group/insert/add_group_action/mod.rs | 7 + .../group/insert/add_group_action/v0/mod.rs | 125 ++++++++++++------ .../document/token_burn_transition.rs | 60 +++++++-- .../token_base_transition_action/mod.rs | 7 +- .../token_base_transition_action/v0/mod.rs | 14 +- .../v0/transformer.rs | 50 ++++--- .../src/util/batch/drive_op_batch/group.rs | 23 ++++ .../src/util/batch/drive_op_batch/mod.rs | 4 + .../rs-drive/src/util/grove_operations/mod.rs | 2 +- .../drive_abci_validation_versions/mod.rs | 1 + 29 files changed, 521 insertions(+), 122 deletions(-) create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/contract_has_no_tokens_error.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs create mode 100644 packages/rs-drive/src/util/batch/drive_op_batch/group.rs diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index 065c3510761..668019c63d3 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -66,13 +66,16 @@ use crate::consensus::basic::{ use crate::consensus::ConsensusError; use crate::consensus::basic::overflow_error::OverflowError; +use crate::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTokensError; +use crate::consensus::basic::token::{ + InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, InvalidTokenPositionError, +}; use crate::consensus::basic::unsupported_version_error::UnsupportedVersionError; use crate::consensus::basic::value_error::ValueError; #[cfg(feature = "json-schema-validation")] use crate::consensus::basic::{ json_schema_compilation_error::JsonSchemaCompilationError, json_schema_error::JsonSchemaError, }; -use crate::consensus::basic::token::{InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, InvalidTokenPositionError}; use crate::consensus::state::identity::master_public_key_update_error::MasterPublicKeyUpdateError; use crate::data_contract::errors::DataContractError; @@ -414,6 +417,9 @@ pub enum BasicError { #[error(transparent)] InvalidTokenPositionError(InvalidTokenPositionError), + #[error(transparent)] + ContractHasNoTokensError(ContractHasNoTokensError), + #[error(transparent)] InvalidGroupPositionError(InvalidGroupPositionError), diff --git a/packages/rs-dpp/src/errors/consensus/basic/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/mod.rs index 3d3f1ac9d40..2b4a596f583 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/mod.rs @@ -7,9 +7,9 @@ pub use unsupported_version_error::*; pub mod data_contract; pub mod decode; pub mod document; -pub mod token; pub mod identity; pub mod incompatible_protocol_version_error; +pub mod token; pub mod unsupported_protocol_version_error; pub mod basic_error; diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/contract_has_no_tokens_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/contract_has_no_tokens_error.rs new file mode 100644 index 00000000000..3fc49a2600a --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/contract_has_no_tokens_error.rs @@ -0,0 +1,31 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Contract {} has no tokens", contract_id)] +#[platform_serialize(unversioned)] +pub struct ContractHasNoTokensError { + contract_id: Identifier, +} + +impl ContractHasNoTokensError { + pub fn new(contract_id: Identifier) -> Self { + Self { contract_id } + } + pub fn contract_id(&self) -> Identifier { + self.contract_id + } +} + +impl From for ConsensusError { + fn from(err: ContractHasNoTokensError) -> Self { + Self::BasicError(BasicError::ContractHasNoTokensError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_action_id_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_action_id_error.rs index cb16b1851bb..51587ab3926 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_action_id_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_action_id_error.rs @@ -1,14 +1,18 @@ use crate::consensus::basic::BasicError; use crate::consensus::ConsensusError; -use crate::ProtocolError; use crate::prelude::Identifier; +use crate::ProtocolError; use bincode::{Decode, Encode}; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use thiserror::Error; #[derive( Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, )] -#[error("Invalid action id {}, expected {}", invalid_action_id, expected_action_id)] +#[error( + "Invalid action id {}, expected {}", + invalid_action_id, + expected_action_id +)] #[platform_serialize(unversioned)] pub struct InvalidActionIdError { expected_action_id: Identifier, @@ -36,4 +40,4 @@ impl From for ConsensusError { fn from(err: InvalidActionIdError) -> Self { Self::BasicError(BasicError::InvalidActionIdError(err)) } -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_group_position_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_group_position_error.rs index 7eab6464cbc..8464f1064aa 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_group_position_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_group_position_error.rs @@ -1,15 +1,19 @@ use crate::consensus::basic::BasicError; use crate::consensus::ConsensusError; -use thiserror::Error; -use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; -use bincode::{Decode, Encode}; use crate::data_contract::GroupContractPosition; use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; #[derive( Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, )] -#[error("Invalid group position {}, expected {}", invalid_group_position, expected_group_position)] +#[error( + "Invalid group position {}, expected {}", + invalid_group_position, + expected_group_position +)] #[platform_serialize(unversioned)] pub struct InvalidGroupPositionError { expected_group_position: GroupContractPosition, @@ -17,7 +21,10 @@ pub struct InvalidGroupPositionError { } impl InvalidGroupPositionError { - pub fn new(expected_group_position: GroupContractPosition, invalid_group_position: GroupContractPosition) -> Self { + pub fn new( + expected_group_position: GroupContractPosition, + invalid_group_position: GroupContractPosition, + ) -> Self { Self { expected_group_position, invalid_group_position, @@ -37,4 +44,4 @@ impl From for ConsensusError { fn from(err: InvalidGroupPositionError) -> Self { Self::BasicError(BasicError::InvalidGroupPositionError(err)) } -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_id_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_id_error.rs index d11856ff0ca..635f126158f 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_id_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_id_error.rs @@ -1,14 +1,18 @@ use crate::consensus::basic::BasicError; use crate::consensus::ConsensusError; -use crate::ProtocolError; use crate::prelude::Identifier; +use crate::ProtocolError; use bincode::{Decode, Encode}; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use thiserror::Error; #[derive( Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, )] -#[error("Invalid token id {}, expected {}", invalid_token_id, expected_token_id)] +#[error( + "Invalid token id {}, expected {}", + invalid_token_id, + expected_token_id +)] #[platform_serialize(unversioned)] pub struct InvalidTokenIdError { expected_token_id: Identifier, @@ -36,4 +40,4 @@ impl From for ConsensusError { fn from(err: InvalidTokenIdError) -> Self { Self::BasicError(BasicError::InvalidTokenIdError(err)) } -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs index fb1b79ae60b..708aa56e851 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs @@ -1,31 +1,38 @@ use crate::consensus::basic::BasicError; use crate::consensus::ConsensusError; +use crate::data_contract::TokenContractPosition; use crate::ProtocolError; -use thiserror::Error; -use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use bincode::{Decode, Encode}; -use crate::data_contract::TokenContractPosition; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; #[derive( Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, )] -#[error("Invalid token position {}, expected {}", invalid_token_position, expected_token_position)] +#[error( + "Invalid token position {}, max {}", + invalid_token_position, + expected_token_position +)] #[platform_serialize(unversioned)] pub struct InvalidTokenPositionError { - expected_token_position: TokenContractPosition, + max_token_position: TokenContractPosition, invalid_token_position: TokenContractPosition, } impl InvalidTokenPositionError { - pub fn new(expected_token_position: TokenContractPosition, invalid_token_position: TokenContractPosition) -> Self { + pub fn new( + max_token_position: TokenContractPosition, + invalid_token_position: TokenContractPosition, + ) -> Self { Self { - expected_token_position, + max_token_position, invalid_token_position, } } - pub fn expected_token_position(&self) -> TokenContractPosition { - self.expected_token_position + pub fn max_token_position(&self) -> TokenContractPosition { + self.max_token_position } pub fn invalid_token_position(&self) -> TokenContractPosition { @@ -37,4 +44,4 @@ impl From for ConsensusError { fn from(err: InvalidTokenPositionError) -> Self { Self::BasicError(BasicError::InvalidTokenPositionError(err)) } -} \ No newline at end of file +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs index 9e2c4bce5ad..5a6eb015fa1 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs @@ -1,9 +1,10 @@ +pub mod contract_has_no_tokens_error; +pub mod invalid_action_id_error; +pub mod invalid_group_position_error; pub mod invalid_token_id_error; pub mod invalid_token_position_error; -pub mod invalid_group_position_error; -pub mod invalid_action_id_error; +pub use invalid_action_id_error::*; +pub use invalid_group_position_error::*; pub use invalid_token_id_error::*; pub use invalid_token_position_error::*; -pub use invalid_group_position_error::*; -pub use invalid_action_id_error::*; \ No newline at end of file diff --git a/packages/rs-dpp/src/group/group_action/mod.rs b/packages/rs-dpp/src/group/group_action/mod.rs index 5f6ac854939..7e39ab631cf 100644 --- a/packages/rs-dpp/src/group/group_action/mod.rs +++ b/packages/rs-dpp/src/group/group_action/mod.rs @@ -1,4 +1,4 @@ -mod v0; +pub mod v0; use crate::group::group_action::v0::GroupActionV0; use crate::ProtocolError; diff --git a/packages/rs-dpp/src/group/mod.rs b/packages/rs-dpp/src/group/mod.rs index 081ea63a1f3..e0ec3861d76 100644 --- a/packages/rs-dpp/src/group/mod.rs +++ b/packages/rs-dpp/src/group/mod.rs @@ -1,3 +1,4 @@ +use crate::data_contract::group::{Group, GroupMemberPower}; use crate::data_contract::GroupContractPosition; use bincode::{Decode, Encode}; use derive_more::Display; @@ -33,3 +34,13 @@ pub struct GroupStateTransitionInfo { )] pub action_is_proposer: bool, } + +#[derive(Debug, Clone, PartialEq)] +pub struct GroupStateTransitionResolvedInfo { + pub group_contract_position: GroupContractPosition, + pub group: Group, + pub action_id: Identifier, + /// This is true if we are the proposer, otherwise we are just voting on a previous action. + pub action_is_proposer: bool, + pub signer_power: GroupMemberPower, +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs index 07330e0192a..d98cd2f4d26 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs @@ -2,8 +2,8 @@ use crate::data_contract::GroupContractPosition; use crate::group::GroupStateTransitionInfo; use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; -use platform_value::Identifier; use crate::util::hash::hash_double; +use platform_value::Identifier; /// A trait that contains getter and setter methods for `TokenBaseTransitionV0` pub trait TokenBaseTransitionV0Methods { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs index 346df2e2284..7860e173e06 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs @@ -22,7 +22,9 @@ impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { } } -pub trait TokenTransferTransitionV0Methods: TokenBaseTransitionAccessors + AllowedAsMultiPartyAction { +pub trait TokenTransferTransitionV0Methods: + TokenBaseTransitionAccessors + AllowedAsMultiPartyAction +{ /// Returns the `amount` field of the `TokenTransferTransitionV0`. fn amount(&self) -> u64; @@ -200,7 +202,12 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { impl AllowedAsMultiPartyAction for TokenTransferTransitionV0 { fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { - let TokenTransferTransitionV0 { base, amount, recipient_owner_id, .. } = self; + let TokenTransferTransitionV0 { + base, + amount, + recipient_owner_id, + .. + } = self; let mut bytes = b"action_token_transfer".to_vec(); bytes.extend_from_slice(base.token_id().as_bytes()); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs index c955ea84fd6..c87e4f26b66 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs @@ -122,14 +122,15 @@ impl BatchTransition { let transition_token_id = transition.base().token_id(); let calculated_token_id = transition.base().calculate_token_id(); - + // We need to verify that the token id is correct if transition_token_id != calculated_token_id { - result.add_error(BasicError::InvalidTokenIdError( - InvalidTokenIdError::new(calculated_token_id, transition_token_id), - )); + result.add_error(BasicError::InvalidTokenIdError(InvalidTokenIdError::new( + calculated_token_id, + transition_token_id, + ))); } - + // We need to verify that the action id given matches the expected action id // But only if we are the proposer if let Some(group_state_transition_info) = transition.base().using_group_info() { @@ -137,7 +138,10 @@ impl BatchTransition { let calculated_action_id = transition.calculate_action_id(self.owner_id()); if group_state_transition_info.action_id != calculated_action_id { result.add_error(BasicError::InvalidActionIdError( - InvalidActionIdError::new(calculated_action_id, group_state_transition_info.action_id), + InvalidActionIdError::new( + calculated_action_id, + group_state_transition_info.action_id, + ), )); } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs index dfd63181b30..7e620c15723 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs @@ -4,6 +4,7 @@ pub(crate) mod document_purchase_transition_action; pub(crate) mod document_replace_transition_action; pub(crate) mod document_transfer_transition_action; pub(crate) mod document_update_price_transition_action; +pub(crate) mod token_base_transition_action; pub(crate) mod token_burn_transition_action; pub(crate) mod token_mint_transition_action; pub(crate) mod token_transfer_transition_action; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs new file mode 100644 index 00000000000..036fda9ca8b --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs @@ -0,0 +1,86 @@ +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use dpp::version::PlatformVersion; +use drive::grovedb::TransactionArg; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::state_v0::TokenBaseTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::structure_v0::TokenBaseTransitionActionStructureValidationV0; +use crate::platform_types::platform::PlatformStateRef; + +mod state_v0; +mod structure_v0; + +pub trait TokenBaseTransitionActionValidation { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result; + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} + +impl TokenBaseTransitionActionValidation for TokenBaseTransitionAction { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_base_transition_structure_validation + { + 0 => self.validate_structure_v0(platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenBaseTransitionAction::validate_structure".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_base_transition_structure_validation + { + 0 => self.validate_state_v0( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenBaseTransitionAction::validate_state".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..1d336206084 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs @@ -0,0 +1,52 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::document::InvalidDocumentTypeError; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; +use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; +use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; +use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; +use dpp::consensus::state::state_error::StateError; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_Base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; +use drive::error::drive::DriveError; +use drive::query::TransactionArg; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::error::Error; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; +use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenBaseTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenBaseTransitionActionStateValidationV0 for TokenBaseTransitionAction { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + // todo verify that minting would not break max supply + + Ok(SimpleConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs new file mode 100644 index 00000000000..8bb185f13f6 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs @@ -0,0 +1,50 @@ +use dpp::consensus::basic::BasicError; +use dpp::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTokensError; +use dpp::consensus::basic::token::InvalidTokenPositionError; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; +use dpp::validation::{SimpleConsensusValidationResult}; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use crate::error::Error; + +pub(super) trait TokenBaseTransitionActionStructureValidationV0 { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenBaseTransitionActionStructureValidationV0 for TokenBaseTransitionAction { + fn validate_structure_v0( + &self, + _platform_version: &PlatformVersion, + ) -> Result { + let token_position = self.token_position(); + let contract = self.data_contract_fetch_info_ref(); + if contract.contract.tokens().get(&token_position).is_none() { + return if contract.contract.tokens().is_empty() { + Ok(SimpleConsensusValidationResult::new_with_error( + BasicError::ContractHasNoTokensError(ContractHasNoTokensError::new( + contract.contract.id(), + )) + .into(), + )) + } else { + Ok(SimpleConsensusValidationResult::new_with_error( + BasicError::InvalidTokenPositionError(InvalidTokenPositionError::new( + *contract + .contract + .tokens() + .keys() + .last() + .expect("we already checked this was not empty"), + token_position, + )) + .into(), + )) + }; + } + Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs index 6e72dbf178a..2fc4f8947a4 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs @@ -66,7 +66,7 @@ impl TokenBurnTransitionActionValidation for TokenBurnTransitionAction { .validation_and_processing .state_transitions .batch_state_transition - .token_issuance_transition_state_validation + .token_burn_transition_state_validation { 0 => self.validate_state_v0( platform, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs index 29127fd7c6a..b403cc05888 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs @@ -27,6 +27,7 @@ impl TokenBurnTransitionActionStructureValidationV0 for TokenBurnTransitionActio &self, platform_version: &PlatformVersion, ) -> Result { + self.base().validate_structure(); let token_configuration = self.base().token_configuration()?; Ok(SimpleConsensusValidationResult::default()) diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/mod.rs index c255a565566..adfbb1c6434 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/mod.rs @@ -8,6 +8,7 @@ use dpp::version::PlatformVersion; use dpp::data_contract::group::GroupMemberPower; use dpp::data_contract::GroupContractPosition; +use dpp::group::group_action::GroupAction; use dpp::prelude::Identifier; use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; @@ -21,6 +22,7 @@ impl Drive { &self, contract_id: Identifier, group_contract_position: GroupContractPosition, + initialize_with_insert_action_info: Option, action_id: Identifier, signer_identity_id: Identifier, signer_power: GroupMemberPower, @@ -33,6 +35,7 @@ impl Drive { 0 => self.add_group_action_v0( contract_id, group_contract_position, + initialize_with_insert_action_info, action_id, signer_identity_id, signer_power, @@ -54,6 +57,7 @@ impl Drive { &self, contract_id: Identifier, group_contract_position: GroupContractPosition, + initialize_with_insert_action_info: Option, action_id: Identifier, signer_identity_id: Identifier, signer_power: GroupMemberPower, @@ -67,6 +71,7 @@ impl Drive { 0 => self.add_group_action_add_to_operations_v0( contract_id, group_contract_position, + initialize_with_insert_action_info, action_id, signer_identity_id, signer_power, @@ -89,6 +94,7 @@ impl Drive { &self, contract_id: Identifier, group_contract_position: GroupContractPosition, + initialize_with_insert_action_info: Option, action_id: Identifier, signer_identity_id: Identifier, signer_power: GroupMemberPower, @@ -103,6 +109,7 @@ impl Drive { 0 => self.add_group_action_operations_v0( contract_id, group_contract_position, + initialize_with_insert_action_info, action_id, signer_identity_id, signer_power, diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs index a0c96f1c0f5..21cd4c4e057 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -1,5 +1,6 @@ use crate::drive::group::{ - group_action_path, group_action_root_path, group_action_signers_path_vec, ACTION_SIGNERS_KEY, + group_action_path, group_action_path_vec, group_action_root_path, + group_action_signers_path_vec, ACTION_INFO_KEY, ACTION_SIGNERS_KEY, }; use crate::drive::Drive; use crate::error::Error; @@ -11,6 +12,7 @@ use dpp::block::block_info::BlockInfo; use dpp::data_contract::group::GroupMemberPower; use dpp::data_contract::GroupContractPosition; use dpp::fee::fee_result::FeeResult; +use dpp::group::group_action::GroupAction; use dpp::identifier::Identifier; use dpp::serialization::PlatformSerializable; use dpp::version::PlatformVersion; @@ -25,6 +27,7 @@ impl Drive { &self, contract_id: Identifier, group_contract_position: GroupContractPosition, + initialize_with_insert_action_info: Option, action_id: Identifier, signer_identity_id: Identifier, signer_power: GroupMemberPower, @@ -37,6 +40,7 @@ impl Drive { self.add_group_action_add_to_operations_v0( contract_id, group_contract_position, + initialize_with_insert_action_info, action_id, signer_identity_id, signer_power, @@ -62,6 +66,7 @@ impl Drive { &self, contract_id: Identifier, group_contract_position: GroupContractPosition, + initialize_with_insert_action_info: Option, action_id: Identifier, signer_identity_id: Identifier, signer_power: GroupMemberPower, @@ -80,6 +85,7 @@ impl Drive { let batch_operations = self.add_group_action_operations( contract_id, group_contract_position, + initialize_with_insert_action_info, action_id, signer_identity_id, signer_power, @@ -103,6 +109,7 @@ impl Drive { &self, contract_id: Identifier, group_contract_position: GroupContractPosition, + initialize_with_insert_action_info: Option, action_id: Identifier, signer_identity_id: Identifier, signer_power: GroupMemberPower, @@ -130,32 +137,61 @@ impl Drive { } }; - // We insert the contract root into the group tree - let inserted_root_action = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKeyRef((group_action_root_path, action_id.as_slice())), - false, - None, - apply_type, - transaction, - &mut None, - &mut batch_operations, - &platform_version.drive, - )?; + let storage_flags = Some(StorageFlags::new_single_epoch( + block_info.epoch.index, + Some(signer_identity_id.to_buffer()), + )); - if inserted_root_action { - let group_action_path = group_action_path( - contract_id.as_slice(), - group_contract_position_bytes.as_slice(), - action_id.as_slice(), - ); - - self.batch_insert_empty_sum_tree( - group_action_path, - DriveKeyInfo::KeyRef(ACTION_SIGNERS_KEY), + let element_flags = StorageFlags::map_to_some_element_flags(storage_flags.as_ref()); + + let mut inserted_root_action = false; + + if let Some(initialize_with_insert_action_info) = initialize_with_insert_action_info { + // We insert the contract root into the group tree + inserted_root_action = self.batch_insert_empty_tree_if_not_exists( + PathFixedSizeKeyRef((group_action_root_path, action_id.as_slice())), + false, None, + apply_type, + transaction, + &mut None, &mut batch_operations, &platform_version.drive, )?; + + if inserted_root_action { + let group_action_path = group_action_path( + contract_id.as_slice(), + group_contract_position_bytes.as_slice(), + action_id.as_slice(), + ); + + self.batch_insert_empty_sum_tree( + group_action_path, + DriveKeyInfo::KeyRef(ACTION_SIGNERS_KEY), + None, + &mut batch_operations, + &platform_version.drive, + )?; + + let group_action_path_vec = group_action_path_vec( + contract_id.as_slice(), + group_contract_position, + action_id.as_slice(), + ); + + let serialized = initialize_with_insert_action_info.serialize_consume_to_bytes()?; + + self.batch_insert( + PathKeyElementInfo::PathKeyRefElement(( + group_action_path_vec, + ACTION_INFO_KEY, + Element::Item(serialized, element_flags.clone()), + )), + &mut batch_operations, + &platform_version.drive, + )?; + } } let signers_path = group_action_signers_path_vec( @@ -164,11 +200,6 @@ impl Drive { action_id.as_slice(), ); - let storage_flags = Some(StorageFlags::new_single_epoch( - block_info.epoch.index, - Some(signer_identity_id.to_buffer()), - )); - let signer_apply_type = if estimated_costs_only_with_layer_info.is_none() { BatchInsertApplyType::StatefulBatchInsert } else { @@ -178,21 +209,31 @@ impl Drive { } }; - self.batch_insert_sum_item_if_not_exists( - PathKeyElementInfo::PathKeyElement(( - signers_path, - signer_identity_id.to_vec(), - Element::SumItem( - signer_power as SumValue, - StorageFlags::map_to_some_element_flags(storage_flags.as_ref()), - ), - )), - true, - signer_apply_type, - transaction, - &mut batch_operations, - &platform_version.drive, - )?; + if inserted_root_action { + self.batch_insert( + PathKeyElementInfo::PathKeyElement(( + signers_path, + signer_identity_id.to_vec(), + Element::SumItem(signer_power as SumValue, element_flags), + )), + &mut batch_operations, + &platform_version.drive, + )?; + } else { + // we should verify it doesn't yet exist + self.batch_insert_sum_item_if_not_exists( + PathKeyElementInfo::PathKeyElement(( + signers_path, + signer_identity_id.to_vec(), + Element::SumItem(signer_power as SumValue, element_flags), + )), + true, + signer_apply_type, + transaction, + &mut batch_operations, + &platform_version.drive, + )?; + } Ok(batch_operations) } diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs index b1b41e6795f..976be1ade2a 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs @@ -1,5 +1,9 @@ use dpp::block::epoch::Epoch; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::group::action_event::GroupActionEvent; +use dpp::group::group_action::GroupAction; +use dpp::group::group_action::v0::GroupActionV0; +use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; use dpp::identifier::Identifier; use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; @@ -9,8 +13,8 @@ use crate::state_transition_action::action_convert_to_operations::document::Driv use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; -use crate::util::batch::drive_op_batch::TokenOperationType; -use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; +use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; +use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { fn into_high_level_document_drive_operations<'b>( @@ -39,19 +43,47 @@ impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { }, )]; - ops.push(TokenOperation(TokenOperationType::TokenBurn { - token_id: self.token_id(), - identity_balance_holder_id: owner_id, - burn_amount: self.burn_amount(), - })); - - let token_configuration = self.base().token_configuration()?; - if token_configuration.keeps_history() { - ops.push(TokenOperation(TokenOperationType::TokenHistory { + if self.base().perform_action() { + ops.push(TokenOperation(TokenOperationType::TokenBurn { token_id: self.token_id(), - owner_id, - nonce: identity_contract_nonce, - event: TokenEvent::Burn(self.burn_amount(), self.public_note_owned()), + identity_balance_holder_id: owner_id, + burn_amount: self.burn_amount(), + })); + + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Burn(self.burn_amount(), self.public_note_owned()), + })); + } + } else if let Some(GroupStateTransitionResolvedInfo { + group_contract_position, + action_id, + action_is_proposer, + signer_power, + .. + }) = self.base().store_in_group() + { + let event = TokenEvent::Burn(self.burn_amount(), self.public_note_owned()); + + let initialize_with_insert_action_info = if action_is_proposer { + Some(GroupAction::V0(GroupActionV0 { + event: GroupActionEvent::TokenEvent(event), + })) + } else { + None + }; + + ops.push(GroupOperation(GroupOperationType::AddGroupAction { + contract_id: data_contract_id, + group_contract_position: *group_contract_position, + initialize_with_insert_action_info, + action_id: *action_id, + signer_identity_id: owner_id, + signer_power: *signer_power, })); } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs index ecbcfac66c8..41e1f300638 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs @@ -1,6 +1,7 @@ use derive_more::From; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; -use dpp::group::GroupStateTransitionInfo; +use dpp::data_contract::TokenContractPosition; +use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; use dpp::platform_value::Identifier; use dpp::prelude::IdentityNonce; use std::sync::Arc; @@ -22,7 +23,7 @@ pub enum TokenBaseTransitionAction { } impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionAction { - fn token_position(&self) -> u16 { + fn token_position(&self) -> TokenContractPosition { match self { TokenBaseTransitionAction::V0(v0) => v0.token_contract_position, } @@ -64,7 +65,7 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionAction { } } - fn store_in_group(&self) -> Option { + fn store_in_group(&self) -> Option<&GroupStateTransitionResolvedInfo> { match self { TokenBaseTransitionAction::V0(v0) => v0.store_in_group(), } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs index d698831c213..b33a4818dbb 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs @@ -3,8 +3,8 @@ use crate::error::Error; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; -use dpp::data_contract::GroupContractPosition; -use dpp::group::GroupStateTransitionInfo; +use dpp::data_contract::{GroupContractPosition, TokenContractPosition}; +use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; use dpp::ProtocolError; @@ -26,7 +26,7 @@ pub struct TokenBaseTransitionActionV0 { pub data_contract: Arc, /// Using group multi party rules for authentication /// If this is set we should store in group - pub store_in_group: Option, + pub store_in_group: Option, /// Should the action be performed. /// This is true if we don't store in group. /// And also true if we store in group and with this have enough signatures to perform the action @@ -36,7 +36,7 @@ pub struct TokenBaseTransitionActionV0 { /// Token base transition action accessors v0 pub trait TokenBaseTransitionActionAccessorsV0 { /// The token position within the data contract - fn token_position(&self) -> u16; + fn token_position(&self) -> TokenContractPosition; /// The token id fn token_id(&self) -> Identifier; @@ -57,7 +57,7 @@ pub trait TokenBaseTransitionActionAccessorsV0 { fn token_configuration(&self) -> Result<&TokenConfiguration, Error>; /// Gets the store_in_group field (optional) - fn store_in_group(&self) -> Option; + fn store_in_group(&self) -> Option<&GroupStateTransitionResolvedInfo>; /// Gets the perform_action field fn perform_action(&self) -> bool; @@ -102,8 +102,8 @@ impl TokenBaseTransitionActionAccessorsV0 for TokenBaseTransitionActionV0 { ))) } - fn store_in_group(&self) -> Option { - self.store_in_group + fn store_in_group(&self) -> Option<&GroupStateTransitionResolvedInfo> { + self.store_in_group.as_ref() } fn perform_action(&self) -> bool { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index e98b83edf10..fd78a82d1a2 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -1,5 +1,5 @@ use std::collections::HashMap; -use dpp::group::GroupStateTransitionInfo; +use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; use dpp::platform_value::Identifier; use grovedb::{EstimatedLayerInformation, TransactionArg}; use std::sync::Arc; @@ -34,30 +34,39 @@ impl TokenBaseTransitionActionV0 { data_contract_id, identity_contract_nonce, token_id, - using_group_info: using_group, + using_group_info, } = value; let data_contract = get_data_contract(data_contract_id)?; - let perform_action = match &using_group { - None => true, + let (perform_action, store_in_group) = match using_group_info { + None => (true, None), Some(GroupStateTransitionInfo { group_contract_position, action_id, + action_is_proposer, }) => { let group = data_contract.contract.group(*group_contract_position)?; let signer_power = group.member_power(owner_id)?; let required_power = group.required_power(); let current_power = drive.fetch_action_id_signers_power_and_add_operations( data_contract_id, - *group_contract_position, - *action_id, + group_contract_position, + action_id, estimated_costs_only_with_layer_info, transaction, drive_operations, platform_version, )?; - current_power + signer_power >= required_power + let perform_action = current_power + signer_power >= required_power; + let store_in_group = GroupStateTransitionResolvedInfo { + group_contract_position, + group: group.clone(), + action_id, + action_is_proposer, + signer_power, + }; + (perform_action, Some(store_in_group)) } }; Ok(TokenBaseTransitionActionV0 { @@ -65,7 +74,7 @@ impl TokenBaseTransitionActionV0 { identity_contract_nonce, token_contract_position, data_contract, - store_in_group: using_group, + store_in_group, perform_action, }) } @@ -88,17 +97,18 @@ impl TokenBaseTransitionActionV0 { data_contract_id, identity_contract_nonce, token_id, - using_group_info: using_group, + using_group_info, } = value; let data_contract = get_data_contract(*data_contract_id)?; - let perform_action = match &using_group { - None => true, + let (perform_action, store_in_group) = match using_group_info { + None => (true, None), Some(GroupStateTransitionInfo { - group_contract_position, - action_id, - }) => { + group_contract_position, + action_id, + action_is_proposer, + }) => { let group = data_contract.contract.group(*group_contract_position)?; let signer_power = group.member_power(owner_id)?; let required_power = group.required_power(); @@ -111,7 +121,15 @@ impl TokenBaseTransitionActionV0 { drive_operations, platform_version, )?; - current_power + signer_power >= required_power + let perform_action = current_power + signer_power >= required_power; + let store_in_group = GroupStateTransitionResolvedInfo { + group_contract_position: *group_contract_position, + group: group.clone(), + action_id: *action_id, + action_is_proposer: *action_is_proposer, + signer_power, + }; + (perform_action, Some(store_in_group)) } }; Ok(TokenBaseTransitionActionV0 { @@ -119,7 +137,7 @@ impl TokenBaseTransitionActionV0 { identity_contract_nonce: *identity_contract_nonce, token_contract_position: *token_contract_position, data_contract, - store_in_group: *using_group, + store_in_group, perform_action, }) } diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/group.rs b/packages/rs-drive/src/util/batch/drive_op_batch/group.rs new file mode 100644 index 00000000000..c53c97153e6 --- /dev/null +++ b/packages/rs-drive/src/util/batch/drive_op_batch/group.rs @@ -0,0 +1,23 @@ +use dpp::data_contract::group::GroupMemberPower; +use dpp::data_contract::GroupContractPosition; +use dpp::group::group_action::GroupAction; +use dpp::identifier::Identifier; + +#[derive(Clone, Debug)] +pub enum GroupOperationType { + /// Adds a group action + AddGroupAction { + /// The contract id + contract_id: Identifier, + /// The group contract position + group_contract_position: GroupContractPosition, + /// Initialize with the action info + initialize_with_insert_action_info: Option, + /// The action id + action_id: Identifier, + /// The identity that is signing + signer_identity_id: Identifier, + /// The signer's power in the group + signer_power: GroupMemberPower, + }, +} diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs index 79a9e096356..a7a9ec7002d 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs @@ -2,6 +2,7 @@ mod contract; mod document; mod drive_methods; mod finalize_task; +mod group; mod identity; mod prefunded_specialized_balance; mod system; @@ -20,6 +21,7 @@ pub use document::DocumentOperation; pub use document::DocumentOperationType; pub use document::DocumentOperationsForContractDocumentType; pub use document::UpdateOperationInfo; +pub use group::GroupOperationType; pub use identity::IdentityOperationType; pub use prefunded_specialized_balance::PrefundedSpecializedBalanceOperationType; pub use system::SystemOperationType; @@ -81,6 +83,8 @@ pub enum DriveOperation<'a> { PrefundedSpecializedBalanceOperation(PrefundedSpecializedBalanceOperationType), /// A system operation SystemOperation(SystemOperationType), + /// A group operation + GroupOperation(GroupOperationType), /// A single low level groveDB operation GroveDBOperation(QualifiedGroveDbOp), /// Multiple low level groveDB operations diff --git a/packages/rs-drive/src/util/grove_operations/mod.rs b/packages/rs-drive/src/util/grove_operations/mod.rs index 119f2d83792..d082409b197 100644 --- a/packages/rs-drive/src/util/grove_operations/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/mod.rs @@ -129,7 +129,7 @@ pub mod grove_get_proved_path_query_with_conditional; /// Inserts an element if it does not exist and returns the existing element if it does in GroveDB. pub mod grove_insert_if_not_exists_return_existing_element; -/// Batch inserts sum items if not already existing +/// Batch inserts sum item if not already existing pub mod batch_insert_sum_item_if_not_exists; /// Moved items that are found in a path query to a new path. pub mod batch_move_items_in_path_query; diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs index e6237451806..3a20be18a85 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs @@ -103,6 +103,7 @@ pub struct DriveAbciDocumentsStateTransitionValidationVersions { pub token_issuance_transition_state_validation: FeatureVersion, pub token_burn_transition_state_validation: FeatureVersion, pub token_transfer_transition_state_validation: FeatureVersion, + pub token_base_transition_structure_validation: FeatureVersion, } #[derive(Clone, Debug, Default)] From f3f9eec202513c204e8710097ae8f0281c12cb7b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 Jan 2025 05:58:29 +0700 Subject: [PATCH 30/61] more work --- .../token/invalid_token_position_error.rs | 2 +- packages/rs-dpp/src/errors/consensus/codes.rs | 1 + .../v0/v0_methods.rs | 1 - .../state_transitions/batch/mod.rs | 4 +- .../state_transitions/batch/state/v0/mod.rs | 2 +- .../group/fetch/fetch_action_id_info/mod.rs | 122 ++++++++++++++++ .../fetch/fetch_action_id_info/v0/mod.rs | 91 ++++++++++++ .../mod.rs | 120 ++++++++++++++++ .../v0/mod.rs | 132 ++++++++++++++++++ .../fetch_action_id_signers_power/mod.rs | 6 +- .../fetch_action_id_signers_power/v0/mod.rs | 15 +- .../rs-drive/src/drive/group/fetch/mod.rs | 2 + .../group/insert/add_group_action/v0/mod.rs | 14 +- .../group/insert/add_new_groups/v0/mod.rs | 71 ---------- .../document/token_burn_transition.rs | 6 +- .../transformer.rs | 43 +++++- .../v0/transformer.rs | 32 +++-- .../transformer.rs | 58 ++++++-- .../v0/transformer.rs | 78 ++++++++--- .../transformer.rs | 49 +++++-- .../v0/transformer.rs | 71 ++++++++-- .../transformer.rs | 60 ++++++-- .../v0/transformer.rs | 82 +++++++++-- .../src/util/batch/drive_op_batch/group.rs | 45 ++++++ .../src/util/batch/drive_op_batch/mod.rs | 8 ++ .../src/util/batch/drive_op_batch/token.rs | 2 +- .../grove_get_raw_item/mod.rs | 55 ++++++++ .../grove_get_raw_item/v0/mod.rs | 83 +++++++++++ .../rs-drive/src/util/grove_operations/mod.rs | 3 + .../drive_abci_validation_versions/v1.rs | 1 + .../drive_abci_validation_versions/v2.rs | 1 + .../drive_abci_validation_versions/v3.rs | 1 + .../drive_abci_validation_versions/v4.rs | 1 + .../drive_group_method_versions/mod.rs | 2 + .../drive_group_method_versions/v1.rs | 2 + .../drive_grove_method_versions/mod.rs | 1 + .../drive_grove_method_versions/v1.rs | 1 + 37 files changed, 1067 insertions(+), 201 deletions(-) create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/v0/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/grove_get_raw_item/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/grove_get_raw_item/v0/mod.rs diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs index 708aa56e851..ac157f4193b 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/invalid_token_position_error.rs @@ -12,7 +12,7 @@ use thiserror::Error; #[error( "Invalid token position {}, max {}", invalid_token_position, - expected_token_position + max_token_position )] #[platform_serialize(unversioned)] pub struct InvalidTokenPositionError { diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index 748cd1648c0..cca99259175 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -126,6 +126,7 @@ impl ErrorWithCode for BasicError { Self::InvalidTokenPositionError(_) => 10451, Self::InvalidGroupPositionError(_) => 10452, Self::InvalidActionIdError(_) => 10453, + Self::ContractHasNoTokensError(_) => 10454, // Identity Errors: 10500-10599 Self::DuplicatedIdentityPublicKeyBasicError(_) => 10500, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs index 7860e173e06..839b2864d6c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs @@ -5,7 +5,6 @@ use crate::state_transition::batch_transition::batched_transition::token_transfe use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; -use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; use crate::util::hash::hash_double; impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index b089e76a4f4..3b9713e2ae5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -38,8 +38,8 @@ use crate::execution::validation::state_transition::ValidationMode; use crate::platform_types::platform_state::v0::PlatformStateV0Methods; 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 { + /// Returns a bool on whether we should validate that batched transitions are valid against the state + pub fn should_validate_batch_valid_against_state(&self) -> bool { match self { ValidationMode::CheckTx => false, ValidationMode::RecheckTx => false, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs index 202a79655a3..0410814b376 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs @@ -248,7 +248,7 @@ impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { let validation_result = self.try_into_action_v0( platform, block_info, - validation_mode.should_validate_document_valid_against_state(), + validation_mode.should_validate_batch_valid_against_state(), tx, &mut execution_context, )?; diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/mod.rs new file mode 100644 index 00000000000..bececbe4708 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/mod.rs @@ -0,0 +1,122 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::group::GroupSumPower; +use dpp::data_contract::GroupContractPosition; +use dpp::group::group_action::GroupAction; +use dpp::identifier::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::HashMap; + +mod v0; + +impl Drive { + /// Fetches the `GroupAction` for the given action ID and group contract position. + /// + /// This function queries the GroveDB to fetch the `GroupAction` associated with a specific + /// group contract position and action ID. The method selects the appropriate version of + /// `fetch_action_id_info` based on the `platform_version` provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `action_id`: The identifier of the action whose `GroupAction` is being fetched. + /// - `transaction`: The transaction argument used for the query. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(GroupAction)`: The `GroupAction` for the specified action ID and contract position. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub fn fetch_action_id_info( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_info + { + 0 => self.fetch_action_id_info_v0( + contract_id, + group_contract_position, + action_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_info".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the `GroupAction` and adds corresponding operations to the drive for the given action ID and group contract position. + /// + /// This function is similar to `fetch_action_id_info` but also adds operations to the drive for state changes or queries. + /// Additionally, it supports cost estimation by interacting with the layer information if provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `action_id`: The identifier of the action whose `GroupAction` is being fetched. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to an optional `HashMap` containing + /// layer information used for cost estimation. + /// - `transaction`: The transaction argument used for the query. + /// - `drive_operations`: A mutable reference to a vector that stores low-level drive operations. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(GroupAction)`: The `GroupAction` for the specified action ID and contract position, along with any added operations. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub(crate) fn fetch_action_id_info_and_add_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_info + { + 0 => self.fetch_action_id_info_and_add_operations_v0( + contract_id, + group_contract_position, + action_id, + estimated_costs_only_with_layer_info, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_signers_and_add_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/v0/mod.rs new file mode 100644 index 00000000000..f17a4674e99 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/v0/mod.rs @@ -0,0 +1,91 @@ +use std::collections::HashMap; + +use crate::drive::group::{group_action_path, ACTION_INFO_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::data_contract::GroupContractPosition; +use dpp::group::group_action::GroupAction; +use dpp::identifier::Identifier; +use dpp::serialization::PlatformDeserializable; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; + +impl Drive { + pub(super) fn fetch_action_id_info_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_action_path( + contract_id.as_ref(), + &group_contract_position_bytes, + action_id.as_ref(), + ); + + let value = self.grove_get_raw_item( + (&path).into(), + ACTION_INFO_KEY, + DirectQueryType::StatefulDirectQuery, + transaction, + &mut vec![], + &platform_version.drive, + )?; + + let group_action = GroupAction::deserialize_from_bytes(&value)?; + + Ok(group_action) + } + + pub(super) fn fetch_action_id_info_and_add_operations_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_action_path( + contract_id.as_ref(), + &group_contract_position_bytes, + action_id.as_ref(), + ); + + // no estimated_costs_only_with_layer_info, means we want to apply to state + let direct_query_type = if estimated_costs_only_with_layer_info.is_none() { + DirectQueryType::StatefulDirectQuery + } else { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums: false, + query_target: QueryTargetValue(8), + } + }; + + let value = self.grove_get_raw_item( + (&path).into(), + ACTION_INFO_KEY, + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + )?; + + let group_action = GroupAction::deserialize_from_bytes(&value)?; + + Ok(group_action) + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/mod.rs new file mode 100644 index 00000000000..515c1d0e4a4 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/mod.rs @@ -0,0 +1,120 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::HashMap; + +mod v0; + +impl Drive { + /// Fetches the serialized `GroupAction` for the given action ID and group contract position. + /// + /// This function retrieves the serialized bytes of the `GroupAction` associated with a specific + /// action ID and group contract position from the GroveDB. The method selects the appropriate version + /// of `fetch_action_id_info_keep_serialized` based on the `platform_version` provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `action_id`: The identifier of the action whose serialized `GroupAction` is being fetched. + /// - `transaction`: The transaction argument used for the query. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Vec)`: The serialized `GroupAction` for the specified action ID and contract position. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub fn fetch_action_id_info_keep_serialized( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_info_keep_serialized + { + 0 => self.fetch_action_id_info_keep_serialized_v0( + contract_id, + group_contract_position, + action_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_info_keep_serialized".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the serialized `GroupAction` and adds corresponding operations to the drive for the given action ID and group contract position. + /// + /// This function is similar to `fetch_action_id_info_keep_serialized`, but also adds operations to the drive for state changes + /// or queries. Additionally, it supports cost estimation by interacting with the layer information if provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `action_id`: The identifier of the action whose serialized `GroupAction` is being fetched. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to an optional `HashMap` containing + /// layer information used for cost estimation. + /// - `transaction`: The transaction argument used for the query. + /// - `drive_operations`: A mutable reference to a vector that stores low-level drive operations. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Vec)`: The serialized `GroupAction` for the specified action ID and contract position, along with any added operations. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub(crate) fn fetch_action_id_info_keep_serialized_and_add_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_info_keep_serialized + { + 0 => self.fetch_action_id_info_keep_serialized_and_add_operations_v0( + contract_id, + group_contract_position, + action_id, + estimated_costs_only_with_layer_info, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_signers_keep_serialized_and_add_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/v0/mod.rs new file mode 100644 index 00000000000..95483153889 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/v0/mod.rs @@ -0,0 +1,132 @@ +use std::collections::HashMap; + +use crate::drive::group::{group_action_path, ACTION_INFO_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; + +impl Drive { + /// v0 implementation of fetching the signers' power for a given action ID within a group contract. + /// + /// This function retrieves the signers' power associated with a specific action ID in a group contract. + /// It constructs the appropriate GroveDB path, fetches the relevant data, deserializes it, and + /// calculates any applicable fees based on the provided epoch. + /// + /// # Parameters + /// * `contract_id` - The identifier of the contract. + /// * `group_contract_position` - The position of the group contract within the data contract. + /// * `action_id` - The identifier of the action whose signers' power is to be fetched. + /// * `apply` - A boolean flag indicating whether to apply certain operations during the fetch. + /// * `transaction` - The GroveDB transaction argument for executing the fetch operation. + /// * `platform_version` - The current platform version, used to ensure compatibility. + /// + /// # Returns + /// * `Ok(Some(Arc))` if the signers' power is successfully fetched. + /// * `Ok(None)` if the signers' power does not exist. + /// * `Err(Error)` if an error occurs during the fetch operation. + /// + /// # Errors + /// * `Error::Drive(DriveError::CorruptedContractPath)` if the fetched path does not refer to a valid sum item. + /// * `Error::Drive(DriveError::CorruptedCodeExecution)` if the element type is unexpected. + /// * `Error::GroveDB` for any underlying GroveDB errors. + pub(super) fn fetch_action_id_info_keep_serialized_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_action_path( + contract_id.as_ref(), + &group_contract_position_bytes, + action_id.as_ref(), + ); + + let value = self.grove_get_raw_item( + (&path).into(), + ACTION_INFO_KEY, + DirectQueryType::StatefulDirectQuery, + transaction, + &mut vec![], + &platform_version.drive, + )?; + + Ok(value) + } + + /// v0 implementation of fetching the signers' power for a given action ID within a group contract and adding related operations. + /// + /// This function not only fetches the signers' power but also appends necessary low-level drive operations based on the provided epoch. + /// It ensures that fees are calculated and added to the `drive_operations` vector when applicable. + /// + /// # Parameters + /// * `contract_id` - The identifier of the contract. + /// * `group_contract_position` - The position of the group contract within the data contract. + /// * `action_id` - The identifier of the action whose signers' power is to be fetched. + /// * `epoch` - An optional reference to an `Epoch` object. If provided, fees will be calculated based on the epoch. + /// * `transaction` - The GroveDB transaction argument for executing the fetch operation. + /// * `drive_operations` - A mutable reference to a vector where low-level drive operations and fees will be appended. + /// * `platform_version` - The current platform version, used to ensure compatibility. + /// + /// # Returns + /// * `Ok(Some(Arc))` if the signers' power is successfully fetched. + /// * `Ok(None)` if the signers' power does not exist. + /// * `Err(Error)` if an error occurs during the fetch operation. + /// + /// # Errors + /// * `Error::Drive(DriveError::CorruptedContractPath)` if the fetched path does not refer to a valid sum item. + /// * `Error::Drive(DriveError::CorruptedCodeExecution)` if the element type is unexpected. + /// * `Error::Drive(DriveError::NotSupportedPrivate)` if stateful batch insertions are attempted. + /// * `Error::GroveDB` for any underlying GroveDB errors. + pub(super) fn fetch_action_id_info_keep_serialized_and_add_operations_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_action_path( + contract_id.as_ref(), + &group_contract_position_bytes, + action_id.as_ref(), + ); + + // no estimated_costs_only_with_layer_info, means we want to apply to state + let direct_query_type = if estimated_costs_only_with_layer_info.is_none() { + DirectQueryType::StatefulDirectQuery + } else { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums: false, + query_target: QueryTargetValue(8), + } + }; + + let value = self.grove_get_raw_item( + (&path).into(), + ACTION_INFO_KEY, + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + )?; + + Ok(value) + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs index 9b9ac635fa8..c74ace258c4 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs @@ -49,9 +49,7 @@ impl Drive { contract_id: Identifier, group_contract_position: GroupContractPosition, action_id: Identifier, - estimated_costs_only_with_layer_info: &mut Option< - HashMap, - >, + estimate_costs_only: bool, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, @@ -67,7 +65,7 @@ impl Drive { contract_id, group_contract_position, action_id, - estimated_costs_only_with_layer_info, + estimate_costs_only, transaction, drive_operations, platform_version, diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs index d6b6531c96f..d50ba422658 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs @@ -1,11 +1,10 @@ use std::collections::HashMap; -use crate::drive::group::{group_action_path, group_action_signers_path, ACTION_SIGNERS_KEY}; +use crate::drive::group::{group_action_path, ACTION_SIGNERS_KEY}; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use crate::util::grove_operations::DirectQueryType; -use crate::util::grove_operations::DirectQueryType::StatefulDirectQuery; use crate::util::grove_operations::QueryTarget::QueryTargetValue; use dpp::data_contract::group::GroupSumPower; use dpp::data_contract::GroupContractPosition; @@ -57,7 +56,7 @@ impl Drive { let value = self.grove_get_sum_tree_total_value( (&path).into(), ACTION_SIGNERS_KEY, - StatefulDirectQuery, + DirectQueryType::StatefulDirectQuery, transaction, &mut vec![], &platform_version.drive, @@ -95,9 +94,7 @@ impl Drive { contract_id: Identifier, group_contract_position: GroupContractPosition, action_id: Identifier, - estimated_costs_only_with_layer_info: &mut Option< - HashMap, - >, + estimate_costs_only: bool, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, @@ -111,13 +108,13 @@ impl Drive { ); // no estimated_costs_only_with_layer_info, means we want to apply to state - let direct_query_type = if estimated_costs_only_with_layer_info.is_none() { - DirectQueryType::StatefulDirectQuery - } else { + let direct_query_type = if estimate_costs_only { DirectQueryType::StatelessDirectQuery { in_tree_using_sums: false, query_target: QueryTargetValue(8), } + } else { + DirectQueryType::StatefulDirectQuery }; let value = self.grove_get_sum_tree_total_value( diff --git a/packages/rs-drive/src/drive/group/fetch/mod.rs b/packages/rs-drive/src/drive/group/fetch/mod.rs index 7954f4ad501..696d6c21d08 100644 --- a/packages/rs-drive/src/drive/group/fetch/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/mod.rs @@ -1 +1,3 @@ +mod fetch_action_id_info; +mod fetch_action_id_info_keep_serialized; mod fetch_action_id_signers_power; diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs index 21cd4c4e057..7c8038d654c 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -174,17 +174,11 @@ impl Drive { &platform_version.drive, )?; - let group_action_path_vec = group_action_path_vec( - contract_id.as_slice(), - group_contract_position, - action_id.as_slice(), - ); - let serialized = initialize_with_insert_action_info.serialize_consume_to_bytes()?; self.batch_insert( - PathKeyElementInfo::PathKeyRefElement(( - group_action_path_vec, + PathKeyElementInfo::PathFixedSizeKeyRefElement::<5>(( + group_action_path, ACTION_INFO_KEY, Element::Item(serialized, element_flags.clone()), )), @@ -211,7 +205,7 @@ impl Drive { if inserted_root_action { self.batch_insert( - PathKeyElementInfo::PathKeyElement(( + PathKeyElementInfo::PathKeyElement::<0>(( signers_path, signer_identity_id.to_vec(), Element::SumItem(signer_power as SumValue, element_flags), @@ -222,7 +216,7 @@ impl Drive { } else { // we should verify it doesn't yet exist self.batch_insert_sum_item_if_not_exists( - PathKeyElementInfo::PathKeyElement(( + PathKeyElementInfo::PathKeyElement::<0>(( signers_path, signer_identity_id.to_vec(), Element::SumItem(signer_power as SumValue, element_flags), diff --git a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs index c8de9a1432d..c5b55d607fd 100644 --- a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs @@ -178,74 +178,3 @@ impl Drive { Ok(batch_operations) } } - -#[cfg(test)] -mod tests { - use crate::util::test_helpers::setup::{setup_drive, setup_drive_with_initial_state_structure}; - - use dpp::block::block_info::BlockInfo; - - use dpp::version::PlatformVersion; - - #[test] - fn test_insert_and_fetch_group_v0() { - let drive = setup_drive(None); - let platform_version = PlatformVersion::first(); - - let transaction = drive.grove.start_transaction(); - - drive - .create_initial_state_structure(Some(&transaction), platform_version) - .expect("expected to create root tree successfully"); - - let group = Identity::random_group(5, Some(12345), platform_version) - .expect("expected a random group"); - - drive - .add_new_groups_v0( - group.clone(), - false, - &BlockInfo::default(), - true, - Some(&transaction), - platform_version, - ) - .expect("expected to insert group"); - - let fetched_group = drive - .fetch_full_group(group.id().to_buffer(), Some(&transaction), platform_version) - .expect("should fetch an group") - .expect("should have an group"); - - assert_eq!(group, fetched_group); - } - - #[test] - fn test_insert_group_v0() { - let drive = setup_drive_with_initial_state_structure(None); - - let db_transaction = drive.grove.start_transaction(); - - let platform_version = PlatformVersion::latest(); - - let group = Identity::random_group(5, Some(12345), platform_version) - .expect("expected a random group"); - - drive - .add_new_groups_v0( - group, - false, - &BlockInfo::default(), - true, - Some(&db_transaction), - platform_version, - ) - .expect("expected to insert group"); - - drive - .grove - .commit_transaction(db_transaction) - .unwrap() - .expect("expected to be able to commit a transaction"); - } -} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs index 976be1ade2a..af8b7a9c017 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs @@ -3,7 +3,7 @@ use dpp::data_contract::associated_token::token_configuration::accessors::v0::To use dpp::group::action_event::GroupActionEvent; use dpp::group::group_action::GroupAction; use dpp::group::group_action::v0::GroupActionV0; -use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; +use dpp::group::GroupStateTransitionResolvedInfo; use dpp::identifier::Identifier; use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; @@ -67,9 +67,9 @@ impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { .. }) = self.base().store_in_group() { - let event = TokenEvent::Burn(self.burn_amount(), self.public_note_owned()); + let event = TokenEvent::Burn(self.burn_amount(), self.public_note().cloned()); - let initialize_with_insert_action_info = if action_is_proposer { + let initialize_with_insert_action_info = if *action_is_proposer { Some(GroupAction::V0(GroupActionV0 { event: GroupActionEvent::TokenEvent(event), })) diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs index 4143ca11a86..e6c75f37250 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs @@ -1,27 +1,40 @@ +use std::collections::HashMap; use dpp::platform_value::Identifier; use std::sync::Arc; -use grovedb::TransactionArg; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; use dpp::ProtocolError; use dpp::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; impl TokenBaseTransitionAction { /// from base transition with contract lookup pub fn try_from_base_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: TokenBaseTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { match value { TokenBaseTransition::V0(v0) => Ok( TokenBaseTransitionActionV0::try_from_base_transition_with_contract_lookup( drive, - transaction, + owner_id, v0, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )? .into(), ), @@ -31,12 +44,28 @@ impl TokenBaseTransitionAction { /// from borrowed base transition with contract lookup pub fn try_from_borrowed_base_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: &TokenBaseTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { match value { - TokenBaseTransition::V0(v0) => Ok(TokenBaseTransitionActionV0::try_from_borrowed_base_transition_with_contract_lookup(drive, transaction, v0, get_data_contract)?.into()), + TokenBaseTransition::V0(v0) => Ok( + TokenBaseTransitionActionV0::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + drive_operations, + get_data_contract, + platform_version, + )? + .into(), + ), } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index fd78a82d1a2..9a039451429 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -1,9 +1,7 @@ -use std::collections::HashMap; use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; use dpp::platform_value::Identifier; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::TransactionArg; use std::sync::Arc; -use grovedb::batch::KeyInfoPath; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::group::accessors::v0::GroupV0Getters; use dpp::ProtocolError; @@ -21,9 +19,7 @@ impl TokenBaseTransitionActionV0 { drive: &Drive, owner_id: Identifier, value: TokenBaseTransitionV0, - estimated_costs_only_with_layer_info: &mut Option< - HashMap, - >, + approximate_without_state_for_costs: bool, transaction: TransactionArg, drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, @@ -46,19 +42,24 @@ impl TokenBaseTransitionActionV0 { action_id, action_is_proposer, }) => { - let group = data_contract.contract.group(*group_contract_position)?; + let group = data_contract.contract.group(group_contract_position)?; let signer_power = group.member_power(owner_id)?; let required_power = group.required_power(); let current_power = drive.fetch_action_id_signers_power_and_add_operations( data_contract_id, group_contract_position, action_id, - estimated_costs_only_with_layer_info, + approximate_without_state_for_costs, transaction, drive_operations, platform_version, )?; - let perform_action = current_power + signer_power >= required_power; + let perform_action = if approximate_without_state_for_costs { + // most expensive case is that we perform action + true + } else { + current_power + signer_power >= required_power + }; let store_in_group = GroupStateTransitionResolvedInfo { group_contract_position, group: group.clone(), @@ -84,9 +85,7 @@ impl TokenBaseTransitionActionV0 { drive: &Drive, owner_id: Identifier, value: &TokenBaseTransitionV0, - estimated_costs_only_with_layer_info: &mut Option< - HashMap, - >, + approximate_without_state_for_costs: bool, transaction: TransactionArg, drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, @@ -116,12 +115,17 @@ impl TokenBaseTransitionActionV0 { *data_contract_id, *group_contract_position, *action_id, - estimated_costs_only_with_layer_info, + approximate_without_state_for_costs, transaction, drive_operations, platform_version, )?; - let perform_action = current_power + signer_power >= required_power; + let perform_action = if approximate_without_state_for_costs { + // most expensive case is that we perform action + true + } else { + current_power + signer_power >= required_power + }; let store_in_group = GroupStateTransitionResolvedInfo { group_contract_position: *group_contract_position, group: group.clone(), diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs index 8413eb68813..6140a5be9f6 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs @@ -8,7 +8,10 @@ use crate::state_transition_action::document::documents_batch::document_transiti TokenBurnTransitionAction, TokenBurnTransitionActionV0, }; use dpp::state_transition::batch_transition::token_burn_transition::TokenBurnTransition; +use platform_version::version::PlatformVersion; use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; /// Implement methods to transform a `TokenBurnTransition` into a `TokenBurnTransitionAction`. impl TokenBurnTransitionAction { @@ -16,27 +19,40 @@ impl TokenBurnTransitionAction { /// /// # Arguments /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the burn transition. + /// * `transaction` - The transaction argument used for state changes. /// * `value` - A `TokenBurnTransition` instance. - /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. /// /// # Returns /// /// * `Result` - A `TokenBurnTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_token_burn_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: TokenBurnTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { match value { TokenBurnTransition::V0(v0) => { - let v0_action = - TokenBurnTransitionActionV0::try_from_token_burn_transition_with_contract_lookup( - drive, - transaction, - v0, - get_data_contract, - )?; + let v0_action = TokenBurnTransitionActionV0::try_from_token_burn_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + drive_operations, + get_data_contract, + platform_version, + )?; Ok(v0_action.into()) } } @@ -46,25 +62,39 @@ impl TokenBurnTransitionAction { /// /// # Arguments /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the burn transition. + /// * `transaction` - The transaction argument used for state changes. /// * `value` - A reference to a `TokenBurnTransition`. - /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. /// /// # Returns /// /// * `Result` - A `TokenBurnTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_borrowed_token_burn_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: &TokenBurnTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { match value { TokenBurnTransition::V0(v0) => { let v0_action = TokenBurnTransitionActionV0::try_from_borrowed_token_burn_transition_with_contract_lookup( drive, - transaction, + owner_id, v0, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; Ok(v0_action.into()) } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index 9c71c39315c..d553218d025 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -3,29 +3,48 @@ use dpp::state_transition::batch_transition::token_burn_transition::v0::TokenBur use dpp::ProtocolError; use grovedb::TransactionArg; use std::sync::Arc; - +use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; impl TokenBurnTransitionActionV0 { - /// Attempt to convert a `TokenBurnTransitionV0` into a `TokenBurnTransitionActionV0` using a data contract lookup function. + /// Attempts to create a `TokenBurnTransitionActionV0` from the given `TokenBurnTransitionV0` value. /// - /// # Arguments + /// This function extracts the necessary data from the provided `TokenBurnTransitionV0` and + /// delegates to the `try_from_base_transition_with_contract_lookup` function to construct the + /// base action. It then constructs the `TokenBurnTransitionActionV0` struct by including the + /// `burn_amount` and `public_note` values, along with the base action. /// - /// * `value` - A `TokenBurnTransitionV0` from which to derive the action - /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` + /// # Parameters + /// - `drive`: A reference to the `Drive` struct which provides access to the system. + /// - `owner_id`: The identifier of the owner initiating the burn transition. + /// - `value`: The `TokenBurnTransitionV0` containing the details for the token burn. + /// - `approximate_without_state_for_costs`: A flag indicating whether to approximate state costs. + /// - `transaction`: The transaction argument used for state changes. + /// - `drive_operations`: A mutable reference to the vector of low-level operations that need to be performed. + /// - `get_data_contract`: A closure function that looks up the data contract for a given identifier. + /// - `platform_version`: The platform version for the context in which the transition is being executed. /// /// # Returns + /// A `Result` containing the constructed `TokenBurnTransitionActionV0` on success, or an error + /// if any issues occur during the process. /// - /// * `Result` - A `TokenBurnTransitionActionV0` if successful, else `ProtocolError`. + /// # Errors + /// - Returns an `Error` if any error occurs while trying to create the base action or process the burn. pub fn try_from_token_burn_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: TokenBurnTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { let TokenBurnTransitionV0 { base, burn_amount, @@ -34,9 +53,13 @@ impl TokenBurnTransitionActionV0 { let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( drive, - transaction, + owner_id, base, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; Ok(TokenBurnTransitionActionV0 { @@ -46,22 +69,39 @@ impl TokenBurnTransitionActionV0 { }) } - /// Attempt to convert a borrowed `TokenBurnTransitionV0` into a `TokenBurnTransitionActionV0` using a data contract lookup function. + /// Attempts to create a `TokenBurnTransitionActionV0` from the borrowed `TokenBurnTransitionV0` value. /// - /// # Arguments + /// This function is similar to `try_from_token_burn_transition_with_contract_lookup`, but it + /// operates on a borrowed `TokenBurnTransitionV0` to avoid ownership transfer. It delegates + /// to `try_from_borrowed_base_transition_with_contract_lookup` for constructing the base action, + /// then combines it with the `burn_amount` and `public_note` to form a `TokenBurnTransitionActionV0`. /// - /// * `value` - A reference to a `TokenBurnTransitionV0` from which to derive the action - /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` + /// # Parameters + /// - `drive`: A reference to the `Drive` struct which provides access to the system. + /// - `owner_id`: The identifier of the owner initiating the burn transition. + /// - `value`: A borrowed reference to the `TokenBurnTransitionV0` containing the details for the token burn. + /// - `approximate_without_state_for_costs`: A flag indicating whether to approximate state costs. + /// - `transaction`: The transaction argument used for state changes. + /// - `drive_operations`: A mutable reference to the vector of low-level operations that need to be performed. + /// - `get_data_contract`: A closure function that looks up the data contract for a given identifier. + /// - `platform_version`: The platform version for the context in which the transition is being executed. /// /// # Returns + /// A `Result` containing the constructed `TokenBurnTransitionActionV0` on success, or an error + /// if any issues occur during the process. /// - /// * `Result` - A `TokenBurnTransitionActionV0` if successful, else `ProtocolError`. + /// # Errors + /// - Returns an `Error` if any error occurs while trying to create the base action or process the burn. pub fn try_from_borrowed_token_burn_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: &TokenBurnTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { let TokenBurnTransitionV0 { base, burn_amount, @@ -71,9 +111,13 @@ impl TokenBurnTransitionActionV0 { let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( drive, - transaction, + owner_id, base, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; Ok(TokenBurnTransitionActionV0 { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs index b808b9e3d66..75b61fcefcd 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs @@ -6,7 +6,10 @@ use std::sync::Arc; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionActionV0, TokenMintTransitionAction}; use dpp::state_transition::batch_transition::token_mint_transition::TokenMintTransition; +use platform_version::version::PlatformVersion; use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; /// Implement methods to transform a `TokenMintTransition` into a `TokenMintTransitionAction`. impl TokenMintTransitionAction { @@ -14,26 +17,40 @@ impl TokenMintTransitionAction { /// /// # Arguments /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the mint transition. + /// * `transaction` - The transaction argument used for state changes. /// * `value` - A `TokenMintTransition` instance. - /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. /// /// # Returns /// /// * `Result` - A `TokenMintTransitionAction` if successful, otherwise `ProtocolError`. - pub fn from_token_mint_transition_with_contract_lookup( + pub fn try_from_token_mint_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: TokenMintTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { match value { TokenMintTransition::V0(v0) => { let v0_action = TokenMintTransitionActionV0::try_from_token_mint_transition_with_contract_lookup( drive, - transaction, + owner_id, v0, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; Ok(v0_action.into()) } @@ -44,25 +61,39 @@ impl TokenMintTransitionAction { /// /// # Arguments /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the mint transition. + /// * `transaction` - The transaction argument used for state changes. /// * `value` - A reference to a `TokenMintTransition`. - /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. /// /// # Returns /// /// * `Result` - A `TokenMintTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_borrowed_token_mint_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: &TokenMintTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { match value { TokenMintTransition::V0(v0) => { let v0_action = TokenMintTransitionActionV0::try_from_borrowed_token_mint_transition_with_contract_lookup( drive, - transaction, + owner_id, v0, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; Ok(v0_action.into()) } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs index fb88935b143..59cd7da505b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs @@ -10,25 +10,46 @@ use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::v0::TokenMintTransitionActionV0; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use platform_version::version::PlatformVersion; use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; impl TokenMintTransitionActionV0 { - /// Attempt to convert a `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using a data contract lookup function. + /// Converts a `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token minting transition and returns the corresponding transition action + /// while looking up necessary data contracts and applying the relevant logic for minting. /// /// # Arguments /// - /// * `value` - A `TokenMintTransitionV0` from which to derive the action - /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the minting transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `transaction` - A transaction context that includes the necessary state and other details for the transition. + /// * `value` - The `TokenMintTransitionV0` struct containing the transition data, including token amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. Useful for optimizing the transaction cost calculations. + /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed + /// during this transition. This allows tracking the changes that need to be persisted. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version, ensuring the transition respects version-specific logic. /// /// # Returns /// - /// * `Result` - A `TokenMintTransitionActionV0` if successful, else `ProtocolError`. + /// * `Result` - Returns the constructed `TokenMintTransitionActionV0` if successful, + /// or an error if any issue arises, such as missing data or an invalid state transition. pub fn try_from_token_mint_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: TokenMintTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { let TokenMintTransitionV0 { base, issued_to_identity_id, @@ -40,9 +61,13 @@ impl TokenMintTransitionActionV0 { let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( drive, - transaction, + owner_id, base, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; let identity_balance_holder_id = issued_to_identity_id @@ -68,22 +93,36 @@ impl TokenMintTransitionActionV0 { }) } - /// Attempt to convert a borrowed `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using a data contract lookup function. + /// Converts a borrowed `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using the provided contract lookup. + /// + /// This method works similarly to `try_from_token_mint_transition_with_contract_lookup`, but it borrows the + /// `TokenMintTransitionV0` to avoid unnecessary cloning of the transition object. /// /// # Arguments /// - /// * `value` - A reference to a `TokenMintTransitionV0` from which to derive the action - /// * `get_data_contract` - A closure that, given a `data_contract_id`, returns an `Arc` + /// * `drive` - A reference to the `Drive` instance for data access. + /// * `owner_id` - The identifier of the owner initiating the minting transition. + /// * `transaction` - The transaction context for state changes. + /// * `value` - A reference to a `TokenMintTransitionV0` struct containing transition data. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without full state. + /// * `drive_operations` - A mutable reference to a vector for tracking low-level drive operations. + /// * `get_data_contract` - A closure to fetch data contract information based on a contract identifier. + /// * `platform_version` - A reference to the platform version for version-specific transition logic. /// /// # Returns /// - /// * `Result` - A `TokenMintTransitionActionV0` if successful, else `ProtocolError`. + /// * `Result` - Returns the resulting `TokenMintTransitionActionV0` if successful, + /// or an error if something goes wrong (e.g., missing data, invalid state). pub fn try_from_borrowed_token_mint_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: &TokenMintTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { let TokenMintTransitionV0 { base, issued_to_identity_id, @@ -94,9 +133,13 @@ impl TokenMintTransitionActionV0 { let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( drive, - transaction, + owner_id, base, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; let identity_balance_holder_id = issued_to_identity_id diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs index 99a2af6f1d2..6c47540ee6a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs @@ -3,19 +3,29 @@ use grovedb::TransactionArg; use dpp::platform_value::Identifier; use dpp::ProtocolError; use dpp::state_transition::batch_transition::TokenTransferTransition; +use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionV0; /// Implement methods to transform a `TokenTransferTransition` into a `TokenTransferTransitionAction`. impl TokenTransferTransitionAction { - /// Transform a `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided data contract lookup. + /// Transform a `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided data contract lookup and additional parameters. /// /// # Arguments /// + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. + /// * `transaction` - The transaction context for state changes and related operations. /// * `value` - A `TokenTransferTransition` instance. - /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// * `owner_id` - The identifier of the owner initiating the transfer. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. + /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed. + /// * `get_data_contract` - A closure that fetches data contract information based on a contract identifier. + /// * `platform_version` - A reference to the platform version for version-specific transition logic. /// /// # Returns /// @@ -24,28 +34,42 @@ impl TokenTransferTransitionAction { drive: &Drive, transaction: TransactionArg, value: TokenTransferTransition, + owner_id: Identifier, + approximate_without_state_for_costs: bool, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { match value { TokenTransferTransition::V0(v0) => { - let v0_action = - TokenTransferTransitionActionV0::try_from_token_transfer_transition_with_contract_lookup( - drive, - transaction, - v0, - get_data_contract, - )?; + let v0_action = TokenTransferTransitionActionV0::try_from_token_transfer_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + drive_operations, + get_data_contract, + platform_version, + )?; Ok(v0_action.into()) } } } - /// Transform a borrowed `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided data contract lookup. + /// Transform a borrowed `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided data contract lookup and additional parameters. /// /// # Arguments /// + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. + /// * `transaction` - The transaction context for state changes and related operations. /// * `value` - A reference to a `TokenTransferTransition`. - /// * `get_data_contract` - A closure that fetches the DataContractFetchInfo given a contract ID. + /// * `owner_id` - The identifier of the owner initiating the transfer. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. + /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed. + /// * `get_data_contract` - A closure that fetches data contract information based on a contract identifier. + /// * `platform_version` - A reference to the platform version for version-specific transition logic. /// /// # Returns /// @@ -54,15 +78,23 @@ impl TokenTransferTransitionAction { drive: &Drive, transaction: TransactionArg, value: &TokenTransferTransition, + owner_id: Identifier, + approximate_without_state_for_costs: bool, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { match value { TokenTransferTransition::V0(v0) => { let v0_action = TokenTransferTransitionActionV0::try_from_borrowed_token_transfer_transition_with_contract_lookup( drive, - transaction, + owner_id, v0, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; Ok(v0_action.into()) } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index 2c27cde2acf..d7ed9086ec2 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -3,20 +3,48 @@ use dpp::state_transition::batch_transition::token_transfer_transition::v0::Toke use dpp::ProtocolError; use grovedb::TransactionArg; use std::sync::Arc; - +use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionActionV0; impl TokenTransferTransitionActionV0 { - /// Convert a `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using contract lookup + /// Converts a `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using the provided contract lookup and additional parameters. + /// + /// This method processes the token transfer transition and returns the corresponding transition action, + /// while looking up necessary data contracts, performing the required checks, and applying the relevant logic for token transfer. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the transfer. + /// * `value` - The `TokenTransferTransitionV0` struct containing the transition data, including token amount, + /// recipient details, and encrypted notes. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. Useful for optimizing the transaction cost calculations. + /// * `transaction` - The transaction context for state changes and related operations. + /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed + /// during this transition. This allows tracking the changes that need to be persisted. + /// * `get_data_contract` - A closure to fetch data contract information based on a contract identifier. + /// * `platform_version` - A reference to the platform version for version-specific transition logic. + /// + /// # Returns + /// + /// * `Result` - Returns the constructed `TokenTransferTransitionActionV0` + /// if successful, or an error if any issue arises (e.g., missing data or an invalid state transition). pub fn try_from_token_transfer_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: TokenTransferTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { let TokenTransferTransitionV0 { base, amount, @@ -26,13 +54,19 @@ impl TokenTransferTransitionActionV0 { private_encrypted_note, } = value; + // Lookup the base action using the base transition data and contract information let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( drive, - transaction, + owner_id, base, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; + // Return the TokenTransferTransitionActionV0 with the relevant data Ok(TokenTransferTransitionActionV0 { base: base_action, amount, @@ -43,13 +77,37 @@ impl TokenTransferTransitionActionV0 { }) } - /// Convert a borrowed `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using contract lookup + /// Converts a borrowed `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using the provided contract lookup and additional parameters. + /// + /// This method works similarly to `try_from_token_transfer_transition_with_contract_lookup`, but it borrows the + /// `TokenTransferTransitionV0` to avoid unnecessary cloning of the transition object. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance for data access. + /// * `owner_id` - The identifier of the owner initiating the transfer. + /// * `value` - A reference to the `TokenTransferTransitionV0` struct containing transition data (borrowed). + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. + /// * `transaction` - The transaction context for state changes and related operations. + /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed. + /// * `get_data_contract` - A closure to fetch data contract information based on a contract identifier. + /// * `platform_version` - A reference to the platform version for version-specific transition logic. + /// + /// # Returns + /// + /// * `Result` - Returns the resulting `TokenTransferTransitionActionV0` + /// if successful, or an error if something goes wrong (e.g., missing data, invalid state). pub fn try_from_borrowed_token_transfer_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, + owner_id: Identifier, value: &TokenTransferTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, - ) -> Result { + platform_version: &PlatformVersion, + ) -> Result { let TokenTransferTransitionV0 { base, amount, @@ -59,14 +117,20 @@ impl TokenTransferTransitionActionV0 { private_encrypted_note, } = value; + // Lookup the base action using the borrowed base transition data and contract information let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( drive, - transaction, + owner_id, &base, + approximate_without_state_for_costs, + transaction, + drive_operations, get_data_contract, + platform_version, )?; + // Return the TokenTransferTransitionActionV0 with the relevant data Ok(TokenTransferTransitionActionV0 { base: base_action.into(), amount: *amount, diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/group.rs b/packages/rs-drive/src/util/batch/drive_op_batch/group.rs index c53c97153e6..ce1a193c451 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/group.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/group.rs @@ -1,8 +1,18 @@ +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::batch::drive_op_batch::DriveLowLevelOperationConverter; +use dpp::block::block_info::BlockInfo; use dpp::data_contract::group::GroupMemberPower; use dpp::data_contract::GroupContractPosition; use dpp::group::group_action::GroupAction; use dpp::identifier::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::HashMap; +/// Group operations requiring many people to agree to something for the action to occur. #[derive(Clone, Debug)] pub enum GroupOperationType { /// Adds a group action @@ -21,3 +31,38 @@ pub enum GroupOperationType { signer_power: GroupMemberPower, }, } + +impl DriveLowLevelOperationConverter for GroupOperationType { + fn into_low_level_drive_operations( + self, + drive: &Drive, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match self { + GroupOperationType::AddGroupAction { + contract_id, + group_contract_position, + initialize_with_insert_action_info, + action_id, + signer_identity_id, + signer_power, + } => drive.add_group_action_operations( + contract_id, + group_contract_position, + initialize_with_insert_action_info, + action_id, + signer_identity_id, + signer_power, + block_info, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + } + } +} diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs index a7a9ec7002d..bfcc14b5fb5 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs @@ -168,6 +168,14 @@ impl DriveLowLevelOperationConverter for DriveOperation<'_> { transaction, platform_version, ), + DriveOperation::GroupOperation(group_operation_type) => group_operation_type + .into_low_level_drive_operations( + drive, + estimated_costs_only_with_layer_info, + block_info, + transaction, + platform_version, + ), } } } diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index 51efa60fbca..3c45712d71e 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -12,7 +12,7 @@ use grovedb::{EstimatedLayerInformation, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::HashMap; -/// Operations on Documents +/// Operations on Tokens #[derive(Clone, Debug)] pub enum TokenOperationType { /// Burns token from the account issuing the . diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/mod.rs new file mode 100644 index 00000000000..50393976ba6 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/mod.rs @@ -0,0 +1,55 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; + +use dpp::version::drive_versions::DriveVersion; + +use grovedb::{Element, TransactionArg}; +use grovedb_path::SubtreePath; + +impl Drive { + /// Handles the retrieval of a raw element from GroveDB at the specified path and key. + /// The operation cost is added to `drive_operations` for later processing. + /// + /// # Parameters + /// * `path`: The groveDB hierarchical authenticated structure path from where the element is to be retrieved. + /// * `key`: The key of the element to be retrieved from the subtree. + /// * `direct_query_type`: The type of query to perform, whether stateless or stateful. + /// * `transaction`: The groveDB transaction associated with this operation. + /// * `drive_operations`: A vector to collect the costs of operations for later computation. + /// * `platform_version`: The platform version to select the correct function version to run. + /// + /// # Returns + /// * `Ok(Some(Element))` if the operation was successful and the element was found. + /// * `Ok(None)` if the operation was successful but the element was not found. + /// * `Err(DriveError::UnknownVersionMismatch)` if the platform version does not match known versions. + pub fn grove_get_raw_item>( + &self, + path: SubtreePath<'_, B>, + key: &[u8], + direct_query_type: DirectQueryType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result, Error> { + match drive_version.grove_methods.basic.grove_get_raw_item { + 0 => self.grove_get_raw_item_v0( + path, + key, + direct_query_type, + transaction, + drive_operations, + drive_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "grove_get_raw_item".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/v0/mod.rs new file mode 100644 index 00000000000..59cdb57e5ec --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/v0/mod.rs @@ -0,0 +1,83 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::fees::op::LowLevelDriveOperation::CalculatedCostOperation; +use crate::util::grove_operations::{DirectQueryType, QueryTarget}; +use grovedb::batch::key_info::KeyInfo; +use grovedb::batch::KeyInfoPath; +use grovedb::{Element, GroveDb, TransactionArg}; +use grovedb_costs::CostContext; +use grovedb_path::SubtreePath; +use itertools::Itertools; +use platform_version::version::drive_versions::DriveVersion; + +impl Drive { + /// grove_get_raw_item basically means that there are no reference hops, this only matters + /// when calculating worst case costs + pub(super) fn grove_get_raw_item_v0>( + &self, + path: SubtreePath<'_, B>, + key: &[u8], + direct_query_type: DirectQueryType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result, Error> { + match direct_query_type { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums, + query_target, + } => { + let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); + let key_info = KeyInfo::KnownKey(key.to_vec()); + let cost = match query_target { + QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + GroveDb::average_case_for_get_tree( + &key_info_path, + &key_info, + flags_size, + is_sum_tree, + in_tree_using_sums, + &drive_version.grove_version, + ) + } + QueryTarget::QueryTargetValue(estimated_value_size) => { + GroveDb::average_case_for_get_raw( + &key_info_path, + &key_info, + estimated_value_size, + in_tree_using_sums, + &drive_version.grove_version, + ) + } + }?; + + drive_operations.push(CalculatedCostOperation(cost)); + Ok(vec![]) + } + DirectQueryType::StatefulDirectQuery => { + //todo remove path clone + let CostContext { value, cost } = self.grove.get_raw( + path.clone(), + key, + transaction, + &drive_version.grove_version, + ); + drive_operations.push(CalculatedCostOperation(cost)); + let element = value.map_err(Error::GroveDB)?; + match element { + Element::Item(value, _) => Ok(value), + _ => Err(Error::Drive(DriveError::CorruptedDriveState(format!( + "path {}/0x{} does not refer to an item", + path.to_vec() + .iter() + .map(|bytes| format!("0x{}", hex::encode(bytes))) + .join("/"), + hex::encode(key) + )))), + } + } + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/mod.rs b/packages/rs-drive/src/util/grove_operations/mod.rs index d082409b197..9e75d2f59aa 100644 --- a/packages/rs-drive/src/util/grove_operations/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/mod.rs @@ -21,6 +21,9 @@ pub mod grove_delete; /// Fetch raw grove data pub mod grove_get_raw; +/// Fetch raw grove data and match that is item +pub mod grove_get_raw_item; + /// Fetch raw grove data if it exists pub mod grove_get_raw_optional; diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs index 6938728daeb..bc3ff85bd0f 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs @@ -135,6 +135,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V1: DriveAbciValidationVersions = token_issuance_transition_state_validation: 0, token_burn_transition_state_validation: 0, token_transfer_transition_state_validation: 0, + token_base_transition_structure_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs index cb84209f96e..c11c3ef29c0 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs @@ -135,6 +135,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V2: DriveAbciValidationVersions = token_issuance_transition_state_validation: 0, token_burn_transition_state_validation: 0, token_transfer_transition_state_validation: 0, + token_base_transition_structure_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs index 2efd6d17c79..95f3bcef537 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs @@ -135,6 +135,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V3: DriveAbciValidationVersions = token_issuance_transition_state_validation: 0, token_burn_transition_state_validation: 0, token_transfer_transition_state_validation: 0, + token_base_transition_structure_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs index fa05318a019..e4c16445998 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs @@ -135,6 +135,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V4: DriveAbciValidationVersions = token_issuance_transition_state_validation: 0, token_burn_transition_state_validation: 0, token_transfer_transition_state_validation: 0, + token_base_transition_structure_validation: 0, }, }, has_nonce_validation: 1, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs index 2fd64eedbdd..95bf59680f0 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs @@ -13,6 +13,8 @@ pub struct DriveGroupMethodVersions { #[derive(Clone, Debug, Default)] pub struct DriveGroupFetchMethodVersions { pub fetch_action_id_signers_power: FeatureVersion, + pub fetch_action_id_info: FeatureVersion, + pub fetch_action_id_info_keep_serialized: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs index e47d8645819..4bd631f3115 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs @@ -6,6 +6,8 @@ use crate::version::drive_versions::drive_group_method_versions::{ pub const DRIVE_GROUP_METHOD_VERSIONS_V1: DriveGroupMethodVersions = DriveGroupMethodVersions { fetch: DriveGroupFetchMethodVersions { fetch_action_id_signers_power: 0, + fetch_action_id_info: 0, + fetch_action_id_info_keep_serialized: 0, }, prove: DriveGroupProveMethodVersions {}, insert: DriveGroupInsertMethodVersions { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs index 209e0c5d816..9746e504599 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs @@ -33,6 +33,7 @@ pub struct DriveGroveBasicMethodVersions { pub grove_get_proved_path_query_with_conditional: FeatureVersion, pub grove_get_sum_tree_total_value: FeatureVersion, pub grove_has_raw: FeatureVersion, + pub grove_get_raw_item: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs index 7d29de08a6b..76800ee0c88 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs @@ -26,6 +26,7 @@ pub const DRIVE_GROVE_METHOD_VERSIONS_V1: DriveGroveMethodVersions = DriveGroveM grove_get_proved_path_query_with_conditional: 0, grove_get_sum_tree_total_value: 0, grove_has_raw: 0, + grove_get_raw_item: 0, }, batch: DriveGroveBatchMethodVersions { batch_insert_empty_tree: 0, From 83fff2f839aec94c4c05bf7c7815ec33b8b54d44 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 Jan 2025 11:19:24 +0700 Subject: [PATCH 31/61] tests passing --- .../src/data_contract/conversion/cbor/mod.rs | 15 +- .../src/data_contract/conversion/value/mod.rs | 6 +- .../data_contract/extra/drive_api_tests.rs | 61 +- .../src/data_contract/factory/v0/mod.rs | 9 +- packages/rs-dpp/src/data_contract/mod.rs | 24 + .../src/data_contract/v1/conversion/value.rs | 14 +- .../token_base_transition/fields.rs | 1 + .../token_base_transition/v0/mod.rs | 3 + .../src/execution/check_tx/v0/mod.rs | 932 ++++++++- .../block_fee_processing/tests.rs | 6 + .../state_v0/mod.rs | 3 +- .../structure_v0/mod.rs | 3 +- .../structure_v0/mod.rs | 3 +- .../batch/advanced_structure/v0/mod.rs | 2 +- .../data_triggers/triggers/dashpay/v0/mod.rs | 1 + .../data_triggers/triggers/dpns/v0/mod.rs | 1 + .../state_transitions/batch/mod.rs | 7 + .../batch/transformer/v0/mod.rs | 134 +- .../data_contract_create/state/v0/mod.rs | 109 +- .../data_contract_update/state/v0/mod.rs | 14 +- .../state_transitions/identity_create/mod.rs | 601 +++++- .../state_transitions/identity_top_up/mod.rs | 135 +- .../state_transition/state_transitions/mod.rs | 3 + .../v0/for_saving.rs | 3 +- .../tests/strategy_tests/main.rs | 85 +- .../rs-drive/src/drive/document/delete/mod.rs | 6 + .../rs-drive/src/drive/document/insert/mod.rs | 7 + .../rs-drive/src/drive/document/update/mod.rs | 10 +- .../group/fetch/fetch_action_id_info/mod.rs | 1 - .../fetch_action_id_signers_power/mod.rs | 4 +- .../fetch_action_id_signers_power/v0/mod.rs | 5 +- .../group/insert/add_group_action/v0/mod.rs | 4 +- packages/rs-drive/src/drive/group/mod.rs | 7 + .../src/drive/initialization/v0/mod.rs | 350 +++- packages/rs-drive/src/drive/mod.rs | 1 + .../token_base_transition_action/mod.rs | 2 +- .../transformer.rs | 4 +- .../token_base_transition_action/v0/mod.rs | 4 +- .../token_burn_transition_action/mod.rs | 9 +- .../transformer.rs | 54 +- .../v0/transformer.rs | 67 +- .../transformer.rs | 24 +- .../v0/transformer.rs | 103 +- .../token_transfer_transition_action/mod.rs | 6 +- .../transformer.rs | 83 +- .../v0/transformer.rs | 124 +- .../src/util/batch/drive_op_batch/mod.rs | 3 + .../v0/mod.rs | 4 +- .../grove_get_raw_item/mod.rs | 2 +- .../rs-drive/src/util/test_helpers/mod.rs | 3 +- .../mod.rs | 1 - .../rs-drive/tests/deterministic_root_hash.rs | 39 +- packages/rs-drive/tests/query_tests.rs | 1676 +++++++++++++++-- .../rs-drive/tests/query_tests_history.rs | 1405 +++++++++++++- .../dpp_versions/dpp_contract_versions/mod.rs | 1 + .../dpp_versions/dpp_contract_versions/v2.rs | 54 + .../drive_contract_method_versions/v2.rs | 2 +- .../rs-platform-version/src/version/v8.rs | 4 +- .../v1/token-history-contract-documents.json | 4 +- .../src/errors/consensus/consensus_error.rs | 21 + 60 files changed, 5734 insertions(+), 535 deletions(-) create mode 100644 packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs diff --git a/packages/rs-dpp/src/data_contract/conversion/cbor/mod.rs b/packages/rs-dpp/src/data_contract/conversion/cbor/mod.rs index 3fe07940141..8683b2dbb42 100644 --- a/packages/rs-dpp/src/data_contract/conversion/cbor/mod.rs +++ b/packages/rs-dpp/src/data_contract/conversion/cbor/mod.rs @@ -1,6 +1,7 @@ mod v0; use crate::data_contract::v0::DataContractV0; +use crate::data_contract::v1::DataContractV1; use crate::prelude::DataContract; use crate::util::cbor_value::CborCanonicalMap; use crate::version::PlatformVersion; @@ -27,9 +28,16 @@ impl DataContractCborConversionMethodsV0 for DataContract { platform_version, )? .into()), + 1 => Ok(DataContractV1::from_cbor_with_id( + cbor_bytes, + contract_id, + full_validation, + platform_version, + )? + .into()), version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContract::from_cbor_with_id".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } @@ -48,9 +56,12 @@ impl DataContractCborConversionMethodsV0 for DataContract { 0 => Ok( DataContractV0::from_cbor(cbor_bytes, full_validation, platform_version)?.into(), ), + 1 => Ok( + DataContractV1::from_cbor(cbor_bytes, full_validation, platform_version)?.into(), + ), version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContract::from_cbor".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } diff --git a/packages/rs-dpp/src/data_contract/conversion/value/mod.rs b/packages/rs-dpp/src/data_contract/conversion/value/mod.rs index 305ac8c9db6..59d07245ca2 100644 --- a/packages/rs-dpp/src/data_contract/conversion/value/mod.rs +++ b/packages/rs-dpp/src/data_contract/conversion/value/mod.rs @@ -2,6 +2,7 @@ pub mod v0; use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; use crate::data_contract::v0::DataContractV0; +use crate::data_contract::v1::DataContractV1; use crate::data_contract::DataContract; use crate::version::PlatformVersion; use crate::ProtocolError; @@ -21,9 +22,12 @@ impl DataContractValueConversionMethodsV0 for DataContract { 0 => Ok( DataContractV0::from_value(raw_object, full_validation, platform_version)?.into(), ), + 1 => Ok( + DataContractV1::from_value(raw_object, full_validation, platform_version)?.into(), + ), version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContract::from_object".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } diff --git a/packages/rs-dpp/src/data_contract/extra/drive_api_tests.rs b/packages/rs-dpp/src/data_contract/extra/drive_api_tests.rs index beafe720de4..67ab7eb8569 100644 --- a/packages/rs-dpp/src/data_contract/extra/drive_api_tests.rs +++ b/packages/rs-dpp/src/data_contract/extra/drive_api_tests.rs @@ -107,7 +107,6 @@ mod test { let data_contract = DataContract::from_cbor(cbor_bytes, true, platform_version) .expect("contract should be deserialized"); - assert_eq!(0, data_contract.feature_version()); assert_eq!(expect_id, data_contract.id().as_bytes()); assert_eq!(expect_owner_id, data_contract.owner_id().as_bytes()); @@ -143,7 +142,7 @@ mod test { platform_version, ) .expect("expected to get a contract") - .into_v0() + .into_latest() .unwrap(); assert!(contract.config.documents_mutable_contract_default()); @@ -196,6 +195,58 @@ mod test { assert!(contact_info_indices[1].properties[0].ascending); } + #[test] + #[cfg(feature = "data-contract-cbor-conversion")] + fn mutability_properties_should_be_stored_and_restored_during_cbor_serialization_contract_v0() { + let platform_version = PlatformVersion::get(7).expect("expected version 7"); + + let mut contract = json_document_to_contract( + "../rs-drive/tests/supporting_files/contract/dashpay/dashpay-contract.json", + false, + platform_version, + ) + .expect("expected to get a cbor document") + .into_v0() + .unwrap(); + + assert!(!contract.config().readonly()); + assert!(!contract.config.keeps_history()); + assert!(contract.config.documents_mutable_contract_default()); + assert!(!contract.config.documents_keep_history_contract_default()); + + contract.config.set_readonly(true); + contract.config.set_keeps_history(true); + contract + .config + .set_documents_mutable_contract_default(false); + contract + .config + .set_documents_can_be_deleted_contract_default(false); + contract + .config + .set_documents_keep_history_contract_default(true); + + let contract_cbor = contract + .to_cbor(platform_version) + .expect("serialization shouldn't fail"); + let deserialized_contract = DataContract::from_cbor(contract_cbor, true, platform_version) + .expect("deserialization shouldn't fail"); + + assert_matches!( + deserialized_contract.config(), + DataContractConfig::V0(DataContractConfigV0 { + can_be_deleted: false, + readonly: true, + keeps_history: true, + documents_mutable_contract_default: false, + documents_keep_history_contract_default: true, + documents_can_be_deleted_contract_default: false, + requires_identity_encryption_bounded_key: None, + requires_identity_decryption_bounded_key: None, + }) + ); + } + #[test] #[cfg(feature = "data-contract-cbor-conversion")] fn mutability_properties_should_be_stored_and_restored_during_cbor_serialization() { @@ -207,7 +258,7 @@ mod test { platform_version, ) .expect("expected to get a cbor document") - .into_v0() + .into_v1() .unwrap(); assert!(!contract.config().readonly()); @@ -259,7 +310,7 @@ mod test { ) .expect("expected to decode a contract"); - let contract_v0 = contract.as_v0_mut().unwrap(); + let contract_v0 = contract.as_latest_mut().unwrap(); assert!(!contract_v0.config().readonly()); assert!(!contract_v0.config.keeps_history()); @@ -286,7 +337,7 @@ mod test { .expect("deserialization shouldn't fail"); assert_eq!( - deserialized_contract.as_v0().unwrap().config, + deserialized_contract.as_latest().unwrap().config, DataContractConfig::V0(DataContractConfigV0 { can_be_deleted: false, readonly: true, diff --git a/packages/rs-dpp/src/data_contract/factory/v0/mod.rs b/packages/rs-dpp/src/data_contract/factory/v0/mod.rs index c9eafdf0216..0c07d25a614 100644 --- a/packages/rs-dpp/src/data_contract/factory/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/factory/v0/mod.rs @@ -20,6 +20,7 @@ use crate::state_transition::data_contract_create_transition::DataContractCreate #[cfg(feature = "state-transitions")] use crate::state_transition::data_contract_update_transition::DataContractUpdateTransition; +use crate::data_contract::v1::DataContractV1; use crate::prelude::IdentityNonce; use crate::version::PlatformVersion; use crate::{errors::ProtocolError, prelude::Identifier}; @@ -117,9 +118,15 @@ impl DataContractFactoryV0 { platform_version, )? .into()), + 1 => Ok(DataContractV1::from_value( + data_contract_object, + full_validation, + platform_version, + )? + .into()), version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContractFactoryV0::create_from_object".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } diff --git a/packages/rs-dpp/src/data_contract/mod.rs b/packages/rs-dpp/src/data_contract/mod.rs index 0897fd20287..818bc3f621e 100644 --- a/packages/rs-dpp/src/data_contract/mod.rs +++ b/packages/rs-dpp/src/data_contract/mod.rs @@ -270,6 +270,30 @@ impl DataContract { } } + /// This should only ever be used in tests, as it will change + #[cfg(test)] + pub fn into_latest(self) -> Option { + self.into_v1() + } + + /// This should only ever be used in tests, as it will change + #[cfg(test)] + pub fn as_latest(&self) -> Option<&DataContractV1> { + match self { + DataContract::V1(v1) => Some(v1), + _ => None, + } + } + + /// This should only ever be used in tests, as it will change + #[cfg(test)] + pub fn as_latest_mut(&mut self) -> Option<&mut DataContractV1> { + match self { + DataContract::V1(v1) => Some(v1), + _ => None, + } + } + pub fn check_version_is_active( protocol_version: u32, data_contract_system_version: FeatureVersion, diff --git a/packages/rs-dpp/src/data_contract/v1/conversion/value.rs b/packages/rs-dpp/src/data_contract/v1/conversion/value.rs index f51e6b36529..ab8452716cf 100644 --- a/packages/rs-dpp/src/data_contract/v1/conversion/value.rs +++ b/packages/rs-dpp/src/data_contract/v1/conversion/value.rs @@ -1,6 +1,7 @@ use crate::data_contract::conversion::value::v0::DataContractValueConversionMethodsV0; use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; +use crate::data_contract::serialized_version::v1::DataContractInSerializationFormatV1; use crate::data_contract::serialized_version::{property_names, DataContractInSerializationFormat}; use crate::data_contract::DataContractV1; use crate::version::PlatformVersion; @@ -34,9 +35,20 @@ impl DataContractValueConversionMethodsV0 for DataContractV1 { platform_version, ) } + "1" => { + let data_contract_data: DataContractInSerializationFormatV1 = + platform_value::from_value(value).map_err(ProtocolError::ValueError)?; + + DataContractV1::try_from_platform_versioned( + data_contract_data.into(), + full_validation, + &mut vec![], // this is not used in consensus code + platform_version, + ) + } version => Err(ProtocolError::UnknownVersionMismatch { method: "DataContractV1::from_value".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version .parse() .map_err(|_| ProtocolError::Generic("Conversion error".to_string()))?, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs index 98529f9e9e5..02391e0be6f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/fields.rs @@ -4,6 +4,7 @@ pub(in crate::state_transition::state_transitions::document::batch_transition) m pub const TOKEN_ID: &str = "$tokenId"; pub const GROUP_CONTRACT_POSITION: &str = "$groupContractPosition"; pub const GROUP_ACTION_ID: &str = "$groupActionId"; + pub const GROUP_ACTION_IS_PROPOSER: &str = "$groupActionIsProposer"; pub const ACTION: &str = "$action"; pub const IDENTITY_CONTRACT_NONCE: &str = "$identityContractNonce"; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs index 4034cdc1706..c3b8595dcca 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/mod.rs @@ -106,6 +106,9 @@ impl TokenBaseTransitionV0 { .remove_hash256_bytes(property_names::GROUP_ACTION_ID) .map_err(ProtocolError::ValueError)? .into(), + action_is_proposer: map + .remove_bool(property_names::GROUP_ACTION_IS_PROPOSER) + .map_err(ProtocolError::ValueError)?, }) }) .transpose()?, 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 8a552fd154e..06292c23421 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 @@ -381,7 +381,7 @@ mod tests { } #[test] - fn data_contract_create_check_tx() { + fn data_contract_create_check_tx_first_protocol_version() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -392,6 +392,7 @@ mod tests { let platform = TestPlatformBuilder::new() .with_config(platform_config) + .with_initial_protocol_version(1) .build_with_mock_rpc(); let platform_state = platform.state.load(); @@ -523,6 +524,149 @@ mod tests { )); } + #[test] + fn data_contract_create_check_tx_latest_protocol_version() { + let platform_config = PlatformConfig { + testing_configs: PlatformTestConfig { + disable_instant_lock_signature_verification: true, + ..Default::default() + }, + ..Default::default() + }; + + let platform = TestPlatformBuilder::new() + .with_config(platform_config) + .build_with_mock_rpc(); + + 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 dashpay = get_dashpay_contract_fixture(Some(identity.id()), 1, protocol_version); + 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 platform_ref = PlatformRef { + drive: &platform.drive, + state: &platform_state, + config: &platform.config, + core_rpc: &platform.core_rpc, + }; + + let validation_result = platform + .check_tx( + serialized.as_slice(), + FirstTimeCheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(validation_result.errors.is_empty()); + + let check_result = platform + .check_tx( + serialized.as_slice(), + Recheck, + &platform_ref, + 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, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 2484410); + + let check_result = platform + .check_tx( + serialized.as_slice(), + Recheck, + &platform_ref, + 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_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(!check_result.is_valid()); // it should no longer be valid, because of the nonce check + + assert!(matches!( + check_result.errors.first().expect("expected an error"), + ConsensusError::StateError(StateError::InvalidIdentityNonceError(_)) + )); + } + #[test] fn data_contract_create_check_tx_for_invalid_contract() { let platform_config = PlatformConfig { @@ -728,7 +872,7 @@ mod tests { } #[test] - fn data_contract_create_check_tx_priority() { + fn data_contract_create_check_tx_priority_first_protocol_version() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -739,6 +883,7 @@ mod tests { let platform = TestPlatformBuilder::new() .with_config(platform_config) + .with_initial_protocol_version(1) .build_with_mock_rpc(); let platform_state = platform.state.load(); @@ -882,7 +1027,7 @@ mod tests { } #[test] - fn data_contract_create_check_tx_after_identity_balance_used_up() { + fn data_contract_create_check_tx_priority_latest_protocol_version() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -923,7 +1068,7 @@ mod tests { 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, ]), public_keys: BTreeMap::from([(1, key.clone())]), - balance: 200000000, // we have enough balance only for 1 insertion (this is where this test is different) + balance: 1000000000, revision: 0, } .into(); @@ -932,6 +1077,9 @@ mod tests { let mut create_contract_state_transition: StateTransition = dashpay .try_into_platform_versioned(platform_version) .expect("expected a state transition"); + + create_contract_state_transition.set_user_fee_increase(100); // This means that things will be twice as expensive + create_contract_state_transition .sign(&key, private_key.as_slice(), &NativeBlsModule) .expect("expected to sign transition"); @@ -961,6 +1109,8 @@ mod tests { assert!(validation_result.errors.is_empty()); + assert_eq!(validation_result.data.unwrap().priority, 10000); + let check_result = platform .check_tx( serialized.as_slice(), @@ -972,9 +1122,11 @@ mod tests { assert!(check_result.is_valid()); + assert_eq!(check_result.data.unwrap().priority, 10000); + let transaction = platform.drive.grove.start_transaction(); - platform + let processing_result = platform .platform .process_raw_state_transitions( &vec![serialized.clone()], @@ -987,6 +1139,10 @@ mod tests { ) .expect("expected to process state transition"); + // The processing fees should be twice as much as a fee multiplier of 0, + // since a fee multiplier of 100 means 100% more of 1 (gives 2) + assert_eq!(processing_result.aggregated_fees().processing_fee, 4968820); + let check_result = platform .check_tx( serialized.as_slice(), @@ -998,6 +1154,8 @@ mod tests { assert!(check_result.is_valid()); // it should still be valid, because we didn't commit the transaction + assert_eq!(check_result.data.unwrap().priority, 10000); + platform .drive .grove @@ -1014,11 +1172,16 @@ mod tests { ) .expect("expected to check tx"); - assert!(!check_result.is_valid()); // the identity shouldn't have enough balance anymore + assert!(!check_result.is_valid()); // it should no longer be valid, because of the nonce check + + assert!(matches!( + check_result.errors.first().expect("expected an error"), + ConsensusError::StateError(StateError::InvalidIdentityNonceError(_)) + )); } #[test] - fn data_contract_update_check_tx() { + fn data_contract_create_check_tx_after_identity_balance_used_up() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -1059,15 +1222,13 @@ mod tests { 166, 203, 222, 4, 64, 31, 215, 199, 149, 151, 190, 246, 251, 44, ]), public_keys: BTreeMap::from([(1, key.clone())]), - balance: 1000000000, + balance: 200000000, // we have enough balance only for 1 insertion (this is where this test is different) revision: 0, } .into(); - let dashpay_created_contract = - get_dashpay_contract_fixture(Some(identity.id()), 1, protocol_version); - let mut modified_dashpay_contract = dashpay_created_contract.data_contract().clone(); - let mut create_contract_state_transition: StateTransition = dashpay_created_contract + let dashpay = get_dashpay_contract_fixture(Some(identity.id()), 1, protocol_version); + let mut create_contract_state_transition: StateTransition = dashpay .try_into_platform_versioned(platform_version) .expect("expected a state transition"); create_contract_state_transition @@ -1079,7 +1240,7 @@ mod tests { platform .drive .add_new_identity( - identity.clone(), + identity, false, &BlockInfo::default(), true, @@ -1088,68 +1249,9 @@ mod tests { ) .expect("expected to insert identity"); - 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, - false, - None, - ) - .expect("expected to process state transition"); - - assert_eq!(processing_result.aggregated_fees().processing_fee, 2483610); - - platform - .drive - .grove - .commit_transaction(transaction) - .unwrap() - .expect("expected to commit"); - - // Now let's do the data contract update - let _dashpay_id = modified_dashpay_contract.id(); - // we need to alter dashpay to make it invalid - - modified_dashpay_contract.set_version(2); - - let document_types = modified_dashpay_contract.document_types_mut(); - - let dpns_contract = - get_dpns_data_contract_fixture(Some(identity.id()), 1, protocol_version) - .data_contract_owned(); - - document_types.insert( - "preorder".to_string(), - dpns_contract - .document_type_for_name("preorder") - .expect("expected document type") - .to_owned_document_type(), - ); - - let mut update_contract_state_transition: StateTransition = - DataContractUpdateTransition::try_from_platform_versioned( - (modified_dashpay_contract, 2), - platform_version, - ) - .expect("expected a state transition") - .into(); - - update_contract_state_transition - .sign(&key, private_key.as_slice(), &NativeBlsModule) - .expect("expected to sign transition"); - let serialized_update = update_contract_state_transition - .serialize_to_bytes() - .expect("serialized state transition"); - let validation_result = platform .check_tx( - serialized_update.as_slice(), + serialized.as_slice(), FirstTimeCheck, &platform_ref, platform_version, @@ -1160,7 +1262,7 @@ mod tests { let check_result = platform .check_tx( - serialized_update.as_slice(), + serialized.as_slice(), Recheck, &platform_ref, platform_version, @@ -1171,10 +1273,10 @@ mod tests { let transaction = platform.drive.grove.start_transaction(); - let update_processing_result = platform + platform .platform .process_raw_state_transitions( - &vec![serialized_update.clone()], + &vec![serialized.clone()], &platform_state, &BlockInfo::default(), &transaction, @@ -1184,17 +1286,9 @@ mod tests { ) .expect("expected to process state transition"); - // We have one invalid paid for state transition - assert_eq!(update_processing_result.valid_count(), 1); - - assert_eq!( - update_processing_result.aggregated_fees().processing_fee, - 2495990 - ); - let check_result = platform .check_tx( - serialized_update.as_slice(), + serialized.as_slice(), Recheck, &platform_ref, platform_version, @@ -1212,14 +1306,430 @@ mod tests { let check_result = platform .check_tx( - serialized_update.as_slice(), + serialized.as_slice(), Recheck, &platform_ref, platform_version, ) .expect("expected to check tx"); - assert!(!check_result.is_valid()); // it should no longer be valid, because of the nonce check + assert!(!check_result.is_valid()); // the identity shouldn't have enough balance anymore + } + + #[test] + fn data_contract_update_check_tx_first_protocol_version() { + let platform_config = PlatformConfig { + testing_configs: PlatformTestConfig { + disable_instant_lock_signature_verification: true, + ..Default::default() + }, + ..Default::default() + }; + + let platform = TestPlatformBuilder::new() + .with_config(platform_config) + .with_initial_protocol_version(1) + .build_with_mock_rpc(); + + 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 platform_ref = PlatformRef { + drive: &platform.drive, + state: &platform_state, + config: &platform.config, + core_rpc: &platform.core_rpc, + }; + + 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 dashpay_created_contract = + get_dashpay_contract_fixture(Some(identity.id()), 1, protocol_version); + let mut modified_dashpay_contract = dashpay_created_contract.data_contract().clone(); + let mut create_contract_state_transition: StateTransition = dashpay_created_contract + .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.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert identity"); + + 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, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 2483610); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + // Now let's do the data contract update + let _dashpay_id = modified_dashpay_contract.id(); + // we need to alter dashpay to make it invalid + + modified_dashpay_contract.set_version(2); + + let document_types = modified_dashpay_contract.document_types_mut(); + + let dpns_contract = + get_dpns_data_contract_fixture(Some(identity.id()), 1, protocol_version) + .data_contract_owned(); + + document_types.insert( + "preorder".to_string(), + dpns_contract + .document_type_for_name("preorder") + .expect("expected document type") + .to_owned_document_type(), + ); + + let mut update_contract_state_transition: StateTransition = + DataContractUpdateTransition::try_from_platform_versioned( + (modified_dashpay_contract, 2), + platform_version, + ) + .expect("expected a state transition") + .into(); + + update_contract_state_transition + .sign(&key, private_key.as_slice(), &NativeBlsModule) + .expect("expected to sign transition"); + let serialized_update = update_contract_state_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let validation_result = platform + .check_tx( + serialized_update.as_slice(), + FirstTimeCheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(validation_result.errors.is_empty()); + + let check_result = platform + .check_tx( + serialized_update.as_slice(), + Recheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(check_result.is_valid()); + + let transaction = platform.drive.grove.start_transaction(); + + let update_processing_result = platform + .platform + .process_raw_state_transitions( + &vec![serialized_update.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + // We have one invalid paid for state transition + assert_eq!(update_processing_result.valid_count(), 1); + + assert_eq!( + update_processing_result.aggregated_fees().processing_fee, + 2495990 + ); + + let check_result = platform + .check_tx( + serialized_update.as_slice(), + Recheck, + &platform_ref, + 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_update.as_slice(), + Recheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(!check_result.is_valid()); // it should no longer be valid, because of the nonce check + + assert!(matches!( + check_result.errors.first().expect("expected an error"), + ConsensusError::StateError(StateError::InvalidIdentityNonceError(_)) + )); + } + + #[test] + fn data_contract_update_check_tx_latest_protocol_version() { + let platform_config = PlatformConfig { + testing_configs: PlatformTestConfig { + disable_instant_lock_signature_verification: true, + ..Default::default() + }, + ..Default::default() + }; + + let platform = TestPlatformBuilder::new() + .with_config(platform_config) + .build_with_mock_rpc(); + + 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 platform_ref = PlatformRef { + drive: &platform.drive, + state: &platform_state, + config: &platform.config, + core_rpc: &platform.core_rpc, + }; + + 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 dashpay_created_contract = + get_dashpay_contract_fixture(Some(identity.id()), 1, protocol_version); + let mut modified_dashpay_contract = dashpay_created_contract.data_contract().clone(); + let mut create_contract_state_transition: StateTransition = dashpay_created_contract + .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.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert identity"); + + 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, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 2484410); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + // Now let's do the data contract update + let _dashpay_id = modified_dashpay_contract.id(); + // we need to alter dashpay to make it invalid + + modified_dashpay_contract.set_version(2); + + let document_types = modified_dashpay_contract.document_types_mut(); + + let dpns_contract = + get_dpns_data_contract_fixture(Some(identity.id()), 1, protocol_version) + .data_contract_owned(); + + document_types.insert( + "preorder".to_string(), + dpns_contract + .document_type_for_name("preorder") + .expect("expected document type") + .to_owned_document_type(), + ); + + let mut update_contract_state_transition: StateTransition = + DataContractUpdateTransition::try_from_platform_versioned( + (modified_dashpay_contract, 2), + platform_version, + ) + .expect("expected a state transition") + .into(); + + update_contract_state_transition + .sign(&key, private_key.as_slice(), &NativeBlsModule) + .expect("expected to sign transition"); + let serialized_update = update_contract_state_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let validation_result = platform + .check_tx( + serialized_update.as_slice(), + FirstTimeCheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(validation_result.errors.is_empty()); + + let check_result = platform + .check_tx( + serialized_update.as_slice(), + Recheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(check_result.is_valid()); + + let transaction = platform.drive.grove.start_transaction(); + + let update_processing_result = platform + .platform + .process_raw_state_transitions( + &vec![serialized_update.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + // We have one invalid paid for state transition + assert_eq!(update_processing_result.valid_count(), 1); + + assert_eq!( + update_processing_result.aggregated_fees().processing_fee, + 2496910 + ); + + let check_result = platform + .check_tx( + serialized_update.as_slice(), + Recheck, + &platform_ref, + 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_update.as_slice(), + Recheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(!check_result.is_valid()); // it should no longer be valid, because of the nonce check assert!(matches!( check_result.errors.first().expect("expected an error"), @@ -1228,7 +1738,7 @@ mod tests { } #[test] - fn data_contract_update_check_tx_for_invalid_update() { + fn data_contract_update_check_tx_for_invalid_update_first_protocol_version() { let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -1239,6 +1749,7 @@ mod tests { let platform = TestPlatformBuilder::new() .with_config(platform_config) + .with_initial_protocol_version(1) .build_with_mock_rpc(); let platform_state = platform.state.load(); @@ -1472,6 +1983,251 @@ mod tests { )); } + #[test] + fn data_contract_update_check_tx_for_invalid_update_latest_protocol_version() { + let platform_config = PlatformConfig { + testing_configs: PlatformTestConfig { + disable_instant_lock_signature_verification: true, + ..Default::default() + }, + ..Default::default() + }; + + let platform = TestPlatformBuilder::new() + .with_config(platform_config) + .build_with_mock_rpc(); + + 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 platform_ref = PlatformRef { + drive: &platform.drive, + state: &platform_state, + config: &platform.config, + core_rpc: &platform.core_rpc, + }; + + 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 dashpay_created_contract = + get_dashpay_contract_fixture(Some(identity.id()), 1, protocol_version); + let mut modified_dashpay_contract = dashpay_created_contract.data_contract().clone(); + let mut create_contract_state_transition: StateTransition = dashpay_created_contract + .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 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, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 2484410); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + // Now let's do the data contract update + let dashpay_id = modified_dashpay_contract.id(); + // we need to alter dashpay to make it invalid + + let document_types = modified_dashpay_contract.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, + documents_can_be_deleted_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 update_contract_state_transition: StateTransition = + DataContractUpdateTransition::try_from_platform_versioned( + (modified_dashpay_contract, 2), + platform_version, + ) + .expect("expected a state transition") + .into(); + + update_contract_state_transition + .sign(&key, private_key.as_slice(), &NativeBlsModule) + .expect("expected to sign transition"); + let serialized_update = update_contract_state_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let validation_result = platform + .check_tx( + serialized_update.as_slice(), + FirstTimeCheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(validation_result.errors.is_empty()); + + let check_result = platform + .check_tx( + serialized_update.as_slice(), + Recheck, + &platform_ref, + 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_update.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .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, 448640); + + let check_result = platform + .check_tx( + serialized_update.as_slice(), + Recheck, + &platform_ref, + 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_update.as_slice(), + Recheck, + &platform_ref, + platform_version, + ) + .expect("expected to check tx"); + + assert!(!check_result.is_valid()); // it should no longer be valid, because of the nonce check + + assert!(matches!( + check_result.errors.first().expect("expected an error"), + ConsensusError::StateError(StateError::InvalidIdentityNonceError(_)) + )); + } + #[test] fn document_update_check_tx() { let platform_config = PlatformConfig { diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs b/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs index 14e8e69fdea..a224d4ee33c 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs @@ -272,6 +272,7 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None, ); let profile = dashpay_contract_no_indexes @@ -368,6 +369,7 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None, ); let profile = dashpay_contract_no_indexes @@ -467,6 +469,7 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None, ); let profile = dashpay_contract_no_indexes @@ -562,6 +565,7 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None, ); let profile = dashpay_contract_no_indexes @@ -657,6 +661,7 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None, ); let profile = dashpay_contract_no_indexes @@ -753,6 +758,7 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None, ); let profile = dashpay_contract_no_indexes diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs index 1d336206084..695ba8ce384 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs @@ -11,12 +11,11 @@ use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_Base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; use drive::error::drive::DriveError; use drive::query::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs index b403cc05888..22fed53d193 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs @@ -15,6 +15,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; pub(super) trait TokenBurnTransitionActionStructureValidationV0 { fn validate_structure_v0( @@ -27,7 +28,7 @@ impl TokenBurnTransitionActionStructureValidationV0 for TokenBurnTransitionActio &self, platform_version: &PlatformVersion, ) -> Result { - self.base().validate_structure(); + self.base().validate_structure(platform_version)?; let token_configuration = self.base().token_configuration()?; Ok(SimpleConsensusValidationResult::default()) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index c385978606c..33599f2fd68 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -1,8 +1,9 @@ use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction, TokenTransferTransitionActionAccessors}; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use dpp::version::PlatformVersion; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; pub(super) trait TokenTransferTransitionActionStructureValidationV0 { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs index f1e68a7c904..418710d0e4b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs @@ -29,7 +29,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionActionAccessors; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use drive::state_transition_action::StateTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::execution::ExecutionError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs index eb030fe8c49..2002e18f3d4 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs @@ -112,6 +112,7 @@ mod test { use crate::test::helpers::setup::TestPlatformBuilder; use super::*; use dpp::errors::consensus::state::data_trigger::DataTriggerError; + use dpp::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; use dpp::tests::fixtures::{get_contact_request_document_fixture, get_dashpay_contract_fixture, get_batched_transitions_fixture, get_identity_fixture}; use dpp::version::DefaultForPlatformVersion; use drive::drive::contract::DataContractFetchInfo; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs index 603c492db0e..8c59ca10e71 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs @@ -380,6 +380,7 @@ mod test { use crate::platform_types::platform_state::v0::PlatformStateV0Methods; use crate::test::helpers::setup::TestPlatformBuilder; use super::*; + use dpp::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; #[test] fn should_return_execution_result_on_dry_run() { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index 3b9713e2ae5..80503cd3461 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -567,6 +567,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-max-length.json", None, None, + None, ); let dashpay_contract = dashpay_contract_no_max_length.clone(); @@ -8391,6 +8392,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, + None, ); let card_game = setup_contract( @@ -8398,6 +8400,7 @@ mod tests { "tests/supporting_files/contract/crypto-card-game/crypto-card-game-direct-purchase.json", None, None, + None, ); let dpns_contract = setup_contract( @@ -8405,6 +8408,7 @@ mod tests { "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index-with-contract-id.json", None, None, + None, ); let preorder = dpns_contract @@ -8840,6 +8844,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, + None, ); let card_game = setup_contract( @@ -8847,6 +8852,7 @@ mod tests { "tests/supporting_files/contract/crypto-card-game/crypto-card-game-direct-purchase.json", None, None, + None, ); let dpns_contract = setup_contract( @@ -8854,6 +8860,7 @@ mod tests { "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index-with-contract-id-null-searchable-true.json", None, None, + None, ); let preorder = dpns_contract diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index 07aca1c1a5b..51ee7602ccf 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -100,18 +100,25 @@ trait BatchTransitionInternalTransformerV0 { fn transform_token_transitions_within_contract_v0( platform: &PlatformStateRef, data_contract_id: &Identifier, + block_info: &BlockInfo, validate_against_state: bool, + owner_id: Identifier, token_transitions: &Vec<&TokenTransition>, transaction: TransactionArg, + execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, ) -> Result>, Error>; /// Transfer token transition fn transform_token_transition_v0( drive: &Drive, transaction: TransactionArg, - full_validation: bool, + block_info: &BlockInfo, + validate_against_state: bool, data_contract_fetch_info: Arc, transition: &TokenTransition, + owner_id: Identifier, + execution_context: &mut StateTransitionExecutionContext, + platform_version: &PlatformVersion, ) -> Result, Error>; /// The data contract can be of multiple difference versions fn transform_document_transition_v0( @@ -203,7 +210,7 @@ impl BatchTransitionTransformerV0 for BatchTransition { } } - let validation_result = document_transitions_by_contracts_and_types + let validation_result_documents = document_transitions_by_contracts_and_types .iter() .map( |(data_contract_id, document_transitions_by_document_type)| { @@ -220,21 +227,32 @@ impl BatchTransitionTransformerV0 for BatchTransition { ) }, ) - .chain(token_transitions_by_contracts.iter().map( - |(data_contract_id, token_transitions)| { - Self::transform_token_transitions_within_contract_v0( - platform, - data_contract_id, - validate_against_state, - token_transitions, - transaction, - platform_version, - ) - }, - )) .collect::>>, Error>>( )?; - let validation_result = ConsensusValidationResult::flatten(validation_result); + + let mut validation_result_tokens = token_transitions_by_contracts + .iter() + .map(|(data_contract_id, token_transitions)| { + Self::transform_token_transitions_within_contract_v0( + platform, + data_contract_id, + block_info, + validate_against_state, + owner_id, + token_transitions, + transaction, + execution_context, + platform_version, + ) + }) + .collect::>>, Error>>( + )?; + + let mut validation_results = validation_result_documents; + + validation_results.append(&mut validation_result_tokens); + + let validation_result = ConsensusValidationResult::flatten(validation_results); if validation_result.has_data() { let (transitions, errors) = validation_result.into_data_and_errors()?; @@ -260,9 +278,12 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { fn transform_token_transitions_within_contract_v0( platform: &PlatformStateRef, data_contract_id: &Identifier, + block_info: &BlockInfo, validate_against_state: bool, + owner_id: Identifier, token_transitions: &Vec<&TokenTransition>, transaction: TransactionArg, + execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, ) -> Result>, Error> { let drive = platform.drive; @@ -291,9 +312,13 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { Self::transform_token_transition_v0( platform.drive, transaction, + block_info, validate_against_state, data_contract_fetch_info.clone(), token_transition, + owner_id, + execution_context, + platform_version, ) }) .collect::>, Error>>()?; @@ -458,55 +483,54 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { fn transform_token_transition_v0( drive: &Drive, transaction: TransactionArg, + block_info: &BlockInfo, validate_against_state: bool, data_contract_fetch_info: Arc, transition: &TokenTransition, + owner_id: Identifier, + execution_context: &mut StateTransitionExecutionContext, + platform_version: &PlatformVersion, ) -> Result, Error> { + let approximate_for_costs = !validate_against_state; match transition { TokenTransition::Burn(token_burn_transition) => { - let result = ConsensusValidationResult::::new(); - let token_burn_action = TokenBurnTransitionAction::try_from_borrowed_token_burn_transition_with_contract_lookup(drive, transaction, token_burn_transition, |_identifier| { + let (token_burn_action, fee_result) = TokenBurnTransitionAction::try_from_borrowed_token_burn_transition_with_contract_lookup(drive, owner_id, token_burn_transition, approximate_for_costs, transaction, block_info, |_identifier| { Ok(data_contract_fetch_info.clone()) - })?; + }, platform_version)?; - if result.is_valid() { - let batched_action = BatchedTransitionAction::TokenAction( - TokenTransitionAction::BurnAction(token_burn_action), - ); - Ok(batched_action.into()) - } else { - Ok(result) - } + execution_context + .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + let batched_action = BatchedTransitionAction::TokenAction( + TokenTransitionAction::BurnAction(token_burn_action), + ); + Ok(batched_action.into()) } TokenTransition::Mint(token_mint_transition) => { - let result = ConsensusValidationResult::::new(); - let token_mint_action = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(drive, transaction, token_mint_transition, |_identifier| { + let (token_mint_action, fee_result) = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(drive, owner_id, token_mint_transition, approximate_for_costs, transaction, block_info, |_identifier| { Ok(data_contract_fetch_info.clone()) - })?; + }, platform_version)?; - if result.is_valid() { - let batched_action = BatchedTransitionAction::TokenAction( - TokenTransitionAction::MintAction(token_mint_action), - ); - Ok(batched_action.into()) - } else { - Ok(result) - } + execution_context + .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + let batched_action = BatchedTransitionAction::TokenAction( + TokenTransitionAction::MintAction(token_mint_action), + ); + Ok(batched_action.into()) } TokenTransition::Transfer(token_transfer_transition) => { - let result = ConsensusValidationResult::::new(); - let token_transfer_action = TokenTransferTransitionAction::try_from_borrowed_token_transfer_transition_with_contract_lookup(drive, transaction, token_transfer_transition, |_identifier| { + let (token_transfer_action, fee_result) = TokenTransferTransitionAction::try_from_borrowed_token_transfer_transition_with_contract_lookup(drive, owner_id, token_transfer_transition, approximate_for_costs, transaction, block_info, |_identifier| { Ok(data_contract_fetch_info.clone()) - })?; + }, platform_version)?; - if result.is_valid() { - let batched_action = BatchedTransitionAction::TokenAction( - TokenTransitionAction::TransferAction(token_transfer_action), - ); - Ok(batched_action.into()) - } else { - Ok(result) - } + execution_context + .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + let batched_action = BatchedTransitionAction::TokenAction( + TokenTransitionAction::TransferAction(token_transfer_action), + ); + Ok(batched_action.into()) } } } @@ -526,8 +550,6 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { ) -> Result, Error> { match transition { DocumentTransition::Create(document_create_transition) => { - let result = ConsensusValidationResult::::new(); - let (document_create_action, fee_result) = DocumentCreateTransitionAction::try_from_document_borrowed_create_transition_with_contract_lookup( drive, transaction, document_create_transition, block_info, |_identifier| { @@ -537,14 +559,10 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { execution_context .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); - if result.is_valid() { - let batched_action = BatchedTransitionAction::DocumentAction( - DocumentTransitionAction::CreateAction(document_create_action), - ); - Ok(batched_action.into()) - } else { - Ok(result) - } + let batched_action = BatchedTransitionAction::DocumentAction( + DocumentTransitionAction::CreateAction(document_create_action), + ); + Ok(batched_action.into()) } DocumentTransition::Replace(document_replace_transition) => { let mut result = ConsensusValidationResult::::new(); 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 27c7a5ce4ed..3385fd125d8 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 @@ -161,8 +161,8 @@ mod tests { use super::*; #[test] - fn should_return_invalid_result_when_transform_into_action_failed() { - let platform_version = PlatformVersion::latest(); + fn should_return_invalid_result_when_transform_into_action_failed_v7() { + let platform_version = PlatformVersion::get(7).expect("expected version 7"); let identity_nonce = IdentityNonce::default(); let platform = TestPlatformBuilder::new() @@ -193,7 +193,103 @@ mod tests { // Make the contract invalid let DataContractInSerializationFormat::V0(ref mut contract) = - data_contract_for_serialization; + data_contract_for_serialization + else { + panic!("expected serialization version 0") + }; + + contract + .document_schemas + .insert("invalidType".to_string(), Value::Null); + + let transition: DataContractCreateTransition = DataContractCreateTransitionV0 { + data_contract: data_contract_for_serialization, + identity_nonce, + user_fee_increase: 0, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + + let mut execution_context = + StateTransitionExecutionContext::default_for_platform_version(platform_version) + .expect("failed to create execution context"); + + let state = platform.state.load_full(); + + let platform_ref = PlatformRef { + drive: &platform.drive, + state: &state, + config: &platform.config, + core_rpc: &platform.core_rpc, + }; + + let result = transition + .validate_state_v0::( + &platform_ref, + ValidationMode::Validator, + &Epoch::default(), + None, + &mut execution_context, + platform_version, + ) + .expect("failed to validate advanced structure"); + + assert_matches!( + result.errors.as_slice(), + [ConsensusError::BasicError( + BasicError::ContractError( + DataContractError::InvalidContractStructure(message) + ) + )] if message == "document schema must be an object: structure error: value is not a map" + ); + + assert_matches!( + result.data, + Some(StateTransitionAction::BumpIdentityNonceAction(action)) if action.identity_id() == identity_id && action.identity_nonce() == identity_nonce + ); + + // We have tons of operations here so not sure we want to assert all of them + assert!(!execution_context.operations_slice().is_empty()); + } + + #[test] + fn should_return_invalid_result_when_transform_into_action_failed_latest() { + let platform_version = PlatformVersion::latest(); + let identity_nonce = IdentityNonce::default(); + + let platform = TestPlatformBuilder::new() + .build_with_mock_rpc() + .set_genesis_state(); + + let data_contract = + get_data_contract_fixture(None, identity_nonce, platform_version.protocol_version) + .data_contract_owned(); + + let identity_id = data_contract.owner_id(); + + platform + .drive + .apply_contract( + &data_contract, + BlockInfo::default(), + true, + None, + None, + platform_version, + ) + .expect("failed to apply contract"); + + let mut data_contract_for_serialization = data_contract + .try_into_platform_versioned(platform_version) + .expect("failed to convert data contract"); + + // Make the contract invalid + let DataContractInSerializationFormat::V1(ref mut contract) = + data_contract_for_serialization + else { + panic!("expected serialization version 1") + }; contract .document_schemas @@ -413,8 +509,11 @@ mod tests { .expect("failed to convert data contract"); // Make the contract invalid - let DataContractInSerializationFormat::V0(ref mut contract) = - data_contract_for_serialization; + let DataContractInSerializationFormat::V1(ref mut contract) = + data_contract_for_serialization + else { + panic!("expected serialization version 1") + }; contract .document_schemas diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs index ef81c1a3650..5435c8ad18d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs @@ -231,8 +231,11 @@ mod tests { .expect("failed to convert data contract"); // Make the contract invalid - let DataContractInSerializationFormat::V0(ref mut contract) = - data_contract_for_serialization; + let DataContractInSerializationFormat::V1(ref mut contract) = + data_contract_for_serialization + else { + panic!("expected serialization version 1") + }; contract .document_schemas @@ -553,8 +556,11 @@ mod tests { .expect("failed to convert data contract"); // Make the contract invalid - let DataContractInSerializationFormat::V0(ref mut contract) = - data_contract_for_serialization; + let DataContractInSerializationFormat::V1(ref mut contract) = + data_contract_for_serialization + else { + panic!("expected serialization version 1") + }; contract .document_schemas 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 1e0d8bf4b00..12b36b9479a 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 @@ -215,7 +215,121 @@ mod tests { use std::collections::BTreeMap; #[test] - fn test_identity_create_validation() { + fn test_identity_create_validation_first_protocol_version() { + let platform_version = PlatformVersion::first(); + let platform_config = PlatformConfig { + testing_configs: PlatformTestConfig { + disable_instant_lock_signature_verification: true, + ..Default::default() + }, + ..Default::default() + }; + + let platform = TestPlatformBuilder::new() + .with_config(platform_config) + .with_initial_protocol_version(1) + .build_with_mock_rpc() + .set_initial_state_structure(); + + let platform_state = platform.state.load(); + + let mut signer = SimpleSigner::default(); + + let mut rng = StdRng::seed_from_u64(567); + + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key( + 0, + Some(58), + platform_version, + ) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + + let (key, private_key) = IdentityPublicKey::random_ecdsa_critical_level_authentication_key( + 1, + Some(999), + platform_version, + ) + .expect("expected to get key pair"); + + signer.add_key(key.clone(), private_key.clone()); + + let (_, pk) = ECDSA_SECP256K1 + .random_public_and_private_key_data(&mut rng, platform_version) + .unwrap(); + + let asset_lock_proof = instant_asset_lock_proof_fixture( + Some(PrivateKey::from_slice(pk.as_slice(), Network::Testnet).unwrap()), + None, + ); + + let identifier = asset_lock_proof + .create_identifier() + .expect("expected an identifier"); + + let identity: Identity = IdentityV0 { + id: identifier, + public_keys: BTreeMap::from([(0, master_key.clone()), (1, key.clone())]), + balance: 1000000000, + revision: 0, + } + .into(); + + let identity_create_transition: StateTransition = + IdentityCreateTransition::try_from_identity_with_signer( + &identity, + asset_lock_proof, + pk.as_slice(), + &signer, + &NativeBlsModule, + 0, + platform_version, + ) + .expect("expected an identity create transition"); + + let identity_create_serialized_transition = identity_create_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![identity_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.valid_count(), 1); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 1871240); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + let identity_balance = platform + .drive + .fetch_identity_balance(identity.id().into_buffer(), None, platform_version) + .expect("expected to get identity balance") + .expect("expected there to be an identity balance for this identity"); + + assert_eq!(identity_balance, 99913915760); + } + + #[test] + fn test_identity_create_validation_latest_protocol_version() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -309,7 +423,230 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 1871240); + assert_eq!(processing_result.aggregated_fees().processing_fee, 1913060); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + let identity_balance = platform + .drive + .fetch_identity_balance(identity.id().into_buffer(), None, platform_version) + .expect("expected to get identity balance") + .expect("expected there to be an identity balance for this identity"); + + assert_eq!(identity_balance, 99913873940); + } + + #[test] + fn test_identity_create_asset_lock_reuse_after_issue_first_protocol_version() { + let platform_version = PlatformVersion::first(); + let platform_config = PlatformConfig { + testing_configs: PlatformTestConfig { + disable_instant_lock_signature_verification: true, + ..Default::default() + }, + ..Default::default() + }; + + let platform = TestPlatformBuilder::new() + .with_config(platform_config) + .with_initial_protocol_version(1) + .build_with_mock_rpc() + .set_initial_state_structure(); + + let platform_state = platform.state.load(); + + let mut signer = SimpleSigner::default(); + + let mut rng = StdRng::seed_from_u64(567); + + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key( + 0, + Some(58), + platform_version, + ) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + + let (critical_public_key_that_is_already_in_system, private_key) = + IdentityPublicKey::random_ecdsa_critical_level_authentication_key( + 1, + Some(999), + platform_version, + ) + .expect("expected to get key pair"); + + // Let's start by adding this critical key to another identity + + let (another_master_key, _) = IdentityPublicKey::random_ecdsa_master_authentication_key( + 0, + Some(53), + platform_version, + ) + .expect("expected to get key pair"); + + let identity_already_in_system: Identity = IdentityV0 { + id: Identifier::random_with_rng(&mut rng), + public_keys: BTreeMap::from([ + (0, another_master_key.clone()), + (1, critical_public_key_that_is_already_in_system.clone()), + ]), + balance: 100000, + revision: 0, + } + .into(); + + // We just add this identity to the system first + + platform + .drive + .add_new_identity( + identity_already_in_system, + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add a new identity"); + + signer.add_key( + critical_public_key_that_is_already_in_system.clone(), + private_key.clone(), + ); + + let (_, pk) = ECDSA_SECP256K1 + .random_public_and_private_key_data(&mut rng, platform_version) + .unwrap(); + + let asset_lock_proof = instant_asset_lock_proof_fixture( + Some(PrivateKey::from_slice(pk.as_slice(), Network::Testnet).unwrap()), + None, + ); + + let identifier = asset_lock_proof + .create_identifier() + .expect("expected an identifier"); + + let mut identity: Identity = IdentityV0 { + id: identifier, + public_keys: BTreeMap::from([ + (0, master_key.clone()), + (1, critical_public_key_that_is_already_in_system.clone()), + ]), + balance: 1000000000, + revision: 0, + } + .into(); + + let identity_create_transition: StateTransition = + IdentityCreateTransition::try_from_identity_with_signer( + &identity, + asset_lock_proof.clone(), + pk.as_slice(), + &signer, + &NativeBlsModule, + 0, + platform_version, + ) + .expect("expected an identity create transition"); + + let identity_create_serialized_transition = identity_create_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![identity_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.invalid_paid_count(), 1); + + assert_eq!(processing_result.invalid_unpaid_count(), 0); + + assert_eq!(processing_result.valid_count(), 0); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 10080700); // 10000000 penalty + 80700 processing + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + // Okay now let us try to reuse the asset lock + + let (new_public_key, new_private_key) = + IdentityPublicKey::random_ecdsa_critical_level_authentication_key( + 1, + Some(13), + platform_version, + ) + .expect("expected to get key pair"); + + signer.add_key(new_public_key.clone(), new_private_key.clone()); + + // let's set the new key to the identity (replacing the one that was causing the issue + identity.set_public_keys(BTreeMap::from([ + (0, master_key.clone()), + (1, new_public_key.clone()), + ])); + + let identity_create_transition: StateTransition = + IdentityCreateTransition::try_from_identity_with_signer( + &identity, + asset_lock_proof, + pk.as_slice(), + &signer, + &NativeBlsModule, + 0, + platform_version, + ) + .expect("expected an identity create transition"); + + let identity_create_serialized_transition = identity_create_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![identity_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.invalid_paid_count(), 0); + + assert_eq!(processing_result.invalid_unpaid_count(), 0); + + assert_eq!(processing_result.valid_count(), 1); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 2146900); platform .drive @@ -324,11 +661,11 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 99913915760); + assert_eq!(identity_balance, 99909310400); // The identity balance is smaller than if there hadn't been any issue } #[test] - fn test_identity_create_asset_lock_reuse_after_issue() { + fn test_identity_create_asset_lock_reuse_after_issue_latest_protocol_version() { let platform_version = PlatformVersion::latest(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { @@ -531,7 +868,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 2146900); + assert_eq!(processing_result.aggregated_fees().processing_fee, 2188720); platform .drive @@ -546,7 +883,7 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 99909310400); // The identity balance is smaller than if there hadn't been any issue + assert_eq!(identity_balance, 99909268580); // The identity balance is smaller than if there hadn't been any issue } #[test] @@ -1007,8 +1344,8 @@ mod tests { } #[test] - fn test_identity_create_asset_lock_replay_attack() { - let platform_version = PlatformVersion::latest(); + fn test_identity_create_asset_lock_replay_attack_first_protocol_version() { + let platform_version = PlatformVersion::first(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -1019,6 +1356,7 @@ mod tests { let platform = TestPlatformBuilder::new() .with_config(platform_config) + .with_initial_protocol_version(1) .build_with_mock_rpc() .set_initial_state_structure(); @@ -1252,4 +1590,251 @@ mod tests { assert_eq!(identity_balance, 99909310400); // The identity balance is smaller than if there hadn't been any issue } + + #[test] + fn test_identity_create_asset_lock_replay_attack_latest_protocol_version() { + let platform_version = PlatformVersion::latest(); + let platform_config = PlatformConfig { + testing_configs: PlatformTestConfig { + disable_instant_lock_signature_verification: true, + ..Default::default() + }, + ..Default::default() + }; + + let platform = TestPlatformBuilder::new() + .with_config(platform_config) + .build_with_mock_rpc() + .set_initial_state_structure(); + + let platform_state = platform.state.load(); + + let mut signer = SimpleSigner::default(); + + let mut rng = StdRng::seed_from_u64(567); + + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key( + 0, + Some(58), + platform_version, + ) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + + let (critical_public_key_that_is_already_in_system, private_key) = + IdentityPublicKey::random_ecdsa_critical_level_authentication_key( + 1, + Some(999), + platform_version, + ) + .expect("expected to get key pair"); + + // Let's start by adding this critical key to another identity + + let (another_master_key, _) = IdentityPublicKey::random_ecdsa_master_authentication_key( + 0, + Some(53), + platform_version, + ) + .expect("expected to get key pair"); + + let identity_already_in_system: Identity = IdentityV0 { + id: Identifier::random_with_rng(&mut rng), + public_keys: BTreeMap::from([ + (0, another_master_key.clone()), + (1, critical_public_key_that_is_already_in_system.clone()), + ]), + balance: 100000, + revision: 0, + } + .into(); + + // We just add this identity to the system first + + platform + .drive + .add_new_identity( + identity_already_in_system, + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add a new identity"); + + signer.add_key( + critical_public_key_that_is_already_in_system.clone(), + private_key.clone(), + ); + + let (_, pk) = ECDSA_SECP256K1 + .random_public_and_private_key_data(&mut rng, platform_version) + .unwrap(); + + let asset_lock_proof = instant_asset_lock_proof_fixture( + Some(PrivateKey::from_slice(pk.as_slice(), Network::Testnet).unwrap()), + None, + ); + + let identifier = asset_lock_proof + .create_identifier() + .expect("expected an identifier"); + + let mut identity: Identity = IdentityV0 { + id: identifier, + public_keys: BTreeMap::from([ + (0, master_key.clone()), + (1, critical_public_key_that_is_already_in_system.clone()), + ]), + balance: 1000000000, + revision: 0, + } + .into(); + + let identity_create_transition: StateTransition = + IdentityCreateTransition::try_from_identity_with_signer( + &identity, + asset_lock_proof.clone(), + pk.as_slice(), + &signer, + &NativeBlsModule, + 0, + platform_version, + ) + .expect("expected an identity create transition"); + + let identity_create_serialized_transition = identity_create_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![identity_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.invalid_paid_count(), 1); + + assert_eq!(processing_result.invalid_unpaid_count(), 0); + + assert_eq!(processing_result.valid_count(), 0); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 10080700); // 10000000 penalty + 80700 processing + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + // let's try to replay the bad transaction + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![identity_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.invalid_paid_count(), 0); + + assert_eq!(processing_result.invalid_unpaid_count(), 1); + + assert_eq!(processing_result.valid_count(), 0); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 0); + + // Okay now let us try to reuse the asset lock + + let (new_public_key, new_private_key) = + IdentityPublicKey::random_ecdsa_critical_level_authentication_key( + 1, + Some(13), + platform_version, + ) + .expect("expected to get key pair"); + + signer.add_key(new_public_key.clone(), new_private_key.clone()); + + // let's set the new key to the identity (replacing the one that was causing the issue + identity.set_public_keys(BTreeMap::from([ + (0, master_key.clone()), + (1, new_public_key.clone()), + ])); + + let identity_create_transition: StateTransition = + IdentityCreateTransition::try_from_identity_with_signer( + &identity, + asset_lock_proof, + pk.as_slice(), + &signer, + &NativeBlsModule, + 0, + platform_version, + ) + .expect("expected an identity create transition"); + + let identity_create_serialized_transition = identity_create_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![identity_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.invalid_paid_count(), 0); + + assert_eq!(processing_result.invalid_unpaid_count(), 0); + + assert_eq!(processing_result.valid_count(), 1); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 2188720); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + let identity_balance = platform + .drive + .fetch_identity_balance(identity.id().into_buffer(), None, platform_version) + .expect("expected to get identity balance") + .expect("expected there to be an identity balance for this identity"); + + assert_eq!(identity_balance, 99909268580); // The identity balance is smaller than if there hadn't been any issue + } } 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 e3fe3482073..eedeea42066 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 @@ -121,8 +121,8 @@ mod tests { use std::collections::BTreeMap; #[test] - fn test_identity_top_up_validation() { - let platform_version = PlatformVersion::latest(); + fn test_identity_top_up_validation_first_version() { + let platform_version = PlatformVersion::first(); let platform_config = PlatformConfig { testing_configs: PlatformTestConfig { disable_instant_lock_signature_verification: true, @@ -133,6 +133,7 @@ mod tests { let platform = TestPlatformBuilder::new() .with_config(platform_config) + .with_initial_protocol_version(1) .build_with_mock_rpc() .set_initial_state_structure(); @@ -249,4 +250,134 @@ mod tests { assert_eq!(identity_balance, 149993654420); // about 0.5 Dash starting balance + 1 Dash asset lock top up } + + #[test] + fn test_identity_top_up_validation_latest_version() { + let platform_version = PlatformVersion::latest(); + let platform_config = PlatformConfig { + testing_configs: PlatformTestConfig { + disable_instant_lock_signature_verification: true, + ..Default::default() + }, + ..Default::default() + }; + + let platform = TestPlatformBuilder::new() + .with_config(platform_config) + .build_with_mock_rpc() + .set_initial_state_structure(); + + let platform_state = platform.state.load(); + + let mut signer = SimpleSigner::default(); + + let mut rng = StdRng::seed_from_u64(567); + + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key( + 0, + Some(58), + platform_version, + ) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + + let (critical_public_key, private_key) = + IdentityPublicKey::random_ecdsa_critical_level_authentication_key( + 1, + Some(999), + platform_version, + ) + .expect("expected to get key pair"); + + let identity_already_in_system: Identity = IdentityV0 { + id: Identifier::random_with_rng(&mut rng), + public_keys: BTreeMap::from([ + (0, master_key.clone()), + (1, critical_public_key.clone()), + ]), + balance: 50000000000, + revision: 0, + } + .into(); + + // We just add this identity to the system first + + platform + .drive + .add_new_identity( + identity_already_in_system.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add a new identity"); + + signer.add_key(critical_public_key.clone(), private_key.clone()); + + let (_, pk) = ECDSA_SECP256K1 + .random_public_and_private_key_data(&mut rng, platform_version) + .unwrap(); + + let asset_lock_proof = instant_asset_lock_proof_fixture( + Some(PrivateKey::from_slice(pk.as_slice(), Network::Testnet).unwrap()), + None, + ); + + let identity_top_up_transition: StateTransition = + IdentityTopUpTransition::try_from_identity( + &identity_already_in_system, + asset_lock_proof, + pk.as_slice(), + 0, + platform_version, + None, + ) + .expect("expected an identity create transition"); + + let identity_top_up_serialized_transition = identity_top_up_transition + .serialize_to_bytes() + .expect("serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![identity_top_up_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_eq!(processing_result.valid_count(), 1); + + assert_eq!(processing_result.aggregated_fees().processing_fee, 582400); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit"); + + let identity_balance = platform + .drive + .fetch_identity_balance( + identity_already_in_system.id().into_buffer(), + None, + platform_version, + ) + .expect("expected to get identity balance") + .expect("expected there to be an identity balance for this identity"); + + assert_eq!(identity_balance, 149993612600); // about 0.5 Dash starting balance + 1 Dash asset lock top up + } } 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 c80e0bd3ea4..4b1e7cfa5a5 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 @@ -894,6 +894,7 @@ pub(in crate::execution) mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, + None, ); let card_game = setup_contract( @@ -901,6 +902,7 @@ pub(in crate::execution) mod tests { "tests/supporting_files/contract/crypto-card-game/crypto-card-game-direct-purchase.json", None, None, + None, ); let (_, _, dpns_contract) = create_dpns_name_contest_on_identities_for_contract_records( @@ -1245,6 +1247,7 @@ pub(in crate::execution) mod tests { "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index-with-contract-id.json", None, None, + None, ); let preorder = dpns_contract diff --git a/packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs b/packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs index a1ce283885a..a18cc263389 100644 --- a/packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs +++ b/packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving.rs @@ -5,11 +5,10 @@ use crate::platform_types::signature_verification_quorum_set::{ Quorums, SignatureVerificationQuorumSetForSaving, SignatureVerificationQuorumSetV0, ThresholdBlsPublicKey, VerificationQuorum, }; +use bincode::{Decode, Encode}; use dashcore_rpc::dashcore::hashes::Hash; use dashcore_rpc::dashcore::QuorumHash; use dashcore_rpc::json::QuorumType; -use dpp::identity::state_transition::asset_lock_proof::Encode; -use dpp::platform_serialization::de::Decode; use dpp::platform_value::Bytes32; #[derive(Debug, Clone, Encode, Decode)] diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index e4e78540512..d326205ac2d 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -462,8 +462,8 @@ mod tests { } #[test] - fn run_chain_one_identity_in_solitude() { - let platform_version = PlatformVersion::latest(); + fn run_chain_one_identity_in_solitude_first_protocol_version() { + let platform_version = PlatformVersion::first(); let strategy = NetworkStrategy { strategy: Strategy { start_contracts: vec![], @@ -508,9 +508,10 @@ mod tests { }; let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) + .with_initial_protocol_version(1) .build_with_mock_rpc(); - let outcome = run_chain_for_strategy(&mut platform, 100, strategy, config, 15, &mut None); + let outcome = run_chain_for_strategy(&mut platform, 2, strategy, config, 15, &mut None); let balance = outcome .abci_app @@ -527,6 +528,84 @@ mod tests { assert_eq!(balance, 99864012200) } + #[test] + fn run_chain_one_identity_in_solitude_latest_protocol_version() { + // This is different because in the root tree we added GroupActions + // DataContract_Documents 64 + // / \ + // Identities 32 Balances 96 + // / \ / \ + // Token_Balances 16 Pools 48 WithdrawalTransactions 80 Votes 112 + // / \ / \ / \ / \ + // NUPKH->I 8 UPKH->I 24 PreFundedSpecializedBalances 40 Masternode Lists 56 (reserved) SpentAssetLockTransactions 72 GroupActions 88 Misc 104 Versions 120 + + // This will cause the costs of insertion of a spent asset lock transition, since group actions now exist we will see a slight difference in processing costs + // This is because WithdrawalTransactions will have a right element in the tree. + + let platform_version = PlatformVersion::latest(); + let strategy = NetworkStrategy { + strategy: Strategy { + start_contracts: vec![], + operations: vec![], + start_identities: StartIdentities::default(), + identity_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() + }, + + identity_contract_nonce_gaps: None, + signer: None, + }, + total_hpmns: 100, + extra_normal_mns: 0, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, + upgrading_info: None, + + proposer_strategy: Default::default(), + rotate_quorums: false, + failure_testing: None, + query_testing: None, + verify_state_transition_results: true, + ..Default::default() + }; + let config = PlatformConfig { + validator_set: ValidatorSetConfig::default_100_67(), + chain_lock: ChainLockConfig::default_100_67(), + instant_lock: InstantLockConfig::default_100_67(), + execution: ExecutionConfig { + verify_sum_trees: true, + + ..Default::default() + }, + block_spacing_ms: 3000, + testing_configs: PlatformTestConfig::default_minimal_verifications(), + ..Default::default() + }; + let mut platform = TestPlatformBuilder::new() + .with_config(config.clone()) + .build_with_mock_rpc(); + + let outcome = run_chain_for_strategy(&mut platform, 2, strategy, config, 15, &mut None); + + let balance = outcome + .abci_app + .platform + .drive + .fetch_identity_balance( + outcome.identities.first().unwrap().id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch balances") + .expect("expected to have an identity to get balance from"); + + assert_eq!(balance, 99864009980) + } + #[test] fn run_chain_core_height_randomly_increasing() { let strategy = NetworkStrategy { diff --git a/packages/rs-drive/src/drive/document/delete/mod.rs b/packages/rs-drive/src/drive/document/delete/mod.rs index c2da69240b2..c3426c15ca5 100644 --- a/packages/rs-drive/src/drive/document/delete/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/mod.rs @@ -99,6 +99,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-reduced.json", None, None, + None, ); let document_type = contract @@ -193,6 +194,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-reduced.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -334,6 +336,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-reduced.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -518,6 +521,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-reduced.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -793,6 +797,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, Some(&db_transaction), + None, ); let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); @@ -893,6 +898,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, Some(&db_transaction), + None, ); let document_type = contract diff --git a/packages/rs-drive/src/drive/document/insert/mod.rs b/packages/rs-drive/src/drive/document/insert/mod.rs index f0eb33b8a78..932fd7687a7 100644 --- a/packages/rs-drive/src/drive/document/insert/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/mod.rs @@ -166,6 +166,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -262,6 +263,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -327,6 +329,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -392,6 +395,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -457,6 +461,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, Some(&db_transaction), + None, ); let random_owner_id = random::<[u8; 32]>(); @@ -533,6 +538,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, Some(&db_transaction), + None, ); let random_owner_id = random::<[u8; 32]>(); @@ -626,6 +632,7 @@ mod tests { "tests/supporting_files/contract/dpns/dpns-contract.json", None, Some(&db_transaction), + None, ); let random_owner_id = rand::thread_rng().gen::<[u8; 32]>(); diff --git a/packages/rs-drive/src/drive/document/update/mod.rs b/packages/rs-drive/src/drive/document/update/mod.rs index fccb43e3e84..03d9927c8ca 100644 --- a/packages/rs-drive/src/drive/document/update/mod.rs +++ b/packages/rs-drive/src/drive/document/update/mod.rs @@ -685,6 +685,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -774,6 +775,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-with-profile-history.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -865,7 +867,7 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, transaction.as_ref()); + let contract = setup_contract(&drive, path, None, transaction.as_ref(), None); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1160,7 +1162,7 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, transaction.as_ref()); + let contract = setup_contract(&drive, path, None, transaction.as_ref(), None); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1359,7 +1361,7 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, transaction.as_ref()); + let contract = setup_contract(&drive, path, None, transaction.as_ref(), None); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1694,7 +1696,7 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, transaction.as_ref()); + let contract = setup_contract(&drive, path, None, transaction.as_ref(), None); let person_0_original = Person { id: Identifier::from([0u8; 32]), diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/mod.rs index bececbe4708..99c38f711eb 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/mod.rs @@ -2,7 +2,6 @@ use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; -use dpp::data_contract::group::GroupSumPower; use dpp::data_contract::GroupContractPosition; use dpp::group::group_action::GroupAction; use dpp::identifier::Identifier; diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs index c74ace258c4..05f4805b733 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs @@ -5,10 +5,8 @@ use crate::fees::op::LowLevelDriveOperation; use dpp::data_contract::group::GroupSumPower; use dpp::data_contract::GroupContractPosition; use dpp::identifier::Identifier; -use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::TransactionArg; use platform_version::version::PlatformVersion; -use std::collections::HashMap; mod v0; diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs index d50ba422658..7e276144002 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use crate::drive::group::{group_action_path, ACTION_SIGNERS_KEY}; use crate::drive::Drive; use crate::error::Error; @@ -10,8 +8,7 @@ use dpp::data_contract::group::GroupSumPower; use dpp::data_contract::GroupContractPosition; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; -use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::TransactionArg; impl Drive { /// v0 implementation of fetching the signers' power for a given action ID within a group contract. diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs index 7c8038d654c..ea331ece925 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -1,6 +1,6 @@ use crate::drive::group::{ - group_action_path, group_action_path_vec, group_action_root_path, - group_action_signers_path_vec, ACTION_INFO_KEY, ACTION_SIGNERS_KEY, + group_action_path, group_action_root_path, group_action_signers_path_vec, ACTION_INFO_KEY, + ACTION_SIGNERS_KEY, }; use crate::drive::Drive; use crate::error::Error; diff --git a/packages/rs-drive/src/drive/group/mod.rs b/packages/rs-drive/src/drive/group/mod.rs index 83799023d9f..7a134413c62 100644 --- a/packages/rs-drive/src/drive/group/mod.rs +++ b/packages/rs-drive/src/drive/group/mod.rs @@ -4,9 +4,16 @@ use dpp::data_contract::GroupContractPosition; mod fetch; mod insert; +/// The key used to identify the group information in storage. pub const GROUP_INFO_KEY: &[u8; 1] = b"I"; + +/// The key used to identify the group actions in storage. pub const GROUP_ACTIONS_KEY: &[u8; 1] = b"M"; + +/// The key used to identify the action information in storage. pub const ACTION_INFO_KEY: &[u8; 1] = b"I"; + +/// The key used to identify the action signers in storage. pub const ACTION_SIGNERS_KEY: &[u8; 1] = b"S"; /// Group root path diff --git a/packages/rs-drive/src/drive/initialization/v0/mod.rs b/packages/rs-drive/src/drive/initialization/v0/mod.rs index daa41b1c243..1d5b0d17831 100644 --- a/packages/rs-drive/src/drive/initialization/v0/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v0/mod.rs @@ -223,7 +223,35 @@ mod tests { use grovedb::{PathQuery, Query, SizedQuery}; #[test] - fn test_create_initial_state_structure() { + fn test_create_initial_state_structure_in_first_protocol_version() { + let platform_version = PlatformVersion::first(); + let drive = setup_drive_with_initial_state_structure(Some(platform_version)); + + let mut query = Query::new(); + query.insert_all(); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let (elements, _) = drive + .grove_get_raw_path_query( + &root_path_query, + None, + QueryElementResultType, + &mut drive_operations, + &platform_version.drive, + ) + .expect("expected to get root elements"); + assert_eq!(elements.len(), 13); + } + + #[test] + fn test_create_initial_state_structure_in_latest_protocol_version() { let drive = setup_drive_with_initial_state_structure(None); let platform_version = PlatformVersion::latest(); @@ -248,16 +276,17 @@ mod tests { &platform_version.drive, ) .expect("expected to get root elements"); - assert_eq!(elements.len(), 13); + assert_eq!(elements.len(), 14); } #[test] - fn test_initial_state_structure_proper_heights() { - let drive = setup_drive_with_initial_state_structure(None); + fn test_initial_state_structure_proper_heights_in_first_protocol_version() { + let platform_version = PlatformVersion::first(); + let drive = setup_drive_with_initial_state_structure(Some(platform_version)); let _db_transaction = drive.grove.start_transaction(); - let platform_version = PlatformVersion::latest(); + let platform_version = PlatformVersion::first(); let drive_version = &platform_version.drive; // Merk Level 0 @@ -540,4 +569,315 @@ mod tests { .expect("expected to get root elements"); assert_eq!(proof.len(), 250); //it + parent + sibling + parent sibling + grandparent + grandparent sibling + great-grandparent } + + #[test] + fn test_initial_state_structure_proper_heights_in_latest_protocol_version() { + let drive = setup_drive_with_initial_state_structure(None); + + let _db_transaction = drive.grove.start_transaction(); + + let platform_version = PlatformVersion::latest(); + let drive_version = &platform_version.drive; + + // Merk Level 0 + let mut query = Query::new(); + query.insert_key(vec![RootTree::DataContractDocuments as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 112); //it + left + right + + // Merk Level 1 + let mut query = Query::new(); + query.insert_key(vec![RootTree::Identities as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 180); //it + left + right + parent + parent other + + let mut query = Query::new(); + query.insert_key(vec![RootTree::Balances as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 181); //it + left + right + parent + parent other + + // Merk Level 2 + let mut query = Query::new(); + query.insert_key(vec![RootTree::Tokens as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 248); //it + left + right + parent + sibling + parent sibling + grandparent + + let mut query = Query::new(); + query.insert_key(vec![RootTree::Pools as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 218); //it + left + parent + sibling + parent sibling + grandparent + + let mut query = Query::new(); + query.insert_key(vec![RootTree::WithdrawalTransactions as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 250); //it + left + right + parent + sibling + parent sibling + grandparent + + let mut query = Query::new(); + query.insert_key(vec![RootTree::Votes as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 250); //it + left + right + parent + sibling + parent sibling + grandparent + + // Merk Level 3 + + let mut query = Query::new(); + query.insert_key(vec![RootTree::UniquePublicKeyHashesToIdentities as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 248); //it + parent + sibling + parent sibling + grandparent + grandparent sibling + great-grandparent + + let mut query = Query::new(); + query.insert_key(vec![ + RootTree::NonUniquePublicKeyKeyHashesToIdentities as u8, + ]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 248); //it + parent + sibling + parent sibling + grandparent + grandparent sibling + great-grandparent + + let mut query = Query::new(); + query.insert_key(vec![RootTree::PreFundedSpecializedBalances as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 217); //it + parent + parent sibling + grandparent + grandparent sibling + great-grandparent + + let mut query = Query::new(); + query.insert_key(vec![RootTree::SpentAssetLockTransactions as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 248); //it + parent + sibling + parent sibling + grandparent + grandparent sibling + great-grandparent + + let mut query = Query::new(); + query.insert_key(vec![RootTree::GroupActions as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 248); //it + parent + sibling + parent sibling + grandparent + grandparent sibling + great-grandparent + + let mut query = Query::new(); + query.insert_key(vec![RootTree::Misc as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 250); //it + parent + sibling + parent sibling + grandparent + grandparent sibling + great-grandparent + + let mut query = Query::new(); + query.insert_key(vec![RootTree::Versions as u8]); + let root_path_query = PathQuery::new( + vec![], + SizedQuery { + query, + limit: None, + offset: None, + }, + ); + let mut drive_operations = vec![]; + let proof = drive + .grove_get_proved_path_query( + &root_path_query, + None, + &mut drive_operations, + drive_version, + ) + .expect("expected to get root elements"); + assert_eq!(proof.len(), 250); //it + parent + sibling + parent sibling + grandparent + grandparent sibling + great-grandparent + } } diff --git a/packages/rs-drive/src/drive/mod.rs b/packages/rs-drive/src/drive/mod.rs index 4a303c4e695..1f8a8f8dc58 100644 --- a/packages/rs-drive/src/drive/mod.rs +++ b/packages/rs-drive/src/drive/mod.rs @@ -48,6 +48,7 @@ pub(crate) mod prefunded_specialized_balances; #[cfg(any(feature = "server", feature = "verify"))] pub mod votes; +/// Group module pub mod group; #[cfg(feature = "server")] mod shared; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs index 41e1f300638..49b42cf17c0 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs @@ -1,7 +1,7 @@ use derive_more::From; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; use dpp::data_contract::TokenContractPosition; -use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; +use dpp::group::GroupStateTransitionResolvedInfo; use dpp::platform_value::Identifier; use dpp::prelude::IdentityNonce; use std::sync::Arc; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs index e6c75f37250..88734b37285 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs @@ -1,8 +1,6 @@ -use std::collections::HashMap; use dpp::platform_value::Identifier; use std::sync::Arc; -use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::TransactionArg; use dpp::ProtocolError; use dpp::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use platform_version::version::PlatformVersion; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs index b33a4818dbb..9995478c57d 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs @@ -3,8 +3,8 @@ use crate::error::Error; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; -use dpp::data_contract::{GroupContractPosition, TokenContractPosition}; -use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; +use dpp::data_contract::TokenContractPosition; +use dpp::group::GroupStateTransitionResolvedInfo; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; use dpp::ProtocolError; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs index e93292f0522..9d2f3cd1c73 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs @@ -1,9 +1,4 @@ use derive_more::From; -use std::sync::Arc; - -use crate::drive::contract::DataContractFetchInfo; -use dpp::identifier::Identifier; -use dpp::prelude::IdentityNonce; /// transformer module for token burn transition action pub mod transformer; @@ -11,9 +6,7 @@ mod v0; pub use v0::*; // re-export the v0 module items (including TokenBurnTransitionActionV0) -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{ - TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0, -}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; /// Token burn transition action #[derive(Debug, Clone, From)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs index 6140a5be9f6..56882c931c0 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs @@ -2,7 +2,8 @@ use dpp::platform_value::Identifier; use dpp::ProtocolError; use grovedb::TransactionArg; use std::sync::Arc; - +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{ TokenBurnTransitionAction, TokenBurnTransitionActionV0, @@ -11,92 +12,97 @@ use dpp::state_transition::batch_transition::token_burn_transition::TokenBurnTra use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::fees::op::LowLevelDriveOperation; /// Implement methods to transform a `TokenBurnTransition` into a `TokenBurnTransitionAction`. impl TokenBurnTransitionAction { /// Transform a `TokenBurnTransition` into a `TokenBurnTransitionAction` using the provided data contract lookup. /// + /// This method processes a `TokenBurnTransition` and converts it into a `TokenBurnTransitionAction` while + /// looking up necessary data contracts and calculating transaction fees. + /// /// # Arguments /// /// * `drive` - A reference to the `Drive` instance used for accessing the system. /// * `owner_id` - The identifier of the owner initiating the burn transition. + /// * `value` - The `TokenBurnTransition` instance to be converted into a `TokenBurnTransitionAction`. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state information. /// * `transaction` - The transaction argument used for state changes. - /// * `value` - A `TokenBurnTransition` instance. - /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. - /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. - /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. - /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// * `block_info` - Block information needed to process the transition. + /// * `get_data_contract` - A closure that retrieves the `DataContractFetchInfo` for a given contract ID. + /// * `platform_version` - The platform version in use for the context of the transition. /// /// # Returns /// - /// * `Result` - A `TokenBurnTransitionAction` if successful, otherwise `ProtocolError`. + /// * `Result<(TokenBurnTransitionAction, FeeResult), Error>` - A result containing the `TokenBurnTransitionAction` and associated fees if successful, otherwise an error. pub fn try_from_token_burn_transition_with_contract_lookup( drive: &Drive, owner_id: Identifier, value: TokenBurnTransition, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { match value { TokenBurnTransition::V0(v0) => { - let v0_action = TokenBurnTransitionActionV0::try_from_token_burn_transition_with_contract_lookup( + let (v0, fee) = TokenBurnTransitionActionV0::try_from_token_burn_transition_with_contract_lookup( drive, owner_id, v0, approximate_without_state_for_costs, transaction, - drive_operations, + block_info, get_data_contract, platform_version, )?; - Ok(v0_action.into()) + Ok((v0.into(), fee)) } } } /// Transform a borrowed `TokenBurnTransition` into a `TokenBurnTransitionAction` using the provided data contract lookup. /// + /// This method processes a borrowed reference to a `TokenBurnTransition` and converts it into a `TokenBurnTransitionAction` + /// while looking up necessary data contracts and calculating transaction fees. + /// /// # Arguments /// /// * `drive` - A reference to the `Drive` instance used for accessing the system. /// * `owner_id` - The identifier of the owner initiating the burn transition. + /// * `value` - A reference to the `TokenBurnTransition` to be converted into a `TokenBurnTransitionAction`. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state information. /// * `transaction` - The transaction argument used for state changes. - /// * `value` - A reference to a `TokenBurnTransition`. - /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. - /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. - /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. - /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// * `block_info` - Block information needed to process the transition. + /// * `get_data_contract` - A closure that retrieves the `DataContractFetchInfo` for a given contract ID. + /// * `platform_version` - The platform version in use for the context of the transition. /// /// # Returns /// - /// * `Result` - A `TokenBurnTransitionAction` if successful, otherwise `ProtocolError`. + /// * `Result<(TokenBurnTransitionAction, FeeResult), Error>` - A result containing the `TokenBurnTransitionAction` and associated fees if successful, otherwise an error. pub fn try_from_borrowed_token_burn_transition_with_contract_lookup( drive: &Drive, owner_id: Identifier, value: &TokenBurnTransition, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { match value { TokenBurnTransition::V0(v0) => { - let v0_action = TokenBurnTransitionActionV0::try_from_borrowed_token_burn_transition_with_contract_lookup( + let (v0, fee) = TokenBurnTransitionActionV0::try_from_borrowed_token_burn_transition_with_contract_lookup( drive, owner_id, v0, approximate_without_state_for_costs, transaction, - drive_operations, + block_info, get_data_contract, platform_version, )?; - Ok(v0_action.into()) + Ok((v0.into(), fee)) } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index d553218d025..0261872631a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -3,11 +3,12 @@ use dpp::state_transition::batch_transition::token_burn_transition::v0::TokenBur use dpp::ProtocolError; use grovedb::TransactionArg; use std::sync::Arc; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; -use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; @@ -25,7 +26,7 @@ impl TokenBurnTransitionActionV0 { /// - `value`: The `TokenBurnTransitionV0` containing the details for the token burn. /// - `approximate_without_state_for_costs`: A flag indicating whether to approximate state costs. /// - `transaction`: The transaction argument used for state changes. - /// - `drive_operations`: A mutable reference to the vector of low-level operations that need to be performed. + /// - `block_info`: Information about the current block to calculate fees. /// - `get_data_contract`: A closure function that looks up the data contract for a given identifier. /// - `platform_version`: The platform version for the context in which the transition is being executed. /// @@ -41,32 +42,46 @@ impl TokenBurnTransitionActionV0 { value: TokenBurnTransitionV0, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { let TokenBurnTransitionV0 { base, burn_amount, public_note, } = value; + let mut drive_operations = vec![]; + let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( drive, owner_id, base, approximate_without_state_for_costs, transaction, - drive_operations, + &mut drive_operations, get_data_contract, platform_version, )?; - Ok(TokenBurnTransitionActionV0 { - base: base_action, - burn_amount, - public_note, - }) + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(( + TokenBurnTransitionActionV0 { + base: base_action, + burn_amount, + public_note, + }, + fee_result, + )) } /// Attempts to create a `TokenBurnTransitionActionV0` from the borrowed `TokenBurnTransitionV0` value. @@ -82,7 +97,7 @@ impl TokenBurnTransitionActionV0 { /// - `value`: A borrowed reference to the `TokenBurnTransitionV0` containing the details for the token burn. /// - `approximate_without_state_for_costs`: A flag indicating whether to approximate state costs. /// - `transaction`: The transaction argument used for state changes. - /// - `drive_operations`: A mutable reference to the vector of low-level operations that need to be performed. + /// - `block_info`: Information about the current block to calculate fees. /// - `get_data_contract`: A closure function that looks up the data contract for a given identifier. /// - `platform_version`: The platform version for the context in which the transition is being executed. /// @@ -98,16 +113,18 @@ impl TokenBurnTransitionActionV0 { value: &TokenBurnTransitionV0, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { let TokenBurnTransitionV0 { base, burn_amount, public_note, } = value; + let mut drive_operations = vec![]; + let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( drive, @@ -115,15 +132,27 @@ impl TokenBurnTransitionActionV0 { base, approximate_without_state_for_costs, transaction, - drive_operations, + &mut drive_operations, get_data_contract, platform_version, )?; - Ok(TokenBurnTransitionActionV0 { - base: base_action, - burn_amount: *burn_amount, - public_note: public_note.clone(), - }) + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(( + TokenBurnTransitionActionV0 { + base: base_action, + burn_amount: *burn_amount, + public_note: public_note.clone(), + }, + fee_result, + )) } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs index 75b61fcefcd..e2e58fa895f 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs @@ -2,14 +2,14 @@ use dpp::platform_value::Identifier; use dpp::ProtocolError; use grovedb::TransactionArg; use std::sync::Arc; - +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionActionV0, TokenMintTransitionAction}; use dpp::state_transition::batch_transition::token_mint_transition::TokenMintTransition; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::fees::op::LowLevelDriveOperation; /// Implement methods to transform a `TokenMintTransition` into a `TokenMintTransitionAction`. impl TokenMintTransitionAction { @@ -35,24 +35,24 @@ impl TokenMintTransitionAction { value: TokenMintTransition, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { match value { TokenMintTransition::V0(v0) => { - let v0_action = + let (v0, fee) = TokenMintTransitionActionV0::try_from_token_mint_transition_with_contract_lookup( drive, owner_id, v0, approximate_without_state_for_costs, transaction, - drive_operations, + block_info, get_data_contract, platform_version, )?; - Ok(v0_action.into()) + Ok((v0.into(), fee)) } } } @@ -79,23 +79,23 @@ impl TokenMintTransitionAction { value: &TokenMintTransition, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { match value { TokenMintTransition::V0(v0) => { - let v0_action = TokenMintTransitionActionV0::try_from_borrowed_token_mint_transition_with_contract_lookup( + let (v0, fee) = TokenMintTransitionActionV0::try_from_borrowed_token_mint_transition_with_contract_lookup( drive, owner_id, v0, approximate_without_state_for_costs, transaction, - drive_operations, + block_info, get_data_contract, platform_version, )?; - Ok(v0_action.into()) + Ok((v0.into(), fee)) } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs index 59cd7da505b..ff4482aa86e 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs @@ -1,5 +1,6 @@ use std::sync::Arc; use grovedb::TransactionArg; +use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_mint_transition::v0::TokenMintTransitionV0; use dpp::ProtocolError; @@ -10,10 +11,10 @@ use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::v0::TokenMintTransitionActionV0; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::fee::fee_result::FeeResult; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::fees::op::LowLevelDriveOperation; impl TokenMintTransitionActionV0 { /// Converts a `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using the provided contract lookup. @@ -30,8 +31,7 @@ impl TokenMintTransitionActionV0 { /// * `value` - The `TokenMintTransitionV0` struct containing the transition data, including token amount and recipient. /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering /// the full state for the operation. Useful for optimizing the transaction cost calculations. - /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed - /// during this transition. This allows tracking the changes that need to be persisted. + /// * `block_info` - Information about the current block to calculate fees. /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` /// containing the data contract details, including token configurations. /// * `platform_version` - A reference to the platform version, ensuring the transition respects version-specific logic. @@ -46,10 +46,10 @@ impl TokenMintTransitionActionV0 { value: TokenMintTransitionV0, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { let TokenMintTransitionV0 { base, issued_to_identity_id, @@ -59,13 +59,15 @@ impl TokenMintTransitionActionV0 { let position = base.token_contract_position(); + let mut drive_operations = vec![]; + let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( drive, owner_id, base, approximate_without_state_for_costs, transaction, - drive_operations, + &mut drive_operations, get_data_contract, platform_version, )?; @@ -85,44 +87,63 @@ impl TokenMintTransitionActionV0 { TokenError::DestinationIdentityForMintingNotSetError.into(), ))?; - Ok(TokenMintTransitionActionV0 { - base: base_action, - mint_amount: amount, - identity_balance_holder_id, - public_note, - }) + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(( + TokenMintTransitionActionV0 { + base: base_action, + mint_amount: amount, + identity_balance_holder_id, + public_note, + }, + fee_result, + )) } /// Converts a borrowed `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using the provided contract lookup. /// - /// This method works similarly to `try_from_token_mint_transition_with_contract_lookup`, but it borrows the - /// `TokenMintTransitionV0` to avoid unnecessary cloning of the transition object. + /// This method processes the token minting transition and constructs the corresponding transition action while + /// looking up necessary data contracts and applying the relevant minting logic. It does not require `drive_operations` + /// to be passed as a parameter, but it manages them internally. /// /// # Arguments /// - /// * `drive` - A reference to the `Drive` instance for data access. - /// * `owner_id` - The identifier of the owner initiating the minting transition. - /// * `transaction` - The transaction context for state changes. - /// * `value` - A reference to a `TokenMintTransitionV0` struct containing transition data. - /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without full state. - /// * `drive_operations` - A mutable reference to a vector for tracking low-level drive operations. - /// * `get_data_contract` - A closure to fetch data contract information based on a contract identifier. - /// * `platform_version` - A reference to the platform version for version-specific transition logic. + /// * `drive` - A reference to the `Drive` instance that handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the minting transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `value` - A reference to the `TokenMintTransitionV0` struct containing the transition data, including token + /// amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to indicate whether costs should be approximated without full + /// state consideration. Useful for optimizing transaction cost calculations in scenarios where full state is not needed. + /// * `transaction` - The transaction context, which includes the necessary state and other details for the transition. + /// * `block_info` - Information about the current block (e.g., epoch) to help calculate transaction fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version to ensure the transition respects version-specific logic. /// - /// # Returns + //// # Returns + /// + /// * `Result<(TokenMintTransitionActionV0, FeeResult), Error>` - Returns a tuple containing the constructed + /// `TokenMintTransitionActionV0` and a `FeeResult` if successful. If an error occurs (e.g., missing data or + /// invalid state transition), it returns an `Error`. /// - /// * `Result` - Returns the resulting `TokenMintTransitionActionV0` if successful, - /// or an error if something goes wrong (e.g., missing data, invalid state). pub fn try_from_borrowed_token_mint_transition_with_contract_lookup( drive: &Drive, owner_id: Identifier, value: &TokenMintTransitionV0, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { let TokenMintTransitionV0 { base, issued_to_identity_id, @@ -130,6 +151,8 @@ impl TokenMintTransitionActionV0 { public_note, } = value; + let mut drive_operations = vec![]; + let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( drive, @@ -137,7 +160,7 @@ impl TokenMintTransitionActionV0 { base, approximate_without_state_for_costs, transaction, - drive_operations, + &mut drive_operations, get_data_contract, platform_version, )?; @@ -157,11 +180,23 @@ impl TokenMintTransitionActionV0 { TokenError::DestinationIdentityForMintingNotSetError.into(), ))?; - Ok(TokenMintTransitionActionV0 { - base: base_action, - mint_amount: *amount, - identity_balance_holder_id, - public_note: public_note.clone(), - }) + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(( + TokenMintTransitionActionV0 { + base: base_action, + mint_amount: *amount, + identity_balance_holder_id, + public_note: public_note.clone(), + }, + fee_result, + )) } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs index 6e0c82cf2cf..c54c4cd9912 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs @@ -3,11 +3,9 @@ use derive_more::From; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::{ TokenTransferTransitionActionV0, TokenTransferTransitionActionAccessorsV0, }; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use dpp::identifier::Identifier; -use dpp::prelude::{DerivationEncryptionKeyIndex, IdentityNonce, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; -use std::sync::Arc; -use crate::drive::contract::DataContractFetchInfo; +use dpp::prelude::{DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; /// transformer module pub mod transformer; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs index 6c47540ee6a..efc4d7337a0 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs @@ -1,5 +1,7 @@ use std::sync::Arc; use grovedb::TransactionArg; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; use dpp::platform_value::Identifier; use dpp::ProtocolError; use dpp::state_transition::batch_transition::TokenTransferTransition; @@ -7,96 +9,103 @@ use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; -use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionV0; /// Implement methods to transform a `TokenTransferTransition` into a `TokenTransferTransitionAction`. impl TokenTransferTransitionAction { - /// Transform a `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided data contract lookup and additional parameters. + /// Converts a `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided contract lookup. + /// + /// This function processes a `TokenTransferTransition` (which may contain multiple versions), looks up the necessary data + /// contracts, and calculates the associated fees for the transaction. Currently, only the `V0` variant of the transition is + /// supported. The result is a `TokenTransferTransitionAction` along with the fee result. /// /// # Arguments /// - /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. - /// * `transaction` - The transaction context for state changes and related operations. - /// * `value` - A `TokenTransferTransition` instance. - /// * `owner_id` - The identifier of the owner initiating the transfer. - /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering - /// the full state for the operation. - /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed. - /// * `get_data_contract` - A closure that fetches data contract information based on a contract identifier. - /// * `platform_version` - A reference to the platform version for version-specific transition logic. + /// * `drive` - A reference to the `Drive` instance for handling data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the token transfer. + /// * `value` - The `TokenTransferTransition` containing the transition data (currently only the `V0` variant is supported). + /// * `approximate_without_state_for_costs` - A flag to approximate transaction costs without full state consideration. + /// * `transaction` - The transaction context, which provides the necessary state for processing the transition. + /// * `block_info` - Information about the current block used to calculate fees for the transition. + /// * `get_data_contract` - A closure that takes an identifier and returns the associated `DataContractFetchInfo`. + /// * `platform_version` - The platform version to ensure the transition is compatible with the current version logic. /// /// # Returns /// - /// * `Result` - A `TokenTransferTransitionAction` if successful, otherwise `ProtocolError`. + /// * `Result<(TokenTransferTransitionAction, FeeResult), Error>` - A result containing the constructed `TokenTransferTransitionAction` + /// and the calculated `FeeResult`, or an error if the transition cannot be processed. pub fn from_token_transfer_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, - value: TokenTransferTransition, owner_id: Identifier, + value: TokenTransferTransition, approximate_without_state_for_costs: bool, - drive_operations: &mut Vec, + transaction: TransactionArg, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { match value { TokenTransferTransition::V0(v0) => { - let v0_action = TokenTransferTransitionActionV0::try_from_token_transfer_transition_with_contract_lookup( + let (v0, fee) = TokenTransferTransitionActionV0::try_from_token_transfer_transition_with_contract_lookup( drive, owner_id, v0, approximate_without_state_for_costs, transaction, - drive_operations, + block_info, get_data_contract, platform_version, )?; - Ok(v0_action.into()) + Ok((v0.into(), fee)) } } } - /// Transform a borrowed `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided data contract lookup and additional parameters. + /// Converts a borrowed reference of a `TokenTransferTransition` into a `TokenTransferTransitionAction` using the provided contract lookup. + /// + /// This function is similar to `from_token_transfer_transition_with_contract_lookup` but operates on a borrowed reference of the + /// `TokenTransferTransition`, which avoids copying the data. It processes the `TokenTransferTransition`, looks up the necessary + /// data contracts, and calculates the associated fees for the transaction. Only the `V0` variant of the transition is supported. /// /// # Arguments /// - /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. - /// * `transaction` - The transaction context for state changes and related operations. - /// * `value` - A reference to a `TokenTransferTransition`. - /// * `owner_id` - The identifier of the owner initiating the transfer. - /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering - /// the full state for the operation. - /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed. - /// * `get_data_contract` - A closure that fetches data contract information based on a contract identifier. - /// * `platform_version` - A reference to the platform version for version-specific transition logic. + /// * `drive` - A reference to the `Drive` instance for handling data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the token transfer. + /// * `value` - A borrowed reference to the `TokenTransferTransition` containing the transition data (currently only the `V0` variant is supported). + /// * `approximate_without_state_for_costs` - A flag to approximate transaction costs without full state consideration. + /// * `transaction` - The transaction context, which provides the necessary state for processing the transition. + /// * `block_info` - Information about the current block used to calculate fees for the transition. + /// * `get_data_contract` - A closure that takes an identifier and returns the associated `DataContractFetchInfo`. + /// * `platform_version` - The platform version to ensure the transition is compatible with the current version logic. /// /// # Returns /// - /// * `Result` - A `TokenTransferTransitionAction` if successful, otherwise `ProtocolError`. + /// * `Result<(TokenTransferTransitionAction, FeeResult), Error>` - A result containing the constructed `TokenTransferTransitionAction` + /// and the calculated `FeeResult`, or an error if the transition cannot be processed. pub fn try_from_borrowed_token_transfer_transition_with_contract_lookup( drive: &Drive, - transaction: TransactionArg, - value: &TokenTransferTransition, owner_id: Identifier, + value: &TokenTransferTransition, approximate_without_state_for_costs: bool, - drive_operations: &mut Vec, + transaction: TransactionArg, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { match value { TokenTransferTransition::V0(v0) => { - let v0_action = TokenTransferTransitionActionV0::try_from_borrowed_token_transfer_transition_with_contract_lookup( + let (v0, fee) = TokenTransferTransitionActionV0::try_from_borrowed_token_transfer_transition_with_contract_lookup( drive, owner_id, v0, approximate_without_state_for_costs, transaction, - drive_operations, + block_info, get_data_contract, platform_version, )?; - Ok(v0_action.into()) + Ok((v0.into(), fee)) } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index d7ed9086ec2..b949531025b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -3,19 +3,20 @@ use dpp::state_transition::batch_transition::token_transfer_transition::v0::Toke use dpp::ProtocolError; use grovedb::TransactionArg; use std::sync::Arc; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; -use crate::fees::op::LowLevelDriveOperation; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionActionV0; impl TokenTransferTransitionActionV0 { - /// Converts a `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using the provided contract lookup and additional parameters. + /// Converts a `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using the provided contract lookup. /// - /// This method processes the token transfer transition and returns the corresponding transition action, - /// while looking up necessary data contracts, performing the required checks, and applying the relevant logic for token transfer. + /// This method processes the token transfer transition, looks up the necessary data contracts, performs required + /// checks, and applies the relevant logic for token transfer. It also calculates the fees associated with the transaction. /// /// # Arguments /// @@ -24,27 +25,27 @@ impl TokenTransferTransitionActionV0 { /// * `value` - The `TokenTransferTransitionV0` struct containing the transition data, including token amount, /// recipient details, and encrypted notes. /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering - /// the full state for the operation. Useful for optimizing the transaction cost calculations. - /// * `transaction` - The transaction context for state changes and related operations. - /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed - /// during this transition. This allows tracking the changes that need to be persisted. - /// * `get_data_contract` - A closure to fetch data contract information based on a contract identifier. - /// * `platform_version` - A reference to the platform version for version-specific transition logic. + /// the full state for the operation. Useful for optimizing transaction cost calculations when full state is not needed. + /// * `transaction` - The transaction context, which includes state details and necessary operations for the transition. + /// * `block_info` - Information about the current block to calculate the fees for the transition. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns the associated `DataContractFetchInfo`. + /// * `platform_version` - A reference to the platform version, ensuring that the transition respects version-specific logic. /// /// # Returns /// - /// * `Result` - Returns the constructed `TokenTransferTransitionActionV0` - /// if successful, or an error if any issue arises (e.g., missing data or an invalid state transition). + /// * `Result<(TokenTransferTransitionActionV0, FeeResult), Error>` - Returns a tuple containing the constructed + /// `TokenTransferTransitionActionV0` and the calculated `FeeResult` if successful, or an error if the transition cannot + /// be created or an issue arises with the provided state or data. pub fn try_from_token_transfer_transition_with_contract_lookup( drive: &Drive, owner_id: Identifier, value: TokenTransferTransitionV0, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { let TokenTransferTransitionV0 { base, amount, @@ -54,6 +55,8 @@ impl TokenTransferTransitionActionV0 { private_encrypted_note, } = value; + let mut drive_operations = vec![]; + // Lookup the base action using the base transition data and contract information let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( drive, @@ -61,53 +64,68 @@ impl TokenTransferTransitionActionV0 { base, approximate_without_state_for_costs, transaction, - drive_operations, + &mut drive_operations, get_data_contract, platform_version, )?; + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + // Return the TokenTransferTransitionActionV0 with the relevant data - Ok(TokenTransferTransitionActionV0 { - base: base_action, - amount, - recipient_id: recipient_owner_id, - public_note, - shared_encrypted_note, - private_encrypted_note, - }) + Ok(( + TokenTransferTransitionActionV0 { + base: base_action, + amount, + recipient_id: recipient_owner_id, + public_note, + shared_encrypted_note, + private_encrypted_note, + }, + fee_result, + )) } - /// Converts a borrowed `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using the provided contract lookup and additional parameters. + /// Converts a borrowed `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using the provided contract lookup. /// - /// This method works similarly to `try_from_token_transfer_transition_with_contract_lookup`, but it borrows the - /// `TokenTransferTransitionV0` to avoid unnecessary cloning of the transition object. + /// This method processes the token transfer transition similarly to the `try_from_token_transfer_transition_with_contract_lookup` + /// method but operates on a borrowed reference of the `TokenTransferTransitionV0`. It performs the same checks and applies + /// the token transfer logic, while avoiding copying the `TokenTransferTransitionV0` struct. /// /// # Arguments /// - /// * `drive` - A reference to the `Drive` instance for data access. + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. /// * `owner_id` - The identifier of the owner initiating the transfer. - /// * `value` - A reference to the `TokenTransferTransitionV0` struct containing transition data (borrowed). + /// * `value` - A reference to the `TokenTransferTransitionV0` struct containing the transition data, including token amount, + /// recipient details, and encrypted notes. /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering - /// the full state for the operation. - /// * `transaction` - The transaction context for state changes and related operations. - /// * `drive_operations` - A mutable reference to a vector that will hold the low-level drive operations performed. - /// * `get_data_contract` - A closure to fetch data contract information based on a contract identifier. - /// * `platform_version` - A reference to the platform version for version-specific transition logic. + /// the full state for the operation. Useful for optimizing transaction cost calculations when full state is not needed. + /// * `transaction` - The transaction context, which includes state details and necessary operations for the transition. + /// * `block_info` - Information about the current block to calculate the fees for the transition. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns the associated `DataContractFetchInfo`. + /// * `platform_version` - A reference to the platform version, ensuring that the transition respects version-specific logic. /// /// # Returns /// - /// * `Result` - Returns the resulting `TokenTransferTransitionActionV0` - /// if successful, or an error if something goes wrong (e.g., missing data, invalid state). + /// * `Result<(TokenTransferTransitionActionV0, FeeResult), Error>` - Returns a tuple containing the constructed + /// `TokenTransferTransitionActionV0` and the calculated `FeeResult` if successful, or an error if the transition cannot + /// be created or an issue arises with the provided state or data. pub fn try_from_borrowed_token_transfer_transition_with_contract_lookup( drive: &Drive, owner_id: Identifier, value: &TokenTransferTransitionV0, approximate_without_state_for_costs: bool, transaction: TransactionArg, - drive_operations: &mut Vec, + block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result<(Self, FeeResult), Error> { let TokenTransferTransitionV0 { base, amount, @@ -117,6 +135,8 @@ impl TokenTransferTransitionActionV0 { private_encrypted_note, } = value; + let mut drive_operations = vec![]; + // Lookup the base action using the borrowed base transition data and contract information let base_action = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( @@ -125,19 +145,31 @@ impl TokenTransferTransitionActionV0 { &base, approximate_without_state_for_costs, transaction, - drive_operations, + &mut drive_operations, get_data_contract, platform_version, )?; + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + // Return the TokenTransferTransitionActionV0 with the relevant data - Ok(TokenTransferTransitionActionV0 { - base: base_action.into(), - amount: *amount, - recipient_id: *recipient_owner_id, - public_note: public_note.clone(), - shared_encrypted_note: shared_encrypted_note.clone(), - private_encrypted_note: private_encrypted_note.clone(), - }) + Ok(( + TokenTransferTransitionActionV0 { + base: base_action.into(), + amount: *amount, + recipient_id: *recipient_owner_id, + public_note: public_note.clone(), + shared_encrypted_note: shared_encrypted_note.clone(), + private_encrypted_note: private_encrypted_note.clone(), + }, + fee_result, + )) } } diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs index bfcc14b5fb5..89373a97cb4 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs @@ -604,6 +604,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -715,6 +716,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-only-age-index.json", None, Some(&db_transaction), + None, ); let document_type = contract @@ -932,6 +934,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-only-age-index.json", None, Some(&db_transaction), + None, ); let document_type = contract diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs index 13e88ba1ca9..f47ff7052cd 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs @@ -109,7 +109,7 @@ impl Drive { drive_version, )?; - if let Some(Element::SumItem(existing_value, _)) = existing_element { + if let Some(Element::SumItem(..)) = existing_element { if error_if_exists { return Err(Error::Drive(DriveError::CorruptedDriveState( "expected no sum item".to_string(), @@ -149,7 +149,7 @@ impl Drive { drive_version, )?; - if let Some(Element::SumItem(existing_value, _)) = existing_element { + if let Some(Element::SumItem(..)) = existing_element { if error_if_exists { return Err(Error::Drive(DriveError::CorruptedDriveState( "expected no sum item".to_string(), diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/mod.rs index 50393976ba6..cd9d7a4d928 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/mod.rs @@ -8,7 +8,7 @@ use crate::util::grove_operations::DirectQueryType; use dpp::version::drive_versions::DriveVersion; -use grovedb::{Element, TransactionArg}; +use grovedb::TransactionArg; use grovedb_path::SubtreePath; impl Drive { diff --git a/packages/rs-drive/src/util/test_helpers/mod.rs b/packages/rs-drive/src/util/test_helpers/mod.rs index 81447b46915..de8f1c63156 100644 --- a/packages/rs-drive/src/util/test_helpers/mod.rs +++ b/packages/rs-drive/src/util/test_helpers/mod.rs @@ -41,8 +41,9 @@ pub fn setup_contract( path: &str, contract_id: Option<[u8; 32]>, transaction: TransactionArg, + use_platform_version: Option<&PlatformVersion>, ) -> DataContract { - let platform_version = PlatformVersion::latest(); + let platform_version = use_platform_version.unwrap_or(PlatformVersion::latest()); let contract = json_document_to_contract_with_ids( path, contract_id.map(Identifier::from), diff --git a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs index 078408d9924..6959213d81e 100644 --- a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs +++ b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/mod.rs @@ -2,7 +2,6 @@ mod v0; use crate::drive::Drive; use dpp::balances::credits::TokenAmount; -use std::collections::BTreeMap; use crate::error::drive::DriveError; diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index e2cd8cc75e4..e6f900f401f 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -19,9 +19,11 @@ mod tests { /// Tests that the root hash is being calculated correctly after inserting empty subtrees into /// the root tree and the DPNS contract. - fn test_root_hash_with_batches(drive: &Drive, db_transaction: &Transaction) { - let platform_version = PlatformVersion::latest(); - + fn test_root_hash_with_batches( + drive: &Drive, + db_transaction: &Transaction, + platform_version: &PlatformVersion, + ) { // [1644293142180] INFO (35 on bf3bb2a2796a): createTree // path: [] // pathHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" @@ -297,20 +299,45 @@ mod tests { .unwrap() .expect("should return app hash"); - let expected_app_hash = "1b80f4a9f00597b3f1ddca904b3cee67576868adcdd802c0a3f91e14209bb402"; + // We expect a different app hash because data contract is not serialized the same way + let expected_app_hash = match platform_version.protocol_version { + 0..7 => "1b80f4a9f00597b3f1ddca904b3cee67576868adcdd802c0a3f91e14209bb402", + _ => "387fe8e2298bb33e0ff79fd377eccb14109fb2534c7338c535bd74b5b8580580", + }; assert_eq!(hex::encode(app_hash), expected_app_hash); } /// Runs `test_root_hash_with_batches` 10 times. #[test] - fn test_deterministic_root_hash_with_batches() { + fn test_deterministic_root_hash_with_batches_first_platform_version() { + let drive = setup_drive(None); + + let platform_version = PlatformVersion::first(); + + let db_transaction = drive.grove.start_transaction(); + + for _ in 0..10 { + test_root_hash_with_batches(&drive, &db_transaction, platform_version); + + drive + .grove + .rollback_transaction(&db_transaction) + .expect("transaction should be rolled back"); + } + } + + /// Runs `test_root_hash_with_batches` 10 times. + #[test] + fn test_deterministic_root_hash_with_batches_latest_platform_version() { let drive = setup_drive(None); + let platform_version = PlatformVersion::latest(); + let db_transaction = drive.grove.start_transaction(); for _ in 0..10 { - test_root_hash_with_batches(&drive, &db_transaction); + test_root_hash_with_batches(&drive, &db_transaction, platform_version); drive .grove diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 6bad5144f95..e5f243f28c4 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -196,7 +196,11 @@ impl PersonWithOptionalValues { #[cfg(feature = "server")] /// Inserts the test "family" contract and adds `count` documents containing randomly named people to it. -pub fn setup_family_tests(count: u32, seed: u64) -> (Drive, DataContract) { +pub fn setup_family_tests( + count: u32, + seed: u64, + platform_version: &PlatformVersion, +) -> (Drive, DataContract) { let drive_config = DriveConfig::default(); let drive = setup_drive(Some(drive_config)); @@ -208,8 +212,6 @@ pub fn setup_family_tests(count: u32, seed: u64) -> (Drive, DataContract) { add_init_contracts_structure_operations(&mut batch); - let platform_version = PlatformVersion::latest(); - drive .grove_apply_batch(batch, false, Some(&db_transaction), &platform_version.drive) .expect("expected to create contracts tree successfully"); @@ -220,6 +222,7 @@ pub fn setup_family_tests(count: u32, seed: u64) -> (Drive, DataContract) { "tests/supporting_files/contract/family/family-contract.json", None, Some(&db_transaction), + Some(platform_version), ); let people = Person::random_people(count, seed); @@ -290,6 +293,7 @@ pub fn setup_family_tests_with_nulls(count: u32, seed: u64) -> (Drive, DataContr "tests/supporting_files/contract/family/family-contract-fields-optional.json", None, Some(&db_transaction), + None, ); let people = PersonWithOptionalValues::random_people(count, seed); @@ -359,6 +363,7 @@ pub fn setup_family_tests_only_first_name_index(count: u32, seed: u64) -> (Drive "tests/supporting_files/contract/family/family-contract-only-first-name-index.json", None, Some(&db_transaction), + None, ); let people = Person::random_people(count, seed); @@ -803,6 +808,7 @@ pub fn setup_dpns_tests_with_batches( count: u32, total_owners: Option, seed: u64, + platform_version: &PlatformVersion, ) -> (Drive, DataContract) { let drive = setup_drive(Some(DriveConfig::default())); @@ -813,8 +819,6 @@ pub fn setup_dpns_tests_with_batches( add_init_contracts_structure_operations(&mut batch); - let platform_version = PlatformVersion::latest(); - drive .grove_apply_batch(batch, false, Some(&db_transaction), &platform_version.drive) .expect("expected to create contracts tree successfully"); @@ -825,6 +829,7 @@ pub fn setup_dpns_tests_with_batches( "tests/supporting_files/contract/dpns/dpns-contract.json", None, Some(&db_transaction), + Some(platform_version), ); add_domains_to_contract( @@ -872,6 +877,7 @@ pub fn setup_withdrawal_tests( "tests/supporting_files/contract/withdrawals/withdrawals-contract.json", None, Some(&db_transaction), + None, ); add_withdrawals_to_contract( @@ -915,6 +921,7 @@ pub fn setup_references_tests(_count: u32, _seed: u64) -> (Drive, DataContract) "tests/supporting_files/contract/references/references_with_contract_history.json", None, Some(&db_transaction), + None, ); drive @@ -950,6 +957,7 @@ pub fn setup_dpns_tests_label_not_required(count: u32, seed: u64) -> (Drive, Dat "tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json", None, Some(&db_transaction), + None, ); add_domains_to_contract(&drive, &contract, Some(&db_transaction), count, None, seed); @@ -985,6 +993,7 @@ pub fn setup_dpns_test_with_data(path: &str) -> (Drive, DataContract) { "tests/supporting_files/contract/dpns/dpns-contract.json", None, Some(&db_transaction), + None, ); let file = File::open(path).expect("should read domains from file"); @@ -1037,7 +1046,8 @@ pub fn setup_dpns_test_with_data(path: &str) -> (Drive, DataContract) { #[test] #[ignore] fn test_query_many() { - let (drive, contract) = setup_family_tests(1600, 73509); + let platform_version = PlatformVersion::latest(); + let (drive, contract) = setup_family_tests(1600, 73509, platform_version); let db_transaction = drive.grove.start_transaction(); let platform_version = PlatformVersion::latest(); @@ -1081,107 +1091,1442 @@ fn test_query_many() { .expect("transaction should be committed"); } -#[cfg(feature = "server")] -#[test] -fn test_reference_proof_single_index() { - let (drive, contract) = setup_family_tests_only_first_name_index(1, 73509); +#[cfg(feature = "server")] +#[test] +fn test_reference_proof_single_index() { + let (drive, contract) = setup_family_tests_only_first_name_index(1, 73509); + + let platform_version = PlatformVersion::latest(); + + let db_transaction = drive.grove.start_transaction(); + + let root_hash = drive + .grove + .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) + .unwrap() + .expect("there is always a root hash"); + + // A query getting all elements by firstName + + let query_value = json!({ + "where": [ + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, Some(&db_transaction), platform_version) + .expect("proof should be executed"); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); +} + +#[cfg(feature = "server")] +#[test] +fn test_non_existence_reference_proof_single_index() { + let (drive, contract) = setup_family_tests_only_first_name_index(0, 73509); + + let platform_version = PlatformVersion::latest(); + + let db_transaction = drive.grove.start_transaction(); + + let root_hash = drive + .grove + .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) + .unwrap() + .expect("there is always a root hash"); + + // A query getting all elements by firstName + + let query_value = json!({ + "where": [ + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, Some(&db_transaction), platform_version) + .expect("proof should be executed"); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); +} + +#[cfg(feature = "server")] +#[test] +fn test_family_basic_queries_first_version() { + let platform_version = PlatformVersion::first(); + let (drive, contract) = setup_family_tests(10, 73509, platform_version); + + let db_transaction = drive.grove.start_transaction(); + + let root_hash = drive + .grove + .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) + .unwrap() + .expect("there is always a root hash"); + + let expected_app_hash = vec![ + 32, 210, 24, 196, 148, 43, 20, 34, 0, 116, 183, 136, 32, 210, 163, 183, 214, 6, 152, 86, + 46, 45, 88, 13, 23, 41, 37, 70, 129, 119, 211, 12, + ]; + + assert_eq!(root_hash.as_slice(), expected_app_hash); + + let all_names = [ + "Adey".to_string(), + "Briney".to_string(), + "Cammi".to_string(), + "Celinda".to_string(), + "Dalia".to_string(), + "Gilligan".to_string(), + "Kevina".to_string(), + "Meta".to_string(), + "Noellyn".to_string(), + "Prissie".to_string(), + ]; + + // A query getting all elements by firstName + + let query_value = json!({ + "where": [ + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, Some(&db_transaction), platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + assert_eq!(names, all_names); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting all people who's first name is Adey (which should exist) + let query_value = json!({ + "where": [ + ["firstName", "==", "Adey"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + assert_eq!(results.len(), 1); + + let (proof_root_hash, proof_results, _) = drive + .query_proof_of_documents_using_cbor_encoded_query_only_get_elements( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting all people who's first name is Adey and lastName Randolf + + let query_value = json!({ + "where": [ + ["firstName", "==", "Adey"], + ["lastName", "==", "Randolf"] + ], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + let (proof_root_hash, proof_results, _) = drive + .query_proof_of_documents_using_cbor_encoded_query_only_get_elements( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + let document = Document::from_bytes( + results.first().unwrap().as_slice(), + person_document_type, + platform_version, + ) + .expect("we should be able to deserialize from bytes"); + let last_name = document + .get("lastName") + .expect("we should be able to get the last name") + .as_text() + .expect("last name must be a string"); + + assert_eq!(last_name, "Randolf"); + + // A query getting all people who's first name is in a range with a single element Adey, + // order by lastName (this should exist) + + let query_value = json!({ + "where": [ + ["firstName", "in", ["Adey"]] + ], + "orderBy": [ + ["firstName", "asc"], + ["lastName", "asc"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + let (proof_root_hash, proof_results, _) = drive + .query_proof_of_documents_using_cbor_encoded_query_only_get_elements( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting all people who's first name is Adey, order by lastName (which should exist) + + let query_value = json!({ + "where": [ + ["firstName", "==", "Adey"] + ], + "orderBy": [ + ["lastName", "asc"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + let (proof_root_hash, proof_results, _) = drive + .query_proof_of_documents_using_cbor_encoded_query_only_get_elements( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + let document = Document::from_bytes( + results.first().unwrap().as_slice(), + person_document_type, + platform_version, + ) + .expect("we should be able to deserialize from bytes"); + let last_name = document + .get("lastName") + .expect("we should be able to get the last name") + .as_text() + .expect("last name must be a string"); + + assert_eq!(last_name, "Randolf"); + + // A query getting all people who's first name is Chris (which is not exist) + + let query_value = json!({ + "where": [ + ["firstName", "==", "Chris"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 0); + + let (proof_root_hash, proof_results, _) = drive + .query_proof_of_documents_using_cbor_encoded_query_only_get_elements( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting a middle name + + let query_value = json!({ + "where": [ + ["middleName", "==", "Briggs"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + let (proof_root_hash, proof_results, _) = drive + .query_proof_of_documents_using_cbor_encoded_query_only_get_elements( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting all people who's first name is before Chris + + let query_value = json!({ + "where": [ + ["firstName", "<", "Chris"] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_names_before_chris = [ + "Adey".to_string(), + "Briney".to_string(), + "Cammi".to_string(), + "Celinda".to_string(), + ]; + assert_eq!(names, expected_names_before_chris); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting all people who's first name starts with C + + let query_value = json!({ + "where": [ + ["firstName", "StartsWith", "C"] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_names_starting_with_c = ["Cammi".to_string(), "Celinda".to_string()]; + assert_eq!(names, expected_names_starting_with_c); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting all people who's first name starts with C, but limit to 1 and be descending + + let query_value = json!({ + "where": [ + ["firstName", "StartsWith", "C"] + ], + "limit": 1, + "orderBy": [ + ["firstName", "desc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_names_starting_with_c_desc_1 = ["Celinda".to_string()]; + assert_eq!(names, expected_names_starting_with_c_desc_1); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting all people who's first name is between Chris and Noellyn included + + let query_value = json!({ + "where": [ + ["firstName", ">", "Chris"], + ["firstName", "<=", "Noellyn"] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + assert_eq!(results.len(), 5); + + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_between_names = [ + "Dalia".to_string(), + "Gilligan".to_string(), + "Kevina".to_string(), + "Meta".to_string(), + "Noellyn".to_string(), + ]; + + assert_eq!(names, expected_between_names); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting back elements having specific names + + let query_value = json!({ + "where": [ + ["firstName", "in", names] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + assert_eq!(names, expected_between_names); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + let query_value = json!({ + "where": [ + ["firstName", "in", names] + ], + "limit": 100, + "orderBy": [ + ["firstName", "desc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_reversed_between_names = [ + "Noellyn".to_string(), + "Meta".to_string(), + "Kevina".to_string(), + "Gilligan".to_string(), + "Dalia".to_string(), + ]; + + assert_eq!(names, expected_reversed_between_names); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting back elements having specific names and over a certain age + + let query_value = json!({ + "where": [ + ["firstName", "in", names], + ["age", ">=", 45] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"], + ["age", "desc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_names_45_over = [ + "Dalia".to_string(), + "Gilligan".to_string(), + "Kevina".to_string(), + "Meta".to_string(), + ]; + + assert_eq!(names, expected_names_45_over); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + // A query getting back elements having specific names and over a certain age + + let query_value = json!({ + "where": [ + ["firstName", "in", names], + ["age", ">", 48] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"], + ["age", "desc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + // Kevina is 48 so she should be now excluded, Dalia is 68, Gilligan is 49 and Meta is 59 + + let expected_names_over_48 = [ + "Dalia".to_string(), + "Gilligan".to_string(), + "Meta".to_string(), + ]; + + assert_eq!(names, expected_names_over_48); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); + + let ages: HashMap = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let name = name_value + .as_text() + .expect("the first name should be a string") + .to_string(); + let age_value = document + .get("age") + .expect("we should be able to get the age"); + let age: u8 = age_value.to_integer().expect("expected u8 value"); + (name, age) + }) + .collect(); + + let meta_age = ages + .get("Meta") + .expect("we should be able to get Kevina as she is 48"); + + assert_eq!(*meta_age, 59); + + // fetching by $id + let mut rng = rand::rngs::StdRng::seed_from_u64(84594); + let id_bytes = bs58::decode("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD") + .into_vec() + .expect("this should decode"); + + let owner_id_bytes = bs58::decode("BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj") + .into_vec() + .expect("this should decode"); + + let fixed_person = Person { + id: id_bytes, + owner_id: owner_id_bytes, + first_name: String::from("Wisdom"), + middle_name: String::from("Madabuchukwu"), + last_name: String::from("Ogwu"), + age: rng.gen_range(0..85), + }; + let serialized_person = serde_json::to_value(fixed_person).expect("serialized person"); + let person_cbor = cbor_serializer::serializable_value_to_cbor(&serialized_person, Some(0)) + .expect("expected to serialize to cbor"); + let document = Document::from_cbor(person_cbor.as_slice(), None, None, platform_version) + .expect("document should be properly deserialized"); + + let document_type = contract + .document_type_for_name("person") + .expect("expected to get document type"); + + let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); + + drive + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo((&document, storage_flags)), + owner_id: None, + }, + contract: &contract, + document_type, + }, + true, + BlockInfo::genesis(), + true, + Some(&db_transaction), + platform_version, + None, + ) + .expect("document should be inserted"); + + let id_two_bytes = bs58::decode("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179") + .into_vec() + .expect("should decode"); + let owner_id_bytes = bs58::decode("Di8dtJXv3L2YnzDNUN4w5rWLPSsSAzv6hLMMQbg3eyVA") + .into_vec() + .expect("this should decode"); + let next_person = Person { + id: id_two_bytes, + owner_id: owner_id_bytes, + first_name: String::from("Wdskdfslgjfdlj"), + middle_name: String::from("Mdsfdsgsdl"), + last_name: String::from("dkfjghfdk"), + age: rng.gen_range(0..85), + }; + let serialized_person = serde_json::to_value(next_person).expect("serialized person"); + let person_cbor = cbor_serializer::serializable_value_to_cbor(&serialized_person, Some(0)) + .expect("expected to serialize to cbor"); + let document = Document::from_cbor(person_cbor.as_slice(), None, None, platform_version) + .expect("document should be properly deserialized"); + + let document_type = contract + .document_type_for_name("person") + .expect("expected to get document type"); + + let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); + + drive + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo((&document, storage_flags)), + owner_id: None, + }, + contract: &contract, + document_type, + }, + true, + BlockInfo::genesis(), + true, + Some(&db_transaction), + platform_version, + None, + ) + .expect("document should be inserted"); + + let query_value = json!({ + "where": [ + ["$id", "in", vec![String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], + ], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + // TODO: Add test for proofs after transaction + // drive.grove.commit_transaction(db_transaction).expect("unable to commit transaction"); + // let (proof_root_hash, proof_results) = drive + // .query_documents_from_contract_as_grove_proof_only_get_elements( + // &contract, + // person_document_type, + // query_cbor.as_slice(), + // None, + // ) + // .expect("query should be executed"); + // assert_eq!(root_hash, proof_root_hash); + // assert_eq!(results, proof_results); + // let db_transaction = drive.grove.start_transaction(); + + // fetching by $id with order by + + let query_value = json!({ + "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], + ], + "orderBy": [["$id", "asc"]], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 2); + + let last_person = Document::from_bytes( + results.first().unwrap().as_slice(), + document_type, + platform_version, + ) + .expect("we should be able to deserialize the document"); + + assert_eq!( + last_person.id().to_vec(), + vec![ + 76, 161, 17, 201, 152, 232, 129, 48, 168, 13, 49, 10, 218, 53, 118, 136, 165, 198, 189, + 116, 116, 22, 133, 92, 104, 165, 186, 249, 94, 81, 45, 20, + ] + ); + + // fetching by $id with order by desc + + let query_value = json!({ + "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], + ], + "orderBy": [["$id", "desc"]], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 2); + + let last_person = Document::from_bytes( + results.first().unwrap().as_slice(), + document_type, + platform_version, + ) + .expect("we should be able to deserialize the document"); + + assert_eq!( + last_person.id().to_vec(), + vec![ + 140, 161, 17, 201, 152, 232, 129, 48, 168, 13, 49, 10, 218, 53, 118, 136, 165, 198, + 189, 116, 116, 22, 133, 92, 104, 165, 186, 249, 94, 81, 45, 20, + ] + ); + + // + // // fetching with empty where and orderBy + // + let query_value = json!({}); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 12); + + // + // // fetching with empty where and orderBy $id desc + // + let query_value = json!({ + "orderBy": [["$id", "desc"]] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 12); + + let last_person = Document::from_bytes( + results.first().unwrap().as_slice(), + document_type, + platform_version, + ) + .expect("we should be able to deserialize the document"); + + assert_eq!( + last_person.id().to_vec(), + vec![ + 249, 170, 70, 122, 181, 31, 35, 176, 175, 131, 70, 150, 250, 223, 194, 203, 175, 200, + 107, 252, 199, 227, 154, 105, 89, 57, 38, 85, 236, 192, 254, 88, + ] + ); + + // + // // fetching with ownerId in a set of values + // + let query_value = json!({ + "where": [ + ["$ownerId", "in", ["BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj", "Di8dtJXv3L2YnzDNUN4w5rWLPSsSAzv6hLMMQbg3eyVA"]] + ], + "orderBy": [["$ownerId", "desc"]] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 2); + + // + // // fetching with ownerId equal and orderBy + // + let query_value = json!({ + "where": [ + ["$ownerId", "==", "BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj"] + ], + "orderBy": [["$ownerId", "asc"]] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + // query empty contract with nested path queries + + let dashpay_contract = json_document_to_contract( + "tests/supporting_files/contract/dashpay/dashpay-contract.json", + false, + platform_version, + ) + .expect("expected to get cbor document"); + + drive + .apply_contract( + &dashpay_contract, + BlockInfo::default(), + true, + StorageFlags::optional_default_as_cow(), + None, + platform_version, + ) + .expect("expected to apply contract successfully"); + + let query_value = json!({ + "where": [ + ["$ownerId", "==", "BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj"], + ["toUserId", "==", "BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj"], + ], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &dashpay_contract, + dashpay_contract + .document_type_for_name("contactRequest") + .expect("should have contact document type"), + &query_cbor, + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 0); - let platform_version = PlatformVersion::latest(); + // using non existing document in startAt - let db_transaction = drive.grove.start_transaction(); + let query_value = json!({ + "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("5A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF178")]], + ], + "orderBy": [["$id", "asc"]], + }); - let root_hash = drive - .grove - .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) - .unwrap() - .expect("there is always a root hash"); + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); - // A query getting all elements by firstName + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + // using non existing document in startAt let query_value = json!({ "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], ], - "limit": 100, - "orderBy": [ - ["firstName", "asc"] - ] + "startAt": String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF178"), + "orderBy": [["$id", "asc"]], }); - let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); + let person_document_type = contract .document_type_for_name("person") .expect("contract should have a person document type"); - let query = DriveDocumentQuery::from_cbor( - where_cbor.as_slice(), + + let result = drive.query_documents_cbor_from_contract( &contract, person_document_type, - &drive.config, - ) - .expect("query should be built"); - let (results, _, _) = query - .execute_raw_results_no_proof(&drive, None, Some(&db_transaction), platform_version) - .expect("proof should be executed"); - - let (proof_root_hash, proof_results, _) = query - .execute_with_proof_only_get_elements(&drive, None, None, platform_version) - .expect("we should be able to a proof"); - assert_eq!(root_hash, proof_root_hash); - assert_eq!(results, proof_results); -} - -#[cfg(feature = "server")] -#[test] -fn test_non_existence_reference_proof_single_index() { - let (drive, contract) = setup_family_tests_only_first_name_index(0, 73509); - - let platform_version = PlatformVersion::latest(); - - let db_transaction = drive.grove.start_transaction(); + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ); - let root_hash = drive - .grove - .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) - .unwrap() - .expect("there is always a root hash"); + assert!( + matches!(result, Err(Error::Query(QuerySyntaxError::StartDocumentNotFound(message))) if message == "startAt document not found") + ); - // A query getting all elements by firstName + // using non existing document in startAfter let query_value = json!({ "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], ], - "limit": 100, - "orderBy": [ - ["firstName", "asc"] - ] + "startAfter": String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF178"), + "orderBy": [["$id", "asc"]], }); - let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) .expect("expected to serialize to cbor"); + let person_document_type = contract .document_type_for_name("person") .expect("contract should have a person document type"); - let query = DriveDocumentQuery::from_cbor( - where_cbor.as_slice(), + + let result = drive.query_documents_cbor_from_contract( &contract, person_document_type, - &drive.config, - ) - .expect("query should be built"); - let (results, _, _) = query - .execute_raw_results_no_proof(&drive, None, Some(&db_transaction), platform_version) - .expect("proof should be executed"); + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ); - let (proof_root_hash, proof_results, _) = query - .execute_with_proof_only_get_elements(&drive, None, None, platform_version) - .expect("we should be able to a proof"); - assert_eq!(root_hash, proof_root_hash); - assert_eq!(results, proof_results); + assert!( + matches!(result, Err(Error::Query(QuerySyntaxError::StartDocumentNotFound(message))) if message == "startAfter document not found") + ); + + // validate eventual root hash + + let root_hash = drive + .grove + .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) + .unwrap() + .expect("there is always a root hash"); + + assert_eq!( + root_hash.as_slice(), + vec![ + 251, 69, 177, 93, 128, 236, 106, 87, 205, 123, 80, 61, 44, 107, 186, 193, 22, 192, 239, + 7, 107, 110, 97, 197, 59, 245, 26, 12, 63, 91, 248, 231 + ], + ); } #[cfg(feature = "server")] #[test] fn test_family_basic_queries() { - let (drive, contract) = setup_family_tests(10, 73509); let platform_version = PlatformVersion::latest(); + let (drive, contract) = setup_family_tests(10, 73509, platform_version); let db_transaction = drive.grove.start_transaction(); @@ -1192,8 +2537,8 @@ fn test_family_basic_queries() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 32, 210, 24, 196, 148, 43, 20, 34, 0, 116, 183, 136, 32, 210, 163, 183, 214, 6, 152, 86, - 46, 45, 88, 13, 23, 41, 37, 70, 129, 119, 211, 12, + 63, 90, 74, 129, 70, 204, 232, 67, 190, 85, 133, 79, 254, 245, 203, 180, 77, 67, 94, 22, + 180, 99, 51, 251, 82, 117, 211, 14, 136, 51, 228, 177, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2506,8 +3851,8 @@ fn test_family_basic_queries() { assert_eq!( root_hash.as_slice(), vec![ - 251, 69, 177, 93, 128, 236, 106, 87, 205, 123, 80, 61, 44, 107, 186, 193, 22, 192, 239, - 7, 107, 110, 97, 197, 59, 245, 26, 12, 63, 91, 248, 231, + 187, 202, 114, 108, 228, 21, 246, 191, 11, 30, 112, 178, 38, 36, 145, 109, 238, 11, + 210, 210, 0, 227, 175, 151, 149, 166, 143, 15, 144, 255, 82, 229, ], ); } @@ -2515,9 +3860,8 @@ fn test_family_basic_queries() { #[cfg(feature = "server")] #[test] fn test_family_person_update() { - let (drive, contract) = setup_family_tests(10, 73509); - let platform_version = PlatformVersion::latest(); + let (drive, contract) = setup_family_tests(10, 73509, platform_version); let epoch_change_fee_version_test: Lazy = Lazy::new(|| BTreeMap::from([(0, FeeVersion::first())])); @@ -2645,9 +3989,8 @@ fn test_family_person_update() { #[cfg(feature = "server")] #[test] fn test_family_starts_at_queries() { - let (drive, contract) = setup_family_tests(10, 73509); - let platform_version = PlatformVersion::latest(); + let (drive, contract) = setup_family_tests(10, 73509, platform_version); let db_transaction = drive.grove.start_transaction(); @@ -2658,8 +4001,8 @@ fn test_family_starts_at_queries() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 32, 210, 24, 196, 148, 43, 20, 34, 0, 116, 183, 136, 32, 210, 163, 183, 214, 6, 152, 86, - 46, 45, 88, 13, 23, 41, 37, 70, 129, 119, 211, 12, + 63, 90, 74, 129, 70, 204, 232, 67, 190, 85, 133, 79, 254, 245, 203, 180, 77, 67, 94, 22, + 180, 99, 51, 251, 82, 117, 211, 14, 136, 51, 228, 177, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -2908,10 +4251,11 @@ fn test_family_starts_at_queries() { #[cfg(feature = "server")] #[test] fn test_family_sql_query() { + let platform_version = PlatformVersion::latest(); // These helpers confirm that sql statements produce the same drive query // as their json counterparts, helpers above confirm that the json queries // produce the correct result set - let (drive, contract) = setup_family_tests(10, 73509); + let (drive, contract) = setup_family_tests(10, 73509, platform_version); let person_document_type = contract .document_type_for_name("person") .expect("contract should have a person document type"); @@ -3109,8 +4453,8 @@ fn test_family_with_nulls_query() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 92, 186, 224, 49, 242, 195, 32, 14, 46, 55, 244, 57, 55, 191, 10, 119, 228, 132, 91, 235, - 170, 114, 36, 41, 126, 136, 180, 51, 132, 17, 26, 182, + 144, 185, 8, 30, 191, 97, 149, 182, 117, 203, 98, 187, 156, 93, 168, 171, 134, 112, 221, + 230, 249, 131, 86, 1, 26, 92, 242, 25, 251, 187, 192, 182, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3219,9 +4563,8 @@ fn test_family_with_nulls_query() { #[cfg(feature = "server")] #[test] fn test_query_with_cached_contract() { - let (drive, contract) = setup_family_tests(10, 73509); - let platform_version = PlatformVersion::latest(); + let (drive, contract) = setup_family_tests(10, 73509, platform_version); let db_transaction = drive.grove.start_transaction(); @@ -3233,8 +4576,8 @@ fn test_query_with_cached_contract() { // Make sure the state is deterministic let expected_app_hash = vec![ - 32, 210, 24, 196, 148, 43, 20, 34, 0, 116, 183, 136, 32, 210, 163, 183, 214, 6, 152, 86, - 46, 45, 88, 13, 23, 41, 37, 70, 129, 119, 211, 12, + 63, 90, 74, 129, 70, 204, 232, 67, 190, 85, 133, 79, 254, 245, 203, 180, 77, 67, 94, 22, + 180, 99, 51, 251, 82, 117, 211, 14, 136, 51, 228, 177, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -3292,9 +4635,8 @@ fn test_query_with_cached_contract() { #[cfg(feature = "server")] #[test] fn test_dpns_query_contract_verification() { - let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456); - let platform_version = PlatformVersion::latest(); + let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456, platform_version); let root_hash = drive .grove @@ -3368,10 +4710,9 @@ fn test_contract_keeps_history_fetch_and_verification() { #[cfg(feature = "server")] #[test] -fn test_dpns_query() { - let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456); - - let platform_version = PlatformVersion::latest(); +fn test_dpns_query_first_version() { + let platform_version = PlatformVersion::first(); + let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456, &platform_version); let db_transaction = drive.grove.start_transaction(); @@ -3919,9 +5260,10 @@ fn test_dpns_insertion_with_aliases() { #[cfg(feature = "server")] #[test] -fn test_dpns_query_start_at() { +fn test_dpns_query_start_at_first_version() { + let platform_version = PlatformVersion::first(); // The point of this test is to test the situation where we have a start at a certain value for the DPNS query. - let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456); + let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456, platform_version); let platform_version = PlatformVersion::latest(); @@ -4011,11 +5353,107 @@ fn test_dpns_query_start_at() { assert_eq!(results, proof_results); } +#[cfg(feature = "server")] +#[test] +fn test_dpns_query_start_at_latest_version() { + let platform_version = PlatformVersion::latest(); + // The point of this test is to test the situation where we have a start at a certain value for the DPNS query. + let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456, platform_version); + + let platform_version = PlatformVersion::latest(); + + let db_transaction = drive.grove.start_transaction(); + + let root_hash = drive + .grove + .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) + .unwrap() + .expect("there is always a root hash"); + + let expected_app_hash = vec![ + 248, 74, 104, 110, 129, 228, 194, 1, 4, 239, 134, 54, 105, 172, 221, 43, 101, 133, 235, + 146, 182, 153, 212, 118, 189, 99, 227, 14, 94, 83, 17, 98, + ]; + + assert_eq!(root_hash.as_slice(), expected_app_hash,); + + // let all_names = [ + // "amalle".to_string(), + // "anna-diane".to_string(), + // "atalanta".to_string(), + // "eden".to_string(), + // "laureen".to_string(), + // "leone".to_string(), + // "marilyn".to_string(), + // "minna".to_string(), + // "mora".to_string(), + // "phillie".to_string(), + // ]; + + // A query getting one element starting with a in dash parent domain asc + + let anna_id = hex::decode("0e97eb86ceca4309751616089336a127a5d48282712473b2d0fc5663afb1a080") + .expect("expected to decode id"); + let encoded_start_at = bs58::encode(anna_id).into_string(); + + let query_value = json!({ + "where": [ + ["normalizedParentDomainName", "==", "dash"] + ], + "startAt": encoded_start_at, + "limit": 1, + "orderBy": [ + ["normalizedLabel", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let domain_document_type = contract + .document_type_for_name("domain") + .expect("contract should have a domain document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + domain_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, Some(&db_transaction), platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), domain_document_type, platform_version) + .expect("we should be able to deserialize the document"); + let normalized_label_value = document + .get("normalizedLabel") + .expect("we should be able to get the first name"); + let normalized_label = normalized_label_value + .as_text() + .expect("the normalized label should be a string"); + String::from(normalized_label) + }) + .collect(); + + let a_names = ["anna-diane".to_string()]; + + assert_eq!(names, a_names); + + let (proof_root_hash, proof_results, _) = query + .execute_with_proof_only_get_elements(&drive, None, None, platform_version) + .expect("we should be able to a proof"); + assert_eq!(root_hash, proof_root_hash); + assert_eq!(results, proof_results); +} + #[cfg(feature = "server")] #[test] fn test_dpns_query_start_after() { + let platform_version = PlatformVersion::latest(); // The point of this test is to test the situation where we have a start at a certain value for the DPNS query. - let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456); + let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456, platform_version); let platform_version = PlatformVersion::latest(); @@ -4028,8 +5466,8 @@ fn test_dpns_query_start_after() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 142, 246, 25, 166, 52, 184, 158, 102, 192, 111, 173, 255, 155, 125, 53, 233, 98, 241, 201, - 233, 2, 58, 47, 90, 209, 207, 147, 204, 83, 68, 183, 143, + 248, 74, 104, 110, 129, 228, 194, 1, 4, 239, 134, 54, 105, 172, 221, 43, 101, 133, 235, + 146, 182, 153, 212, 118, 189, 99, 227, 14, 94, 83, 17, 98, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -4108,8 +5546,9 @@ fn test_dpns_query_start_after() { #[cfg(feature = "server")] #[test] fn test_dpns_query_start_at_desc() { + let platform_version = PlatformVersion::latest(); // The point of this test is to test the situation where we have a start at a certain value for the DPNS query. - let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456); + let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456, platform_version); let platform_version = PlatformVersion::latest(); @@ -4122,8 +5561,8 @@ fn test_dpns_query_start_at_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 142, 246, 25, 166, 52, 184, 158, 102, 192, 111, 173, 255, 155, 125, 53, 233, 98, 241, 201, - 233, 2, 58, 47, 90, 209, 207, 147, 204, 83, 68, 183, 143, + 248, 74, 104, 110, 129, 228, 194, 1, 4, 239, 134, 54, 105, 172, 221, 43, 101, 133, 235, + 146, 182, 153, 212, 118, 189, 99, 227, 14, 94, 83, 17, 98, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -4202,8 +5641,9 @@ fn test_dpns_query_start_at_desc() { #[cfg(feature = "server")] #[test] fn test_dpns_query_start_after_desc() { + let platform_version = PlatformVersion::latest(); // The point of this test is to test the situation where we have a start at a certain value for the DPNS query. - let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456); + let (drive, contract) = setup_dpns_tests_with_batches(10, None, 11456, platform_version); let platform_version = PlatformVersion::latest(); @@ -4216,8 +5656,8 @@ fn test_dpns_query_start_after_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 142, 246, 25, 166, 52, 184, 158, 102, 192, 111, 173, 255, 155, 125, 53, 233, 98, 241, 201, - 233, 2, 58, 47, 90, 209, 207, 147, 204, 83, 68, 183, 143, + 248, 74, 104, 110, 129, 228, 194, 1, 4, 239, 134, 54, 105, 172, 221, 43, 101, 133, 235, + 146, 182, 153, 212, 118, 189, 99, 227, 14, 94, 83, 17, 98, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -4410,8 +5850,8 @@ fn test_dpns_query_start_at_with_null_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 72, 138, 172, 70, 225, 95, 64, 122, 142, 96, 131, 223, 154, 119, 132, 79, 182, 97, 202, 63, - 120, 116, 39, 217, 25, 208, 176, 49, 242, 138, 67, 112, + 11, 67, 98, 193, 214, 56, 66, 244, 193, 131, 252, 190, 5, 52, 29, 96, 160, 27, 222, 78, 91, + 150, 54, 85, 81, 249, 14, 74, 213, 181, 254, 120, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -4615,8 +6055,8 @@ fn test_dpns_query_start_after_with_null_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 72, 138, 172, 70, 225, 95, 64, 122, 142, 96, 131, 223, 154, 119, 132, 79, 182, 97, 202, 63, - 120, 116, 39, 217, 25, 208, 176, 49, 242, 138, 67, 112, + 11, 67, 98, 193, 214, 56, 66, 244, 193, 131, 252, 190, 5, 52, 29, 96, 160, 27, 222, 78, 91, + 150, 54, 85, 81, 249, 14, 74, 213, 181, 254, 120, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -4823,8 +6263,8 @@ fn test_dpns_query_start_after_with_null_id_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 72, 138, 172, 70, 225, 95, 64, 122, 142, 96, 131, 223, 154, 119, 132, 79, 182, 97, 202, 63, - 120, 116, 39, 217, 25, 208, 176, 49, 242, 138, 67, 112, + 11, 67, 98, 193, 214, 56, 66, 244, 193, 131, 252, 190, 5, 52, 29, 96, 160, 27, 222, 78, 91, + 150, 54, 85, 81, 249, 14, 74, 213, 181, 254, 120, ]; assert_eq!(root_hash.as_slice(), expected_app_hash,); @@ -5036,8 +6476,8 @@ fn test_withdrawals_query_by_owner_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 144, 177, 24, 41, 104, 174, 220, 135, 164, 0, 240, 215, 42, 60, 249, 142, 150, 169, 135, - 72, 151, 35, 238, 131, 164, 229, 106, 83, 198, 109, 65, 211, + 27, 172, 224, 121, 173, 248, 170, 255, 202, 209, 7, 83, 203, 185, 208, 102, 157, 75, 55, + 21, 217, 212, 91, 174, 144, 146, 135, 92, 97, 156, 166, 6, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -5116,8 +6556,8 @@ fn test_withdrawals_query_start_after_query_by_owner_id() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 144, 177, 24, 41, 104, 174, 220, 135, 164, 0, 240, 215, 42, 60, 249, 142, 150, 169, 135, - 72, 151, 35, 238, 131, 164, 229, 106, 83, 198, 109, 65, 211, + 27, 172, 224, 121, 173, 248, 170, 255, 202, 209, 7, 83, 203, 185, 208, 102, 157, 75, 55, + 21, 217, 212, 91, 174, 144, 146, 135, 92, 97, 156, 166, 6, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); @@ -5217,8 +6657,8 @@ fn test_withdrawals_query_start_after_query_by_owner_id_desc() { .expect("there is always a root hash"); let expected_app_hash = vec![ - 144, 177, 24, 41, 104, 174, 220, 135, 164, 0, 240, 215, 42, 60, 249, 142, 150, 169, 135, - 72, 151, 35, 238, 131, 164, 229, 106, 83, 198, 109, 65, 211, + 27, 172, 224, 121, 173, 248, 170, 255, 202, 209, 7, 83, 203, 185, 208, 102, 157, 75, 55, + 21, 217, 212, 91, 174, 144, 146, 135, 92, 97, 156, 166, 6, ]; assert_eq!(root_hash.as_slice(), expected_app_hash); diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index c14dfeca9e9..697487eb11c 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -161,11 +161,10 @@ pub fn setup( count: usize, restrict_to_inserts: Option>, seed: u64, + platform_version: &PlatformVersion, ) -> (Drive, DataContract) { let drive_config = DriveConfig::default(); - let platform_version = PlatformVersion::latest(); - let epoch_change_fee_version_test: Lazy = Lazy::new(|| BTreeMap::from([(0, FeeVersion::first())])); @@ -188,6 +187,7 @@ pub fn setup( "tests/supporting_files/contract/family/family-contract-with-history.json", None, Some(&db_transaction), + Some(platform_version), ); let block_times: Vec = vec![0, 15, 100, 1000]; @@ -250,15 +250,15 @@ pub fn setup( #[test] fn test_setup() { let range_inserts = vec![0, 2]; - setup(10, Some(range_inserts), 73509); + let platform_version = PlatformVersion::latest(); + setup(10, Some(range_inserts), 73509, platform_version); } #[cfg(feature = "server")] #[test] -fn test_query_historical() { - let (drive, contract) = setup(10, None, 73509); - - let platform_version = PlatformVersion::latest(); +fn test_query_historical_first_platform_version() { + let platform_version = PlatformVersion::first(); + let (drive, contract) = setup(10, None, 73509, platform_version); let epoch_change_fee_version_test: Lazy = Lazy::new(|| BTreeMap::from([(0, FeeVersion::first())])); @@ -1644,3 +1644,1394 @@ fn test_query_historical() { ] ); } + +#[cfg(feature = "server")] +#[test] +fn test_query_historical_latest_platform_version() { + let platform_version = PlatformVersion::latest(); + let (drive, contract) = setup(10, None, 73509, platform_version); + + let epoch_change_fee_version_test: Lazy = + Lazy::new(|| BTreeMap::from([(0, FeeVersion::first())])); + + let db_transaction = drive.grove.start_transaction(); + + let root_hash = drive + .grove + .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) + .unwrap() + .expect("there is always a root hash"); + assert_eq!( + root_hash.as_slice(), + vec![ + 5, 227, 59, 163, 38, 58, 181, 91, 23, 56, 47, 52, 138, 63, 5, 54, 205, 249, 205, 225, + 78, 225, 195, 2, 104, 6, 11, 77, 56, 69, 113, 237, + ] + ); + + let all_names = [ + "Adey".to_string(), + "Briney".to_string(), + "Cammi".to_string(), + "Celinda".to_string(), + "Dalia".to_string(), + "Gilligan".to_string(), + "Kevina".to_string(), + "Meta".to_string(), + "Noellyn".to_string(), + "Prissie".to_string(), + ]; + + // A query getting all elements by firstName + + let query_value = json!({ + "where": [ + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, Some(&db_transaction), platform_version) + .expect("proof should be executed"); + let names: Vec = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + assert_eq!(names, all_names); + + // A query getting all people who's first name is Chris (which should exist) + + let query_value = json!({ + "where": [ + ["firstName", "==", "Adey"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + // A query getting all people who's first name is Adey and lastName Randolf + + let query_value = json!({ + "where": [ + ["firstName", "==", "Adey"], + ["lastName", "==", "Randolf"] + ], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + let document = Document::from_bytes( + results.first().unwrap().as_slice(), + person_document_type, + platform_version, + ) + .expect("we should be able to deserialize the cbor"); + let last_name = document + .get("lastName") + .expect("we should be able to get the last name") + .as_text() + .expect("last name must be a string"); + + assert_eq!(last_name, "Randolf"); + + // A query getting all people who's first name is in a range with a single element Adey, + // order by lastName (this should exist) + + let query_value = json!({ + "where": [ + ["firstName", "in", ["Adey"]] + ], + "orderBy": [ + ["firstName", "asc"], + ["lastName", "asc"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + // A query getting all people who's first name is Adey, order by lastName (which should exist) + + let query_value = json!({ + "where": [ + ["firstName", "==", "Adey"] + ], + "orderBy": [ + ["lastName", "asc"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + let document = Document::from_bytes( + results.first().unwrap().as_slice(), + person_document_type, + platform_version, + ) + .expect("we should be able to deserialize the cbor"); + let last_name = document + .get("lastName") + .expect("we should be able to get the last name") + .as_text() + .expect("last name must be a string"); + + assert_eq!(last_name, "Randolf"); + + // A query getting all people who's first name is Chris (which is not exist) + + let query_value = json!({ + "where": [ + ["firstName", "==", "Chris"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 0); + + // A query getting a middle name + + let query_value = json!({ + "where": [ + ["middleName", "==", "Briggs"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + None, + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + // A query getting all people who's first name is before Chris + + let query_value = json!({ + "where": [ + ["firstName", "<", "Chris"] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_names_before_chris = [ + "Adey".to_string(), + "Briney".to_string(), + "Cammi".to_string(), + "Celinda".to_string(), + ]; + assert_eq!(names, expected_names_before_chris); + + // A query getting all people who's first name is before Chris + + let query_value = json!({ + "where": [ + ["firstName", "StartsWith", "C"] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_names_before_chris = ["Cammi".to_string(), "Celinda".to_string()]; + assert_eq!(names, expected_names_before_chris); + + // A query getting all people who's first name is between Chris and Noellyn included + + let query_value = json!({ + "where": [ + ["firstName", ">", "Chris"], + ["firstName", "<=", "Noellyn"] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + assert_eq!(results.len(), 5); + + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_between_names = [ + "Dalia".to_string(), + "Gilligan".to_string(), + "Kevina".to_string(), + "Meta".to_string(), + "Noellyn".to_string(), + ]; + + assert_eq!(names, expected_between_names); + + // A query getting all people who's first name is between Chris and Noellyn included + // However here there will be a startAt of the ID of Kevina + + // Let's first get the ID of Kevina + let ids: HashMap> = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let name = name_value + .as_text() + .expect("the first name should be a string") + .to_string(); + (name, document.id().to_vec()) + }) + .collect(); + + let kevina_id = ids + .get("Kevina") + .expect("We should be able to get back Kevina's Id"); + let kevina_encoded_id = bs58::encode(kevina_id).into_string(); + + let query_value = json!({ + "where": [ + ["firstName", ">", "Chris"], + ["firstName", "<=", "Noellyn"] + ], + "startAt": kevina_encoded_id, //Kevina + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + assert_eq!(results.len(), 3); + + let reduced_names_after: Vec = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_reduced_names = [ + "Kevina".to_string(), + "Meta".to_string(), + "Noellyn".to_string(), + ]; + + assert_eq!(reduced_names_after, expected_reduced_names); + + // Now lets try startsAfter + + let query_value = json!({ + "where": [ + ["firstName", ">", "Chris"], + ["firstName", "<=", "Noellyn"] + ], + "startAfter": kevina_encoded_id, //Kevina + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + assert_eq!(results.len(), 2); + + let reduced_names_after: Vec = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let expected_reduced_names = ["Meta".to_string(), "Noellyn".to_string()]; + + assert_eq!(reduced_names_after, expected_reduced_names); + + // A query getting back elements having specific names + + let query_value = json!({ + "where": [ + ["firstName", "in", names] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + assert_eq!(names, expected_between_names); + + let query_value = json!({ + "where": [ + ["firstName", "in", names] + ], + "limit": 100, + "orderBy": [ + ["firstName", "desc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .clone() + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + let ages: Vec = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let age_value = document + .get("age") + .expect("we should be able to get the age"); + let age: u64 = age_value + .to_integer() + .expect("the age should be put in an u64"); + age + }) + .collect(); + + let expected_reversed_between_names = [ + "Noellyn".to_string(), // 40 + "Meta".to_string(), // 69 + "Kevina".to_string(), // 58 + "Gilligan".to_string(), // 59 + "Dalia".to_string(), // 78 + ]; + + assert_eq!(names, expected_reversed_between_names); + + let expected_ages = [40, 69, 58, 59, 78]; + + assert_eq!(ages, expected_ages); + + // A query getting back elements having specific names and over a certain age + + let query_value = json!({ + "where": [ + ["firstName", "in", names], + ["age", ">=", 45] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"], + ["age", "desc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + // Kevina is 55, and is excluded from this test + let expected_names_45_over = [ + "Dalia".to_string(), + "Gilligan".to_string(), + "Kevina".to_string(), + "Meta".to_string(), + ]; + + assert_eq!(names, expected_names_45_over); + + // A query getting back elements having specific names and over a certain age + + let query_value = json!({ + "where": [ + ["firstName", "in", names], + ["age", ">", 58] + ], + "limit": 100, + "orderBy": [ + ["firstName", "asc"], + ["age", "desc"] + ] + }); + let where_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + let query = DriveDocumentQuery::from_cbor( + where_cbor.as_slice(), + &contract, + person_document_type, + &drive.config, + ) + .expect("query should be built"); + let (results, _, _) = query + .execute_raw_results_no_proof(&drive, None, None, platform_version) + .expect("proof should be executed"); + let names: Vec = results + .iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let first_name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let first_name = first_name_value + .as_text() + .expect("the first name should be a string"); + String::from(first_name) + }) + .collect(); + + // Kevina is 48 so she should be now excluded, Dalia is 68, Gilligan is 49 and Meta is 59 + + let expected_names_over_48 = [ + "Dalia".to_string(), + "Gilligan".to_string(), + "Meta".to_string(), + ]; + + assert_eq!(names, expected_names_over_48); + + let ages: HashMap = results + .into_iter() + .map(|result| { + let document = + Document::from_bytes(result.as_slice(), person_document_type, platform_version) + .expect("we should be able to deserialize the cbor"); + let name_value = document + .get("firstName") + .expect("we should be able to get the first name"); + let name = name_value + .as_text() + .expect("the first name should be a string") + .to_string(); + let age_value = document + .get("age") + .expect("we should be able to get the age"); + let age: u8 = age_value.to_integer().expect("age should be an integer"); + (name, age) + }) + .collect(); + + let meta_age = ages + .get("Meta") + .expect("we should be able to get Kevina as she is 48"); + + assert_eq!(*meta_age, 69); + + // fetching by $id + let mut rng = rand::rngs::StdRng::seed_from_u64(84594); + let id_bytes = bs58::decode("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD") + .into_vec() + .expect("this should decode"); + + let owner_id_bytes = bs58::decode("BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj") + .into_vec() + .expect("this should decode"); + + let fixed_person = Person { + id: id_bytes, + owner_id: owner_id_bytes, + first_name: String::from("Wisdom"), + middle_name: String::from("Madabuchukwu"), + last_name: String::from("Ogwu"), + message: Some(String::from("Oh no")), + age: rng.gen_range(0..85), + }; + let serialized_person = serde_json::to_value(fixed_person).expect("serialized person"); + let person_cbor = cbor_serializer::serializable_value_to_cbor(&serialized_person, Some(0)) + .expect("expected to serialize to cbor"); + let document = Document::from_cbor(person_cbor.as_slice(), None, None, platform_version) + .expect("document should be properly deserialized"); + + let document_type = contract + .document_type_for_name("person") + .expect("expected to get document type"); + + let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); + + drive + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo((&document, storage_flags)), + owner_id: None, + }, + contract: &contract, + document_type, + }, + true, + BlockInfo::genesis(), + true, + Some(&db_transaction), + platform_version, + Some(&epoch_change_fee_version_test), + ) + .expect("document should be inserted"); + + let id_two_bytes = bs58::decode("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179") + .into_vec() + .expect("should decode"); + let owner_id_bytes = bs58::decode("Di8dtJXv3L2YnzDNUN4w5rWLPSsSAzv6hLMMQbg3eyVA") + .into_vec() + .expect("this should decode"); + let next_person = Person { + id: id_two_bytes, + owner_id: owner_id_bytes, + first_name: String::from("Wdskdfslgjfdlj"), + middle_name: String::from("Mdsfdsgsdl"), + last_name: String::from("dkfjghfdk"), + message: Some(String::from("Bad name")), + age: rng.gen_range(0..85), + }; + let serialized_person = serde_json::to_value(next_person).expect("serialized person"); + let person_cbor = cbor_serializer::serializable_value_to_cbor(&serialized_person, Some(0)) + .expect("expected to serialize to cbor"); + let document = Document::from_cbor(person_cbor.as_slice(), None, None, platform_version) + .expect("document should be properly deserialized"); + + let document_type = contract + .document_type_for_name("person") + .expect("expected to get document type"); + + let storage_flags = Some(Cow::Owned(StorageFlags::SingleEpoch(0))); + + drive + .add_document_for_contract( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentRefInfo((&document, storage_flags)), + owner_id: None, + }, + contract: &contract, + document_type, + }, + true, + BlockInfo::genesis(), + true, + Some(&db_transaction), + platform_version, + None, + ) + .expect("document should be inserted"); + + let query_value = json!({ + "where": [ + ["$id", "in", vec![String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], + ], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + let query_value = json!({ + "where": [ + ["$id", "==", "6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179"] + ] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + let query_value = json!({ + "where": [ + ["$id", "==", "6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179"] + ], + "blockTime": 300 + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + // fetching by $id with order by + + let query_value = json!({ + "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], + ], + "orderBy": [["$id", "asc"]], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 2); + + let last_person = Document::from_bytes( + results.first().unwrap().as_slice(), + person_document_type, + platform_version, + ) + .expect("we should be able to deserialize the cbor"); + + assert_eq!( + last_person.id().to_vec(), + vec![ + 76, 161, 17, 201, 152, 232, 129, 48, 168, 13, 49, 10, 218, 53, 118, 136, 165, 198, 189, + 116, 116, 22, 133, 92, 104, 165, 186, 249, 94, 81, 45, 20 + ] + .as_slice() + ); + + // fetching by $id with order by desc + + let query_value = json!({ + "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], + ], + "orderBy": [["$id", "desc"]], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 2); + + let last_person = Document::from_bytes( + results.first().unwrap().as_slice(), + person_document_type, + platform_version, + ) + .expect("we should be able to deserialize the cbor"); + + assert_eq!( + last_person.id().to_vec(), + vec![ + 140, 161, 17, 201, 152, 232, 129, 48, 168, 13, 49, 10, 218, 53, 118, 136, 165, 198, + 189, 116, 116, 22, 133, 92, 104, 165, 186, 249, 94, 81, 45, 20 + ] + .as_slice() + ); + + // + // // fetching with empty where and orderBy + // + let query_value = json!({}); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 12); + + // + // // fetching with empty where and orderBy $id desc + // + let query_value = json!({ + "orderBy": [["$id", "desc"]] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 12); + + let last_person = Document::from_bytes( + results.first().unwrap().as_slice(), + person_document_type, + platform_version, + ) + .expect("we should be able to deserialize the cbor"); + + assert_eq!( + last_person.id().to_vec(), + vec![ + 249, 170, 70, 122, 181, 31, 35, 176, 175, 131, 70, 150, 250, 223, 194, 203, 175, 200, + 107, 252, 199, 227, 154, 105, 89, 57, 38, 85, 236, 192, 254, 88 + ] + .as_slice() + ); + + let message_value = last_person.get("message").unwrap(); + + let message = message_value + .as_text() + .expect("the message should be a string") + .to_string(); + + assert_eq!( + message, + String::from("“Since it’s the customer that pays our salary, our responsibility is to make the product they want, when they want it, and deliv") + ); + + // + // // fetching with empty where and orderBy $id desc with a blockTime + // + let query_value = json!({ + "orderBy": [["$id", "desc"]], + "blockTime": 300 + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect_err("not yet implemented"); + + // assert_eq!(results.len(), 12); + // + // let last_person = Document::from_bytes(results.first().unwrap().as_slice(), person_document_type, platform_version) + // .expect("we should be able to deserialize the cbor"); + // + // assert_eq!( + // last_person.id, + // vec![ + // 249, 170, 70, 122, 181, 31, 35, 176, 175, 131, 70, 150, 250, 223, 194, 203, 175, 200, + // 107, 252, 199, 227, 154, 105, 89, 57, 38, 85, 236, 192, 254, 88 + // ] + // .as_slice() + // ); + // + // let message_value = last_person.get("message").unwrap(); + // + // let message = message_value + // .as_text() + // .expect("the message should be a string") + // .to_string(); + // + // assert_eq!( + // message, + // String::from("“Since it’s the customer that pays our salary, our responsibility is to make the product they want, when they want it, and deliver quality that satisfies them.” Retired factory worker, Kiyoshi Tsutsumi (Osono et al 2008, 136)") + // ); + + // + // // fetching with ownerId in a set of values + // + let query_value = json!({ + "where": [ + ["$ownerId", "in", ["BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj", "Di8dtJXv3L2YnzDNUN4w5rWLPSsSAzv6hLMMQbg3eyVA"]] + ], + "orderBy": [["$ownerId", "desc"]] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 2); + + // + // // fetching with ownerId equal and orderBy + // + let query_value = json!({ + "where": [ + ["$ownerId", "==", "BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj"] + ], + "orderBy": [["$ownerId", "asc"]] + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 1); + + // query empty contract with nested path queries + + let dashpay_contract = json_document_to_contract( + "tests/supporting_files/contract/dashpay/dashpay-contract.json", + false, + platform_version, + ) + .expect("expected to get cbor document"); + + drive + .apply_contract( + &dashpay_contract, + BlockInfo::default(), + true, + StorageFlags::optional_default_as_cow(), + Some(&db_transaction), + platform_version, + ) + .expect("expected to apply contract successfully"); + + let query_value = json!({ + "where": [ + ["$ownerId", "==", "BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj"], + ["toUserId", "==", "BYR3zJgXDuz1BYAkEagwSjVqTcE1gbqEojd6RwAGuMzj"], + ], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let (results, _, _) = drive + .query_documents_cbor_from_contract( + &dashpay_contract, + dashpay_contract + .document_type_for_name("contactRequest") + .expect("should have contact document type"), + &query_cbor, + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ) + .expect("query should be executed"); + + assert_eq!(results.len(), 0); + + // using non existing document in startAt + + let query_value = json!({ + "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], + ], + "startAt": String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF178"), + "orderBy": [["$id", "asc"]], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let result = drive.query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ); + + assert!( + matches!(result, Err(Error::Query(QuerySyntaxError::StartDocumentNotFound(message))) if message == "startAt document not found") + ); + + // using non-existing document in startAfter + + let query_value = json!({ + "where": [ + ["$id", "in", [String::from("ATxXeP5AvY4aeUFA6WRo7uaBKTBgPQCjTrgtNpCMNVRD"), String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF179")]], + ], + "startAfter": String::from("6A8SGgdmj2NtWCYoYDPDpbsYkq2MCbgi6Lx4ALLfF178"), + "orderBy": [["$id", "asc"]], + }); + + let query_cbor = cbor_serializer::serializable_value_to_cbor(&query_value, None) + .expect("expected to serialize to cbor"); + + let person_document_type = contract + .document_type_for_name("person") + .expect("contract should have a person document type"); + + let result = drive.query_documents_cbor_from_contract( + &contract, + person_document_type, + query_cbor.as_slice(), + None, + Some(&db_transaction), + Some(platform_version.protocol_version), + ); + + assert!( + matches!(result, Err(Error::Query(QuerySyntaxError::StartDocumentNotFound(message))) if message == "startAfter document not found") + ); + + // validate eventual root hash + + let root_hash = drive + .grove + .root_hash(Some(&db_transaction), &platform_version.drive.grove_version) + .unwrap() + .expect("there is always a root hash"); + assert_eq!( + root_hash.as_slice(), + vec![ + 203, 160, 200, 71, 200, 156, 249, 93, 201, 35, 171, 6, 57, 176, 159, 104, 26, 253, 141, + 193, 153, 0, 212, 9, 207, 239, 250, 51, 68, 228, 210, 164 + ] + ); +} diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rs index 91fd85cbae1..6f74987f92e 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/mod.rs @@ -1,5 +1,6 @@ use versioned_feature_core::{FeatureVersion, FeatureVersionBounds}; pub mod v1; +pub mod v2; #[derive(Clone, Debug, Default)] pub struct DPPContractVersions { diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs new file mode 100644 index 00000000000..db759e5c5f7 --- /dev/null +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs @@ -0,0 +1,54 @@ +use crate::version::dpp_versions::dpp_contract_versions::{ + DPPContractVersions, DataContractMethodVersions, DocumentTypeClassMethodVersions, + DocumentTypeIndexVersions, DocumentTypeMethodVersions, DocumentTypeSchemaVersions, + DocumentTypeVersions, RecursiveSchemaValidatorVersions, +}; +use versioned_feature_core::FeatureVersionBounds; + +pub const CONTRACT_VERSIONS_V2: DPPContractVersions = DPPContractVersions { + max_serialized_size: 65000, + contract_serialization_version: FeatureVersionBounds { + min_version: 0, + max_version: 1, + default_current_version: 1, + }, + contract_structure_version: 1, + created_data_contract_structure: 0, + config: 0, + methods: DataContractMethodVersions { + validate_document: 0, + validate_update: 0, + schema: 0, + }, + document_type_versions: DocumentTypeVersions { + index_versions: DocumentTypeIndexVersions { + index_levels_from_indices: 0, + }, + class_method_versions: DocumentTypeClassMethodVersions { + try_from_schema: 0, + create_document_types_from_document_schemas: 0, + }, + structure_version: 0, + schema: DocumentTypeSchemaVersions { + enrich_with_base_schema: 0, + find_identifier_and_binary_paths: 0, + validate_max_depth: 0, + max_depth: 256, + recursive_schema_validator_versions: RecursiveSchemaValidatorVersions { + traversal_validator: 0, + }, + validate_schema_compatibility: 0, + }, + methods: DocumentTypeMethodVersions { + create_document_from_data: 0, + create_document_with_prevalidated_properties: 0, + prefunded_voting_balance_for_document: 0, + contested_vote_poll_for_document: 0, + estimated_size: 0, + index_for_types: 0, + max_size: 0, + serialize_value_for_key: 0, + deserialize_value_for_key: 0, + }, + }, +}; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs b/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs index ea5387a78b4..5197624ade2 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_contract_method_versions/v2.rs @@ -12,7 +12,7 @@ pub const DRIVE_CONTRACT_METHOD_VERSIONS_V2: DriveContractMethodVersions = prove_contracts: 0, }, apply: DriveContractApplyMethodVersions { - apply_contract: 1, // <--- changed to v1 for inserting groups + apply_contract: 0, apply_contract_with_serialization: 0, }, insert: DriveContractInsertMethodVersions { diff --git a/packages/rs-platform-version/src/version/v8.rs b/packages/rs-platform-version/src/version/v8.rs index 3eb5de2b5dc..d6e7f016a57 100644 --- a/packages/rs-platform-version/src/version/v8.rs +++ b/packages/rs-platform-version/src/version/v8.rs @@ -1,6 +1,6 @@ use crate::version::consensus_versions::ConsensusVersions; use crate::version::dpp_versions::dpp_asset_lock_versions::v1::DPP_ASSET_LOCK_VERSIONS_V1; -use crate::version::dpp_versions::dpp_contract_versions::v1::CONTRACT_VERSIONS_V1; +use crate::version::dpp_versions::dpp_contract_versions::v2::CONTRACT_VERSIONS_V2; use crate::version::dpp_versions::dpp_costs_versions::v1::DPP_COSTS_VERSIONS_V1; use crate::version::dpp_versions::dpp_document_versions::v1::DOCUMENT_VERSIONS_V1; use crate::version::dpp_versions::dpp_factory_versions::v1::DPP_FACTORY_VERSIONS_V1; @@ -47,7 +47,7 @@ pub const PLATFORM_V8: PlatformVersion = PlatformVersion { state_transition_conversion_versions: STATE_TRANSITION_CONVERSION_VERSIONS_V2, state_transition_method_versions: STATE_TRANSITION_METHOD_VERSIONS_V1, state_transitions: STATE_TRANSITION_VERSIONS_V2, - contract_versions: CONTRACT_VERSIONS_V1, + contract_versions: CONTRACT_VERSIONS_V2, // changed document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, diff --git a/packages/token-history-contract/schema/v1/token-history-contract-documents.json b/packages/token-history-contract/schema/v1/token-history-contract-documents.json index a364d38776f..79ec99ddf4c 100644 --- a/packages/token-history-contract/schema/v1/token-history-contract-documents.json +++ b/packages/token-history-contract/schema/v1/token-history-contract-documents.json @@ -334,7 +334,7 @@ "minItems": 32, "maxItems": 32, "description": "The identity Id of the frozen token account", - "position": 2 + "position": 1 } }, "required": [ @@ -395,7 +395,7 @@ "minItems": 32, "maxItems": 32, "description": "The identity Id of the frozen token account", - "position": 2 + "position": 1 } }, "required": [ diff --git a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs index 496ab2fc6f3..392b15ebb0d 100644 --- a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs @@ -65,6 +65,8 @@ use dpp::consensus::basic::data_contract::{ContestedUniqueIndexOnMutableDocument use dpp::consensus::basic::document::{ContestedDocumentsTemporarilyNotAllowedError, DocumentCreationNotAllowedError, DocumentFieldMaxSizeExceededError, MaxDocumentsTransitionsExceededError, MissingPositionsInDocumentTypePropertiesError}; use dpp::consensus::basic::identity::{DataContractBoundsNotPresentError, DisablingKeyIdAlsoBeingAddedInSameTransitionError, InvalidIdentityCreditWithdrawalTransitionAmountError, InvalidIdentityUpdateTransitionDisableKeysError, InvalidIdentityUpdateTransitionEmptyError, TooManyMasterPublicKeyError, WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError}; use dpp::consensus::basic::overflow_error::OverflowError; +use dpp::consensus::basic::token::{InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, InvalidTokenPositionError}; +use dpp::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTokensError; use dpp::consensus::state::data_contract::document_type_update_error::DocumentTypeUpdateError; use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; use dpp::consensus::state::document::document_contest_document_with_same_id_already_present_error::DocumentContestDocumentWithSameIdAlreadyPresentError; @@ -574,6 +576,25 @@ fn from_basic_error(basic_error: &BasicError) -> JsValue { BasicError::DataContractTokenConfigurationUpdateError(e) => { generic_consensus_error!(DataContractTokenConfigurationUpdateError, e).into() } + BasicError::InvalidTokenIdError(e) => { + generic_consensus_error!(InvalidTokenIdError, e).into() + } + + BasicError::InvalidTokenPositionError(e) => { + generic_consensus_error!(InvalidTokenPositionError, e).into() + } + + BasicError::ContractHasNoTokensError(e) => { + generic_consensus_error!(ContractHasNoTokensError, e).into() + } + + BasicError::InvalidGroupPositionError(e) => { + generic_consensus_error!(InvalidGroupPositionError, e).into() + } + + BasicError::InvalidActionIdError(e) => { + generic_consensus_error!(InvalidActionIdError, e).into() + } } } From 4712d05d7c668a9be23186ba422536e125e7aaf6 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 Jan 2025 12:50:34 +0700 Subject: [PATCH 32/61] some more work on deserialization of tokens --- .../token_configuration/v0/mod.rs | 34 +++++- .../authorized_action_takers.rs | 3 +- .../change_control_rules/v0/mod.rs | 2 +- .../mod.rs | 17 ++- .../v1/mod.rs | 66 +++++++++++ .../serialized_version/v1/mod.rs | 33 ++++++ .../src/data_contract/v0/methods/schema.rs | 1 + .../src/data_contract/v0/serialization/mod.rs | 2 + .../src/data_contract/v1/methods/schema.rs | 1 + .../src/data_contract/v1/serialization/mod.rs | 2 + .../tests/strategy_tests/main.rs | 1 + .../tests/strategy_tests/token_tests.rs | 100 +++++++++++++++++ .../contract/basic-token/basic-token.json | 18 +++ .../dpp_versions/dpp_contract_versions/v2.rs | 6 +- packages/strategy-tests/src/operations.rs | 104 ++++++++++++++++++ 15 files changed, 383 insertions(+), 7 deletions(-) create mode 100644 packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v1/mod.rs create mode 100644 packages/rs-drive-abci/tests/strategy_tests/token_tests.rs create mode 100644 packages/rs-drive-abci/tests/supporting_files/contract/basic-token/basic-token.json diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index ad86bc0d76b..286d2cb393c 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -18,13 +18,20 @@ pub struct TokenConfigurationLocalizationsV0 { pub plural_form: String, } -#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, Default)] #[serde(rename_all = "camelCase")] pub struct TokenConfigurationConventionV0 { + #[serde(default)] pub localizations: BTreeMap, + #[serde(default = "default_decimals")] pub decimals: u16, } +// Default function for `decimals` +fn default_decimals() -> u16 { + 8 // Default value for decimals +} + #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct TokenConfigurationV0 { @@ -32,22 +39,47 @@ pub struct TokenConfigurationV0 { /// The supply at the creation of the token pub base_supply: u64, /// The maximum supply the token can ever have + #[serde(default)] pub max_supply: Option, /// Do we keep history, default is true. + #[serde(default = "default_keeps_history")] pub keeps_history: bool, /// Who can change the max supply /// Even if set no one can ever change this under the base supply + #[serde(default = "default_change_control_rules")] pub max_supply_change_rules: ChangeControlRules, + #[serde(default)] pub new_tokens_destination_identity: Option, + #[serde(default = "default_change_control_rules")] pub new_tokens_destination_identity_rules: ChangeControlRules, + #[serde(default = "default_change_control_rules")] pub manual_minting_rules: ChangeControlRules, + #[serde(default = "default_change_control_rules")] pub manual_burning_rules: ChangeControlRules, + #[serde(default = "default_change_control_rules")] pub freeze_rules: ChangeControlRules, + #[serde(default = "default_change_control_rules")] pub unfreeze_rules: ChangeControlRules, + #[serde(default)] pub main_control_group: Option<(BTreeSet, RequiredSigners)>, + #[serde(default)] pub main_control_group_can_be_modified: AuthorizedActionTakers, } +// Default function for `keeps_history` +fn default_keeps_history() -> bool { + true // Default to `true` for keeps_history +} + +fn default_change_control_rules() -> ChangeControlRules { + ChangeControlRules::V0(ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }) +} + impl fmt::Display for TokenConfigurationV0 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Using debug formatting for nested fields diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs b/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs index e669504cda4..32ada12f685 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs @@ -5,8 +5,9 @@ use bincode::{Decode, Encode}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, Default)] pub enum AuthorizedActionTakers { + #[default] NoOne, ContractOwner, MainGroup, diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs index db59f7d7e63..b82f7391903 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs @@ -5,7 +5,7 @@ use bincode::{Decode, Encode}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, Default)] pub struct ChangeControlRulesV0 { /// This is who is authorized to make such a change pub authorized_to_make_change: AuthorizedActionTakers, diff --git a/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/mod.rs b/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/mod.rs index c9c8ee76e92..cdd1666e026 100644 --- a/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/mod.rs @@ -1,4 +1,5 @@ mod v0; +mod v1; use crate::data_contract::document_type::v0::DocumentTypeV0; use crate::data_contract::document_type::DocumentType; @@ -41,6 +42,7 @@ impl DocumentType { documents_mutable_contract_default: bool, documents_can_be_deleted_contract_default: bool, full_validation: bool, + has_tokens: bool, validation_operations: &mut Vec, platform_version: &PlatformVersion, ) -> Result, ProtocolError> { @@ -62,9 +64,22 @@ impl DocumentType { validation_operations, platform_version, ), + // in v1 we add the ability to have contracts without documents and just tokens + 1 => DocumentTypeV0::create_document_types_from_document_schemas_v1( + data_contract_id, + document_schemas, + schema_defs, + documents_keep_history_contract_default, + documents_mutable_contract_default, + documents_can_be_deleted_contract_default, + full_validation, + has_tokens, + validation_operations, + platform_version, + ), version => Err(ProtocolError::UnknownVersionMismatch { method: "create_document_types_from_document_schemas".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, }), } diff --git a/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v1/mod.rs b/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v1/mod.rs new file mode 100644 index 00000000000..720dc9fe835 --- /dev/null +++ b/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v1/mod.rs @@ -0,0 +1,66 @@ +use crate::consensus::basic::data_contract::DocumentTypesAreMissingError; +use crate::data_contract::document_type::class_methods::consensus_or_protocol_data_contract_error; +use crate::data_contract::document_type::v0::DocumentTypeV0; +use crate::data_contract::document_type::DocumentType; +use crate::data_contract::DocumentName; +use crate::validation::operations::ProtocolValidationOperation; +use crate::version::PlatformVersion; +use crate::ProtocolError; +use platform_value::{Identifier, Value}; +use std::collections::BTreeMap; + +impl DocumentTypeV0 { + pub(in crate::data_contract) fn create_document_types_from_document_schemas_v1( + data_contract_id: Identifier, + document_schemas: BTreeMap, + schema_defs: Option<&BTreeMap>, + documents_keep_history_contract_default: bool, + documents_mutable_contract_default: bool, + documents_can_be_deleted_contract_default: bool, + full_validation: bool, + has_tokens: bool, + validation_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, ProtocolError> { + let mut contract_document_types: BTreeMap = BTreeMap::new(); + + if document_schemas.is_empty() && !has_tokens { + return Err(consensus_or_protocol_data_contract_error( + DocumentTypesAreMissingError::new(data_contract_id).into(), + )); + } + + for (name, schema) in document_schemas.into_iter() { + let document_type = match platform_version + .dpp + .contract_versions + .document_type_versions + .structure_version + { + 0 => DocumentType::try_from_schema( + data_contract_id, + &name, + schema, + schema_defs, + documents_keep_history_contract_default, + documents_mutable_contract_default, + documents_can_be_deleted_contract_default, + full_validation, + validation_operations, + platform_version, + )?, + version => { + return Err(ProtocolError::UnknownVersionMismatch { + method: "get_document_types_from_value_array_v0 inner document type" + .to_string(), + known_versions: vec![0], + received: version, + }) + } + }; + + contract_document_types.insert(name.to_string(), document_type); + } + Ok(contract_document_types) + } +} diff --git a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs index 176f06f57d1..d24ed1402cd 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/v1/mod.rs @@ -37,12 +37,45 @@ pub struct DataContractInSerializationFormatV1 { pub document_schemas: BTreeMap, /// Groups that allow for specific multiparty actions on the contract + #[serde(default, deserialize_with = "deserialize_u16_group_map")] pub groups: BTreeMap, /// The tokens on the contract. + #[serde(default, deserialize_with = "deserialize_u16_token_configuration_map")] pub tokens: BTreeMap, } +fn deserialize_u16_group_map<'de, D>( + deserializer: D, +) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let map: BTreeMap = BTreeMap::deserialize(deserializer)?; + map.into_iter() + .map(|(k, v)| { + k.parse::() + .map_err(serde::de::Error::custom) + .map(|key| (key, v)) + }) + .collect() +} +fn deserialize_u16_token_configuration_map<'de, D>( + deserializer: D, +) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let map: BTreeMap = BTreeMap::deserialize(deserializer)?; + map.into_iter() + .map(|(k, v)| { + k.parse::() + .map_err(serde::de::Error::custom) + .map(|key| (key, v)) + }) + .collect() +} + impl From for DataContractInSerializationFormatV1 { fn from(value: DataContract) -> Self { match value { diff --git a/packages/rs-dpp/src/data_contract/v0/methods/schema.rs b/packages/rs-dpp/src/data_contract/v0/methods/schema.rs index d97cb54045c..dddd285a6c3 100644 --- a/packages/rs-dpp/src/data_contract/v0/methods/schema.rs +++ b/packages/rs-dpp/src/data_contract/v0/methods/schema.rs @@ -27,6 +27,7 @@ impl DataContractSchemaMethodsV0 for DataContractV0 { self.config.documents_mutable_contract_default(), self.config.documents_can_be_deleted_contract_default(), full_validation, + false, validation_operations, platform_version, )?; diff --git a/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs b/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs index e6dca7127e8..2a79edd3627 100644 --- a/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs +++ b/packages/rs-dpp/src/data_contract/v0/serialization/mod.rs @@ -95,6 +95,7 @@ impl DataContractV0 { config.documents_mutable_contract_default(), config.documents_can_be_deleted_contract_default(), full_validation, + false, validation_operations, platform_version, )?; @@ -136,6 +137,7 @@ impl DataContractV0 { config.documents_mutable_contract_default(), config.documents_can_be_deleted_contract_default(), full_validation, + false, validation_operations, platform_version, )?; diff --git a/packages/rs-dpp/src/data_contract/v1/methods/schema.rs b/packages/rs-dpp/src/data_contract/v1/methods/schema.rs index 3b88cc59142..901813af168 100644 --- a/packages/rs-dpp/src/data_contract/v1/methods/schema.rs +++ b/packages/rs-dpp/src/data_contract/v1/methods/schema.rs @@ -26,6 +26,7 @@ impl DataContractSchemaMethodsV0 for DataContractV1 { self.config.documents_mutable_contract_default(), self.config.documents_can_be_deleted_contract_default(), full_validation, + !self.tokens.is_empty(), validation_operations, platform_version, )?; diff --git a/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs b/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs index 56e79d1c994..9939a80e85b 100644 --- a/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/serialization/mod.rs @@ -94,6 +94,7 @@ impl DataContractV1 { config.documents_mutable_contract_default(), config.documents_can_be_deleted_contract_default(), full_validation, + false, validation_operations, platform_version, )?; @@ -138,6 +139,7 @@ impl DataContractV1 { config.documents_mutable_contract_default(), config.documents_can_be_deleted_contract_default(), full_validation, + !tokens.is_empty(), validation_operations, platform_version, )?; diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index d326205ac2d..051b2d4e559 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -27,6 +27,7 @@ mod masternodes; mod patch_platform_tests; mod query; mod strategy; +mod token_tests; mod upgrade_fork_tests; mod verify_state_transitions; mod voting_tests; diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs new file mode 100644 index 00000000000..bb6259b823c --- /dev/null +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -0,0 +1,100 @@ +#[cfg(test)] +mod tests { + use crate::execution::run_chain_for_strategy; + use crate::strategy::NetworkStrategy; + use dpp::tests::json_document::json_document_to_created_contract; + use dpp::tokens::token_event::TokenEvent; + use drive_abci::config::{ + ChainLockConfig, ExecutionConfig, InstantLockConfig, PlatformConfig, PlatformTestConfig, + ValidatorSetConfig, + }; + use drive_abci::test::helpers::setup::TestPlatformBuilder; + use platform_version::version::PlatformVersion; + use strategy_tests::frequency::Frequency; + use strategy_tests::operations::{Operation, OperationType, TokenOp}; + use strategy_tests::{IdentityInsertInfo, StartIdentities, Strategy}; + + #[test] + fn run_chain_insert_one_new_identity_per_block_and_a_token_transfer_with_epoch_change() { + let platform_version = PlatformVersion::latest(); + let created_contract = json_document_to_created_contract( + "tests/supporting_files/contract/basic-token/basic-token.json", + 1, + true, + platform_version, + ) + .expect("expected to get contract from a json document"); + + let contract = created_contract.data_contract(); + + let token_op = TokenOp { + contract: contract.clone(), + token_id: Default::default(), + action: TokenEvent::Mint(1000, None), + }; + + let strategy = NetworkStrategy { + strategy: Strategy { + start_contracts: vec![(created_contract, None)], + operations: vec![Operation { + op_type: OperationType::Token(token_op), + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + }], + start_identities: StartIdentities::default(), + identity_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() + }, + + identity_contract_nonce_gaps: None, + signer: None, + }, + total_hpmns: 100, + extra_normal_mns: 0, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, + upgrading_info: None, + + proposer_strategy: Default::default(), + rotate_quorums: false, + failure_testing: None, + query_testing: None, + verify_state_transition_results: true, + ..Default::default() + }; + let day_in_ms = 1000 * 60 * 60 * 24; + let config = PlatformConfig { + validator_set: ValidatorSetConfig::default_100_67(), + chain_lock: ChainLockConfig::default_100_67(), + instant_lock: InstantLockConfig::default_100_67(), + execution: ExecutionConfig { + verify_sum_trees: true, + + ..Default::default() + }, + block_spacing_ms: day_in_ms, + testing_configs: PlatformTestConfig::default_minimal_verifications(), + ..Default::default() + }; + let block_count = 120; + let mut platform = TestPlatformBuilder::new() + .with_config(config.clone()) + .build_with_mock_rpc(); + + let outcome = + run_chain_for_strategy(&mut platform, block_count, strategy, config, 15, &mut None); + assert_eq!(outcome.identities.len() as u64, block_count); + assert_eq!(outcome.masternode_identity_balances.len(), 100); + let all_have_balances = outcome + .masternode_identity_balances + .iter() + .all(|(_, balance)| *balance != 0); + assert!(all_have_balances, "all masternodes should have a balance"); + } +} diff --git a/packages/rs-drive-abci/tests/supporting_files/contract/basic-token/basic-token.json b/packages/rs-drive-abci/tests/supporting_files/contract/basic-token/basic-token.json new file mode 100644 index 00000000000..7f103653d8e --- /dev/null +++ b/packages/rs-drive-abci/tests/supporting_files/contract/basic-token/basic-token.json @@ -0,0 +1,18 @@ +{ + "$format_version": "1", + "id": "EbL1zYg1JrpPX9rYbASihRsSEgwKbqZAJu6B1Z2SKKU2", + "ownerId": "F1Ue2M5PfDjDX69NqrZdChdEbwF2SYZ8UF4qNjsCQu1d", + "version": 1, + "documentSchemas": {}, + "tokens": { + "0": { + "$format_version": "0", + "conventions": { + "decimals": 8 + }, + "baseSupply": 100000, + "maxSupply": null, + "keepsHistory": true + } + } +} \ No newline at end of file diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs index db759e5c5f7..5dd797e201a 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_contract_versions/v2.rs @@ -10,9 +10,9 @@ pub const CONTRACT_VERSIONS_V2: DPPContractVersions = DPPContractVersions { contract_serialization_version: FeatureVersionBounds { min_version: 0, max_version: 1, - default_current_version: 1, + default_current_version: 1, //changed }, - contract_structure_version: 1, + contract_structure_version: 1, //changed created_data_contract_structure: 0, config: 0, methods: DataContractMethodVersions { @@ -26,7 +26,7 @@ pub const CONTRACT_VERSIONS_V2: DPPContractVersions = DPPContractVersions { }, class_method_versions: DocumentTypeClassMethodVersions { try_from_schema: 0, - create_document_types_from_document_schemas: 0, + create_document_types_from_document_schemas: 1, //changed to allow contracts with only tokens }, structure_version: 0, schema: DocumentTypeSchemaVersions { diff --git a/packages/strategy-tests/src/operations.rs b/packages/strategy-tests/src/operations.rs index d35fc9f5036..7d354614a94 100644 --- a/packages/strategy-tests/src/operations.rs +++ b/packages/strategy-tests/src/operations.rs @@ -17,6 +17,7 @@ use dpp::serialization::{ PlatformDeserializableWithPotentialValidationFromVersionedStructure, PlatformSerializableWithPlatformVersion, }; +use dpp::tokens::token_event::TokenEvent; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use dpp::ProtocolError; use dpp::ProtocolError::{PlatformDeserializationError, PlatformSerializationError}; @@ -29,6 +30,94 @@ use rand::prelude::StdRng; use std::collections::BTreeMap; use std::ops::{Range, RangeInclusive}; +#[derive(Clone, Debug, PartialEq)] +pub struct TokenOp { + pub contract: Contract, + pub token_id: Identifier, + pub action: TokenEvent, +} + +#[derive(Clone, Debug, Encode, Decode)] +pub struct TokenOpInSerializationFormat { + pub contract: DataContractInSerializationFormat, + pub token_id: Identifier, + pub action: TokenEvent, +} + +impl PlatformSerializableWithPlatformVersion for TokenOp { + type Error = ProtocolError; + + fn serialize_to_bytes_with_platform_version( + &self, + platform_version: &PlatformVersion, + ) -> Result, ProtocolError> { + self.clone() + .serialize_consume_to_bytes_with_platform_version(platform_version) + } + + fn serialize_consume_to_bytes_with_platform_version( + self, + platform_version: &PlatformVersion, + ) -> Result, ProtocolError> { + let TokenOp { + contract, + token_id, + action, + } = self; + let data_contract_serialization_format: DataContractInSerializationFormat = + contract.try_into_platform_versioned(platform_version)?; + + let document_op = TokenOpInSerializationFormat { + contract: data_contract_serialization_format, + token_id, + action, + }; + let config = bincode::config::standard() + .with_big_endian() + .with_no_limit(); + bincode::encode_to_vec(document_op, config).map_err(|e| { + PlatformSerializationError(format!("unable to serialize DocumentOp: {}", e)) + }) + } +} + +impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for TokenOp { + fn versioned_deserialize( + data: &[u8], + full_validation: bool, + platform_version: &PlatformVersion, + ) -> Result + where + Self: Sized, + { + let config = bincode::config::standard() + .with_big_endian() + .with_no_limit(); + let token_op_in_serialization_format: TokenOpInSerializationFormat = + bincode::borrow_decode_from_slice(data, config) + .map_err(|e| { + PlatformDeserializationError(format!("unable to deserialize DocumentOp: {}", e)) + })? + .0; + let TokenOpInSerializationFormat { + contract, + token_id, + action, + } = token_op_in_serialization_format; + let data_contract = DataContract::try_from_platform_versioned( + contract, + full_validation, + &mut vec![], + platform_version, + )?; + Ok(TokenOp { + contract: data_contract, + token_id, + action, + }) + } +} + #[derive(Clone, Debug, PartialEq, Encode, Decode)] pub enum DocumentAction { DocumentActionInsertRandom(DocumentFieldFillType, DocumentFieldFillSize), @@ -514,6 +603,7 @@ pub enum OperationType { ContractUpdate(DataContractUpdateOp), IdentityTransfer(Option), ResourceVote(ResourceVoteOp), + Token(TokenOp), } #[derive(Clone, Debug, Encode, Decode)] @@ -526,6 +616,7 @@ enum OperationTypeInSerializationFormat { ContractUpdate(Vec), IdentityTransfer(Option), ResourceVote(ResourceVoteOpSerializable), + Token(Vec), } impl PlatformSerializableWithPlatformVersion for OperationType { @@ -578,6 +669,11 @@ impl PlatformSerializableWithPlatformVersion for OperationType { resource_vote_op.try_into_platform_versioned(platform_version)?; OperationTypeInSerializationFormat::ResourceVote(vote_op_in_serialization_format) } + OperationType::Token(token_op) => { + let token_op_in_serialization_format = + token_op.serialize_consume_to_bytes_with_platform_version(platform_version)?; + OperationTypeInSerializationFormat::Token(token_op_in_serialization_format) + } }; let config = bincode::config::standard() .with_big_endian() @@ -642,6 +738,14 @@ impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for Ope let vote_op = resource_vote_op.try_into_platform_versioned(platform_version)?; OperationType::ResourceVote(vote_op) } + OperationTypeInSerializationFormat::Token(serialized_token_op) => { + let token_op = TokenOp::versioned_deserialize( + serialized_token_op.as_slice(), + full_validation, + platform_version, + )?; + OperationType::Token(token_op) + } }) } } From fbcfd6e7afda7e8bbcb72c9944def7ec648bb2eb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 Jan 2025 13:35:54 +0700 Subject: [PATCH 33/61] basic strategy structure --- .../tests/strategy_tests/strategy.rs | 86 +++++++++++++++++-- .../tests/strategy_tests/token_tests.rs | 64 ++++++++++---- 2 files changed, 129 insertions(+), 21 deletions(-) diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index fadc6ecb9dd..578c279924f 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -15,7 +15,7 @@ use strategy_tests::frequency::Frequency; use strategy_tests::operations::FinalizeBlockOperation::IdentityAddKeys; use strategy_tests::operations::{ AmountRange, DocumentAction, DocumentOp, FinalizeBlockOperation, IdentityUpdateOp, - OperationType, + OperationType, TokenOp, }; use dpp::document::DocumentV0Getters; @@ -31,6 +31,7 @@ use drive::drive::identity::key::fetch::{IdentityKeysRequest, KeyRequestType}; use drive::drive::Drive; use drive::util::storage_flags::StorageFlags::SingleEpoch; +use crate::strategy::CoreHeightIncrease::NoCoreHeightIncrease; use dpp::dashcore::hashes::Hash; use dpp::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; @@ -46,17 +47,23 @@ use dpp::state_transition::batch_transition::batched_transition::document_delete use dpp::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::DocumentTransferTransitionV0; use dpp::state_transition::batch_transition::batched_transition::{ - DocumentDeleteTransition, DocumentReplaceTransition, DocumentTransferTransition, + BatchedTransition, DocumentDeleteTransition, DocumentReplaceTransition, + DocumentTransferTransition, }; use dpp::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; use dpp::state_transition::batch_transition::document_create_transition::{ DocumentCreateTransition, DocumentCreateTransitionV0, }; -use dpp::state_transition::batch_transition::{BatchTransition, BatchTransitionV0}; +use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use dpp::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; +use dpp::state_transition::batch_transition::{ + BatchTransition, BatchTransitionV0, BatchTransitionV1, TokenMintTransition, +}; use dpp::state_transition::data_contract_create_transition::methods::v0::DataContractCreateTransitionMethodsV0; use dpp::state_transition::data_contract_update_transition::methods::DataContractUpdateTransitionMethodsV0; use dpp::state_transition::masternode_vote_transition::methods::MasternodeVoteTransitionMethodsV0; use dpp::state_transition::masternode_vote_transition::MasternodeVoteTransition; +use dpp::tokens::token_event::TokenEvent; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use dpp::voting::vote_polls::VotePoll; use dpp::voting::votes::resource_vote::v0::ResourceVoteV0; @@ -76,6 +83,7 @@ use drive_abci::platform_types::withdrawal::unsigned_withdrawal_txs::v0::Unsigne use drive_abci::rpc::core::MockCoreRPCLike; use rand::prelude::{IteratorRandom, SliceRandom, StdRng}; use rand::Rng; +use simple_signer::signer::SimpleSigner; use std::borrow::Cow; use std::collections::{BTreeMap, HashMap, HashSet}; use std::ops::RangeInclusive; @@ -87,9 +95,6 @@ use strategy_tests::transitions::{ use strategy_tests::Strategy; use tenderdash_abci::proto::abci::{ExecTxResult, ValidatorSetUpdate}; -use crate::strategy::CoreHeightIncrease::NoCoreHeightIncrease; -use simple_signer::signer::SimpleSigner; - #[derive(Clone, Debug, Default)] pub struct MasternodeListChangesStrategy { /// How many new hpmns on average per core chain lock increase @@ -1408,6 +1413,75 @@ impl NetworkStrategy { operations.push(state_transition); } } + OperationType::Token(TokenOp { + contract, + token_id, + action: TokenEvent::Mint(amount, note), + }) if current_identities.len() > 1 => { + let random_index = rng.gen_range(0..current_identities.len()); + let random_identity_id = current_identities[random_index].id(); + + let request = IdentityKeysRequest { + identity_id: random_identity_id.to_buffer(), + request_type: KeyRequestType::SpecificKeys(vec![1]), + limit: Some(1), + offset: None, + }; + let identity = platform + .drive + .fetch_identity_balance_with_keys(request, None, platform_version) + .expect("expected to be able to get identity") + .expect("expected to get an identity"); + let identity_contract_nonce = contract_nonce_counter + .entry((random_identity_id, contract.id())) + .or_default(); + *identity_contract_nonce += 1; + let token_mint_transition: TokenMintTransition = TokenMintTransitionV0 { + base: TokenBaseTransitionV0 { + identity_contract_nonce: *identity_contract_nonce, + token_contract_position: 0, + data_contract_id: contract.id(), + token_id: *token_id, + using_group_info: None, + } + .into(), + issued_to_identity_id: Some(random_identity_id), + amount: *amount, + public_note: note.clone(), + } + .into(); + + let batch_transition: BatchTransition = BatchTransitionV1 { + owner_id: identity.id, + transitions: vec![BatchedTransition::Token( + token_mint_transition.into(), + )], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: BinaryData::default(), + } + .into(); + + let mut batch_transition: StateTransition = batch_transition.into(); + + let identity_public_key = identity + .loaded_public_keys + .values() + .next() + .expect("expected a key"); + + batch_transition + .sign_external( + identity_public_key, + signer, + Some(|_data_contract_id, _document_type_name| { + Ok(SecurityLevel::HIGH) + }), + ) + .expect("expected to sign"); + + operations.push(batch_transition); + } _ => {} } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs index bb6259b823c..457d85f48f2 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -2,6 +2,10 @@ mod tests { use crate::execution::run_chain_for_strategy; use crate::strategy::NetworkStrategy; + use dpp::dash_to_duffs; + use dpp::data_contract::accessors::v1::DataContractV1Getters; + use dpp::identity::Identity; + use dpp::state_transition::StateTransition; use dpp::tests::json_document::json_document_to_created_contract; use dpp::tokens::token_event::TokenEvent; use drive_abci::config::{ @@ -10,8 +14,12 @@ mod tests { }; use drive_abci::test::helpers::setup::TestPlatformBuilder; use platform_version::version::PlatformVersion; + use rand::prelude::StdRng; + use rand::SeedableRng; + use simple_signer::signer::SimpleSigner; use strategy_tests::frequency::Frequency; use strategy_tests::operations::{Operation, OperationType, TokenOp}; + use strategy_tests::transitions::create_state_transitions_for_identities; use strategy_tests::{IdentityInsertInfo, StartIdentities, Strategy}; #[test] @@ -25,11 +33,46 @@ mod tests { ) .expect("expected to get contract from a json document"); + let mut rng = StdRng::seed_from_u64(567); + + let mut simple_signer = SimpleSigner::default(); + + let (identity1, keys1) = + Identity::random_identity_with_main_keys_with_private_key::>( + 2, + &mut rng, + platform_version, + ) + .unwrap(); + + let (identity2, keys2) = + Identity::random_identity_with_main_keys_with_private_key::>( + 2, + &mut rng, + platform_version, + ) + .unwrap(); + + simple_signer.add_keys(keys1); + simple_signer.add_keys(keys2); + + let start_identities: Vec<(Identity, Option)> = + create_state_transitions_for_identities( + vec![identity1, identity2], + &(dash_to_duffs!(1)..=dash_to_duffs!(1)), + &simple_signer, + &mut rng, + platform_version, + ) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) + .collect(); + let contract = created_contract.data_contract(); let token_op = TokenOp { contract: contract.clone(), - token_id: Default::default(), + token_id: contract.token_id(0).expect("expected to get token_id"), action: TokenEvent::Mint(1000, None), }; @@ -43,17 +86,14 @@ mod tests { chance_per_block: None, }, }], - start_identities: StartIdentities::default(), - identity_inserts: IdentityInsertInfo { - frequency: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, - }, + start_identities: StartIdentities { + hard_coded: start_identities.clone(), ..Default::default() }, + identity_inserts: IdentityInsertInfo::default(), identity_contract_nonce_gaps: None, - signer: None, + signer: Some(simple_signer), }, total_hpmns: 100, extra_normal_mns: 0, @@ -89,12 +129,6 @@ mod tests { let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15, &mut None); - assert_eq!(outcome.identities.len() as u64, block_count); - assert_eq!(outcome.masternode_identity_balances.len(), 100); - let all_have_balances = outcome - .masternode_identity_balances - .iter() - .all(|(_, balance)| *balance != 0); - assert!(all_have_balances, "all masternodes should have a balance"); + println!("ye") } } From 39e6d5d58df1b7442949da3dd83b77fddc01873c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Jan 2025 06:09:30 +0700 Subject: [PATCH 34/61] more tests --- .../data_contract/serialized_version/mod.rs | 20 +- .../src/data_contract/v1/accessors/mod.rs | 10 +- .../src/errors/consensus/basic/basic_error.rs | 19 +- .../invalid_token_base_supply_error.rs | 41 +++ .../consensus/basic/data_contract/mod.rs | 6 + ...ntiguous_contract_group_positions_error.rs | 52 ++++ ...ntiguous_contract_token_positions_error.rs | 52 ++++ packages/rs-dpp/src/errors/consensus/codes.rs | 3 + .../token_base_transition/v0/v0_methods.rs | 10 +- packages/rs-dpp/src/tokens/mod.rs | 9 + .../advanced_structure/v0/mod.rs | 36 ++- .../data_contract_create/mod.rs | 284 ++++++++++++++++++ .../tests/strategy_tests/strategy.rs | 11 + .../tests/strategy_tests/token_tests.rs | 153 +++++++++- .../contract/insert/insert_contract/v1/mod.rs | 87 +++++- .../add_to_previous_token_balance/mod.rs | 3 +- .../add_to_token_total_supply/v0/mod.rs | 9 +- .../remove_from_token_total_supply/v0/mod.rs | 9 +- packages/strategy-tests/src/operations.rs | 8 +- 19 files changed, 782 insertions(+), 40 deletions(-) create mode 100644 packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_base_supply_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/data_contract/non_contiguous_contract_group_positions_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/data_contract/non_contiguous_contract_token_positions_error.rs diff --git a/packages/rs-dpp/src/data_contract/serialized_version/mod.rs b/packages/rs-dpp/src/data_contract/serialized_version/mod.rs index fce0a9eb677..a88d93413bb 100644 --- a/packages/rs-dpp/src/data_contract/serialized_version/mod.rs +++ b/packages/rs-dpp/src/data_contract/serialized_version/mod.rs @@ -1,8 +1,13 @@ use crate::data_contract::serialized_version::v0::DataContractInSerializationFormatV0; -use crate::data_contract::{DataContract, DefinitionName, DocumentName}; +use crate::data_contract::{ + DataContract, DefinitionName, DocumentName, GroupContractPosition, TokenContractPosition, + EMPTY_GROUPS, EMPTY_TOKENS, +}; use crate::version::PlatformVersion; use std::collections::BTreeMap; +use crate::data_contract::associated_token::token_configuration::TokenConfiguration; +use crate::data_contract::group::Group; use crate::data_contract::serialized_version::v1::DataContractInSerializationFormatV1; use crate::data_contract::v0::DataContractV0; use crate::data_contract::v1::DataContractV1; @@ -78,6 +83,19 @@ impl DataContractInSerializationFormat { DataContractInSerializationFormat::V1(v1) => v1.version, } } + + pub fn groups(&self) -> &BTreeMap { + match self { + DataContractInSerializationFormat::V0(_) => &EMPTY_GROUPS, + DataContractInSerializationFormat::V1(v1) => &v1.groups, + } + } + pub fn tokens(&self) -> &BTreeMap { + match self { + DataContractInSerializationFormat::V0(_) => &EMPTY_TOKENS, + DataContractInSerializationFormat::V1(v1) => &v1.tokens, + } + } } impl TryFromPlatformVersioned for DataContractInSerializationFormat { diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs index a1987129762..562c6cc1183 100644 --- a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -11,6 +11,7 @@ use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1S use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::group::Group; +use crate::tokens::calculate_token_id; use crate::util::hash::hash_double; use crate::ProtocolError; use platform_value::Identifier; @@ -173,12 +174,9 @@ impl DataContractV1Getters for DataContractV1 { /// Returns the token id if a token exists at that position fn token_id(&self, position: TokenContractPosition) -> Option { - self.tokens.get(&position).map(|_| { - let mut bytes = b"dash_token".to_vec(); - bytes.extend_from_slice(self.id().as_bytes()); - bytes.extend_from_slice(&position.to_be_bytes()); - hash_double(bytes).into() - }) + self.tokens + .get(&position) + .map(|_| calculate_token_id(self.id.as_bytes(), position).into()) } } diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index 668019c63d3..df42e05e3fd 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -15,10 +15,12 @@ use crate::consensus::basic::data_contract::{ IncompatibleRe2PatternError, InvalidCompoundIndexError, InvalidDataContractIdError, InvalidDataContractVersionError, InvalidDocumentTypeNameError, InvalidDocumentTypeRequiredSecurityLevelError, InvalidIndexPropertyTypeError, - InvalidIndexedPropertyConstraintError, SystemPropertyIndexAlreadyPresentError, - UndefinedIndexPropertyError, UniqueIndicesLimitReachedError, - UnknownDocumentCreationRestrictionModeError, UnknownSecurityLevelError, - UnknownStorageKeyRequirementsError, UnknownTradeModeError, UnknownTransferableTypeError, + InvalidIndexedPropertyConstraintError, InvalidTokenBaseSupplyError, + NonContiguousContractGroupPositionsError, NonContiguousContractTokenPositionsError, + SystemPropertyIndexAlreadyPresentError, UndefinedIndexPropertyError, + UniqueIndicesLimitReachedError, UnknownDocumentCreationRestrictionModeError, + UnknownSecurityLevelError, UnknownStorageKeyRequirementsError, UnknownTradeModeError, + UnknownTransferableTypeError, }; use crate::consensus::basic::decode::{ ProtocolVersionParsingError, SerializedObjectParsingError, VersionError, @@ -199,6 +201,15 @@ pub enum BasicError { #[error(transparent)] DataContractHaveNewUniqueIndexError(DataContractHaveNewUniqueIndexError), + #[error(transparent)] + NonContiguousContractTokenPositionsError(NonContiguousContractTokenPositionsError), + + #[error(transparent)] + NonContiguousContractGroupPositionsError(NonContiguousContractGroupPositionsError), + + #[error(transparent)] + InvalidTokenBaseSupplyError(InvalidTokenBaseSupplyError), + // Document #[error(transparent)] DataContractNotPresentError(DataContractNotPresentError), diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_base_supply_error.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_base_supply_error.rs new file mode 100644 index 00000000000..738be8b2223 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/invalid_token_base_supply_error.rs @@ -0,0 +1,41 @@ +use crate::consensus::basic::BasicError; +use crate::errors::ProtocolError; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; + +use crate::consensus::ConsensusError; + +use bincode::{Decode, Encode}; +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Invalid token base supply. Given base supply: {}, Max allowed base supply: {}", + base_supply, + i64::MAX +)] +#[platform_serialize(unversioned)] +pub struct InvalidTokenBaseSupplyError { + /* + + DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION + + */ + base_supply: u64, +} + +impl InvalidTokenBaseSupplyError { + pub fn new(base_supply: u64) -> Self { + Self { base_supply } + } + + pub fn base_supply(&self) -> u64 { + self.base_supply + } +} + +impl From for ConsensusError { + fn from(err: InvalidTokenBaseSupplyError) -> Self { + Self::BasicError(BasicError::InvalidTokenBaseSupplyError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs index 1553f179989..2fc29ce57f5 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/mod.rs @@ -21,6 +21,9 @@ mod invalid_index_property_type_error; mod invalid_indexed_property_constraint_error; #[cfg(feature = "json-schema-validation")] mod invalid_json_schema_ref_error; +mod invalid_token_base_supply_error; +mod non_contiguous_contract_group_positions_error; +mod non_contiguous_contract_token_positions_error; mod system_property_index_already_present_error; mod undefined_index_property_error; mod unique_indices_limit_reached_error; @@ -57,6 +60,9 @@ pub use contested_unique_index_on_mutable_document_type_error::*; pub use contested_unique_index_with_unique_index_error::*; pub use incompatible_document_type_schema_error::*; pub use invalid_document_type_name_error::*; +pub use invalid_token_base_supply_error::*; +pub use non_contiguous_contract_group_positions_error::*; +pub use non_contiguous_contract_token_positions_error::*; pub use unknown_document_creation_restriction_mode_error::*; pub use unknown_security_level_error::*; pub use unknown_storage_key_requirements_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/non_contiguous_contract_group_positions_error.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/non_contiguous_contract_group_positions_error.rs new file mode 100644 index 00000000000..3409e866f8c --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/non_contiguous_contract_group_positions_error.rs @@ -0,0 +1,52 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::data_contract::GroupContractPosition; +use crate::errors::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Contract Group Positions are not contiguous. Missing position: {}, Followed position: {}", + missing_position, + followed_position +)] +#[platform_serialize(unversioned)] +pub struct NonContiguousContractGroupPositionsError { + /* + + DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION + + */ + missing_position: GroupContractPosition, + followed_position: GroupContractPosition, +} + +impl NonContiguousContractGroupPositionsError { + pub fn new( + missing_position: GroupContractPosition, + followed_position: GroupContractPosition, + ) -> Self { + Self { + missing_position, + followed_position, + } + } + + pub fn missing_position(&self) -> u16 { + self.missing_position + } + + pub fn followed_position(&self) -> u16 { + self.followed_position + } +} + +impl From for ConsensusError { + fn from(err: NonContiguousContractGroupPositionsError) -> Self { + Self::BasicError(BasicError::NonContiguousContractGroupPositionsError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/data_contract/non_contiguous_contract_token_positions_error.rs b/packages/rs-dpp/src/errors/consensus/basic/data_contract/non_contiguous_contract_token_positions_error.rs new file mode 100644 index 00000000000..2875f2bb420 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/data_contract/non_contiguous_contract_token_positions_error.rs @@ -0,0 +1,52 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::data_contract::TokenContractPosition; +use crate::errors::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Contract Token Positions are not contiguous. Missing position: {}, Followed position: {}", + missing_position, + followed_position +)] +#[platform_serialize(unversioned)] +pub struct NonContiguousContractTokenPositionsError { + /* + + DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION + + */ + missing_position: TokenContractPosition, + followed_position: TokenContractPosition, +} + +impl NonContiguousContractTokenPositionsError { + pub fn new( + missing_position: TokenContractPosition, + followed_position: TokenContractPosition, + ) -> Self { + Self { + missing_position, + followed_position, + } + } + + pub fn missing_position(&self) -> u16 { + self.missing_position + } + + pub fn followed_position(&self) -> u16 { + self.followed_position + } +} + +impl From for ConsensusError { + fn from(err: NonContiguousContractTokenPositionsError) -> Self { + Self::BasicError(BasicError::NonContiguousContractTokenPositionsError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index cca99259175..aea17297690 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -99,6 +99,9 @@ impl ErrorWithCode for BasicError { Self::ContestedUniqueIndexOnMutableDocumentTypeError(_) => 10248, Self::ContestedUniqueIndexWithUniqueIndexError(_) => 10249, Self::DataContractTokenConfigurationUpdateError { .. } => 10250, + Self::InvalidTokenBaseSupplyError(_) => 10251, + Self::NonContiguousContractGroupPositionsError(_) => 10252, + Self::NonContiguousContractTokenPositionsError(_) => 10253, // Document Errors: 10400-10449 Self::DataContractNotPresentError { .. } => 10400, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs index d98cd2f4d26..65b1cda7d09 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs @@ -2,6 +2,7 @@ use crate::data_contract::GroupContractPosition; use crate::group::GroupStateTransitionInfo; use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use crate::tokens::calculate_token_id; use crate::util::hash::hash_double; use platform_value::Identifier; @@ -19,10 +20,11 @@ pub trait TokenBaseTransitionV0Methods { /// Calculates the token ID. fn calculate_token_id(&self) -> Identifier { - let mut bytes = b"token".to_vec(); - bytes.extend_from_slice(self.data_contract_id().as_bytes()); - bytes.extend_from_slice(&self.token_contract_position().to_be_bytes()); - hash_double(bytes).into() + calculate_token_id( + self.data_contract_id().as_bytes(), + self.token_contract_position(), + ) + .into() } /// Returns the token ID. diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs index f5325ea4371..c9d7ace1187 100644 --- a/packages/rs-dpp/src/tokens/mod.rs +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -1,3 +1,12 @@ +use crate::data_contract::TokenContractPosition; +use crate::util::hash::hash_double; + pub mod allowed_currency; pub mod errors; pub mod token_event; +pub fn calculate_token_id(contract_id: &[u8; 32], token_pos: TokenContractPosition) -> [u8; 32] { + let mut bytes = b"dash_token".to_vec(); + bytes.extend_from_slice(contract_id); + bytes.extend_from_slice(&token_pos.to_be_bytes()); + hash_double(bytes) +} 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 index 9bdc1119eb6..6d81da251c3 100644 --- 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 @@ -4,9 +4,11 @@ use crate::execution::types::state_transition_execution_context::{ StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0, }; use dpp::consensus::basic::data_contract::{ - InvalidDataContractIdError, InvalidDataContractVersionError, + InvalidDataContractIdError, InvalidDataContractVersionError, InvalidTokenBaseSupplyError, + NonContiguousContractTokenPositionsError, }; use dpp::consensus::basic::BasicError; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::data_contract::INITIAL_DATA_CONTRACT_VERSION; use dpp::prelude::DataContract; use dpp::state_transition::data_contract_create_transition::accessors::DataContractCreateTransitionAccessorsV0; @@ -67,6 +69,38 @@ impl DataContractCreatedStateTransitionAdvancedStructureValidationV0 )); } + let expected_position = 0; + + for (token_contract_position, token_configuration) in self.data_contract().tokens() { + if expected_position != *token_contract_position { + let bump_action = StateTransitionAction::BumpIdentityNonceAction( + BumpIdentityNonceAction::from_borrowed_data_contract_create_transition(self), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + vec![NonContiguousContractTokenPositionsError::new( + expected_position, + *token_contract_position, + ) + .into()], + )); + } + + if token_configuration.base_supply() > i64::MAX as u64 { + let bump_action = StateTransitionAction::BumpIdentityNonceAction( + BumpIdentityNonceAction::from_borrowed_data_contract_create_transition(self), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + vec![ + InvalidTokenBaseSupplyError::new(token_configuration.base_supply()).into(), + ], + )); + } + } + Ok(ConsensusValidationResult::default()) } } 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 c22ef31de13..487841aae3f 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 @@ -149,11 +149,16 @@ mod tests { use dpp::consensus::basic::BasicError; use dpp::consensus::ConsensusError; use dpp::dash_to_credits; + use dpp::data_contract::accessors::v1::DataContractV1Getters; + use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Setters; + use dpp::data_contract::DataContract; + use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; use dpp::serialization::PlatformSerializable; use dpp::state_transition::data_contract_create_transition::methods::DataContractCreateTransitionMethodsV0; use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; use dpp::tests::json_document::json_document_to_contract_with_ids; + use dpp::tokens::calculate_token_id; use platform_version::version::PlatformVersion; #[test] @@ -347,4 +352,283 @@ mod tests { .unwrap() .expect("expected to commit transaction"); } + + #[test] + fn test_data_contract_creation_with_single_token() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .build_with_mock_rpc() + .set_genesis_state(); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + + let mut data_contract = json_document_to_contract_with_ids( + "tests/supporting_files/contract/basic-token/basic-token.json", + None, + None, + false, //no need to validate the data contracts in tests for drive + platform_version, + ) + .expect("expected to get json based contract"); + + let identity_id = identity.id(); + + let base_supply_start_amount = 0; + + { + let token_config = data_contract + .tokens_mut() + .expect("expected tokens") + .get_mut(&0) + .expect("expected first token"); + token_config.set_base_supply(base_supply_start_amount); + } + + let data_contract_id = DataContract::generate_data_contract_id_v0(identity_id, 1); + + let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); + + let data_contract_create_transition = DataContractCreateTransition::new_from_data_contract( + data_contract, + 1, + &identity.into_partial_identity_info(), + key.id(), + &signer, + platform_version, + None, + ) + .expect("expect to create documents batch transition"); + + let data_contract_create_serialized_transition = data_contract_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![data_contract_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id, + identity_id.to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + + #[test] + fn test_data_contract_creation_with_single_token_with_starting_balance() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .build_with_mock_rpc() + .set_genesis_state(); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + + let mut data_contract = json_document_to_contract_with_ids( + "tests/supporting_files/contract/basic-token/basic-token.json", + None, + None, + false, //no need to validate the data contracts in tests for drive + platform_version, + ) + .expect("expected to get json based contract"); + + let base_supply_start_amount = 10000; + + { + let token_config = data_contract + .tokens_mut() + .expect("expected tokens") + .get_mut(&0) + .expect("expected first token"); + token_config.set_base_supply(base_supply_start_amount); + } + + let identity_id = identity.id(); + + let data_contract_id = DataContract::generate_data_contract_id_v0(identity_id, 1); + + let data_contract_create_transition = DataContractCreateTransition::new_from_data_contract( + data_contract, + 1, + &identity.into_partial_identity_info(), + key.id(), + &signer, + platform_version, + None, + ) + .expect("expect to create documents batch transition"); + + let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); + + let data_contract_create_serialized_transition = data_contract_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![data_contract_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id, + identity_id.to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(base_supply_start_amount)); + } + + #[test] + fn test_data_contract_creation_with_single_token_with_starting_balance_over_limit_should_cause_error( + ) { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .build_with_mock_rpc() + .set_genesis_state(); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = setup_identity(&mut platform, 958, dash_to_credits!(0.1)); + + let mut data_contract = json_document_to_contract_with_ids( + "tests/supporting_files/contract/basic-token/basic-token.json", + None, + None, + false, //no need to validate the data contracts in tests for drive + platform_version, + ) + .expect("expected to get json based contract"); + + let base_supply_start_amount = u64::MAX; + + { + let token_config = data_contract + .tokens_mut() + .expect("expected tokens") + .get_mut(&0) + .expect("expected first token"); + token_config.set_base_supply(base_supply_start_amount); + } + + let identity_id = identity.id(); + + let data_contract_id = DataContract::generate_data_contract_id_v0(identity_id, 1); + + let data_contract_create_transition = DataContractCreateTransition::new_from_data_contract( + data_contract, + 1, + &identity.into_partial_identity_info(), + key.id(), + &signer, + platform_version, + None, + ) + .expect("expect to create documents batch transition"); + + let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); + + let data_contract_create_serialized_transition = data_contract_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![data_contract_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::BasicError(BasicError::InvalidTokenBaseSupplyError(_)), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id, + identity_id.to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index 578c279924f..9dbbd3a1ed8 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -63,6 +63,7 @@ use dpp::state_transition::data_contract_create_transition::methods::v0::DataCon use dpp::state_transition::data_contract_update_transition::methods::DataContractUpdateTransitionMethodsV0; use dpp::state_transition::masternode_vote_transition::methods::MasternodeVoteTransitionMethodsV0; use dpp::state_transition::masternode_vote_transition::MasternodeVoteTransition; +use dpp::tokens::calculate_token_id; use dpp::tokens::token_event::TokenEvent; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use dpp::voting::vote_polls::VotePoll; @@ -495,6 +496,15 @@ impl NetworkStrategy { .expect("document type must exist") .to_owned_document_type(); } + } else if let OperationType::Token(token_op) = &mut operation.op_type { + if token_op.contract.id() == old_id { + token_op.contract.set_id(contract.id()); + token_op.token_id = calculate_token_id( + contract.id_ref().as_bytes(), + token_op.token_pos, + ) + .into(); + } } }); @@ -1416,6 +1426,7 @@ impl NetworkStrategy { OperationType::Token(TokenOp { contract, token_id, + token_pos, action: TokenEvent::Mint(amount, note), }) if current_identities.len() > 1 => { let random_index = rng.gen_range(0..current_identities.len()); diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs index 457d85f48f2..d253aef1462 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -3,8 +3,12 @@ mod tests { use crate::execution::run_chain_for_strategy; use crate::strategy::NetworkStrategy; use dpp::dash_to_duffs; + use dpp::data_contract::accessors::v0::DataContractV0Setters; use dpp::data_contract::accessors::v1::DataContractV1Getters; + use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::Identity; + use dpp::platform_value::string_encoding::Encoding; + use dpp::prelude::Identifier; use dpp::state_transition::StateTransition; use dpp::tests::json_document::json_document_to_created_contract; use dpp::tokens::token_event::TokenEvent; @@ -23,7 +27,133 @@ mod tests { use strategy_tests::{IdentityInsertInfo, StartIdentities, Strategy}; #[test] - fn run_chain_insert_one_new_identity_per_block_and_a_token_transfer_with_epoch_change() { + fn run_chain_insert_one_new_identity_per_block_and_a_token_mint() { + let platform_version = PlatformVersion::latest(); + let mut created_contract = json_document_to_created_contract( + "tests/supporting_files/contract/basic-token/basic-token.json", + 1, + true, + platform_version, + ) + .expect("expected to get contract from a json document"); + + let mut rng = StdRng::seed_from_u64(567); + + let mut simple_signer = SimpleSigner::default(); + + let (identity1, keys1) = + Identity::random_identity_with_main_keys_with_private_key::>( + 2, + &mut rng, + platform_version, + ) + .unwrap(); + + let (identity2, keys2) = + Identity::random_identity_with_main_keys_with_private_key::>( + 2, + &mut rng, + platform_version, + ) + .unwrap(); + + simple_signer.add_keys(keys1); + simple_signer.add_keys(keys2); + + let start_identities: Vec<(Identity, Option)> = + create_state_transitions_for_identities( + vec![identity1.clone(), identity2.clone()], + &(dash_to_duffs!(1)..=dash_to_duffs!(1)), + &simple_signer, + &mut rng, + platform_version, + ) + .into_iter() + .map(|(identity, transition)| (identity, Some(transition))) + .collect(); + + let contract = created_contract.data_contract_mut(); + let token_id = contract.token_id(0).expect("expected to get token_id"); + + let token_op = TokenOp { + contract: contract.clone(), + token_id, + token_pos: 0, + action: TokenEvent::Mint(1000, None), + }; + + let strategy = NetworkStrategy { + strategy: Strategy { + start_contracts: vec![(created_contract, None)], + operations: vec![Operation { + op_type: OperationType::Token(token_op), + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + }], + start_identities: StartIdentities { + hard_coded: start_identities.clone(), + ..Default::default() + }, + identity_inserts: IdentityInsertInfo::default(), + + identity_contract_nonce_gaps: None, + signer: Some(simple_signer), + }, + total_hpmns: 100, + extra_normal_mns: 0, + validator_quorum_count: 24, + chain_lock_quorum_count: 24, + upgrading_info: None, + + proposer_strategy: Default::default(), + rotate_quorums: false, + failure_testing: None, + query_testing: None, + verify_state_transition_results: true, + ..Default::default() + }; + let day_in_ms = 1000 * 60 * 60 * 24; + let config = PlatformConfig { + validator_set: ValidatorSetConfig::default_100_67(), + chain_lock: ChainLockConfig::default_100_67(), + instant_lock: InstantLockConfig::default_100_67(), + execution: ExecutionConfig { + verify_sum_trees: true, + + ..Default::default() + }, + block_spacing_ms: day_in_ms, + testing_configs: PlatformTestConfig::default_minimal_verifications(), + ..Default::default() + }; + let block_count = 12; + let mut platform = TestPlatformBuilder::new() + .with_config(config.clone()) + .build_with_mock_rpc(); + + let outcome = + run_chain_for_strategy(&mut platform, block_count, strategy, config, 15, &mut None); + + println!("{:?}", &outcome.state_transition_results_per_block); + + let drive = &outcome.abci_app.platform.drive; + let identity_ids = vec![identity1.id().to_buffer(), identity2.id().to_buffer()]; + let balances = drive + .fetch_identities_token_balances( + token_id.to_buffer(), + identity_ids.as_slice(), + None, + platform_version, + ) + .expect("expected to get balances"); + + println!("{:?}", balances); + } + + #[test] + fn run_chain_insert_one_new_identity_per_block_and_a_token_transfer() { let platform_version = PlatformVersion::latest(); let created_contract = json_document_to_created_contract( "tests/supporting_files/contract/basic-token/basic-token.json", @@ -58,7 +188,7 @@ mod tests { let start_identities: Vec<(Identity, Option)> = create_state_transitions_for_identities( - vec![identity1, identity2], + vec![identity1.clone(), identity2.clone()], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, @@ -70,9 +200,12 @@ mod tests { let contract = created_contract.data_contract(); + let token_id = contract.token_id(0).expect("expected to get token_id"); + let token_op = TokenOp { contract: contract.clone(), - token_id: contract.token_id(0).expect("expected to get token_id"), + token_id, + token_pos: 0, action: TokenEvent::Mint(1000, None), }; @@ -129,6 +262,18 @@ mod tests { let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15, &mut None); - println!("ye") + + let drive = &outcome.abci_app.platform.drive; + let identity_ids = vec![identity1.id().to_buffer(), identity2.id().to_buffer()]; + let balances = drive + .fetch_identities_token_balances( + token_id.to_buffer(), + identity_ids.as_slice(), + None, + platform_version, + ) + .expect("expected to get balances"); + + println!("{:?}", balances); } } diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs index b28f13f4811..e0f615f470f 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs @@ -9,15 +9,22 @@ use dpp::data_contract::config::v0::DataContractConfigGettersV0; use dpp::data_contract::DataContract; use dpp::fee::fee_result::FeeResult; -use crate::drive::balances::total_tokens_root_supply_path; -use crate::drive::tokens::{token_path, tokens_root_path, TOKEN_BALANCES_KEY}; +use crate::drive::balances::total_tokens_root_supply_path_vec; +use crate::drive::tokens::{ + token_balances_path_vec, token_path, tokens_root_path, TOKEN_BALANCES_KEY, +}; use crate::error::contract::DataContractError; use crate::util::object_size_info::DriveKeyInfo; +use crate::util::object_size_info::PathKeyElementInfo::PathKeyElement; use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::serialization::PlatformSerializableWithPlatformVersion; use dpp::version::PlatformVersion; +use dpp::ProtocolError; use grovedb::batch::KeyInfoPath; +use grovedb::Element::Item; use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use integer_encoding::VarInt; use std::collections::HashMap; impl Drive { @@ -164,7 +171,7 @@ impl Drive { platform_version, )?; - for token_pos in contract.tokens().keys() { + for (token_pos, token_config) in contract.tokens() { let token_id = contract.token_id(*token_pos).ok_or(Error::DataContract( DataContractError::CorruptedDataContract(format!( "data contract has a token at position {}, but can not find it", @@ -172,29 +179,85 @@ impl Drive { )), ))?; + let token_id_bytes = token_id.to_buffer(); + + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info + { + Drive::add_estimation_costs_for_token_balances( + token_id_bytes, + false, + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + Drive::add_estimation_costs_for_token_total_supply( + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + } + self.batch_insert_empty_tree( tokens_root_path(), - DriveKeyInfo::KeyRef(token_id.as_bytes()), + DriveKeyInfo::KeyRef(&token_id_bytes), None, &mut batch_operations, &platform_version.drive, )?; self.batch_insert_empty_tree( - token_path(token_id.as_bytes()), + token_path(&token_id_bytes), DriveKeyInfo::Key(vec![TOKEN_BALANCES_KEY]), None, &mut batch_operations, &platform_version.drive, )?; - self.batch_insert_empty_tree( - total_tokens_root_supply_path(), - DriveKeyInfo::KeyRef(token_id.as_bytes()), - None, - &mut batch_operations, - &platform_version.drive, - )?; + let path_holding_total_token_supply = total_tokens_root_supply_path_vec(); + + if token_config.base_supply() > 0 { + // We have a base supply that needs to be distributed on contract creation + let destination_identity_id = token_config + .new_tokens_destination_identity() + .unwrap_or(contract.owner_id()); + let token_balance_path = token_balances_path_vec(token_id_bytes); + + if token_config.base_supply() > i64::MAX as u64 { + return Err( + ProtocolError::CriticalCorruptedCreditsCodeExecution(format!( + "Token base supply over i64 max, is {}", + token_config.base_supply() + )) + .into(), + ); + } + self.batch_insert::<0>( + PathKeyElement(( + token_balance_path, + destination_identity_id.to_vec(), + Element::new_sum_item(token_config.base_supply() as i64), + )), + &mut batch_operations, + &platform_version.drive, + )?; + self.batch_insert::<0>( + PathKeyElement(( + path_holding_total_token_supply, + token_id.to_vec(), + Item(token_config.base_supply().encode_var_vec(), None), + )), + &mut batch_operations, + &platform_version.drive, + )?; + } else { + self.batch_insert::<0>( + PathKeyElement(( + path_holding_total_token_supply, + token_id.to_vec(), + Item(0u64.encode_var_vec(), None), + )), + &mut batch_operations, + &platform_version.drive, + )?; + } } if !contract.groups().is_empty() { diff --git a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs index 24cf8ad32a8..ba521297a22 100644 --- a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/mod.rs @@ -8,6 +8,7 @@ use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::fee::Credits; +use dpp::balances::credits::TokenAmount; use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; @@ -86,7 +87,7 @@ impl Drive { &self, token_id: [u8; 32], identity_id: [u8; 32], - balance_to_add: Credits, + balance_to_add: TokenAmount, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, diff --git a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs index ddfc7ef1c89..97abd31e189 100644 --- a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs @@ -1,4 +1,7 @@ -use crate::drive::balances::{total_token_supply_path, total_token_supply_path_vec}; +use crate::drive::balances::{ + total_token_supply_path, total_token_supply_path_vec, total_tokens_root_supply_path, + total_tokens_root_supply_path_vec, +}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; @@ -103,8 +106,8 @@ impl Drive { )?; } - let path_holding_total_token_supply = total_token_supply_path(&token_id); - let path_holding_total_token_supply_vec = total_token_supply_path_vec(token_id); + let path_holding_total_token_supply = total_tokens_root_supply_path(); + let path_holding_total_token_supply_vec = total_tokens_root_supply_path_vec(); let total_token_supply_in_platform = self.grove_get_raw_value_u64_from_encoded_var_vec( (&path_holding_total_token_supply).into(), &token_id, diff --git a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs index b5a94e75825..fa9c5bd3eaf 100644 --- a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs @@ -1,4 +1,7 @@ -use crate::drive::balances::{total_token_supply_path, total_token_supply_path_vec}; +use crate::drive::balances::{ + total_token_supply_path, total_token_supply_path_vec, total_tokens_root_supply_path, + total_tokens_root_supply_path_vec, +}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; @@ -98,7 +101,7 @@ impl Drive { )?; } - let path_holding_total_token_supply = total_token_supply_path(&token_id); + let path_holding_total_token_supply = total_tokens_root_supply_path(); let total_token_supply_in_platform = self .grove_get_raw_value_u64_from_encoded_var_vec( (&path_holding_total_token_supply).into(), @@ -116,7 +119,7 @@ impl Drive { .ok_or(Error::Drive(DriveError::CriticalCorruptedState( "trying to subtract an amount that would underflow total supply", )))?; - let path_holding_total_token_supply_vec = total_token_supply_path_vec(token_id); + let path_holding_total_token_supply_vec = total_tokens_root_supply_path_vec(); let replace_op = QualifiedGroveDbOp::replace_op( path_holding_total_token_supply_vec, token_id.to_vec(), diff --git a/packages/strategy-tests/src/operations.rs b/packages/strategy-tests/src/operations.rs index 7d354614a94..7f9728bb1b1 100644 --- a/packages/strategy-tests/src/operations.rs +++ b/packages/strategy-tests/src/operations.rs @@ -8,7 +8,7 @@ use dpp::data_contract::document_type::random_document::{ use dpp::data_contract::document_type::v0::random_document_type::RandomDocumentTypeParameters; use dpp::data_contract::document_type::DocumentType; use dpp::data_contract::serialized_version::DataContractInSerializationFormat; -use dpp::data_contract::{DataContract as Contract, DataContract}; +use dpp::data_contract::{DataContract as Contract, DataContract, TokenContractPosition}; use dpp::fee::Credits; use dpp::identifier::Identifier; use dpp::identity::IdentityPublicKey; @@ -34,6 +34,7 @@ use std::ops::{Range, RangeInclusive}; pub struct TokenOp { pub contract: Contract, pub token_id: Identifier, + pub token_pos: TokenContractPosition, pub action: TokenEvent, } @@ -41,6 +42,7 @@ pub struct TokenOp { pub struct TokenOpInSerializationFormat { pub contract: DataContractInSerializationFormat, pub token_id: Identifier, + pub token_pos: TokenContractPosition, pub action: TokenEvent, } @@ -62,6 +64,7 @@ impl PlatformSerializableWithPlatformVersion for TokenOp { let TokenOp { contract, token_id, + token_pos, action, } = self; let data_contract_serialization_format: DataContractInSerializationFormat = @@ -70,6 +73,7 @@ impl PlatformSerializableWithPlatformVersion for TokenOp { let document_op = TokenOpInSerializationFormat { contract: data_contract_serialization_format, token_id, + token_pos, action, }; let config = bincode::config::standard() @@ -102,6 +106,7 @@ impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for Tok let TokenOpInSerializationFormat { contract, token_id, + token_pos, action, } = token_op_in_serialization_format; let data_contract = DataContract::try_from_platform_versioned( @@ -113,6 +118,7 @@ impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for Tok Ok(TokenOp { contract: data_contract, token_id, + token_pos, action, }) } From b21024e65d5db542c0b879f9ddfa18a81f59c61f Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 3 Jan 2025 13:11:14 +0700 Subject: [PATCH 35/61] minting is validated --- .../rs-dpp/src/data_contract/accessors/mod.rs | 12 + .../src/data_contract/accessors/v1/mod.rs | 6 + .../token_configuration/accessors/mod.rs | 25 + .../token_configuration/accessors/v0/mod.rs | 8 + .../token_configuration/v0/accessors.rs | 20 + .../token_configuration/v0/mod.rs | 22 +- .../src/data_contract/v1/accessors/mod.rs | 8 +- .../src/errors/consensus/basic/basic_error.rs | 10 +- ..._token_mint_recipient_not_allowed_error.rs | 31 + ...dentity_for_token_minting_not_set_error.rs | 33 + .../src/errors/consensus/basic/token/mod.rs | 4 + packages/rs-dpp/src/errors/consensus/codes.rs | 7 +- .../rs-dpp/src/errors/consensus/state/mod.rs | 1 + .../src/errors/consensus/state/state_error.rs | 4 + .../src/errors/consensus/state/token/mod.rs | 3 + ...recipient_identity_does_not_exist_error.rs | 31 + .../token_base_transition/v0/v0_methods.rs | 1 - .../token_transfer_transition/v0/mod.rs | 4 +- .../v0/v0_methods.rs | 22 +- .../token_transfer_transition/v0_methods.rs | 12 +- .../document/batch_transition/methods/mod.rs | 199 +++- .../batch_transition/methods/v1/mod.rs | 81 ++ .../batch_transition/v1/v0_methods.rs | 175 +++- packages/rs-dpp/src/tokens/errors.rs | 2 - packages/rs-dpp/src/tokens/token_event.rs | 6 +- .../block_fee_processing/tests.rs | 13 + .../create_genesis_state/common.rs | 101 ++ .../create_genesis_state/mod.rs | 10 +- .../create_genesis_state/v0/mod.rs | 93 +- .../create_genesis_state/v1/mod.rs | 125 +++ .../state_v0/mod.rs | 26 +- .../structure_v0/mod.rs | 2 + .../state_transitions/batch/mod.rs | 967 +++++++++++++++++- .../batch/transformer/v0/mod.rs | 10 +- .../state_transition/state_transitions/mod.rs | 39 + .../rs-drive/src/drive/document/delete/mod.rs | 12 + .../rs-drive/src/drive/document/insert/mod.rs | 14 + .../rs-drive/src/drive/document/update/mod.rs | 12 +- .../v0/mod.rs | 3 +- .../document/mod.rs | 2 +- ...transition.rs => token_mint_transition.rs} | 12 +- .../transformer.rs | 49 +- .../v0/transformer.rs | 212 +++- .../v0/transformer.rs | 8 +- .../src/util/batch/drive_op_batch/mod.rs | 6 + .../rs-drive/src/util/test_helpers/mod.rs | 10 +- packages/rs-drive/tests/query_tests.rs | 16 + .../rs-drive/tests/query_tests_history.rs | 2 + .../drive_abci_method_versions/mod.rs | 1 + .../drive_abci_method_versions/v5.rs | 122 +++ .../mod.rs | 2 +- .../v1.rs | 2 +- .../rs-platform-version/src/version/v8.rs | 4 +- .../v1/token-history-contract-documents.json | 27 +- 54 files changed, 2407 insertions(+), 222 deletions(-) create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/choosing_token_mint_recipient_not_allowed_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/destination_identity_for_token_minting_not_set_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/state/token/mod.rs create mode 100644 packages/rs-dpp/src/errors/consensus/state/token/recipient_identity_does_not_exist_error.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/common.rs create mode 100644 packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/v1/mod.rs rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/{token_issuance_transition.rs => token_mint_transition.rs} (86%) create mode 100644 packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index b47f1d7efa6..e5b1f3bdb5d 100644 --- a/packages/rs-dpp/src/data_contract/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/mod.rs @@ -233,6 +233,18 @@ impl DataContractV1Getters for DataContract { } } + /// Returns a mutable reference to a token configuration + /// Returns `None` for V0 since it doesn't have tokens. + fn token_configuration_mut( + &mut self, + position: TokenContractPosition, + ) -> Option<&mut TokenConfiguration> { + match self { + DataContract::V0(_) => None, + DataContract::V1(v1) => v1.tokens.get_mut(&position), + } + } + fn token_id(&self, position: TokenContractPosition) -> Option { match self { DataContract::V0(_) => None, diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs index 5f43439f635..c90c353edab 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -20,6 +20,12 @@ pub trait DataContractV1Getters: DataContractV0Getters { /// Returns a mutable reference to the tokens map. fn tokens_mut(&mut self) -> Option<&mut BTreeMap>; + /// Returns a mutable reference to a token configuration + /// Returns `None` for V0 since it doesn't have tokens. + fn token_configuration_mut( + &mut self, + position: TokenContractPosition, + ) -> Option<&mut TokenConfiguration>; /// Returns the token id at a certain position fn token_id(&self, position: TokenContractPosition) -> Option; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs index 580288845c6..6312ac274b3 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs @@ -68,6 +68,19 @@ impl TokenConfigurationV0Getters for TokenConfiguration { TokenConfiguration::V0(v0) => v0.new_tokens_destination_identity_rules(), } } + /// Returns whether minting allows choosing a destination. + fn minting_allow_choosing_destination(&self) -> bool { + match self { + TokenConfiguration::V0(v0) => v0.minting_allow_choosing_destination(), + } + } + + /// Returns the rules for minting destination selection. + fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.minting_allow_choosing_destination_rules(), + } + } /// Returns the manual minting rules. fn manual_minting_rules(&self) -> &ChangeControlRules { @@ -197,4 +210,16 @@ impl TokenConfigurationV0Setters for TokenConfiguration { TokenConfiguration::V0(v0) => v0.set_main_control_group_can_be_modified(action_takers), } } + + fn set_minting_allow_choosing_destination(&mut self, value: bool) { + match self { + TokenConfiguration::V0(v0) => v0.set_minting_allow_choosing_destination(value), + } + } + + fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_minting_allow_choosing_destination_rules(rules), + } + } } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs index ff06d882bd5..079f97b7398 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -29,6 +29,10 @@ pub trait TokenConfigurationV0Getters { /// Returns the new tokens destination identity rules. fn new_tokens_destination_identity_rules(&self) -> &ChangeControlRules; + /// Returns whether minting allows choosing a destination. + fn minting_allow_choosing_destination(&self) -> bool; + /// Returns the rules for minting destination selection. + fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules; /// Returns the manual minting rules. fn manual_minting_rules(&self) -> &ChangeControlRules; @@ -86,4 +90,8 @@ pub trait TokenConfigurationV0Setters { /// Sets the main control group can be modified. fn set_main_control_group_can_be_modified(&mut self, action_takers: AuthorizedActionTakers); + /// Sets whether minting allows choosing a destination. + fn set_minting_allow_choosing_destination(&mut self, value: bool); + /// Sets the rules for minting destination selection. + fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules); } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs index c93436316f2..f6b52d00d7b 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs @@ -52,6 +52,16 @@ impl TokenConfigurationV0Getters for TokenConfigurationV0 { &self.new_tokens_destination_identity_rules } + /// Returns whether minting allows choosing a destination. + fn minting_allow_choosing_destination(&self) -> bool { + self.minting_allow_choosing_destination + } + + /// Returns the rules for minting destination selection. + fn minting_allow_choosing_destination_rules(&self) -> &ChangeControlRules { + &self.minting_allow_choosing_destination_rules + } + /// Returns the manual minting rules. fn manual_minting_rules(&self) -> &ChangeControlRules { &self.manual_minting_rules @@ -144,4 +154,14 @@ impl TokenConfigurationV0Setters for TokenConfigurationV0 { fn set_main_control_group_can_be_modified(&mut self, action_takers: AuthorizedActionTakers) { self.main_control_group_can_be_modified = action_takers; } + + /// Sets whether minting allows choosing a destination. + fn set_minting_allow_choosing_destination(&mut self, value: bool) { + self.minting_allow_choosing_destination = value; + } + + /// Sets the rules for minting destination selection. + fn set_minting_allow_choosing_destination_rules(&mut self, rules: ChangeControlRules) { + self.minting_allow_choosing_destination_rules = rules; + } } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 286d2cb393c..d7ebc4f7c99 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -52,6 +52,10 @@ pub struct TokenConfigurationV0 { pub new_tokens_destination_identity: Option, #[serde(default = "default_change_control_rules")] pub new_tokens_destination_identity_rules: ChangeControlRules, + #[serde(default = "default_minting_allow_choosing_destination")] + pub minting_allow_choosing_destination: bool, + #[serde(default = "default_change_control_rules")] + pub minting_allow_choosing_destination_rules: ChangeControlRules, #[serde(default = "default_change_control_rules")] pub manual_minting_rules: ChangeControlRules, #[serde(default = "default_change_control_rules")] @@ -66,6 +70,11 @@ pub struct TokenConfigurationV0 { pub main_control_group_can_be_modified: AuthorizedActionTakers, } +// Default function for `minting_allow_choosing_destination` to return `true` +fn default_minting_allow_choosing_destination() -> bool { + true +} + // Default function for `keeps_history` fn default_keeps_history() -> bool { true // Default to `true` for keeps_history @@ -82,16 +91,17 @@ fn default_change_control_rules() -> ChangeControlRules { impl fmt::Display for TokenConfigurationV0 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Using debug formatting for nested fields write!( f, - "TokenConfigurationV0 {{ conventions: {:?}, base_supply: {}, max_supply: {:?}, max_supply_change_rules: {:?}, new_tokens_destination_identity: {:?}, new_tokens_destination_identity_rules: {:?}, manual_minting_rules: {:?}, manual_burning_rules: {:?}, freeze_rules: {:?}, unfreeze_rules: {:?}, main_control_group: {:?}, main_control_group_can_be_modified: {:?} }}", + "TokenConfigurationV0 {{\n conventions: {:?},\n base_supply: {},\n max_supply: {:?},\n max_supply_change_rules: {:?},\n new_tokens_destination_identity: {:?},\n new_tokens_destination_identity_rules: {:?},\n minting_allow_choosing_destination: {},\n minting_allow_choosing_destination_rules: {:?},\n manual_minting_rules: {:?},\n manual_burning_rules: {:?},\n freeze_rules: {:?},\n unfreeze_rules: {:?},\n main_control_group: {:?},\n main_control_group_can_be_modified: {:?}\n}}", self.conventions, self.base_supply, self.max_supply, self.max_supply_change_rules, self.new_tokens_destination_identity, self.new_tokens_destination_identity_rules, + self.minting_allow_choosing_destination, + self.minting_allow_choosing_destination_rules, self.manual_minting_rules, self.manual_burning_rules, self.freeze_rules, @@ -127,6 +137,14 @@ impl TokenConfigurationV0 { changing_authorized_action_takers_to_contract_owner_allowed: false, } .into(), + minting_allow_choosing_destination: true, + minting_allow_choosing_destination_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + } + .into(), manual_minting_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs index 562c6cc1183..4bc22fbccde 100644 --- a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -12,7 +12,6 @@ use crate::data_contract::associated_token::token_configuration::TokenConfigurat use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::group::Group; use crate::tokens::calculate_token_id; -use crate::util::hash::hash_double; use crate::ProtocolError; use platform_value::Identifier; use std::collections::BTreeMap; @@ -172,6 +171,13 @@ impl DataContractV1Getters for DataContractV1 { Some(&mut self.tokens) } + fn token_configuration_mut( + &mut self, + position: TokenContractPosition, + ) -> Option<&mut TokenConfiguration> { + self.tokens.get_mut(&position) + } + /// Returns the token id if a token exists at that position fn token_id(&self, position: TokenContractPosition) -> Option { self.tokens diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index df42e05e3fd..ca24b187a50 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -70,7 +70,9 @@ use crate::consensus::ConsensusError; use crate::consensus::basic::overflow_error::OverflowError; use crate::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTokensError; use crate::consensus::basic::token::{ - InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, InvalidTokenPositionError, + ChoosingTokenMintRecipientNotAllowedError, DestinationIdentityForTokenMintingNotSetError, + InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, + InvalidTokenPositionError, }; use crate::consensus::basic::unsupported_version_error::UnsupportedVersionError; use crate::consensus::basic::value_error::ValueError; @@ -436,6 +438,12 @@ pub enum BasicError { #[error(transparent)] InvalidActionIdError(InvalidActionIdError), + + #[error(transparent)] + DestinationIdentityForTokenMintingNotSetError(DestinationIdentityForTokenMintingNotSetError), + + #[error(transparent)] + ChoosingTokenMintRecipientNotAllowedError(ChoosingTokenMintRecipientNotAllowedError), } impl From for ConsensusError { diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/choosing_token_mint_recipient_not_allowed_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/choosing_token_mint_recipient_not_allowed_error.rs new file mode 100644 index 00000000000..9d5f2dfc901 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/choosing_token_mint_recipient_not_allowed_error.rs @@ -0,0 +1,31 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Choosing token mint recipient not allowed for token {}", token_id)] +#[platform_serialize(unversioned)] +pub struct ChoosingTokenMintRecipientNotAllowedError { + token_id: Identifier, +} + +impl ChoosingTokenMintRecipientNotAllowedError { + pub fn new(token_id: Identifier) -> Self { + Self { token_id } + } + pub fn token_id(&self) -> Identifier { + self.token_id + } +} + +impl From for ConsensusError { + fn from(err: ChoosingTokenMintRecipientNotAllowedError) -> Self { + Self::BasicError(BasicError::ChoosingTokenMintRecipientNotAllowedError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/destination_identity_for_token_minting_not_set_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/destination_identity_for_token_minting_not_set_error.rs new file mode 100644 index 00000000000..7136a46e66f --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/destination_identity_for_token_minting_not_set_error.rs @@ -0,0 +1,33 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Destination identity for minting not set for token {}", token_id)] +#[platform_serialize(unversioned)] +pub struct DestinationIdentityForTokenMintingNotSetError { + token_id: Identifier, +} + +impl DestinationIdentityForTokenMintingNotSetError { + pub fn new(token_id: Identifier) -> Self { + Self { token_id } + } + pub fn token_id(&self) -> Identifier { + self.token_id + } +} + +impl From for ConsensusError { + fn from(err: DestinationIdentityForTokenMintingNotSetError) -> Self { + Self::BasicError(BasicError::DestinationIdentityForTokenMintingNotSetError( + err, + )) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs index 5a6eb015fa1..ff2432f254c 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs @@ -1,9 +1,13 @@ +pub mod choosing_token_mint_recipient_not_allowed_error; pub mod contract_has_no_tokens_error; +pub mod destination_identity_for_token_minting_not_set_error; pub mod invalid_action_id_error; pub mod invalid_group_position_error; pub mod invalid_token_id_error; pub mod invalid_token_position_error; +pub use choosing_token_mint_recipient_not_allowed_error::*; +pub use destination_identity_for_token_minting_not_set_error::*; pub use invalid_action_id_error::*; pub use invalid_group_position_error::*; pub use invalid_token_id_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index aea17297690..907cf2fed18 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -130,6 +130,8 @@ impl ErrorWithCode for BasicError { Self::InvalidGroupPositionError(_) => 10452, Self::InvalidActionIdError(_) => 10453, Self::ContractHasNoTokensError(_) => 10454, + Self::DestinationIdentityForTokenMintingNotSetError(_) => 10455, + Self::ChoosingTokenMintRecipientNotAllowedError(_) => 10456, // Identity Errors: 10500-10599 Self::DuplicatedIdentityPublicKeyBasicError(_) => 10500, @@ -212,7 +214,7 @@ impl ErrorWithCode for StateError { Self::DataContractIsReadonlyError { .. } => 40001, Self::DataContractConfigUpdateError { .. } => 40002, - // Document Errors: 40100-40199 + // Document Errors: 40100-40149 Self::DocumentAlreadyPresentError { .. } => 40100, Self::DocumentNotFoundError { .. } => 40101, Self::DocumentOwnerIdMismatchError { .. } => 40102, @@ -229,6 +231,9 @@ impl ErrorWithCode for StateError { Self::DocumentContestDocumentWithSameIdAlreadyPresentError(_) => 40113, Self::DocumentContestNotPaidForError(_) => 40114, + // Token errors: 40150-40199 + Self::RecipientIdentityDoesNotExistError(_) => 40150, + // Identity Errors: 40200-40299 Self::IdentityAlreadyExistsError(_) => 40200, Self::IdentityPublicKeyIsReadOnlyError { .. } => 40201, diff --git a/packages/rs-dpp/src/errors/consensus/state/mod.rs b/packages/rs-dpp/src/errors/consensus/state/mod.rs index 118ca4b10c0..3b410662c0e 100644 --- a/packages/rs-dpp/src/errors/consensus/state/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/state/mod.rs @@ -5,4 +5,5 @@ pub mod document; pub mod identity; pub mod prefunded_specialized_balances; pub mod state_error; +pub mod token; pub mod voting; diff --git a/packages/rs-dpp/src/errors/consensus/state/state_error.rs b/packages/rs-dpp/src/errors/consensus/state/state_error.rs index 8b0ac2b26bb..d945b82ba47 100644 --- a/packages/rs-dpp/src/errors/consensus/state/state_error.rs +++ b/packages/rs-dpp/src/errors/consensus/state/state_error.rs @@ -42,6 +42,7 @@ use crate::consensus::state::identity::missing_transfer_key_error::MissingTransf use crate::consensus::state::identity::no_transfer_key_for_core_withdrawal_available_error::NoTransferKeyForCoreWithdrawalAvailableError; use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_insufficient_error::PrefundedSpecializedBalanceInsufficientError; use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_not_found_error::PrefundedSpecializedBalanceNotFoundError; +use crate::consensus::state::token::RecipientIdentityDoesNotExistError; use crate::consensus::state::voting::masternode_incorrect_voter_identity_id_error::MasternodeIncorrectVoterIdentityIdError; use crate::consensus::state::voting::masternode_incorrect_voting_address_error::MasternodeIncorrectVotingAddressError; use crate::consensus::state::voting::masternode_not_found_error::MasternodeNotFoundError; @@ -199,6 +200,9 @@ pub enum StateError { #[error(transparent)] MasternodeVoteAlreadyPresentError(MasternodeVoteAlreadyPresentError), + + #[error(transparent)] + RecipientIdentityDoesNotExistError(RecipientIdentityDoesNotExistError), } impl From for ConsensusError { diff --git a/packages/rs-dpp/src/errors/consensus/state/token/mod.rs b/packages/rs-dpp/src/errors/consensus/state/token/mod.rs new file mode 100644 index 00000000000..c482ef72cd2 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/token/mod.rs @@ -0,0 +1,3 @@ +mod recipient_identity_does_not_exist_error; + +pub use recipient_identity_does_not_exist_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/state/token/recipient_identity_does_not_exist_error.rs b/packages/rs-dpp/src/errors/consensus/state/token/recipient_identity_does_not_exist_error.rs new file mode 100644 index 00000000000..dc6a838f76f --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/token/recipient_identity_does_not_exist_error.rs @@ -0,0 +1,31 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Recipient identity {} does not exist", recipient_id)] +#[platform_serialize(unversioned)] +pub struct RecipientIdentityDoesNotExistError { + recipient_id: Identifier, +} + +impl RecipientIdentityDoesNotExistError { + pub fn new(recipient_id: Identifier) -> Self { + Self { recipient_id } + } + pub fn recipient_id(&self) -> Identifier { + self.recipient_id + } +} + +impl From for ConsensusError { + fn from(err: RecipientIdentityDoesNotExistError) -> Self { + Self::StateError(StateError::RecipientIdentityDoesNotExistError(err)) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs index 65b1cda7d09..40369689bd3 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_base_transition/v0/v0_methods.rs @@ -3,7 +3,6 @@ use crate::group::GroupStateTransitionInfo; use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use crate::tokens::calculate_token_id; -use crate::util::hash::hash_double; use platform_value::Identifier; /// A trait that contains getter and setter methods for `TokenBaseTransitionV0` diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs index f3d3d00a52e..0f3da97343e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/mod.rs @@ -39,9 +39,9 @@ pub struct TokenTransferTransitionV0 { pub amount: u64, #[cfg_attr( feature = "state-transition-serde-conversion", - serde(rename = "recipientOwnerId") + serde(rename = "recipientId") )] - pub recipient_owner_id: Identifier, + pub recipient_id: Identifier, /// The public note #[cfg_attr( feature = "state-transition-serde-conversion", diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs index 839b2864d6c..a4203feee1f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs @@ -31,13 +31,13 @@ pub trait TokenTransferTransitionV0Methods: fn set_amount(&mut self, amount: u64); /// Returns the `recipient_owner_id` field of the `TokenTransferTransitionV0`. - fn recipient_owner_id(&self) -> Identifier; + fn recipient_id(&self) -> Identifier; /// Returns a reference to the `recipient_owner_id` field of the `TokenTransferTransitionV0`. - fn recipient_owner_id_ref(&self) -> &Identifier; + fn recipient_id_ref(&self) -> &Identifier; /// Sets the value of the `recipient_owner_id` field in the `TokenTransferTransitionV0`. - fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier); + fn set_recipient_id(&mut self, recipient_owner_id: Identifier); /// Returns the `public_note` field of the `TokenTransferTransitionV0`. fn public_note(&self) -> Option<&String>; @@ -111,16 +111,16 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { self.amount = amount; } - fn recipient_owner_id(&self) -> Identifier { - self.recipient_owner_id + fn recipient_id(&self) -> Identifier { + self.recipient_id } - fn recipient_owner_id_ref(&self) -> &Identifier { - &self.recipient_owner_id + fn recipient_id_ref(&self) -> &Identifier { + &self.recipient_id } - fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier) { - self.recipient_owner_id = recipient_owner_id; + fn set_recipient_id(&mut self, recipient_owner_id: Identifier) { + self.recipient_id = recipient_owner_id; } fn public_note(&self) -> Option<&String> { self.public_note.as_ref() @@ -204,14 +204,14 @@ impl AllowedAsMultiPartyAction for TokenTransferTransitionV0 { let TokenTransferTransitionV0 { base, amount, - recipient_owner_id, + recipient_id, .. } = self; let mut bytes = b"action_token_transfer".to_vec(); bytes.extend_from_slice(base.token_id().as_bytes()); bytes.extend_from_slice(owner_id.as_bytes()); - bytes.extend_from_slice(recipient_owner_id.as_bytes()); + bytes.extend_from_slice(recipient_id.as_bytes()); bytes.extend_from_slice(&base.identity_contract_nonce().to_be_bytes()); bytes.extend_from_slice(&amount.to_be_bytes()); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs index b849bb7aef6..45c05094d4d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs @@ -39,21 +39,21 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransition { } } - fn recipient_owner_id(&self) -> Identifier { + fn recipient_id(&self) -> Identifier { match self { - TokenTransferTransition::V0(v0) => v0.recipient_owner_id, + TokenTransferTransition::V0(v0) => v0.recipient_id, } } - fn recipient_owner_id_ref(&self) -> &Identifier { + fn recipient_id_ref(&self) -> &Identifier { match self { - TokenTransferTransition::V0(v0) => &v0.recipient_owner_id, + TokenTransferTransition::V0(v0) => &v0.recipient_id, } } - fn set_recipient_owner_id(&mut self, recipient_owner_id: Identifier) { + fn set_recipient_id(&mut self, recipient_id: Identifier) { match self { - TokenTransferTransition::V0(v0) => v0.recipient_owner_id = recipient_owner_id, + TokenTransferTransition::V0(v0) => v0.recipient_id = recipient_id, } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs index ac0a77f8c9d..a3ecf2b33ba 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs @@ -1,17 +1,24 @@ +use crate::balances::credits::TokenAmount; #[cfg(feature = "state-transition-signing")] use crate::data_contract::document_type::DocumentTypeRef; +use crate::data_contract::TokenContractPosition; #[cfg(feature = "state-transition-signing")] use crate::document::Document; use crate::fee::Credits; +use crate::group::GroupStateTransitionInfo; #[cfg(feature = "state-transition-signing")] use crate::identity::signer::Signer; #[cfg(feature = "state-transition-signing")] use crate::identity::IdentityPublicKey; -use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-signing")] use crate::prelude::UserFeeIncrease; +use crate::prelude::{ + DerivationEncryptionKeyIndex, IdentityNonce, RecipientKeyIndex, RootEncryptionKeyIndex, + SenderKeyIndex, +}; use crate::state_transition::batch_transition::batched_transition::BatchedTransition; use crate::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; +use crate::state_transition::batch_transition::methods::v1::DocumentsBatchTransitionMethodsV1; use crate::state_transition::batch_transition::BatchTransition; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::{BatchTransitionV0, BatchTransitionV1}; @@ -24,6 +31,7 @@ use platform_value::Identifier; use platform_version::version::{FeatureVersion, PlatformVersion}; pub mod v0; +pub mod v1; impl DocumentsBatchTransitionMethodsV0 for BatchTransition { fn all_document_purchases_amount(&self) -> Result, ProtocolError> { @@ -415,3 +423,192 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { } } } + +impl DocumentsBatchTransitionMethodsV1 for BatchTransition { + fn new_token_mint_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: TokenContractPosition, + amount: TokenAmount, + issued_to_identity_id: Option, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + match batch_feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .default_current_version, + ) { + 1 | 0 + if platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .max_version + >= 1 => + { + BatchTransitionV1::new_token_mint_transition( + token_id, + owner_id, + data_contract_id, + token_contract_position, + amount, + issued_to_identity_id, + public_note, + using_group_info, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + delete_feature_version, + base_feature_version, + ) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DocumentsBatchTransition::new_token_mint_transition".to_string(), + known_versions: vec![1], + received: version, + }), + } + } + + fn new_token_burn_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + amount: TokenAmount, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + match batch_feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .default_current_version, + ) { + 1 | 0 + if platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .max_version + >= 1 => + { + BatchTransitionV1::new_token_burn_transition( + token_id, + owner_id, + data_contract_id, + token_contract_position, + amount, + public_note, + using_group_info, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + delete_feature_version, + base_feature_version, + ) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DocumentsBatchTransition::new_token_burn_transition".to_string(), + known_versions: vec![1], + received: version, + }), + } + } + + fn new_token_transfer_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + amount: TokenAmount, + recipient_id: Identifier, + public_note: Option, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + match batch_feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .default_current_version, + ) { + 1 | 0 + if platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .max_version + >= 1 => + { + // Create the transfer transition for batch version 1 + BatchTransitionV1::new_token_transfer_transition( + token_id, + owner_id, + data_contract_id, + token_contract_position, + amount, + recipient_id, + public_note, + shared_encrypted_note, + private_encrypted_note, + using_group_info, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + delete_feature_version, + base_feature_version, + ) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DocumentsBatchTransition::new_token_transfer_transition".to_string(), + known_versions: vec![1], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs new file mode 100644 index 00000000000..7d8641377ff --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs @@ -0,0 +1,81 @@ +use crate::balances::credits::TokenAmount; +use crate::group::GroupStateTransitionInfo; +use crate::identity::signer::Signer; +use crate::identity::IdentityPublicKey; +use crate::prelude::{ + DerivationEncryptionKeyIndex, IdentityNonce, RecipientKeyIndex, RootEncryptionKeyIndex, + SenderKeyIndex, UserFeeIncrease, +}; +use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use crate::state_transition::StateTransition; +use crate::version::FeatureVersion; +use crate::ProtocolError; +use platform_value::Identifier; +use platform_version::version::PlatformVersion; + +pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 { + #[cfg(feature = "state-transition-signing")] + fn new_token_mint_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + amount: TokenAmount, + issued_to_identity_id: Option, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result; + + #[cfg(feature = "state-transition-signing")] + fn new_token_burn_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + amount: TokenAmount, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result; + + #[cfg(feature = "state-transition-signing")] + fn new_token_transfer_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + amount: TokenAmount, + recipient_id: Identifier, + public_note: Option, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result; +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index 37308b6d1ed..1b38ea8e714 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -7,11 +7,14 @@ use crate::fee::Credits; use crate::identity::signer::Signer; #[cfg(feature = "state-transition-signing")] use crate::identity::SecurityLevel; -use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-signing")] use crate::prelude::IdentityPublicKey; #[cfg(feature = "state-transition-signing")] use crate::prelude::UserFeeIncrease; +use crate::prelude::{ + DerivationEncryptionKeyIndex, IdentityNonce, RecipientKeyIndex, RootEncryptionKeyIndex, + SenderKeyIndex, +}; use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use crate::state_transition::batch_transition::batched_transition::{ BatchedTransition, BatchedTransitionRef, @@ -27,7 +30,7 @@ use crate::state_transition::batch_transition::methods::v0::DocumentsBatchTransi use std::iter::Map; use std::slice::Iter; -use crate::state_transition::batch_transition::BatchTransitionV1; +use crate::state_transition::batch_transition::{BatchTransitionV1, TokenBurnTransition, TokenMintTransition, TokenTransferTransition}; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::{ BatchTransition, DocumentDeleteTransition, @@ -39,9 +42,17 @@ use crate::ProtocolError; use platform_value::Identifier; #[cfg(feature = "state-transition-signing")] use platform_version::version::{FeatureVersion, PlatformVersion}; +use crate::balances::credits::TokenAmount; +use crate::group::GroupStateTransitionInfo; use crate::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; +use crate::state_transition::batch_transition::methods::v1::DocumentsBatchTransitionMethodsV1; use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use crate::state_transition::batch_transition::token_burn_transition::TokenBurnTransitionV0; +use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; +use crate::state_transition::batch_transition::token_transfer_transition::TokenTransferTransitionV0; impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV1 { type IterType<'a> = Map, fn(&'a BatchedTransition) -> BatchedTransitionRef<'a>> @@ -382,3 +393,163 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { } } } + +impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { + fn new_token_mint_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + amount: TokenAmount, + issued_to_identity_id: Option, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + _platform_version: &PlatformVersion, + _batch_feature_version: Option, + _delete_feature_version: Option, + _base_feature_version: Option, + ) -> Result { + let mint_transition = TokenMintTransition::V0(TokenMintTransitionV0 { + base: TokenBaseTransition::V0(TokenBaseTransitionV0 { + identity_contract_nonce, + token_contract_position, + data_contract_id, + token_id, + using_group_info, + }), + issued_to_identity_id, + amount, + public_note, + }); + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Token(mint_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + fn new_token_burn_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + amount: TokenAmount, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + _platform_version: &PlatformVersion, + _batch_feature_version: Option, + _delete_feature_version: Option, + _base_feature_version: Option, + ) -> Result { + let burn_transition = TokenBurnTransition::V0(TokenBurnTransitionV0 { + base: TokenBaseTransition::V0(TokenBaseTransitionV0 { + identity_contract_nonce, + token_contract_position, + data_contract_id, + token_id, + using_group_info, + }), + burn_amount: amount, + public_note, + }); + + // Wrap in a batch transition + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Token(burn_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + + // Create the state transition + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + + Ok(state_transition) + } + + fn new_token_transfer_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + amount: TokenAmount, + recipient_id: Identifier, + public_note: Option, + shared_encrypted_note: Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + private_encrypted_note: Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + _platform_version: &PlatformVersion, + _batch_feature_version: Option, + _delete_feature_version: Option, + _base_feature_version: Option, + ) -> Result { + // Create the transfer transition for batch version 1 + let transfer_transition = TokenTransferTransition::V0(TokenTransferTransitionV0 { + base: TokenBaseTransition::V0(TokenBaseTransitionV0 { + identity_contract_nonce, + token_contract_position, + data_contract_id, + token_id, + using_group_info, + }), + recipient_id, + amount, + public_note, + shared_encrypted_note, + private_encrypted_note, + }); + + // Wrap in a batch transition + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Token(transfer_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + + // Create the state transition + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + + Ok(state_transition) + } +} diff --git a/packages/rs-dpp/src/tokens/errors.rs b/packages/rs-dpp/src/tokens/errors.rs index 823e1f577c2..bf4445568b7 100644 --- a/packages/rs-dpp/src/tokens/errors.rs +++ b/packages/rs-dpp/src/tokens/errors.rs @@ -2,8 +2,6 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum TokenError { - #[error("There is no destination identity to put the token balance to")] - DestinationIdentityForMintingNotSetError, #[error("There is no token at this position")] TokenNotFoundAtPositionError, } diff --git a/packages/rs-dpp/src/tokens/token_event.rs b/packages/rs-dpp/src/tokens/token_event.rs index c79056872b2..d21734fbf05 100644 --- a/packages/rs-dpp/src/tokens/token_event.rs +++ b/packages/rs-dpp/src/tokens/token_event.rs @@ -15,15 +15,17 @@ pub type TokenEventPersonalEncryptedNote = Option<( )>; use crate::ProtocolError; +pub type RecipientIdentifier = Identifier; + #[derive( Debug, PartialEq, PartialOrd, Clone, Eq, Encode, Decode, PlatformDeserialize, PlatformSerialize, )] #[platform_serialize(unversioned)] //versioned directly, no need to use platform_version pub enum TokenEvent { - Mint(TokenAmount, TokenEventPublicNote), + Mint(TokenAmount, RecipientIdentifier, TokenEventPublicNote), Burn(TokenAmount, TokenEventPublicNote), Transfer( - Identifier, + RecipientIdentifier, TokenEventPublicNote, TokenEventSharedEncryptedNote, TokenEventPersonalEncryptedNote, diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs b/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs index a224d4ee33c..617502349bb 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs @@ -16,6 +16,7 @@ mod refund_tests { CreateRandomDocument, DocumentFieldFillSize, DocumentFieldFillType, }; use dpp::data_contract::document_type::DocumentTypeRef; + use dpp::data_contract::DataContract; use dpp::document::document_methods::DocumentMethodsV0; use dpp::document::serialization_traits::DocumentPlatformConversionMethodsV0; use dpp::document::{Document, DocumentV0Setters}; @@ -272,6 +273,8 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None::, + None, None, ); @@ -369,6 +372,8 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None::, + None, None, ); @@ -469,6 +474,8 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None::, + None, None, ); @@ -565,6 +572,8 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None::, + None, None, ); @@ -661,6 +670,8 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None::, + None, None, ); @@ -758,6 +769,8 @@ mod refund_tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-indexes.json", None, None, + None::, + None, None, ); diff --git a/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/common.rs b/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/common.rs new file mode 100644 index 00000000000..9d0a27dec46 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/common.rs @@ -0,0 +1,101 @@ +use crate::error::Error; +use crate::platform_types::platform::Platform; + +use dpp::platform_value::platform_value; +use dpp::ProtocolError; + +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::DataContract; +use dpp::document::DocumentV0; +use dpp::serialization::PlatformSerializableWithPlatformVersion; +use dpp::system_data_contracts::dpns_contract::DPNS_DASH_TLD_DOCUMENT_ID; +use dpp::version::PlatformVersion; +use drive::dpp::identity::TimestampMillis; +use drive::util::batch::{DataContractOperationType, DocumentOperationType, DriveOperation}; +use drive::util::object_size_info::{ + DataContractInfo, DocumentInfo, DocumentTypeInfo, OwnedDocumentInfo, +}; +use std::borrow::Cow; + +impl Platform { + pub(in crate::execution::platform_events::initialization::create_genesis_state) fn register_system_data_contract_operations< + 'a, + >( + &self, + data_contract: &'a DataContract, + operations: &mut Vec>, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let serialization = + data_contract.serialize_to_bytes_with_platform_version(platform_version)?; + operations.push(DriveOperation::DataContractOperation( + DataContractOperationType::ApplyContractWithSerialization { + contract: Cow::Borrowed(data_contract), + serialized_contract: serialization, + storage_flags: None, + }, + )); + Ok(()) + } + + pub(in crate::execution::platform_events::initialization::create_genesis_state) fn register_dpns_top_level_domain_operations< + 'a, + >( + &'a self, + contract: &'a DataContract, + genesis_time: TimestampMillis, + operations: &mut Vec>, + ) -> Result<(), Error> { + let domain = "dash"; + + let document_stub_properties_value = platform_value!({ + "label" : domain, + "normalizedLabel" : domain, + "parentDomainName" : "", + "normalizedParentDomainName" : "", + "records" : { + "identity" : contract.owner_id(), + }, + "subdomainRules": { + "allowSubdomains": true, + } + }); + + let document_stub_properties = document_stub_properties_value + .into_btree_string_map() + .map_err(|e| Error::Protocol(ProtocolError::ValueError(e)))?; + + let document = DocumentV0 { + id: DPNS_DASH_TLD_DOCUMENT_ID.into(), + properties: document_stub_properties, + owner_id: contract.owner_id(), + revision: None, + created_at: Some(genesis_time), + updated_at: Some(genesis_time), + transferred_at: Some(genesis_time), + created_at_block_height: None, + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: None, + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + + let document_type = contract.document_type_for_name("domain")?; + + let operation = DriveOperation::DocumentOperation(DocumentOperationType::AddDocument { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentInfo::DocumentOwnedInfo((document, None)), + owner_id: None, + }, + contract_info: DataContractInfo::BorrowedDataContract(contract), + document_type_info: DocumentTypeInfo::DocumentTypeRef(document_type), + override_document: false, + }); + + operations.push(operation); + + Ok(()) + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/mod.rs index e046d8bc3d4..72819eb9936 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/mod.rs @@ -6,7 +6,9 @@ use dpp::prelude::CoreBlockHeight; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; +mod common; pub mod v0; +pub mod v1; impl Platform { /// Creates trees and populates them with necessary identities, contracts and documents @@ -29,9 +31,15 @@ impl Platform { transaction, platform_version, ), + 1 => self.create_genesis_state_v1( + genesis_core_height, + genesis_time, + transaction, + platform_version, + ), version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { method: "create_genesis_state".to_string(), - known_versions: vec![0], + known_versions: vec![0, 1], received: version, })), } diff --git a/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/v0/mod.rs index e343d710c81..89f8ccd79ef 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/v0/mod.rs @@ -1,27 +1,13 @@ use crate::error::Error; use crate::platform_types::platform::Platform; -use dpp::platform_value::platform_value; -use dpp::ProtocolError; - use drive::dpp::identity::TimestampMillis; use dpp::block::block_info::BlockInfo; -use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::data_contract::DataContract; -use dpp::document::DocumentV0; -use dpp::serialization::PlatformSerializableWithPlatformVersion; +use dpp::prelude::CoreBlockHeight; use dpp::version::PlatformVersion; use drive::dpp::system_data_contracts::SystemDataContract; -use drive::util::batch::{DataContractOperationType, DocumentOperationType, DriveOperation}; - -use dpp::prelude::CoreBlockHeight; -use dpp::system_data_contracts::dpns_contract::DPNS_DASH_TLD_DOCUMENT_ID; use drive::query::TransactionArg; -use drive::util::object_size_info::{ - DataContractInfo, DocumentInfo, DocumentTypeInfo, OwnedDocumentInfo, -}; -use std::borrow::Cow; use std::collections::BTreeMap; impl Platform { @@ -92,83 +78,6 @@ impl Platform { Ok(()) } - - fn register_system_data_contract_operations<'a>( - &self, - data_contract: &'a DataContract, - operations: &mut Vec>, - platform_version: &PlatformVersion, - ) -> Result<(), Error> { - let serialization = - data_contract.serialize_to_bytes_with_platform_version(platform_version)?; - operations.push(DriveOperation::DataContractOperation( - DataContractOperationType::ApplyContractWithSerialization { - contract: Cow::Borrowed(data_contract), - serialized_contract: serialization, - storage_flags: None, - }, - )); - Ok(()) - } - - fn register_dpns_top_level_domain_operations<'a>( - &'a self, - contract: &'a DataContract, - genesis_time: TimestampMillis, - operations: &mut Vec>, - ) -> Result<(), Error> { - let domain = "dash"; - - let document_stub_properties_value = platform_value!({ - "label" : domain, - "normalizedLabel" : domain, - "parentDomainName" : "", - "normalizedParentDomainName" : "", - "records" : { - "identity" : contract.owner_id(), - }, - "subdomainRules": { - "allowSubdomains": true, - } - }); - - let document_stub_properties = document_stub_properties_value - .into_btree_string_map() - .map_err(|e| Error::Protocol(ProtocolError::ValueError(e)))?; - - let document = DocumentV0 { - id: DPNS_DASH_TLD_DOCUMENT_ID.into(), - properties: document_stub_properties, - owner_id: contract.owner_id(), - revision: None, - created_at: Some(genesis_time), - updated_at: Some(genesis_time), - transferred_at: Some(genesis_time), - created_at_block_height: None, - updated_at_block_height: None, - transferred_at_block_height: None, - created_at_core_block_height: None, - updated_at_core_block_height: None, - transferred_at_core_block_height: None, - } - .into(); - - let document_type = contract.document_type_for_name("domain")?; - - let operation = DriveOperation::DocumentOperation(DocumentOperationType::AddDocument { - owned_document_info: OwnedDocumentInfo { - document_info: DocumentInfo::DocumentOwnedInfo((document, None)), - owner_id: None, - }, - contract_info: DataContractInfo::BorrowedDataContract(contract), - document_type_info: DocumentTypeInfo::DocumentTypeRef(document_type), - override_document: false, - }); - - operations.push(operation); - - Ok(()) - } } #[cfg(test)] diff --git a/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/v1/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/v1/mod.rs new file mode 100644 index 00000000000..d6a1cf70396 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/initialization/create_genesis_state/v1/mod.rs @@ -0,0 +1,125 @@ +use crate::error::Error; +use crate::platform_types::platform::Platform; + +use drive::dpp::identity::TimestampMillis; + +use dpp::block::block_info::BlockInfo; +use dpp::prelude::CoreBlockHeight; +use dpp::version::PlatformVersion; +use drive::dpp::system_data_contracts::SystemDataContract; +use drive::query::TransactionArg; +use std::collections::BTreeMap; + +impl Platform { + /// Creates trees and populates them with necessary identities, contracts and documents + #[inline(always)] + pub(super) fn create_genesis_state_v1( + &self, + genesis_core_height: CoreBlockHeight, + genesis_time: TimestampMillis, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + //versioned call + self.drive + .create_initial_state_structure(transaction, platform_version)?; + + self.drive + .store_genesis_core_height(genesis_core_height, transaction, platform_version)?; + + let mut operations = vec![]; + + // Create system identities and contracts + + let system_data_contracts = &self.drive.cache.system_data_contracts; + + let system_data_contract_types = BTreeMap::from_iter([ + (SystemDataContract::DPNS, system_data_contracts.load_dpns()), + ( + SystemDataContract::Withdrawals, + system_data_contracts.load_withdrawals(), + ), + ( + SystemDataContract::Dashpay, + system_data_contracts.load_dashpay(), + ), + ( + SystemDataContract::MasternodeRewards, + system_data_contracts.load_masternode_reward_shares(), + ), + ( + SystemDataContract::TokenHistory, + system_data_contracts.load_token_history(), + ), + ]); + //todo add Wallet Utils (maybe) + + for data_contract in system_data_contract_types.values() { + self.register_system_data_contract_operations( + data_contract, + &mut operations, + platform_version, + )?; + } + + let dpns_contract = system_data_contracts.load_dpns(); + + self.register_dpns_top_level_domain_operations( + &dpns_contract, + genesis_time, + &mut operations, + )?; + + let block_info = BlockInfo::default_with_time(genesis_time); + + self.drive.apply_drive_operations( + operations, + true, + &block_info, + transaction, + platform_version, + None, // No previous_fee_versions needed for genesis state creation + )?; + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + mod create_genesis_state { + use crate::config::PlatformConfig; + use crate::test::helpers::setup::TestPlatformBuilder; + use drive::config::DriveConfig; + use platform_version::version::{PlatformVersion, INITIAL_PROTOCOL_VERSION}; + + #[test] + pub fn should_create_genesis_state_deterministically() { + let platform_version = PlatformVersion::first(); + let platform = TestPlatformBuilder::new() + .with_config(PlatformConfig { + drive: DriveConfig { + epochs_per_era: 20, + ..Default::default() + }, + ..Default::default() + }) + .with_initial_protocol_version(INITIAL_PROTOCOL_VERSION) + .build_with_mock_rpc() + .set_genesis_state(); + + let root_hash = platform + .drive + .grove + .root_hash(None, &platform_version.drive.grove_version) + .unwrap() + .expect("should obtain root hash"); + + // This should never be changed + assert_eq!( + hex::encode(root_hash), + "dc5b0d4be407428adda2315db7d782e64015cbe2d2b7df963f05622390dc3c9f" + ) + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs index 820493d91f8..3d0fd657409 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs @@ -6,6 +6,7 @@ use dpp::consensus::state::document::document_contest_currently_locked_error::Do use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; use dpp::consensus::state::state_error::StateError; +use dpp::consensus::state::token::RecipientIdentityDoesNotExistError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::{ConsensusValidationResult, Identifier}; @@ -18,7 +19,7 @@ use drive::error::drive::DriveError; use drive::query::TransactionArg; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; -use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::execution_operation::{RetrieveIdentityInfo, ValidationOperation}; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; @@ -47,6 +48,29 @@ impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { ) -> Result { // todo verify that minting would not break max supply + // We need to verify that the receiver is a valid identity + + let recipient = self.identity_balance_holder_id(); + if recipient != owner_id { + // We have already checked that this user exists if the recipient is the owner id + let balance = platform.drive.fetch_identity_balance( + recipient.to_buffer(), + transaction, + platform_version, + )?; + execution_context.add_operation(ValidationOperation::RetrieveIdentity( + RetrieveIdentityInfo::only_balance(), + )); + if balance.is_none() { + // The identity does not exist + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::RecipientIdentityDoesNotExistError( + RecipientIdentityDoesNotExistError::new(recipient), + )), + )); + } + } + Ok(SimpleConsensusValidationResult::new()) } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs index 69473c0f849..e7162316951 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs @@ -9,6 +9,8 @@ use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; use dpp::data_contract::document_type::restricted_creation::CreationRestrictionMode; use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; use dpp::identifier::Identifier; +use dpp::ProtocolError; +use dpp::tokens::errors::TokenError; use dpp::validation::{SimpleConsensusValidationResult}; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index 80503cd3461..aff4792e578 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -243,7 +243,11 @@ mod tests { use crate::platform_types::platform_state::v0::PlatformStateV0Methods; use crate::platform_types::state_transitions_processing_result::StateTransitionExecutionResult; use crate::test::helpers::setup::TestPlatformBuilder; + use assert_matches::assert_matches; use dpp::block::block_info::BlockInfo; + use dpp::consensus::basic::BasicError; + use dpp::consensus::state::state_error::StateError; + use dpp::consensus::ConsensusError; use dpp::dash_to_credits; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; @@ -255,6 +259,7 @@ mod tests { use dpp::document::{DocumentV0Getters, DocumentV0Setters}; use dpp::fee::fee_result::BalanceChange; use dpp::fee::Credits; + use dpp::identifier::Identifier; use dpp::identity::accessors::IdentityGettersV0; use dpp::nft::TradeMode; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; @@ -269,10 +274,10 @@ mod tests { use drive::util::storage_flags::StorageFlags; use platform_version::version::PlatformVersion; use rand::prelude::StdRng; + use rand::Rng; use rand::SeedableRng; mod creation_tests { - use rand::Rng; use dapi_grpc::platform::v0::{get_contested_resource_vote_state_request, get_contested_resource_vote_state_response, GetContestedResourceVoteStateRequest, GetContestedResourceVoteStateResponse}; use dapi_grpc::platform::v0::get_contested_resource_vote_state_request::get_contested_resource_vote_state_request_v0::ResultType; use dapi_grpc::platform::v0::get_contested_resource_vote_state_request::GetContestedResourceVoteStateRequestV0; @@ -304,6 +309,7 @@ mod tests { use dpp::consensus::state::state_error::StateError; use dpp::dashcore::Network; use dpp::dashcore::Network::Testnet; + use dpp::data_contract::DataContract; use dpp::identity::SecurityLevel; use dpp::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use dpp::state_transition::batch_transition::document_create_transition::DocumentCreateTransitionV0; @@ -567,6 +573,8 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-no-max-length.json", None, None, + None::, + None, None, ); @@ -8355,6 +8363,7 @@ mod tests { use dpp::data_contract::document_type::random_document::{ DocumentFieldFillSize, DocumentFieldFillType, }; + use dpp::data_contract::DataContract; use dpp::platform_value::Bytes32; use dpp::state_transition::batch_transition::BatchTransition; use dpp::util::hash::hash_double; @@ -8363,7 +8372,6 @@ mod tests { use indexmap::IndexMap; use platform_version::version::PlatformVersion; use rand::prelude::StdRng; - use rand::Rng; use std::collections::BTreeMap; #[test] @@ -8392,6 +8400,8 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, + None::, + None, None, ); @@ -8400,6 +8410,8 @@ mod tests { "tests/supporting_files/contract/crypto-card-game/crypto-card-game-direct-purchase.json", None, None, + None::, + None, None, ); @@ -8408,6 +8420,8 @@ mod tests { "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index-with-contract-id.json", None, None, + None::, + None, None, ); @@ -8844,6 +8858,8 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, + None::, + None, None, ); @@ -8852,6 +8868,8 @@ mod tests { "tests/supporting_files/contract/crypto-card-game/crypto-card-game-direct-purchase.json", None, None, + None::, + None, None, ); @@ -8860,6 +8878,8 @@ mod tests { "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index-with-contract-id-null-searchable-true.json", None, None, + None::, + None, None, ); @@ -9256,4 +9276,947 @@ mod tests { assert_eq!(documents.len(), 2); } } + + mod token_tests { + use super::*; + use crate::execution::validation::state_transition::tests::create_token_contract_with_owner_identity; + use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Setters; + use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; + use dpp::state_transition::batch_transition::methods::v1::DocumentsBatchTransitionMethodsV1; + mod token_mint_tests { + use super::*; + + mod token_mint_tests_normal_scenarios { + use super::*; + + #[test] + fn test_token_mint_by_owned_id_allowed_sending_to_self() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(101337)); + } + + #[test] + fn test_token_mint_by_owned_id_allowed_sending_to_other() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (receiver, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(receiver.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + receiver.id().to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(1337)); + } + + #[test] + fn test_token_mint_sending_to_non_existing_identity_causes_error() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let receiver = Identifier::random_with_rng(&mut rng); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(receiver), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError( + StateError::RecipientIdentityDoesNotExistError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + receiver.to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + + #[test] + fn test_token_mint_by_owned_id_no_destination_causes_error() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + None, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::BasicError( + BasicError::DestinationIdentityForTokenMintingNotSetError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + } + } + + mod token_mint_tests_no_recipient_minting { + use super::*; + + #[test] + fn test_token_mint_by_owned_id_allowed_sending_to_self() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_minting_allow_choosing_destination(false); + }), + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::BasicError( + BasicError::ChoosingTokenMintRecipientNotAllowedError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + } + + #[test] + fn test_token_mint_by_owned_id_allowed_sending_to_other() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (receiver, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_minting_allow_choosing_destination(false); + }), + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(receiver.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::BasicError( + BasicError::ChoosingTokenMintRecipientNotAllowedError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + receiver.id().to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + + #[test] + fn test_token_mint_by_owned_id_no_destination_causes_error() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_minting_allow_choosing_destination(false); + }), + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + None, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::BasicError( + BasicError::DestinationIdentityForTokenMintingNotSetError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + } + } + + mod token_mint_tests_contract_has_recipient { + use super::*; + + #[test] + fn test_token_mint_by_owned_id_allowed_sending_to_self() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_minting_allow_choosing_destination(false); + token_configuration + .set_new_tokens_destination_identity(Some(identity.id())); + }), + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::BasicError( + BasicError::ChoosingTokenMintRecipientNotAllowedError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + } + + #[test] + fn test_token_mint_by_owned_id_allowed_sending_to_other() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (receiver, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_minting_allow_choosing_destination(false); + token_configuration + .set_new_tokens_destination_identity(Some(identity.id())); + }), + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(receiver.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::BasicError( + BasicError::ChoosingTokenMintRecipientNotAllowedError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + receiver.id().to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + + #[test] + fn test_token_mint_by_owned_id_no_set_destination_should_use_contracts() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_minting_allow_choosing_destination(false); + token_configuration + .set_new_tokens_destination_identity(Some(identity.id())); + }), + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + None, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + true, + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(101337)); + } + } + } + } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index 51ee7602ccf..01bf85774c3 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -23,7 +23,8 @@ use dpp::fee::Credits; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::prelude::Revision; use dpp::validation::SimpleConsensusValidationResult; -use dpp::{consensus::ConsensusError, prelude::Identifier, validation::ConsensusValidationResult}; +use dpp::{consensus::ConsensusError, prelude::Identifier, ProtocolError, validation::ConsensusValidationResult}; +use dpp::fee::fee_result::FeeResult; use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use dpp::state_transition::batch_transition::batched_transition::BatchedTransitionRef; use dpp::state_transition::batch_transition::BatchTransition; @@ -507,17 +508,14 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { Ok(batched_action.into()) } TokenTransition::Mint(token_mint_transition) => { - let (token_mint_action, fee_result) = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(drive, owner_id, token_mint_transition, approximate_for_costs, transaction, block_info, |_identifier| { + let (batched_action, fee_result) = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(drive, owner_id, token_mint_transition, approximate_for_costs, transaction, block_info, |_identifier| { Ok(data_contract_fetch_info.clone()) }, platform_version)?; execution_context .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); - let batched_action = BatchedTransitionAction::TokenAction( - TokenTransitionAction::MintAction(token_mint_action), - ); - Ok(batched_action.into()) + Ok(batched_action) } TokenTransition::Transfer(token_transfer_transition) => { let (token_transfer_action, fee_result) = TokenTransferTransitionAction::try_from_borrowed_token_transfer_transition_with_contract_lookup(drive, owner_id, token_transfer_transition, approximate_for_costs, transaction, block_info, |_identifier| { 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 4b1e7cfa5a5..afc44a34719 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 @@ -78,6 +78,7 @@ pub(in crate::execution) mod tests { use dpp::dashcore::{ProTxHash, Txid}; use dpp::dashcore::hashes::Hash; use dpp::data_contract::accessors::v0::DataContractV0Getters; + use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::DataContract; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::data_contract::document_type::random_document::{CreateRandomDocument, DocumentFieldFillSize, DocumentFieldFillType}; @@ -95,6 +96,7 @@ pub(in crate::execution) mod tests { use dpp::state_transition::masternode_vote_transition::MasternodeVoteTransition; use dpp::state_transition::masternode_vote_transition::methods::MasternodeVoteTransitionMethodsV0; use dpp::state_transition::StateTransition; + use dpp::tokens::calculate_token_id; use dpp::util::hash::hash_double; use dpp::util::strings::convert_to_homograph_safe_chars; use dpp::voting::contender_structs::{Contender, ContenderV0}; @@ -123,6 +125,7 @@ pub(in crate::execution) mod tests { use crate::platform_types::epoch_info::v0::EpochInfoV0; use crate::execution::types::block_fees::v0::BlockFeesV0; use crate::execution::types::processed_block_fees_outcome::v0::ProcessedBlockFeesOutcome; + use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; /// We add an identity, but we also add the same amount to system credits pub(in crate::execution) fn setup_identity_with_system_credits( @@ -894,6 +897,8 @@ pub(in crate::execution) mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, + None::, + None, None, ); @@ -902,6 +907,8 @@ pub(in crate::execution) mod tests { "tests/supporting_files/contract/crypto-card-game/crypto-card-game-direct-purchase.json", None, None, + None::, + None, None, ); @@ -1247,6 +1254,8 @@ pub(in crate::execution) mod tests { "tests/supporting_files/contract/dpns/dpns-contract-contested-unique-index-with-contract-id.json", None, None, + None::, + None, None, ); @@ -2277,4 +2286,34 @@ pub(in crate::execution) mod tests { finished_vote_info, ) } + + pub(in crate::execution) fn create_token_contract_with_owner_identity( + platform: &mut TempPlatform, + identity_id: Identifier, + token_configuration_modification: Option, + platform_version: &PlatformVersion, + ) -> (DataContract, Identifier) { + let data_contract_id = DataContract::generate_data_contract_id_v0(identity_id, 1); + + let basic_token_contract = setup_contract( + &platform.drive, + "tests/supporting_files/contract/basic-token/basic-token.json", + Some(data_contract_id.to_buffer()), + Some(identity_id.to_buffer()), + Some(|data_contract: &mut DataContract| { + if let Some(token_configuration_modification) = token_configuration_modification { + let token_configuration = data_contract + .token_configuration_mut(0) + .expect("expected token configuration"); + token_configuration_modification(token_configuration); + } + }), + None, + Some(platform_version), + ); + + let token_id = calculate_token_id(data_contract_id.as_bytes(), 0); + + (basic_token_contract, token_id.into()) + } } diff --git a/packages/rs-drive/src/drive/document/delete/mod.rs b/packages/rs-drive/src/drive/document/delete/mod.rs index c3426c15ca5..04b780b6d5d 100644 --- a/packages/rs-drive/src/drive/document/delete/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/mod.rs @@ -100,6 +100,8 @@ mod tests { None, None, None, + None, + None, ); let document_type = contract @@ -193,6 +195,8 @@ mod tests { &drive, "tests/supporting_files/contract/family/family-contract-reduced.json", None, + None, + None, Some(&db_transaction), None, ); @@ -335,6 +339,8 @@ mod tests { &drive, "tests/supporting_files/contract/family/family-contract-reduced.json", None, + None, + None, Some(&db_transaction), None, ); @@ -520,6 +526,8 @@ mod tests { &drive, "tests/supporting_files/contract/family/family-contract-reduced.json", None, + None, + None, Some(&db_transaction), None, ); @@ -796,6 +804,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, + None, + None, Some(&db_transaction), None, ); @@ -897,6 +907,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, + None, + None, Some(&db_transaction), None, ); diff --git a/packages/rs-drive/src/drive/document/insert/mod.rs b/packages/rs-drive/src/drive/document/insert/mod.rs index 932fd7687a7..a351a305ccf 100644 --- a/packages/rs-drive/src/drive/document/insert/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/mod.rs @@ -165,6 +165,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, + None, + None, Some(&db_transaction), None, ); @@ -262,6 +264,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, + None, + None, Some(&db_transaction), None, ); @@ -328,6 +332,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, + None, + None, Some(&db_transaction), None, ); @@ -394,6 +400,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, + None, + None, Some(&db_transaction), None, ); @@ -460,6 +468,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, + None, + None, Some(&db_transaction), None, ); @@ -537,6 +547,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, + None, + None, Some(&db_transaction), None, ); @@ -631,6 +643,8 @@ mod tests { &drive, "tests/supporting_files/contract/dpns/dpns-contract.json", None, + None, + None, Some(&db_transaction), None, ); diff --git a/packages/rs-drive/src/drive/document/update/mod.rs b/packages/rs-drive/src/drive/document/update/mod.rs index 03d9927c8ca..793594a31f0 100644 --- a/packages/rs-drive/src/drive/document/update/mod.rs +++ b/packages/rs-drive/src/drive/document/update/mod.rs @@ -684,6 +684,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, + None, + None, Some(&db_transaction), None, ); @@ -774,6 +776,8 @@ mod tests { &drive, "tests/supporting_files/contract/dashpay/dashpay-contract-with-profile-history.json", None, + None, + None, Some(&db_transaction), None, ); @@ -867,7 +871,7 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, transaction.as_ref(), None); + let contract = setup_contract(&drive, path, None, None, None, transaction.as_ref(), None); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1162,7 +1166,7 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, transaction.as_ref(), None); + let contract = setup_contract(&drive, path, None, None, None, transaction.as_ref(), None); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1361,7 +1365,7 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, transaction.as_ref(), None); + let contract = setup_contract(&drive, path, None, None, None, transaction.as_ref(), None); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1696,7 +1700,7 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, transaction.as_ref(), None); + let contract = setup_contract(&drive, path, None, None, None, transaction.as_ref(), None); let person_0_original = Person { id: Identifier::from([0u8; 32]), diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs index 3f5760b53db..c7dcf08ee8d 100644 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs @@ -34,7 +34,7 @@ impl Drive { let contract = self.cache.system_data_contracts.load_token_history(); match event { - TokenEvent::Mint(mint_amount, public_note) => { + TokenEvent::Mint(mint_amount, recipient_id, public_note) => { let document_type = contract.document_type_for_name("mint")?; let document_id = Document::generate_document_id_v0( &contract.id(), @@ -44,6 +44,7 @@ impl Drive { ); let mut properties = BTreeMap::from([ ("tokenId".to_string(), token_id.into()), + ("recipientId".to_string(), recipient_id.into()), ("amount".to_string(), mint_amount.into()), ]); if let Some(note) = public_note { diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs index dbe4d386613..0c46a74bd61 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs @@ -14,7 +14,7 @@ mod document_transition; mod document_update_price_transition; mod documents_batch_transition; mod token_burn_transition; -mod token_issuance_transition; +mod token_mint_transition; mod token_transfer_transition; mod token_transition; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_mint_transition.rs similarity index 86% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_mint_transition.rs index 0ffc9c77d36..deb56e4851a 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_issuance_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_mint_transition.rs @@ -24,7 +24,7 @@ impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { .methods .state_transitions .convert_to_high_level_operations - .token_issuance_transition + .token_mint_transition { 0 => { let data_contract_id = self.base().data_contract_id(); @@ -41,7 +41,7 @@ impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { ops.push(TokenOperation(TokenOperationType::TokenMint { token_id: self.token_id(), - identity_balance_holder_id: owner_id, + identity_balance_holder_id: self.identity_balance_holder_id(), mint_amount: self.mint_amount(), allow_first_mint: false, })); @@ -52,14 +52,18 @@ impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { token_id: self.token_id(), owner_id, nonce: identity_contract_nonce, - event: TokenEvent::Mint(self.mint_amount(), self.public_note_owned()), + event: TokenEvent::Mint( + self.mint_amount(), + self.identity_balance_holder_id(), + self.public_note_owned(), + ), })); } Ok(ops) } version => Err(Error::Drive(DriveError::UnknownVersionMismatch { - method: "TokenIssuanceTransitionAction::into_high_level_document_drive_operations" + method: "TokenMintTransitionAction::into_high_level_document_drive_operations" .to_string(), known_versions: vec![0], received: version, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs index e2e58fa895f..91b79f56bba 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs @@ -4,12 +4,14 @@ use grovedb::TransactionArg; use std::sync::Arc; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; +use dpp::prelude::ConsensusValidationResult; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionActionV0, TokenMintTransitionAction}; use dpp::state_transition::batch_transition::token_mint_transition::TokenMintTransition; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; +use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; /// Implement methods to transform a `TokenMintTransition` into a `TokenMintTransitionAction`. impl TokenMintTransitionAction { @@ -28,7 +30,7 @@ impl TokenMintTransitionAction { /// /// # Returns /// - /// * `Result` - A `TokenMintTransitionAction` if successful, otherwise `ProtocolError`. + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenMintTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_token_mint_transition_with_contract_lookup( drive: &Drive, owner_id: Identifier, @@ -38,21 +40,25 @@ impl TokenMintTransitionAction { block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result<(Self, FeeResult), Error> { + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { match value { TokenMintTransition::V0(v0) => { - let (v0, fee) = - TokenMintTransitionActionV0::try_from_token_mint_transition_with_contract_lookup( - drive, - owner_id, - v0, - approximate_without_state_for_costs, - transaction, - block_info, - get_data_contract, - platform_version, - )?; - Ok((v0.into(), fee)) + TokenMintTransitionActionV0::try_from_token_mint_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + get_data_contract, + platform_version, + ) } } } @@ -72,7 +78,7 @@ impl TokenMintTransitionAction { /// /// # Returns /// - /// * `Result` - A `TokenMintTransitionAction` if successful, otherwise `ProtocolError`. + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenMintTransitionAction` if successful, otherwise `ProtocolError`. pub fn try_from_borrowed_token_mint_transition_with_contract_lookup( drive: &Drive, owner_id: Identifier, @@ -82,10 +88,16 @@ impl TokenMintTransitionAction { block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result<(Self, FeeResult), Error> { + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { match value { TokenMintTransition::V0(v0) => { - let (v0, fee) = TokenMintTransitionActionV0::try_from_borrowed_token_mint_transition_with_contract_lookup( + TokenMintTransitionActionV0::try_from_borrowed_token_mint_transition_with_contract_lookup( drive, owner_id, v0, @@ -94,8 +106,7 @@ impl TokenMintTransitionAction { block_info, get_data_contract, platform_version, - )?; - Ok((v0.into(), fee)) + ) } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs index ff4482aa86e..0c7e0643e43 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs @@ -1,20 +1,24 @@ use std::sync::Arc; use grovedb::TransactionArg; use dpp::block::block_info::BlockInfo; +use dpp::consensus::basic::BasicError; +use dpp::consensus::basic::token::{ChoosingTokenMintRecipientNotAllowedError, DestinationIdentityForTokenMintingNotSetError}; use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_mint_transition::v0::TokenMintTransitionV0; use dpp::ProtocolError; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; -use dpp::tokens::errors::TokenError; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::v0::TokenMintTransitionActionV0; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::fee::fee_result::FeeResult; +use dpp::prelude::ConsensusValidationResult; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; +use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; +use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; impl TokenMintTransitionActionV0 { /// Converts a `TokenMintTransitionV0` into a `TokenMintTransitionActionV0` using the provided contract lookup. @@ -38,7 +42,7 @@ impl TokenMintTransitionActionV0 { /// /// # Returns /// - /// * `Result` - Returns the constructed `TokenMintTransitionActionV0` if successful, + /// * `Result, Error>` - Returns the constructed `TokenMintTransitionActionV0` if successful, /// or an error if any issue arises, such as missing data or an invalid state transition. pub fn try_from_token_mint_transition_with_contract_lookup( drive: &Drive, @@ -49,7 +53,13 @@ impl TokenMintTransitionActionV0 { block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result<(Self, FeeResult), Error> { + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { let TokenMintTransitionV0 { base, issued_to_identity_id, @@ -72,21 +82,6 @@ impl TokenMintTransitionActionV0 { platform_version, )?; - let identity_balance_holder_id = issued_to_identity_id - .or_else(|| { - base_action - .data_contract_fetch_info_ref() - .contract - .tokens() - .get(&position) - .and_then(|token_configuration| { - token_configuration.new_tokens_destination_identity() - }) - }) - .ok_or(ProtocolError::Token( - TokenError::DestinationIdentityForMintingNotSetError.into(), - ))?; - let fee_result = Drive::calculate_fee( None, Some(drive_operations), @@ -96,13 +91,79 @@ impl TokenMintTransitionActionV0 { None, )?; + if !base_action + .token_configuration()? + .minting_allow_choosing_destination() + && issued_to_identity_id.is_some() + { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action( + &base_action, + owner_id, + 0, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + vec![BasicError::ChoosingTokenMintRecipientNotAllowedError( + ChoosingTokenMintRecipientNotAllowedError::new(base_action.token_id()), + ) + .into()], + ), + fee_result, + )); + } + + let identity_balance_holder_id = match issued_to_identity_id.or_else(|| { + base_action + .data_contract_fetch_info_ref() + .contract + .tokens() + .get(&position) + .and_then(|token_configuration| { + token_configuration.new_tokens_destination_identity() + }) + }) { + Some(identity_balance_holder_id) => identity_balance_holder_id, + None => { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action( + &base_action, + owner_id, + 0, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + vec![BasicError::DestinationIdentityForTokenMintingNotSetError( + DestinationIdentityForTokenMintingNotSetError::new( + base_action.token_id(), + ), + ) + .into()], + ), + fee_result, + )); + } + }; + Ok(( - TokenMintTransitionActionV0 { - base: base_action, - mint_amount: amount, - identity_balance_holder_id, - public_note, - }, + BatchedTransitionAction::TokenAction(TokenTransitionAction::MintAction( + TokenMintTransitionActionV0 { + base: base_action, + mint_amount: amount, + identity_balance_holder_id, + public_note, + } + .into(), + )) + .into(), fee_result, )) } @@ -130,7 +191,7 @@ impl TokenMintTransitionActionV0 { /// //// # Returns /// - /// * `Result<(TokenMintTransitionActionV0, FeeResult), Error>` - Returns a tuple containing the constructed + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - Returns a tuple containing the constructed /// `TokenMintTransitionActionV0` and a `FeeResult` if successful. If an error occurs (e.g., missing data or /// invalid state transition), it returns an `Error`. /// @@ -143,7 +204,13 @@ impl TokenMintTransitionActionV0 { block_info: &BlockInfo, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result<(Self, FeeResult), Error> { + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { let TokenMintTransitionV0 { base, issued_to_identity_id, @@ -165,21 +232,6 @@ impl TokenMintTransitionActionV0 { platform_version, )?; - let identity_balance_holder_id = issued_to_identity_id - .or_else(|| { - base_action - .data_contract_fetch_info_ref() - .contract - .tokens() - .get(&base.token_contract_position()) - .and_then(|token_configuration| { - token_configuration.new_tokens_destination_identity() - }) - }) - .ok_or(ProtocolError::Token( - TokenError::DestinationIdentityForMintingNotSetError.into(), - ))?; - let fee_result = Drive::calculate_fee( None, Some(drive_operations), @@ -189,13 +241,79 @@ impl TokenMintTransitionActionV0 { None, )?; + if !base_action + .token_configuration()? + .minting_allow_choosing_destination() + && issued_to_identity_id.is_some() + { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action( + &base_action, + owner_id, + 0, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + vec![BasicError::ChoosingTokenMintRecipientNotAllowedError( + ChoosingTokenMintRecipientNotAllowedError::new(base_action.token_id()), + ) + .into()], + ), + fee_result, + )); + } + + let identity_balance_holder_id = match issued_to_identity_id.or_else(|| { + base_action + .data_contract_fetch_info_ref() + .contract + .tokens() + .get(&base.token_contract_position()) + .and_then(|token_configuration| { + token_configuration.new_tokens_destination_identity() + }) + }) { + Some(identity_balance_holder_id) => identity_balance_holder_id, + None => { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action( + &base_action, + owner_id, + 0, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + vec![BasicError::DestinationIdentityForTokenMintingNotSetError( + DestinationIdentityForTokenMintingNotSetError::new( + base_action.token_id(), + ), + ) + .into()], + ), + fee_result, + )); + } + }; + Ok(( - TokenMintTransitionActionV0 { - base: base_action, - mint_amount: *amount, - identity_balance_holder_id, - public_note: public_note.clone(), - }, + BatchedTransitionAction::TokenAction(TokenTransitionAction::MintAction( + TokenMintTransitionActionV0 { + base: base_action, + mint_amount: *amount, + identity_balance_holder_id, + public_note: public_note.clone(), + } + .into(), + )) + .into(), fee_result, )) } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index b949531025b..5a6e083615c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -49,7 +49,7 @@ impl TokenTransferTransitionActionV0 { let TokenTransferTransitionV0 { base, amount, - recipient_owner_id, + recipient_id, public_note, shared_encrypted_note, private_encrypted_note, @@ -83,7 +83,7 @@ impl TokenTransferTransitionActionV0 { TokenTransferTransitionActionV0 { base: base_action, amount, - recipient_id: recipient_owner_id, + recipient_id, public_note, shared_encrypted_note, private_encrypted_note, @@ -129,7 +129,7 @@ impl TokenTransferTransitionActionV0 { let TokenTransferTransitionV0 { base, amount, - recipient_owner_id, + recipient_id, public_note, shared_encrypted_note, private_encrypted_note, @@ -164,7 +164,7 @@ impl TokenTransferTransitionActionV0 { TokenTransferTransitionActionV0 { base: base_action.into(), amount: *amount, - recipient_id: *recipient_owner_id, + recipient_id: *recipient_id, public_note: public_note.clone(), shared_encrypted_note: shared_encrypted_note.clone(), private_encrypted_note: private_encrypted_note.clone(), diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs index 89373a97cb4..ba7d64ad56f 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs @@ -603,6 +603,8 @@ mod tests { &drive, "tests/supporting_files/contract/family/family-contract.json", None, + None, + None, Some(&db_transaction), None, ); @@ -715,6 +717,8 @@ mod tests { &drive, "tests/supporting_files/contract/family/family-contract-only-age-index.json", None, + None, + None, Some(&db_transaction), None, ); @@ -933,6 +937,8 @@ mod tests { &drive, "tests/supporting_files/contract/family/family-contract-only-age-index.json", None, + None, + None, Some(&db_transaction), None, ); diff --git a/packages/rs-drive/src/util/test_helpers/mod.rs b/packages/rs-drive/src/util/test_helpers/mod.rs index de8f1c63156..8600f2eddbd 100644 --- a/packages/rs-drive/src/util/test_helpers/mod.rs +++ b/packages/rs-drive/src/util/test_helpers/mod.rs @@ -40,19 +40,25 @@ pub fn setup_contract( drive: &Drive, path: &str, contract_id: Option<[u8; 32]>, + owner_id: Option<[u8; 32]>, + contract_modification: Option, transaction: TransactionArg, use_platform_version: Option<&PlatformVersion>, ) -> DataContract { let platform_version = use_platform_version.unwrap_or(PlatformVersion::latest()); - let contract = json_document_to_contract_with_ids( + let mut contract = json_document_to_contract_with_ids( path, contract_id.map(Identifier::from), - None, + owner_id.map(Identifier::from), false, //no need to validate the data contracts in tests for drive platform_version, ) .expect("expected to get json based contract"); + if let Some(contract_modification) = contract_modification { + contract_modification(&mut contract); + } + drive .apply_contract( &contract, diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index e5f243f28c4..8e4503817d4 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -221,6 +221,8 @@ pub fn setup_family_tests( &drive, "tests/supporting_files/contract/family/family-contract.json", None, + None, + None, Some(&db_transaction), Some(platform_version), ); @@ -292,6 +294,8 @@ pub fn setup_family_tests_with_nulls(count: u32, seed: u64) -> (Drive, DataContr &drive, "tests/supporting_files/contract/family/family-contract-fields-optional.json", None, + None, + None, Some(&db_transaction), None, ); @@ -362,6 +366,8 @@ pub fn setup_family_tests_only_first_name_index(count: u32, seed: u64) -> (Drive &drive, "tests/supporting_files/contract/family/family-contract-only-first-name-index.json", None, + None, + None, Some(&db_transaction), None, ); @@ -828,6 +834,8 @@ pub fn setup_dpns_tests_with_batches( &drive, "tests/supporting_files/contract/dpns/dpns-contract.json", None, + None, + None, Some(&db_transaction), Some(platform_version), ); @@ -876,6 +884,8 @@ pub fn setup_withdrawal_tests( &drive, "tests/supporting_files/contract/withdrawals/withdrawals-contract.json", None, + None, + None, Some(&db_transaction), None, ); @@ -920,6 +930,8 @@ pub fn setup_references_tests(_count: u32, _seed: u64) -> (Drive, DataContract) &drive, "tests/supporting_files/contract/references/references_with_contract_history.json", None, + None, + None, Some(&db_transaction), None, ); @@ -956,6 +968,8 @@ pub fn setup_dpns_tests_label_not_required(count: u32, seed: u64) -> (Drive, Dat &drive, "tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json", None, + None, + None, Some(&db_transaction), None, ); @@ -992,6 +1006,8 @@ pub fn setup_dpns_test_with_data(path: &str) -> (Drive, DataContract) { &drive, "tests/supporting_files/contract/dpns/dpns-contract.json", None, + None, + None, Some(&db_transaction), None, ); diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 697487eb11c..6ea120b342e 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -186,6 +186,8 @@ pub fn setup( &drive, "tests/supporting_files/contract/family/family-contract-with-history.json", None, + None, + None, Some(&db_transaction), Some(platform_version), ); diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs index 48caab4b3ca..8d671176f41 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs @@ -4,6 +4,7 @@ pub mod v1; pub mod v2; pub mod v3; pub mod v4; +pub mod v5; #[derive(Clone, Debug, Default)] pub struct DriveAbciMethodVersions { diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs new file mode 100644 index 00000000000..f02d1679d38 --- /dev/null +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs @@ -0,0 +1,122 @@ +use crate::version::drive_abci_versions::drive_abci_method_versions::{ + DriveAbciBlockEndMethodVersions, DriveAbciBlockFeeProcessingMethodVersions, + DriveAbciBlockStartMethodVersions, DriveAbciCoreBasedUpdatesMethodVersions, + DriveAbciCoreChainLockMethodVersionsAndConstants, DriveAbciCoreInstantSendLockMethodVersions, + DriveAbciEngineMethodVersions, DriveAbciEpochMethodVersions, + DriveAbciFeePoolInwardsDistributionMethodVersions, + DriveAbciFeePoolOutwardsDistributionMethodVersions, + DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, + DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, + DriveAbciPlatformStateStorageMethodVersions, DriveAbciProtocolUpgradeMethodVersions, + DriveAbciStateTransitionProcessingMethodVersions, DriveAbciVotingMethodVersions, +}; + +// Introduced in Protocol version 8 for tokens +pub const DRIVE_ABCI_METHOD_VERSIONS_V5: DriveAbciMethodVersions = DriveAbciMethodVersions { + engine: DriveAbciEngineMethodVersions { + init_chain: 0, + check_tx: 0, + run_block_proposal: 0, + finalize_block_proposal: 0, + consensus_params_update: 1, + }, + initialization: DriveAbciInitializationMethodVersions { + initial_core_height_and_time: 0, + create_genesis_state: 1, // register the additional contracts (tokens and wallet utils) + }, + core_based_updates: DriveAbciCoreBasedUpdatesMethodVersions { + update_core_info: 0, + update_masternode_list: 0, + update_quorum_info: 0, + masternode_updates: DriveAbciMasternodeIdentitiesUpdatesMethodVersions { + get_voter_identity_key: 0, + get_operator_identity_keys: 0, + get_owner_identity_withdrawal_key: 0, + get_owner_identity_owner_key: 0, + get_voter_identifier_from_masternode_list_item: 0, + get_operator_identifier_from_masternode_list_item: 0, + create_operator_identity: 0, + create_owner_identity: 1, + create_voter_identity: 0, + disable_identity_keys: 0, + update_masternode_identities: 0, + update_operator_identity: 0, + update_owner_withdrawal_address: 1, + update_voter_identity: 0, + }, + }, + protocol_upgrade: DriveAbciProtocolUpgradeMethodVersions { + check_for_desired_protocol_upgrade: 1, + upgrade_protocol_version_on_epoch_change: 0, + perform_events_on_first_block_of_protocol_change: Some(0), + protocol_version_upgrade_percentage_needed: 67, + }, + block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions { + add_process_epoch_change_operations: 0, + process_block_fees: 0, + }, + core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { + choose_quorum: 0, + verify_chain_lock: 0, + verify_chain_lock_locally: 0, + verify_chain_lock_through_core: 0, + make_sure_core_is_synced_to_chain_lock: 0, + recent_block_count_amount: 2, + }, + core_instant_send_lock: DriveAbciCoreInstantSendLockMethodVersions { + verify_recent_signature_locally: 0, + }, + fee_pool_inwards_distribution: DriveAbciFeePoolInwardsDistributionMethodVersions { + add_distribute_block_fees_into_pools_operations: 0, + add_distribute_storage_fee_to_epochs_operations: 0, + }, + fee_pool_outwards_distribution: DriveAbciFeePoolOutwardsDistributionMethodVersions { + add_distribute_fees_from_oldest_unpaid_epoch_pool_to_proposers_operations: 0, + add_epoch_pool_to_proposers_payout_operations: 0, + find_oldest_epoch_needing_payment: 0, + fetch_reward_shares_list_for_masternode: 0, + }, + withdrawals: DriveAbciIdentityCreditWithdrawalMethodVersions { + build_untied_withdrawal_transactions_from_documents: 0, + dequeue_and_build_unsigned_withdrawal_transactions: 0, + fetch_transactions_block_inclusion_status: 0, + pool_withdrawals_into_transactions_queue: 0, + update_broadcasted_withdrawal_statuses: 0, + rebroadcast_expired_withdrawal_documents: 0, + append_signatures_and_broadcast_withdrawal_transactions: 0, + cleanup_expired_locks_of_withdrawal_amounts: 0, + }, + voting: DriveAbciVotingMethodVersions { + keep_record_of_finished_contested_resource_vote_poll: 0, + clean_up_after_vote_poll_end: 0, + clean_up_after_contested_resources_vote_poll_end: 0, + check_for_ended_vote_polls: 0, + tally_votes_for_contested_document_resource_vote_poll: 0, + award_document_to_winner: 0, + delay_vote_poll: 0, + run_dao_platform_events: 0, + remove_votes_for_removed_masternodes: 0, + }, + state_transition_processing: DriveAbciStateTransitionProcessingMethodVersions { + execute_event: 0, + process_raw_state_transitions: 0, + decode_raw_state_transitions: 0, + validate_fees_of_event: 0, + }, + epoch: DriveAbciEpochMethodVersions { + gather_epoch_info: 0, + get_genesis_time: 0, + }, + block_start: DriveAbciBlockStartMethodVersions { + clear_drive_block_cache: 0, + }, + block_end: DriveAbciBlockEndMethodVersions { + update_state_cache: 0, + update_drive_cache: 0, + validator_set_update: 2, + }, + platform_state_storage: DriveAbciPlatformStateStorageMethodVersions { + fetch_platform_state: 0, + store_platform_state: 0, + }, +}; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs index 72cc00bf3ff..bb4adfbb9d9 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs @@ -21,7 +21,7 @@ pub struct DriveStateTransitionActionConvertToHighLevelOperationsMethodVersions pub document_transfer_transition: FeatureVersion, pub document_update_price_transition: FeatureVersion, pub token_burn_transition: FeatureVersion, - pub token_issuance_transition: FeatureVersion, + pub token_mint_transition: FeatureVersion, pub token_transfer_transition: FeatureVersion, pub documents_batch_transition: FeatureVersion, pub identity_create_transition: FeatureVersion, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs index 3b694dbfb4e..e12a719fdd7 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs @@ -23,7 +23,7 @@ pub const DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1: DriveStateTransitionMethodV document_transfer_transition: 0, document_update_price_transition: 0, token_burn_transition: 0, - token_issuance_transition: 0, + token_mint_transition: 0, token_transfer_transition: 0, documents_batch_transition: 0, identity_create_transition: 0, diff --git a/packages/rs-platform-version/src/version/v8.rs b/packages/rs-platform-version/src/version/v8.rs index d6e7f016a57..068105e7292 100644 --- a/packages/rs-platform-version/src/version/v8.rs +++ b/packages/rs-platform-version/src/version/v8.rs @@ -13,7 +13,7 @@ use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANS use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; -use crate::version::drive_abci_versions::drive_abci_method_versions::v4::DRIVE_ABCI_METHOD_VERSIONS_V4; +use crate::version::drive_abci_versions::drive_abci_method_versions::v5::DRIVE_ABCI_METHOD_VERSIONS_V5; use crate::version::drive_abci_versions::drive_abci_query_versions::v1::DRIVE_ABCI_QUERY_VERSIONS_V1; use crate::version::drive_abci_versions::drive_abci_structure_versions::v1::DRIVE_ABCI_STRUCTURE_VERSIONS_V1; use crate::version::drive_abci_versions::drive_abci_validation_versions::v4::DRIVE_ABCI_VALIDATION_VERSIONS_V4; @@ -35,7 +35,7 @@ pub const PLATFORM_V8: PlatformVersion = PlatformVersion { drive: DRIVE_VERSION_V3, // changed (for data contract insert) drive_abci: DriveAbciVersion { structs: DRIVE_ABCI_STRUCTURE_VERSIONS_V1, - methods: DRIVE_ABCI_METHOD_VERSIONS_V4, + methods: DRIVE_ABCI_METHOD_VERSIONS_V5, // changed because of the genesis state validation_and_processing: DRIVE_ABCI_VALIDATION_VERSIONS_V4, withdrawal_constants: DRIVE_ABCI_WITHDRAWAL_CONSTANTS_V2, query: DRIVE_ABCI_QUERY_VERSIONS_V1, diff --git a/packages/token-history-contract/schema/v1/token-history-contract-documents.json b/packages/token-history-contract/schema/v1/token-history-contract-documents.json index 79ec99ddf4c..7bc7732d124 100644 --- a/packages/token-history-contract/schema/v1/token-history-contract-documents.json +++ b/packages/token-history-contract/schema/v1/token-history-contract-documents.json @@ -114,6 +114,20 @@ "$createdAt": "asc" } ] + }, + { + "name": "byRecipientId", + "properties": [ + { + "tokenId": "asc" + }, + { + "recipientId": "asc" + }, + { + "$createdAt": "asc" + } + ] } ], "properties": { @@ -125,22 +139,31 @@ "description": "The token ID", "position": 0 }, + "recipientId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The token ID", + "position": 1 + }, "amount": { "type": "integer", "minimum": 0, "description": "The amount that was burned", - "position": 1 + "position": 2 }, "note": { "type": "string", "maxLength": 2048, "description": "An optional explanation of why this mint took place", - "position": 2 + "position": 3 } }, "required": [ "tokenId", "amount", + "recipientId", "$createdAt", "$createdAtBlockHeight", "$createdAtCoreBlockHeight" From 78394e0d0c46da5cb563186bf56db43959d09bcb Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 5 Jan 2025 01:45:17 +0700 Subject: [PATCH 36/61] more token tests --- .../rs-dpp/src/data_contract/accessors/mod.rs | 36 + .../src/data_contract/accessors/v1/mod.rs | 14 +- .../token_configuration/accessors/mod.rs | 5 +- .../token_configuration/accessors/v0/mod.rs | 5 +- .../mod.rs | 6 +- .../v0/mod.rs | 78 ++- .../token_configuration/v0/accessors.rs | 9 +- .../token_configuration/v0/mod.rs | 19 +- .../authorized_action_takers.rs | 26 +- .../data_contract/change_control_rules/mod.rs | 34 +- .../change_control_rules/v0/mod.rs | 24 +- .../rs-dpp/src/data_contract/group/mod.rs | 2 +- .../src/data_contract/v1/accessors/mod.rs | 20 + packages/rs-dpp/src/errors/consensus/codes.rs | 2 + .../src/errors/consensus/state/state_error.rs | 8 +- ...oes_not_have_enough_token_balance_error.rs | 63 ++ .../src/errors/consensus/state/token/mod.rs | 4 + .../token/unauthorized_token_action_error.rs | 56 ++ packages/rs-dpp/src/tokens/errors.rs | 2 + .../types/execution_operation/mod.rs | 14 + .../state_v0/mod.rs | 55 +- .../state_v0/mod.rs | 31 +- .../state_transitions/batch/mod.rs | 648 +++++++++++++++++- .../data_contract_create/mod.rs | 24 +- .../state_transition/state_transitions/mod.rs | 9 +- .../v0/mod.rs | 2 +- .../src/drive/tokens/balance/fetch/mod.rs | 2 - .../src/drive/tokens/balance/fetch/v0/mod.rs | 3 +- .../src/version/fee/processing/mod.rs | 4 + .../src/version/fee/processing/v1.rs | 1 + 30 files changed, 1132 insertions(+), 74 deletions(-) create mode 100644 packages/rs-dpp/src/errors/consensus/state/token/identity_does_not_have_enough_token_balance_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/state/token/unauthorized_token_action_error.rs diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index e5b1f3bdb5d..92fdb99bd94 100644 --- a/packages/rs-dpp/src/data_contract/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/mod.rs @@ -13,6 +13,7 @@ use crate::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1S use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::errors::DataContractError; use crate::data_contract::group::Group; +use crate::tokens::errors::TokenError; use crate::ProtocolError; use std::collections::BTreeMap; @@ -216,6 +217,25 @@ impl DataContractV1Getters for DataContract { } } + /// Returns a reference to a group or an error. + /// Returns an Error for V0 since it doesn't have groups. + fn expected_group(&self, position: GroupContractPosition) -> Result<&Group, ProtocolError> { + match self { + DataContract::V0(_) => Err(ProtocolError::GroupNotFound( + "Group not found in contract V0".to_string(), + )), + DataContract::V1(v1) => { + v1.groups + .get(&position) + .ok_or(ProtocolError::GroupNotFound(format!( + "Group not found at position {} in contract {}", + position, + self.id() + ))) + } + } + } + /// Returns a reference to the tokens map. fn tokens(&self) -> &BTreeMap { match self { @@ -233,6 +253,22 @@ impl DataContractV1Getters for DataContract { } } + /// Returns a mutable reference to a token configuration or an error. + /// Returns an Error for V0 since it doesn't have tokens. + fn expected_token_configuration( + &self, + position: TokenContractPosition, + ) -> Result<&TokenConfiguration, ProtocolError> { + match self { + DataContract::V0(_) => Err(ProtocolError::Token( + TokenError::TokenNotFoundOnContractVersion.into(), + )), + DataContract::V1(v1) => v1.tokens.get(&position).ok_or(ProtocolError::Token( + TokenError::TokenNotFoundAtPositionError.into(), + )), + } + } + /// Returns a mutable reference to a token configuration /// Returns `None` for V0 since it doesn't have tokens. fn token_configuration_mut( diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs index c90c353edab..a3c4d000465 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -1,7 +1,8 @@ use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::group::Group; -use crate::data_contract::{GroupContractPosition, TokenContractPosition}; +use crate::data_contract::{DataContract, GroupContractPosition, TokenContractPosition}; +use crate::tokens::errors::TokenError; use crate::ProtocolError; use platform_value::Identifier; use std::collections::BTreeMap; @@ -14,12 +15,23 @@ pub trait DataContractV1Getters: DataContractV0Getters { /// Returns a mutable reference to the groups map. fn groups_mut(&mut self) -> Option<&mut BTreeMap>; + /// Returns a reference to a group or an error. + /// Returns an Error for V0 since it doesn't have groups. + fn expected_group(&self, position: GroupContractPosition) -> Result<&Group, ProtocolError>; /// Returns a reference to the tokens map. fn tokens(&self) -> &BTreeMap; /// Returns a mutable reference to the tokens map. fn tokens_mut(&mut self) -> Option<&mut BTreeMap>; + + /// Returns a mutable reference to a token configuration or an error. + /// Returns an Error for V0 since it doesn't have tokens. + fn expected_token_configuration( + &self, + position: TokenContractPosition, + ) -> Result<&TokenConfiguration, ProtocolError>; + /// Returns a mutable reference to a token configuration /// Returns `None` for V0 since it doesn't have tokens. fn token_configuration_mut( diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs index 6312ac274b3..5b575c265ea 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs @@ -8,6 +8,7 @@ use crate::data_contract::associated_token::token_configuration::TokenConfigurat use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::group::RequiredSigners; +use crate::data_contract::GroupContractPosition; use platform_value::Identifier; use std::collections::BTreeSet; @@ -111,7 +112,7 @@ impl TokenConfigurationV0Getters for TokenConfiguration { } /// Returns the main control group. - fn main_control_group(&self) -> Option<&(BTreeSet, RequiredSigners)> { + fn main_control_group(&self) -> Option { match self { TokenConfiguration::V0(v0) => v0.main_control_group(), } @@ -198,7 +199,7 @@ impl TokenConfigurationV0Setters for TokenConfiguration { } /// Sets the main control group. - fn set_main_control_group(&mut self, group: Option<(BTreeSet, RequiredSigners)>) { + fn set_main_control_group(&mut self, group: Option) { match self { TokenConfiguration::V0(v0) => v0.set_main_control_group(group), } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs index 079f97b7398..bcd49b06429 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -2,6 +2,7 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfig use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; use crate::data_contract::group::RequiredSigners; +use crate::data_contract::GroupContractPosition; use platform_value::Identifier; use std::collections::BTreeSet; @@ -47,7 +48,7 @@ pub trait TokenConfigurationV0Getters { fn unfreeze_rules(&self) -> &ChangeControlRules; /// Returns the main control group. - fn main_control_group(&self) -> Option<&(BTreeSet, RequiredSigners)>; + fn main_control_group(&self) -> Option; /// Returns the main control group can be modified. fn main_control_group_can_be_modified(&self) -> &AuthorizedActionTakers; @@ -86,7 +87,7 @@ pub trait TokenConfigurationV0Setters { fn set_unfreeze_rules(&mut self, rules: ChangeControlRules); /// Sets the main control group. - fn set_main_control_group(&mut self, group: Option<(BTreeSet, RequiredSigners)>); + fn set_main_control_group(&mut self, group: Option); /// Sets the main control group can be modified. fn set_main_control_group_can_be_modified(&mut self, action_takers: AuthorizedActionTakers); diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs index dd6b1348904..9dda53c9848 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/mod.rs @@ -1,10 +1,12 @@ use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::group::Group; +use crate::data_contract::GroupContractPosition; use crate::multi_identity_events::ActionTaker; use crate::validation::SimpleConsensusValidationResult; use crate::ProtocolError; use platform_value::Identifier; use platform_version::version::PlatformVersion; +use std::collections::BTreeMap; mod v0; @@ -13,7 +15,8 @@ impl TokenConfiguration { &self, new_config: &TokenConfiguration, contract_owner_id: &Identifier, - main_group: &Group, + main_group: Option<&Group>, + groups: &BTreeMap, action_taker: &ActionTaker, platform_version: &PlatformVersion, ) -> Result { @@ -27,6 +30,7 @@ impl TokenConfiguration { new_config, contract_owner_id, main_group, + groups, action_taker, )), version => Err(ProtocolError::UnknownVersionMismatch { diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index 4a78953ce8a..68eb8c54a9c 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -1,9 +1,11 @@ use crate::consensus::basic::data_contract::DataContractTokenConfigurationUpdateError; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::group::Group; +use crate::data_contract::GroupContractPosition; use crate::multi_identity_events::ActionTaker; use crate::validation::SimpleConsensusValidationResult; use platform_value::Identifier; +use std::collections::BTreeMap; impl TokenConfiguration { #[inline(always)] @@ -11,7 +13,8 @@ impl TokenConfiguration { &self, new_config: &TokenConfiguration, contract_owner_id: &Identifier, - main_group: &Group, + main_group: Option<&Group>, + groups: &BTreeMap, action_taker: &ActionTaker, ) -> SimpleConsensusValidationResult { let old = self.as_cow_v0(); @@ -51,6 +54,7 @@ impl TokenConfiguration { &new.max_supply_change_rules, contract_owner_id, main_group, + groups, action_taker, ) { return SimpleConsensusValidationResult::new_with_error( @@ -74,6 +78,7 @@ impl TokenConfiguration { &new.new_tokens_destination_identity_rules, contract_owner_id, main_group, + groups, action_taker, ) { return SimpleConsensusValidationResult::new_with_error( @@ -89,12 +94,38 @@ impl TokenConfiguration { } } + // Check changes to minting_allow_choosing_destination and its rules + if old.minting_allow_choosing_destination != new.minting_allow_choosing_destination + || old.minting_allow_choosing_destination_rules + != new.minting_allow_choosing_destination_rules + { + if !old.minting_allow_choosing_destination_rules.can_change_to( + &new.minting_allow_choosing_destination_rules, + contract_owner_id, + main_group, + groups, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "mintingAllowChoosingDestination or mintingAllowChoosingDestinationRules" + .to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + // Check changes to manual_minting_rules if old.manual_minting_rules != new.manual_minting_rules { if !old.manual_minting_rules.can_change_to( &new.manual_minting_rules, contract_owner_id, main_group, + groups, action_taker, ) { return SimpleConsensusValidationResult::new_with_error( @@ -115,6 +146,7 @@ impl TokenConfiguration { &new.manual_burning_rules, contract_owner_id, main_group, + groups, action_taker, ) { return SimpleConsensusValidationResult::new_with_error( @@ -129,11 +161,53 @@ impl TokenConfiguration { } } + // Check changes to freeze_rules + if old.freeze_rules != new.freeze_rules { + if !old.freeze_rules.can_change_to( + &new.freeze_rules, + contract_owner_id, + main_group, + groups, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "freezeRules".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + + // Check changes to unfreeze_rules + if old.unfreeze_rules != new.unfreeze_rules { + if !old.unfreeze_rules.can_change_to( + &new.unfreeze_rules, + contract_owner_id, + main_group, + groups, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "unfreezeRules".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + // Check changes to main_control_group if old.main_control_group != new.main_control_group { if !old .main_control_group_can_be_modified - .allowed_for_action_taker(contract_owner_id, main_group, action_taker) + .allowed_for_action_taker(contract_owner_id, main_group, groups, action_taker) { return SimpleConsensusValidationResult::new_with_error( DataContractTokenConfigurationUpdateError::new( diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs index f6b52d00d7b..55eda9646e4 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs @@ -6,9 +6,8 @@ use crate::data_contract::associated_token::token_configuration::v0::{ }; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; -use crate::data_contract::group::RequiredSigners; +use crate::data_contract::GroupContractPosition; use platform_value::Identifier; -use std::collections::BTreeSet; /// Implementing `TokenConfigurationV0Getters` for `TokenConfigurationV0` impl TokenConfigurationV0Getters for TokenConfigurationV0 { @@ -83,8 +82,8 @@ impl TokenConfigurationV0Getters for TokenConfigurationV0 { } /// Returns the main control group. - fn main_control_group(&self) -> Option<&(BTreeSet, RequiredSigners)> { - self.main_control_group.as_ref() + fn main_control_group(&self) -> Option { + self.main_control_group } /// Returns the main control group can be modified. @@ -146,7 +145,7 @@ impl TokenConfigurationV0Setters for TokenConfigurationV0 { } /// Sets the main control group. - fn set_main_control_group(&mut self, group: Option<(BTreeSet, RequiredSigners)>) { + fn set_main_control_group(&mut self, group: Option) { self.main_control_group = group; } diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index d7ebc4f7c99..773f42291c0 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -3,11 +3,11 @@ mod accessors; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; use crate::data_contract::change_control_rules::ChangeControlRules; -use crate::data_contract::group::RequiredSigners; +use crate::data_contract::GroupContractPosition; use bincode::{Decode, Encode}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; -use std::collections::{BTreeMap, BTreeSet}; +use std::collections::BTreeMap; use std::fmt; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq)] @@ -56,16 +56,16 @@ pub struct TokenConfigurationV0 { pub minting_allow_choosing_destination: bool, #[serde(default = "default_change_control_rules")] pub minting_allow_choosing_destination_rules: ChangeControlRules, - #[serde(default = "default_change_control_rules")] + #[serde(default = "default_contract_owner_change_control_rules")] pub manual_minting_rules: ChangeControlRules, - #[serde(default = "default_change_control_rules")] + #[serde(default = "default_contract_owner_change_control_rules")] pub manual_burning_rules: ChangeControlRules, #[serde(default = "default_change_control_rules")] pub freeze_rules: ChangeControlRules, #[serde(default = "default_change_control_rules")] pub unfreeze_rules: ChangeControlRules, #[serde(default)] - pub main_control_group: Option<(BTreeSet, RequiredSigners)>, + pub main_control_group: Option, #[serde(default)] pub main_control_group_can_be_modified: AuthorizedActionTakers, } @@ -89,6 +89,15 @@ fn default_change_control_rules() -> ChangeControlRules { }) } +fn default_contract_owner_change_control_rules() -> ChangeControlRules { + ChangeControlRules::V0(ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::ContractOwner, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }) +} + impl fmt::Display for TokenConfigurationV0 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs b/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs index 32ada12f685..7a23c4259d1 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/authorized_action_takers.rs @@ -1,9 +1,11 @@ use crate::data_contract::group::accessors::v0::GroupV0Getters; use crate::data_contract::group::{Group, GroupMemberPower}; +use crate::data_contract::GroupContractPosition; use crate::multi_identity_events::ActionTaker; use bincode::{Decode, Encode}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, Default)] pub enum AuthorizedActionTakers { @@ -11,14 +13,15 @@ pub enum AuthorizedActionTakers { NoOne, ContractOwner, MainGroup, - Group(Group), + Group(GroupContractPosition), } impl AuthorizedActionTakers { pub fn allowed_for_action_taker( &self, contract_owner_id: &Identifier, - main_group: &Group, + main_group: Option<&Group>, + groups: &BTreeMap, action_taker: &ActionTaker, ) -> bool { match self { @@ -35,12 +38,20 @@ impl AuthorizedActionTakers { // MainGroup allows multiparty actions with specific power requirements AuthorizedActionTakers::MainGroup => { - Self::is_action_taker_authorized(main_group, action_taker) + if let Some(main_group) = main_group { + Self::is_action_taker_authorized(main_group, action_taker) + } else { + false + } } // Group-specific permissions with power aggregation logic - AuthorizedActionTakers::Group(group) => { - Self::is_action_taker_authorized(group, action_taker) + AuthorizedActionTakers::Group(group_contract_position) => { + if let Some(group) = groups.get(group_contract_position) { + Self::is_action_taker_authorized(group, action_taker) + } else { + false + } } } } @@ -48,7 +59,10 @@ impl AuthorizedActionTakers { /// Helper method to check if action takers meet the group's required power threshold. fn is_action_taker_authorized(group: &Group, action_taker: &ActionTaker) -> bool { match action_taker { - ActionTaker::SingleIdentity(_) => false, + ActionTaker::SingleIdentity(member_id) => { + let power = group.members().get(member_id).cloned().unwrap_or_default(); + power >= group.required_power() + } ActionTaker::SpecifiedIdentities(action_takers) => { // Calculate the total power of action takers who are members of the group let total_power: GroupMemberPower = group diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs index 756c507014f..2385e114355 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/mod.rs @@ -1,13 +1,16 @@ pub mod authorized_action_takers; pub mod v0; +use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::v0::ChangeControlRulesV0; use crate::data_contract::group::Group; +use crate::data_contract::GroupContractPosition; use crate::multi_identity_events::ActionTaker; use bincode::{Decode, Encode}; use derive_more::From; use platform_value::Identifier; use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, From)] pub enum ChangeControlRules { @@ -15,17 +18,40 @@ pub enum ChangeControlRules { } impl ChangeControlRules { + pub fn authorized_to_make_change_action_takers(&self) -> &AuthorizedActionTakers { + match self { + ChangeControlRules::V0(v0) => &v0.authorized_to_make_change, + } + } + pub fn can_make_change( + &self, + contract_owner_id: &Identifier, + main_group: Option<&Group>, + groups: &BTreeMap, + action_taker: &ActionTaker, + ) -> bool { + match self { + ChangeControlRules::V0(v0) => { + v0.can_make_change(contract_owner_id, main_group, groups, action_taker) + } + } + } pub fn can_change_to( &self, other: &ChangeControlRules, contract_owner_id: &Identifier, - main_group: &Group, + main_group: Option<&Group>, + groups: &BTreeMap, action_taker: &ActionTaker, ) -> bool { match (self, other) { - (ChangeControlRules::V0(v0), ChangeControlRules::V0(v0_other)) => { - v0.can_change_to(v0_other, contract_owner_id, main_group, action_taker) - } + (ChangeControlRules::V0(v0), ChangeControlRules::V0(v0_other)) => v0.can_change_to( + v0_other, + contract_owner_id, + main_group, + groups, + action_taker, + ), } } } diff --git a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs index b82f7391903..41261680cec 100644 --- a/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/change_control_rules/v0/mod.rs @@ -1,9 +1,11 @@ use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::group::Group; +use crate::data_contract::GroupContractPosition; use crate::multi_identity_events::ActionTaker; use bincode::{Decode, Encode}; use platform_value::Identifier; use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; #[derive(Serialize, Deserialize, Decode, Encode, Debug, Clone, PartialEq, Eq, Default)] pub struct ChangeControlRulesV0 { @@ -18,17 +20,33 @@ pub struct ChangeControlRulesV0 { } impl ChangeControlRulesV0 { + pub fn can_make_change( + &self, + contract_owner_id: &Identifier, + main_group: Option<&Group>, + groups: &BTreeMap, + action_taker: &ActionTaker, + ) -> bool { + self.authorized_to_make_change.allowed_for_action_taker( + contract_owner_id, + main_group, + groups, + action_taker, + ) + } pub fn can_change_to( &self, other: &ChangeControlRulesV0, contract_owner_id: &Identifier, - main_group: &Group, + main_group: Option<&Group>, + groups: &BTreeMap, action_taker: &ActionTaker, ) -> bool { // First, check if the action taker is allowed to make any changes at all if !self.authorized_to_make_change.allowed_for_action_taker( contract_owner_id, main_group, + groups, action_taker, ) { return false; @@ -40,7 +58,7 @@ impl ChangeControlRulesV0 { // authorized_to_change_authorized_action_takers in the current rules if !self .authorized_to_change_authorized_action_takers - .allowed_for_action_taker(contract_owner_id, main_group, action_taker) + .allowed_for_action_taker(contract_owner_id, main_group, groups, action_taker) { return false; } @@ -67,7 +85,7 @@ impl ChangeControlRulesV0 { // Must be allowed by the current authorized_to_change_authorized_action_takers if !self .authorized_to_change_authorized_action_takers - .allowed_for_action_taker(contract_owner_id, main_group, action_taker) + .allowed_for_action_taker(contract_owner_id, main_group, groups, action_taker) { return false; } diff --git a/packages/rs-dpp/src/data_contract/group/mod.rs b/packages/rs-dpp/src/data_contract/group/mod.rs index 01919b161a4..26e3c036292 100644 --- a/packages/rs-dpp/src/data_contract/group/mod.rs +++ b/packages/rs-dpp/src/data_contract/group/mod.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; pub mod accessors; -mod v0; +pub mod v0; pub type RequiredSigners = u8; pub type GroupMemberPower = u32; diff --git a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs index 4bc22fbccde..d62a46ddfd0 100644 --- a/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/v1/accessors/mod.rs @@ -12,6 +12,7 @@ use crate::data_contract::associated_token::token_configuration::TokenConfigurat use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::group::Group; use crate::tokens::calculate_token_id; +use crate::tokens::errors::TokenError; use crate::ProtocolError; use platform_value::Identifier; use std::collections::BTreeMap; @@ -163,6 +164,16 @@ impl DataContractV1Getters for DataContractV1 { Some(&mut self.groups) } + fn expected_group(&self, position: GroupContractPosition) -> Result<&Group, ProtocolError> { + self.groups + .get(&position) + .ok_or(ProtocolError::GroupNotFound(format!( + "Group not found at position {} in contract {}", + position, + self.id() + ))) + } + fn tokens(&self) -> &BTreeMap { &self.tokens } @@ -171,6 +182,15 @@ impl DataContractV1Getters for DataContractV1 { Some(&mut self.tokens) } + fn expected_token_configuration( + &self, + position: TokenContractPosition, + ) -> Result<&TokenConfiguration, ProtocolError> { + self.tokens.get(&position).ok_or(ProtocolError::Token( + TokenError::TokenNotFoundAtPositionError.into(), + )) + } + fn token_configuration_mut( &mut self, position: TokenContractPosition, diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index 907cf2fed18..852418a3cbb 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -233,6 +233,8 @@ impl ErrorWithCode for StateError { // Token errors: 40150-40199 Self::RecipientIdentityDoesNotExistError(_) => 40150, + Self::IdentityDoesNotHaveEnoughTokenBalanceError(_) => 40151, + Self::UnauthorizedTokenActionError(_) => 40152, // Identity Errors: 40200-40299 Self::IdentityAlreadyExistsError(_) => 40200, diff --git a/packages/rs-dpp/src/errors/consensus/state/state_error.rs b/packages/rs-dpp/src/errors/consensus/state/state_error.rs index d945b82ba47..7d0783ff8e5 100644 --- a/packages/rs-dpp/src/errors/consensus/state/state_error.rs +++ b/packages/rs-dpp/src/errors/consensus/state/state_error.rs @@ -42,7 +42,7 @@ use crate::consensus::state::identity::missing_transfer_key_error::MissingTransf use crate::consensus::state::identity::no_transfer_key_for_core_withdrawal_available_error::NoTransferKeyForCoreWithdrawalAvailableError; use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_insufficient_error::PrefundedSpecializedBalanceInsufficientError; use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_not_found_error::PrefundedSpecializedBalanceNotFoundError; -use crate::consensus::state::token::RecipientIdentityDoesNotExistError; +use crate::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, RecipientIdentityDoesNotExistError, UnauthorizedTokenActionError}; use crate::consensus::state::voting::masternode_incorrect_voter_identity_id_error::MasternodeIncorrectVoterIdentityIdError; use crate::consensus::state::voting::masternode_incorrect_voting_address_error::MasternodeIncorrectVotingAddressError; use crate::consensus::state::voting::masternode_not_found_error::MasternodeNotFoundError; @@ -203,6 +203,12 @@ pub enum StateError { #[error(transparent)] RecipientIdentityDoesNotExistError(RecipientIdentityDoesNotExistError), + + #[error(transparent)] + IdentityDoesNotHaveEnoughTokenBalanceError(IdentityDoesNotHaveEnoughTokenBalanceError), + + #[error(transparent)] + UnauthorizedTokenActionError(UnauthorizedTokenActionError), } impl From for ConsensusError { diff --git a/packages/rs-dpp/src/errors/consensus/state/token/identity_does_not_have_enough_token_balance_error.rs b/packages/rs-dpp/src/errors/consensus/state/token/identity_does_not_have_enough_token_balance_error.rs new file mode 100644 index 00000000000..ada238196e6 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/token/identity_does_not_have_enough_token_balance_error.rs @@ -0,0 +1,63 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Identity {} does not have enough token balance: required {}, actual {}, action: {}", + identity_id, + required_balance, + actual_balance, + action +)] +#[platform_serialize(unversioned)] +pub struct IdentityDoesNotHaveEnoughTokenBalanceError { + identity_id: Identifier, + required_balance: u64, + actual_balance: u64, + action: String, +} + +impl IdentityDoesNotHaveEnoughTokenBalanceError { + pub fn new( + identity_id: Identifier, + required_balance: u64, + actual_balance: u64, + action: String, + ) -> Self { + Self { + identity_id, + required_balance, + actual_balance, + action, + } + } + + pub fn identity_id(&self) -> &Identifier { + &self.identity_id + } + + pub fn required_balance(&self) -> u64 { + self.required_balance + } + + pub fn actual_balance(&self) -> u64 { + self.actual_balance + } + + pub fn action(&self) -> &str { + &self.action + } +} + +impl From for ConsensusError { + fn from(err: IdentityDoesNotHaveEnoughTokenBalanceError) -> Self { + Self::StateError(StateError::IdentityDoesNotHaveEnoughTokenBalanceError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/state/token/mod.rs b/packages/rs-dpp/src/errors/consensus/state/token/mod.rs index c482ef72cd2..2a4e3ce701f 100644 --- a/packages/rs-dpp/src/errors/consensus/state/token/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/state/token/mod.rs @@ -1,3 +1,7 @@ +mod identity_does_not_have_enough_token_balance_error; mod recipient_identity_does_not_exist_error; +mod unauthorized_token_action_error; +pub use identity_does_not_have_enough_token_balance_error::*; pub use recipient_identity_does_not_exist_error::*; +pub use unauthorized_token_action_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/state/token/unauthorized_token_action_error.rs b/packages/rs-dpp/src/errors/consensus/state/token/unauthorized_token_action_error.rs new file mode 100644 index 00000000000..c71df7267a6 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/token/unauthorized_token_action_error.rs @@ -0,0 +1,56 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Identity {} is not authorized to perform action: {}. Authorized action takers: {:?}", + identity_id, + action, + authorized_action_takers +)] +#[platform_serialize(unversioned)] +pub struct UnauthorizedTokenActionError { + identity_id: Identifier, + action: String, + authorized_action_takers: AuthorizedActionTakers, +} + +impl UnauthorizedTokenActionError { + pub fn new( + identity_id: Identifier, + action: String, + authorized_action_takers: AuthorizedActionTakers, + ) -> Self { + Self { + identity_id, + action, + authorized_action_takers, + } + } + + pub fn identity_id(&self) -> &Identifier { + &self.identity_id + } + + pub fn action(&self) -> &str { + &self.action + } + + pub fn authorized_action_takers(&self) -> &AuthorizedActionTakers { + &self.authorized_action_takers + } +} + +impl From for ConsensusError { + fn from(err: UnauthorizedTokenActionError) -> Self { + Self::StateError(StateError::UnauthorizedTokenActionError(err)) + } +} diff --git a/packages/rs-dpp/src/tokens/errors.rs b/packages/rs-dpp/src/tokens/errors.rs index bf4445568b7..c23e6194103 100644 --- a/packages/rs-dpp/src/tokens/errors.rs +++ b/packages/rs-dpp/src/tokens/errors.rs @@ -4,4 +4,6 @@ use thiserror::Error; pub enum TokenError { #[error("There is no token at this position")] TokenNotFoundAtPositionError, + #[error("The contract version does not allow tokens")] + TokenNotFoundOnContractVersion, } diff --git a/packages/rs-drive-abci/src/execution/types/execution_operation/mod.rs b/packages/rs-drive-abci/src/execution/types/execution_operation/mod.rs index d44b854495e..c0dc1fa91e8 100644 --- a/packages/rs-drive-abci/src/execution/types/execution_operation/mod.rs +++ b/packages/rs-drive-abci/src/execution/types/execution_operation/mod.rs @@ -65,6 +65,7 @@ pub const SHA256_BLOCK_SIZE: u16 = 64; #[derive(Debug, Clone, PartialEq, Eq)] pub enum ValidationOperation { Protocol(ProtocolValidationOperation), + RetrieveIdentityTokenBalance, RetrieveIdentity(RetrieveIdentityInfo), RetrievePrefundedSpecializedBalance, PerformNetworkThresholdSigning, @@ -224,6 +225,19 @@ impl ValidationOperation { "execution processing fee overflow error", ))?; } + ValidationOperation::RetrieveIdentityTokenBalance => { + let operation_cost = platform_version + .fee_version + .processing + .fetch_identity_token_balance_processing_cost; + + fee_result.processing_fee = fee_result + .processing_fee + .checked_add(operation_cost) + .ok_or(ExecutionError::Overflow( + "execution processing fee overflow error", + ))?; + } } } Ok(()) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs index 62c099b7f90..caea4adbf8e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs @@ -6,8 +6,12 @@ use dpp::consensus::state::document::document_contest_currently_locked_error::Do use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; use dpp::consensus::state::state_error::StateError; +use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, UnauthorizedTokenActionError}; use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::multi_identity_events::ActionTaker; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; @@ -45,7 +49,56 @@ impl TokenBurnTransitionActionStateValidationV0 for TokenBurnTransitionAction { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result { - // todo verify that minting would not break max supply + // Let's first check to see if we are authorized to perform this action + let contract = &self.data_contract_fetch_info_ref().contract; + let token_configuration = contract.expected_token_configuration(self.token_position())?; + let rules = token_configuration.manual_burning_rules(); + let main_control_group = token_configuration + .main_control_group() + .map(|position| contract.expected_group(position)) + .transpose()?; + + if !rules.can_make_change( + &contract.owner_id(), + main_control_group, + contract.groups(), + &ActionTaker::SingleIdentity(owner_id), + ) { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + owner_id, + "burn".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )); + } + + // We need to verify that we have enough of the token + let balance = platform + .drive + .fetch_identity_token_balance( + self.token_id().to_buffer(), + owner_id.to_buffer(), + transaction, + platform_version, + )? + .unwrap_or_default(); + execution_context.add_operation(ValidationOperation::RetrieveIdentityTokenBalance); + if balance < self.burn_amount() { + // The identity does not exist + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::IdentityDoesNotHaveEnoughTokenBalanceError( + IdentityDoesNotHaveEnoughTokenBalanceError::new( + owner_id, + self.burn_amount(), + balance, + "burn".to_string(), + ), + )), + )); + } Ok(SimpleConsensusValidationResult::new()) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs index 3d0fd657409..d37f56c1a6b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs @@ -6,9 +6,12 @@ use dpp::consensus::state::document::document_contest_currently_locked_error::Do use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::RecipientIdentityDoesNotExistError; +use dpp::consensus::state::token::{RecipientIdentityDoesNotExistError, UnauthorizedTokenActionError}; use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::multi_identity_events::ActionTaker; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; @@ -46,6 +49,32 @@ impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result { + // Let's first check to see if we are authorized to perform this action + let contract = &self.data_contract_fetch_info_ref().contract; + let token_configuration = contract.expected_token_configuration(self.token_position())?; + let rules = token_configuration.manual_minting_rules(); + let main_control_group = token_configuration + .main_control_group() + .map(|position| contract.expected_group(position)) + .transpose()?; + + if !rules.can_make_change( + &contract.owner_id(), + main_control_group, + contract.groups(), + &ActionTaker::SingleIdentity(owner_id), + ) { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + owner_id, + "mint".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )); + } + // todo verify that minting would not break max supply // We need to verify that the receiver is a valid identity diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index aff4792e578..d41ce48bf2f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -9290,7 +9290,7 @@ mod tests { use super::*; #[test] - fn test_token_mint_by_owned_id_allowed_sending_to_self() { + fn test_token_mint_by_owner_allowed_sending_to_self() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -9308,6 +9308,7 @@ mod tests { &mut platform, identity.id(), None::, + None, platform_version, ); @@ -9369,7 +9370,6 @@ mod tests { .fetch_identity_token_balance( token_id.to_buffer(), identity.id().to_buffer(), - true, None, platform_version, ) @@ -9378,7 +9378,7 @@ mod tests { } #[test] - fn test_token_mint_by_owned_id_allowed_sending_to_other() { + fn test_token_mint_by_owner_allowed_sending_to_other() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -9399,6 +9399,7 @@ mod tests { &mut platform, identity.id(), None::, + None, platform_version, ); @@ -9460,7 +9461,6 @@ mod tests { .fetch_identity_token_balance( token_id.to_buffer(), receiver.id().to_buffer(), - true, None, platform_version, ) @@ -9489,6 +9489,7 @@ mod tests { &mut platform, identity.id(), None::, + None, platform_version, ); @@ -9555,7 +9556,6 @@ mod tests { .fetch_identity_token_balance( token_id.to_buffer(), receiver.to_buffer(), - true, None, platform_version, ) @@ -9564,7 +9564,7 @@ mod tests { } #[test] - fn test_token_mint_by_owned_id_no_destination_causes_error() { + fn test_token_mint_by_owner_no_destination_causes_error() { let platform_version = PlatformVersion::latest(); let mut platform = TestPlatformBuilder::new() .with_latest_protocol_version() @@ -9582,6 +9582,7 @@ mod tests { &mut platform, identity.id(), None::, + None, platform_version, ); @@ -9669,6 +9670,7 @@ mod tests { Some(|token_configuration: &mut TokenConfiguration| { token_configuration.set_minting_allow_choosing_destination(false); }), + None, platform_version, ); @@ -9735,7 +9737,6 @@ mod tests { .fetch_identity_token_balance( token_id.to_buffer(), identity.id().to_buffer(), - true, None, platform_version, ) @@ -9767,6 +9768,7 @@ mod tests { Some(|token_configuration: &mut TokenConfiguration| { token_configuration.set_minting_allow_choosing_destination(false); }), + None, platform_version, ); @@ -9833,7 +9835,6 @@ mod tests { .fetch_identity_token_balance( token_id.to_buffer(), receiver.id().to_buffer(), - true, None, platform_version, ) @@ -9862,6 +9863,7 @@ mod tests { Some(|token_configuration: &mut TokenConfiguration| { token_configuration.set_minting_allow_choosing_destination(false); }), + None, platform_version, ); @@ -9951,6 +9953,7 @@ mod tests { token_configuration .set_new_tokens_destination_identity(Some(identity.id())); }), + None, platform_version, ); @@ -10017,7 +10020,6 @@ mod tests { .fetch_identity_token_balance( token_id.to_buffer(), identity.id().to_buffer(), - true, None, platform_version, ) @@ -10051,6 +10053,7 @@ mod tests { token_configuration .set_new_tokens_destination_identity(Some(identity.id())); }), + None, platform_version, ); @@ -10117,7 +10120,6 @@ mod tests { .fetch_identity_token_balance( token_id.to_buffer(), receiver.id().to_buffer(), - true, None, platform_version, ) @@ -10148,6 +10150,7 @@ mod tests { token_configuration .set_new_tokens_destination_identity(Some(identity.id())); }), + None, platform_version, ); @@ -10209,7 +10212,6 @@ mod tests { .fetch_identity_token_balance( token_id.to_buffer(), identity.id().to_buffer(), - true, None, platform_version, ) @@ -10217,6 +10219,630 @@ mod tests { assert_eq!(token_balance, Some(101337)); } } + + mod token_mint_tests_authorization_scenarios { + use super::*; + use dpp::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; + use dpp::data_contract::change_control_rules::v0::ChangeControlRulesV0; + use dpp::data_contract::change_control_rules::ChangeControlRules; + use dpp::data_contract::group::v0::GroupV0; + use dpp::data_contract::group::Group; + + #[test] + fn test_token_mint_by_owner_sending_to_self_minting_not_allowed() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + None, + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError(_)), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + } + + #[test] + fn test_token_mint_by_owner_sending_to_self_minting_only_allowed_by_group() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [(identity.id(), 5), (identity_2.id(), 5)].into(), + required_power: 10, + }), + )] + .into(), + ), + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError(_)), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + } + + #[test] + fn test_token_mint_by_owner_sending_to_self_minting_only_allowed_by_group_enough_member_power( + ) { + // We are using a group, but our member alone has enough power in the group to do the action + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [(identity.id(), 5), (identity_2.id(), 1)].into(), + required_power: 5, + }), + )] + .into(), + ), + platform_version, + ); + + let documents_batch_create_transition = + BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(101337)); + } + } + } + + mod token_burn_tests { + use super::*; + use platform_version::version::PlatformVersion; + + #[test] + fn test_token_burn() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + None, + platform_version, + ); + + let documents_batch_create_transition = BatchTransition::new_token_burn_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 100000 - 1337; + assert_eq!(token_balance, Some(expected_amount)); + } + + #[test] + fn test_token_burn_trying_to_burn_more_than_we_have() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + None, + platform_version, + ); + + let documents_batch_create_transition = BatchTransition::new_token_burn_transition( + token_id, + identity.id(), + contract.id(), + 0, + 200000, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError( + StateError::IdentityDoesNotHaveEnoughTokenBalanceError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); // nothing was burned + } + + #[test] + fn test_token_burn_gives_error_if_trying_to_burn_from_not_allowed_identity() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (contract_owner_identity, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + contract_owner_identity.id(), + None::, + None, + platform_version, + ); + + let documents_batch_create_transition = BatchTransition::new_token_burn_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let documents_batch_create_serialized_transition = + documents_batch_create_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![documents_batch_create_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError(_)), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + contract_owner_identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } } } } 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 487841aae3f..a5a09832025 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 @@ -434,13 +434,7 @@ mod tests { let token_balance = platform .drive - .fetch_identity_token_balance( - token_id, - identity_id.to_buffer(), - true, - None, - platform_version, - ) + .fetch_identity_token_balance(token_id, identity_id.to_buffer(), None, platform_version) .expect("expected to fetch token balance"); assert_eq!(token_balance, None); } @@ -526,13 +520,7 @@ mod tests { let token_balance = platform .drive - .fetch_identity_token_balance( - token_id, - identity_id.to_buffer(), - true, - None, - platform_version, - ) + .fetch_identity_token_balance(token_id, identity_id.to_buffer(), None, platform_version) .expect("expected to fetch token balance"); assert_eq!(token_balance, Some(base_supply_start_amount)); } @@ -621,13 +609,7 @@ mod tests { let token_balance = platform .drive - .fetch_identity_token_balance( - token_id, - identity_id.to_buffer(), - true, - None, - platform_version, - ) + .fetch_identity_token_balance(token_id, identity_id.to_buffer(), None, platform_version) .expect("expected to fetch token balance"); assert_eq!(token_balance, None); } 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 afc44a34719..bea871af407 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 @@ -78,8 +78,8 @@ pub(in crate::execution) mod tests { use dpp::dashcore::{ProTxHash, Txid}; use dpp::dashcore::hashes::Hash; use dpp::data_contract::accessors::v0::DataContractV0Getters; - use dpp::data_contract::accessors::v1::DataContractV1Getters; - use dpp::data_contract::DataContract; + use dpp::data_contract::accessors::v1::{DataContractV1Getters, DataContractV1Setters}; + use dpp::data_contract::{DataContract, GroupContractPosition}; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::data_contract::document_type::random_document::{CreateRandomDocument, DocumentFieldFillSize, DocumentFieldFillType}; use dpp::document::{Document, DocumentV0Getters, DocumentV0Setters}; @@ -126,6 +126,7 @@ pub(in crate::execution) mod tests { use crate::execution::types::block_fees::v0::BlockFeesV0; use crate::execution::types::processed_block_fees_outcome::v0::ProcessedBlockFeesOutcome; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; + use dpp::data_contract::group::Group; /// We add an identity, but we also add the same amount to system credits pub(in crate::execution) fn setup_identity_with_system_credits( @@ -2291,6 +2292,7 @@ pub(in crate::execution) mod tests { platform: &mut TempPlatform, identity_id: Identifier, token_configuration_modification: Option, + add_groups: Option>, platform_version: &PlatformVersion, ) -> (DataContract, Identifier) { let data_contract_id = DataContract::generate_data_contract_id_v0(identity_id, 1); @@ -2307,6 +2309,9 @@ pub(in crate::execution) mod tests { .expect("expected token configuration"); token_configuration_modification(token_configuration); } + if let Some(add_groups) = add_groups { + data_contract.set_groups(add_groups); + } }), None, Some(platform_version), diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs index c7dcf08ee8d..185da14ed49 100644 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs @@ -84,7 +84,7 @@ impl Drive { )?; } TokenEvent::Burn(burn_amount, public_note) => { - let document_type = contract.document_type_for_name("mint")?; + let document_type = contract.document_type_for_name("burn")?; let document_id = Document::generate_document_id_v0( &contract.id(), &owner_id, diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs index 6f52a71afcc..8b563ae97b4 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs @@ -30,7 +30,6 @@ impl Drive { &self, token_id: [u8; 32], identity_id: [u8; 32], - apply: bool, transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { @@ -44,7 +43,6 @@ impl Drive { 0 => self.fetch_identity_token_balance_v0( token_id, identity_id, - apply, transaction, platform_version, ), diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs index 40c941cc0a5..5adbb9f513c 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs @@ -15,14 +15,13 @@ impl Drive { &self, token_id: [u8; 32], identity_id: [u8; 32], - apply: bool, transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { self.fetch_identity_token_balance_operations_v0( token_id, identity_id, - apply, + true, transaction, &mut vec![], platform_version, diff --git a/packages/rs-platform-version/src/version/fee/processing/mod.rs b/packages/rs-platform-version/src/version/fee/processing/mod.rs index a4f33696c06..715e060c4a5 100644 --- a/packages/rs-platform-version/src/version/fee/processing/mod.rs +++ b/packages/rs-platform-version/src/version/fee/processing/mod.rs @@ -9,6 +9,7 @@ pub struct FeeProcessingVersion { pub fetch_identity_revision_processing_cost: u64, pub fetch_identity_balance_and_revision_processing_cost: u64, pub fetch_identity_cost_per_look_up_key_by_id: u64, + pub fetch_identity_token_balance_processing_cost: u64, pub fetch_prefunded_specialized_balance_processing_cost: u64, pub fetch_single_identity_key_processing_cost: u64, pub validate_key_structure: u64, @@ -39,6 +40,9 @@ impl From for FeeProcessingVersi .fetch_identity_balance_and_revision_processing_cost, fetch_identity_cost_per_look_up_key_by_id: old .fetch_identity_cost_per_look_up_key_by_id, + fetch_identity_token_balance_processing_cost: FEE_VERSION1 + .processing + .fetch_identity_token_balance_processing_cost, fetch_prefunded_specialized_balance_processing_cost: old .fetch_prefunded_specialized_balance_processing_cost, fetch_single_identity_key_processing_cost: old diff --git a/packages/rs-platform-version/src/version/fee/processing/v1.rs b/packages/rs-platform-version/src/version/fee/processing/v1.rs index b6ba5ca9986..fae3ec4939b 100644 --- a/packages/rs-platform-version/src/version/fee/processing/v1.rs +++ b/packages/rs-platform-version/src/version/fee/processing/v1.rs @@ -5,6 +5,7 @@ pub const FEE_PROCESSING_VERSION1: FeeProcessingVersion = FeeProcessingVersion { fetch_identity_revision_processing_cost: 9000, fetch_identity_balance_and_revision_processing_cost: 15000, fetch_identity_cost_per_look_up_key_by_id: 9000, + fetch_identity_token_balance_processing_cost: 10000, fetch_prefunded_specialized_balance_processing_cost: 10000, fetch_single_identity_key_processing_cost: 10000, perform_network_threshold_signing: 100000000, // 1mDash (2.5 cents at 25$/Dash) From 83796655f407aafa03e2655cb15fe663a20c68cc Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 5 Jan 2025 02:38:22 +0700 Subject: [PATCH 37/61] transfer tests --- .../state_v0/mod.rs | 32 ++- .../state_transitions/batch/mod.rs | 222 +++++++++++++++++- 2 files changed, 249 insertions(+), 5 deletions(-) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs index 93f1ae55340..b491ac4b89f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs @@ -1,4 +1,7 @@ use dpp::block::block_info::BlockInfo; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::state_error::StateError; +use dpp::consensus::state::token::IdentityDoesNotHaveEnoughTokenBalanceError; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; @@ -8,8 +11,10 @@ use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{C use drive::error::drive::DriveError; use drive::query::TransactionArg; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; -use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenTransferTransitionActionStateValidationV0 { @@ -33,7 +38,30 @@ impl TokenTransferTransitionActionStateValidationV0 for TokenTransferTransitionA transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result { - // todo verify that minting would not break max supply + // We need to verify that we have enough of the token + let balance = platform + .drive + .fetch_identity_token_balance( + self.token_id().to_buffer(), + owner_id.to_buffer(), + transaction, + platform_version, + )? + .unwrap_or_default(); + execution_context.add_operation(ValidationOperation::RetrieveIdentityTokenBalance); + if balance < self.amount() { + // The identity does not exist + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::IdentityDoesNotHaveEnoughTokenBalanceError( + IdentityDoesNotHaveEnoughTokenBalanceError::new( + owner_id, + self.amount(), + balance, + "transfer".to_string(), + ), + )), + )); + } Ok(SimpleConsensusValidationResult::new()) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index d41ce48bf2f..f4f822a89ec 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -2882,7 +2882,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 1341740); + assert_eq!(processing_result.aggregated_fees().processing_fee, 1443820); let issues = platform .drive @@ -4818,7 +4818,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 1609340); + assert_eq!(processing_result.aggregated_fees().processing_fee, 1711420); let issues = platform .drive @@ -10561,7 +10561,6 @@ mod tests { mod token_burn_tests { use super::*; - use platform_version::version::PlatformVersion; #[test] fn test_token_burn() { @@ -10844,5 +10843,222 @@ mod tests { assert_eq!(token_balance, None); } } + + mod token_transfer_tests { + use super::*; + + #[test] + fn test_token_transfer() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (recipient, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + None, + platform_version, + ); + + let token_transfer_transition = BatchTransition::new_token_transfer_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + recipient.id(), + None, + None, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_transfer_serialized_transition = token_transfer_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_transfer_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 100000 - 1337; + assert_eq!(token_balance, Some(expected_amount)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + recipient.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 1337; + assert_eq!(token_balance, Some(expected_amount)); + } + + #[test] + fn test_token_transfer_trying_to_send_more_than_we_have() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (recipient, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + None, + platform_version, + ); + + let token_transfer_transition = BatchTransition::new_token_transfer_transition( + token_id, + identity.id(), + contract.id(), + 0, + 200000, + recipient.id(), + None, + None, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_transfer_serialized_transition = token_transfer_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_transfer_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError( + StateError::IdentityDoesNotHaveEnoughTokenBalanceError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 100000; + assert_eq!(token_balance, Some(expected_amount)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + recipient.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 1337; + assert_eq!(token_balance, None); + } + } } } From a4331ce389c3e944242fae67a368a56bc1a6b7b4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 5 Jan 2025 12:19:03 +0700 Subject: [PATCH 38/61] more tests --- .../src/data_contract/accessors/v1/mod.rs | 3 +- .../token_configuration/accessors/mod.rs | 2 - .../token_configuration/accessors/v0/mod.rs | 2 - .../src/errors/consensus/basic/basic_error.rs | 4 + ..._action_not_allowed_on_transition_error.rs | 31 + .../src/errors/consensus/basic/group/mod.rs | 3 + .../rs-dpp/src/errors/consensus/basic/mod.rs | 1 + packages/rs-dpp/src/errors/consensus/codes.rs | 7 + .../group_action_already_completed_error.rs | 55 + ...action_already_signed_by_identity_error.rs | 64 + .../group_action_does_not_exist_error.rs | 56 + .../identity_not_member_of_group_error.rs | 56 + .../src/errors/consensus/state/group/mod.rs | 9 + .../rs-dpp/src/errors/consensus/state/mod.rs | 1 + .../src/errors/consensus/state/state_error.rs | 13 + packages/rs-dpp/src/group/mod.rs | 20 + .../batch_transition/accessors/mod.rs | 15 +- .../batch_transition/accessors/v0/mod.rs | 6 +- .../batched_transition/mod.rs | 21 + .../token_mint_transition/v0/v0_methods.rs | 15 +- .../token_mint_transition/v0_methods.rs | 20 + .../v0/v0_methods.rs | 27 +- .../token_transfer_transition/v0_methods.rs | 9 - .../batched_transition/token_transition.rs | 19 +- .../token_transition_action_type.rs | 18 +- .../document/batch_transition/methods/mod.rs | 12 +- .../batch_transition/methods/v1/mod.rs | 7 +- .../batch_transition/v0/v0_methods.rs | 8 +- .../batch_transition/v1/v0_methods.rs | 72 +- .../validate_basic_structure/v0/mod.rs | 29 +- .../state_v0/mod.rs | 19 +- .../structure_v0/mod.rs | 1 - .../state_v0/mod.rs | 14 +- .../state_v0/mod.rs | 97 +- .../structure_v0/mod.rs | 2 + .../state_v0/mod.rs | 6 +- .../structure_v0/mod.rs | 2 + .../state_transitions/batch/mod.rs | 1095 ++++++++++++++++- .../batch/transformer/v0/mod.rs | 19 +- .../for_add_group_action/mod.rs | 79 ++ .../for_add_group_action/v0/mod.rs | 170 +++ .../src/drive/group/estimated_costs/mod.rs | 1 + .../fetch/fetch_action_id_has_signer/mod.rs | 78 ++ .../fetch_action_id_has_signer/v0/mod.rs | 132 ++ .../fetch_action_id_signers_power/mod.rs | 4 +- .../fetch_action_id_signers_power/v0/mod.rs | 44 +- .../rs-drive/src/drive/group/fetch/mod.rs | 1 + .../group/insert/add_group_action/v0/mod.rs | 10 + .../group/insert/add_new_groups/v0/mod.rs | 36 +- packages/rs-drive/src/drive/group/mod.rs | 1 + .../add_to_token_total_supply/v0/mod.rs | 5 +- .../remove_from_token_total_supply/v0/mod.rs | 5 +- .../{document => batch}/batch_transition.rs | 2 +- .../document_create_transition.rs | 2 +- .../document_delete_transition.rs | 2 +- .../document_purchase_transition.rs | 2 +- .../document_replace_transition.rs | 2 +- .../document_transfer_transition.rs | 2 +- .../document_transition.rs | 2 +- .../document_update_price_transition.rs | 2 +- .../documents_batch_transition.rs | 2 +- .../{document => batch}/mod.rs | 0 .../token_burn_transition.rs | 2 +- .../batch/token_mint_transition.rs | 109 ++ .../token_transfer_transition.rs | 2 +- .../{document => batch}/token_transition.rs | 2 +- .../document/token_mint_transition.rs | 73 -- .../action_convert_to_operations/mod.rs | 2 +- .../transformer.rs | 10 +- .../v0/transformer.rs | 120 +- .../transformer.rs | 32 +- .../v0/transformer.rs | 118 +- .../transformer.rs | 6 +- .../v0/transformer.rs | 74 +- .../v0/transformer.rs | 6 +- .../mod.rs | 58 + .../v0/mod.rs | 72 ++ .../rs-drive/src/util/grove_operations/mod.rs | 3 + .../drive_group_method_versions/mod.rs | 5 +- .../drive_group_method_versions/v1.rs | 4 +- .../drive_grove_method_versions/mod.rs | 1 + .../drive_grove_method_versions/v1.rs | 1 + 82 files changed, 2783 insertions(+), 361 deletions(-) create mode 100644 packages/rs-dpp/src/errors/consensus/basic/group/group_action_not_allowed_on_transition_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/basic/group/mod.rs create mode 100644 packages/rs-dpp/src/errors/consensus/state/group/group_action_already_completed_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/state/group/group_action_already_signed_by_identity_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/state/group/group_action_does_not_exist_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/state/group/identity_not_member_of_group_error.rs create mode 100644 packages/rs-dpp/src/errors/consensus/state/group/mod.rs create mode 100644 packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/mod.rs create mode 100644 packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/group/estimated_costs/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/batch_transition.rs (96%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/document_create_transition.rs (99%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/document_delete_transition.rs (98%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/document_purchase_transition.rs (98%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/document_replace_transition.rs (98%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/document_transfer_transition.rs (98%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/document_transition.rs (97%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/document_update_price_transition.rs (98%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/documents_batch_transition.rs (97%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/mod.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/token_burn_transition.rs (98%) create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/token_transfer_transition.rs (98%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/{document => batch}/token_transition.rs (96%) delete mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_mint_transition.rs create mode 100644 packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/v0/mod.rs diff --git a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs index a3c4d000465..0727a24a21d 100644 --- a/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs +++ b/packages/rs-dpp/src/data_contract/accessors/v1/mod.rs @@ -1,8 +1,7 @@ use crate::data_contract::accessors::v0::{DataContractV0Getters, DataContractV0Setters}; use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::group::Group; -use crate::data_contract::{DataContract, GroupContractPosition, TokenContractPosition}; -use crate::tokens::errors::TokenError; +use crate::data_contract::{GroupContractPosition, TokenContractPosition}; use crate::ProtocolError; use platform_value::Identifier; use std::collections::BTreeMap; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs index 5b575c265ea..4d528fc16d2 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs @@ -7,10 +7,8 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfig use crate::data_contract::associated_token::token_configuration::TokenConfiguration; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; -use crate::data_contract::group::RequiredSigners; use crate::data_contract::GroupContractPosition; use platform_value::Identifier; -use std::collections::BTreeSet; /// Implementing TokenConfigurationV0Getters for TokenConfiguration impl TokenConfigurationV0Getters for TokenConfiguration { diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs index bcd49b06429..dfd34414d67 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -1,10 +1,8 @@ use crate::data_contract::associated_token::token_configuration::v0::TokenConfigurationConventionV0; use crate::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use crate::data_contract::change_control_rules::ChangeControlRules; -use crate::data_contract::group::RequiredSigners; use crate::data_contract::GroupContractPosition; use platform_value::Identifier; -use std::collections::BTreeSet; /// Accessor trait for getters of `TokenConfigurationV0` pub trait TokenConfigurationV0Getters { diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index ca24b187a50..6ddfc332366 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -67,6 +67,7 @@ use crate::consensus::basic::{ }; use crate::consensus::ConsensusError; +use crate::consensus::basic::group::GroupActionNotAllowedOnTransitionError; use crate::consensus::basic::overflow_error::OverflowError; use crate::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTokensError; use crate::consensus::basic::token::{ @@ -444,6 +445,9 @@ pub enum BasicError { #[error(transparent)] ChoosingTokenMintRecipientNotAllowedError(ChoosingTokenMintRecipientNotAllowedError), + + #[error(transparent)] + GroupActionNotAllowedOnTransitionError(GroupActionNotAllowedOnTransitionError), } impl From for ConsensusError { diff --git a/packages/rs-dpp/src/errors/consensus/basic/group/group_action_not_allowed_on_transition_error.rs b/packages/rs-dpp/src/errors/consensus/basic/group/group_action_not_allowed_on_transition_error.rs new file mode 100644 index 00000000000..8f2862fa9ab --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/group/group_action_not_allowed_on_transition_error.rs @@ -0,0 +1,31 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Group action is not allowed during transition: {}", transition_type)] +#[platform_serialize(unversioned)] +pub struct GroupActionNotAllowedOnTransitionError { + transition_type: String, +} + +impl GroupActionNotAllowedOnTransitionError { + pub fn new(transition_type: String) -> Self { + Self { transition_type } + } + + pub fn transition_type(&self) -> &str { + &self.transition_type + } +} + +impl From for ConsensusError { + fn from(err: GroupActionNotAllowedOnTransitionError) -> Self { + Self::BasicError(BasicError::GroupActionNotAllowedOnTransitionError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/basic/group/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/group/mod.rs new file mode 100644 index 00000000000..32c6ce2d357 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/group/mod.rs @@ -0,0 +1,3 @@ +mod group_action_not_allowed_on_transition_error; + +pub use group_action_not_allowed_on_transition_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/basic/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/mod.rs index 2b4a596f583..b05ec735e6b 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/mod.rs @@ -13,6 +13,7 @@ pub mod token; pub mod unsupported_protocol_version_error; pub mod basic_error; +pub mod group; pub mod invalid_identifier_error; #[cfg(feature = "json-schema-validation")] pub mod json_schema_compilation_error; diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index 852418a3cbb..34142db436c 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -175,6 +175,7 @@ impl ErrorWithCode for BasicError { // General Errors 10700-10799 Self::OverflowError(_) => 10700, + Self::GroupActionNotAllowedOnTransitionError(_) => 10701, } } } @@ -270,6 +271,12 @@ impl ErrorWithCode for StateError { // Data trigger errors: 40500-40799 #[cfg(feature = "state-transition-validation")] Self::DataTriggerError(ref e) => e.code(), + + // Group errors: 40800-40899 + #[cfg(feature = "state-transition-validation")] + Self::IdentityNotMemberOfGroupError(_) => 40800, + Self::GroupActionDoesNotExistError(_) => 40801, + Self::GroupActionAlreadyCompletedError(_) => 40802, } } } diff --git a/packages/rs-dpp/src/errors/consensus/state/group/group_action_already_completed_error.rs b/packages/rs-dpp/src/errors/consensus/state/group/group_action_already_completed_error.rs new file mode 100644 index 00000000000..2d700d72a3f --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/group/group_action_already_completed_error.rs @@ -0,0 +1,55 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::data_contract::GroupContractPosition; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( +"Group action has already been completed for data contract {} at group position {} with action ID {}", + data_contract_id, + group_contract_position, + action_id +)] +#[platform_serialize(unversioned)] +pub struct GroupActionAlreadyCompletedError { + data_contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, +} + +impl GroupActionAlreadyCompletedError { + pub fn new( + data_contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + ) -> Self { + Self { + data_contract_id, + group_contract_position, + action_id, + } + } + + pub fn data_contract_id(&self) -> Identifier { + self.data_contract_id + } + + pub fn group_contract_position(&self) -> &GroupContractPosition { + &self.group_contract_position + } + + pub fn action_id(&self) -> Identifier { + self.action_id + } +} + +impl From for ConsensusError { + fn from(err: GroupActionAlreadyCompletedError) -> Self { + Self::StateError(StateError::GroupActionAlreadyCompletedError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/state/group/group_action_already_signed_by_identity_error.rs b/packages/rs-dpp/src/errors/consensus/state/group/group_action_already_signed_by_identity_error.rs new file mode 100644 index 00000000000..1fcdbf0419c --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/group/group_action_already_signed_by_identity_error.rs @@ -0,0 +1,64 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::data_contract::GroupContractPosition; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( +"Group action with action ID {} has already been signed by identity {} for data contract {} at group position {}", + action_id, + identity_id, + data_contract_id, + group_contract_position +)] +#[platform_serialize(unversioned)] +pub struct GroupActionAlreadySignedByIdentityError { + identity_id: Identifier, + data_contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, +} + +impl GroupActionAlreadySignedByIdentityError { + pub fn new( + identity_id: Identifier, + data_contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + ) -> Self { + Self { + identity_id, + data_contract_id, + group_contract_position, + action_id, + } + } + + pub fn identity_id(&self) -> Identifier { + self.identity_id + } + + pub fn data_contract_id(&self) -> Identifier { + self.data_contract_id + } + + pub fn group_contract_position(&self) -> GroupContractPosition { + self.group_contract_position + } + + pub fn action_id(&self) -> Identifier { + self.action_id + } +} + +impl From for ConsensusError { + fn from(err: GroupActionAlreadySignedByIdentityError) -> Self { + Self::StateError(StateError::GroupActionAlreadySignedByIdentityError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/state/group/group_action_does_not_exist_error.rs b/packages/rs-dpp/src/errors/consensus/state/group/group_action_does_not_exist_error.rs new file mode 100644 index 00000000000..c57af3cc4d2 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/group/group_action_does_not_exist_error.rs @@ -0,0 +1,56 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::data_contract::GroupContractPosition; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Group action does not exist for data contract {} at group position {} with action ID {}", + data_contract_id, + group_contract_position, + action_id +)] +#[platform_serialize(unversioned)] +pub struct GroupActionDoesNotExistError { + data_contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, +} + +impl GroupActionDoesNotExistError { + pub fn new( + data_contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + ) -> Self { + Self { + data_contract_id, + group_contract_position, + action_id, + } + } + + pub fn data_contract_id(&self) -> Identifier { + self.data_contract_id + } + + pub fn group_contract_position(&self) -> &GroupContractPosition { + &self.group_contract_position + } + + pub fn action_id(&self) -> Identifier { + self.action_id + } +} + +impl From for ConsensusError { + fn from(err: GroupActionDoesNotExistError) -> Self { + Self::StateError(StateError::GroupActionDoesNotExistError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/state/group/identity_not_member_of_group_error.rs b/packages/rs-dpp/src/errors/consensus/state/group/identity_not_member_of_group_error.rs new file mode 100644 index 00000000000..afd5bf06ffb --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/group/identity_not_member_of_group_error.rs @@ -0,0 +1,56 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::data_contract::GroupContractPosition; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Identity {} is not a member of the group for data contract {} at position {}", + identity_id, + data_contract_id, + group_contract_position +)] +#[platform_serialize(unversioned)] +pub struct IdentityNotMemberOfGroupError { + identity_id: Identifier, + data_contract_id: Identifier, + group_contract_position: GroupContractPosition, +} + +impl IdentityNotMemberOfGroupError { + pub fn new( + identity_id: Identifier, + data_contract_id: Identifier, + group_contract_position: GroupContractPosition, + ) -> Self { + Self { + identity_id, + data_contract_id, + group_contract_position, + } + } + + pub fn identity_id(&self) -> &Identifier { + &self.identity_id + } + + pub fn data_contract_id(&self) -> &Identifier { + &self.data_contract_id + } + + pub fn group_contract_position(&self) -> GroupContractPosition { + self.group_contract_position + } +} + +impl From for ConsensusError { + fn from(err: IdentityNotMemberOfGroupError) -> Self { + Self::StateError(StateError::IdentityNotMemberOfGroupError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/state/group/mod.rs b/packages/rs-dpp/src/errors/consensus/state/group/mod.rs new file mode 100644 index 00000000000..133ee7e1a5a --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/group/mod.rs @@ -0,0 +1,9 @@ +mod group_action_already_completed_error; +mod group_action_already_signed_by_identity_error; +mod group_action_does_not_exist_error; +mod identity_not_member_of_group_error; + +pub use group_action_already_completed_error::*; +pub use group_action_already_signed_by_identity_error::*; +pub use group_action_does_not_exist_error::*; +pub use identity_not_member_of_group_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/state/mod.rs b/packages/rs-dpp/src/errors/consensus/state/mod.rs index 3b410662c0e..ee10b800d11 100644 --- a/packages/rs-dpp/src/errors/consensus/state/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/state/mod.rs @@ -2,6 +2,7 @@ pub mod data_contract; #[cfg(feature = "state-transition-validation")] pub mod data_trigger; pub mod document; +pub mod group; pub mod identity; pub mod prefunded_specialized_balances; pub mod state_error; diff --git a/packages/rs-dpp/src/errors/consensus/state/state_error.rs b/packages/rs-dpp/src/errors/consensus/state/state_error.rs index 7d0783ff8e5..620d794b329 100644 --- a/packages/rs-dpp/src/errors/consensus/state/state_error.rs +++ b/packages/rs-dpp/src/errors/consensus/state/state_error.rs @@ -36,6 +36,7 @@ use crate::consensus::state::document::document_contest_not_joinable_error::Docu use crate::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError; use crate::consensus::state::document::document_incorrect_purchase_price_error::DocumentIncorrectPurchasePriceError; use crate::consensus::state::document::document_not_for_sale_error::DocumentNotForSaleError; +use crate::consensus::state::group::{GroupActionAlreadyCompletedError, GroupActionAlreadySignedByIdentityError, GroupActionDoesNotExistError, IdentityNotMemberOfGroupError}; use crate::consensus::state::identity::identity_public_key_already_exists_for_unique_contract_bounds_error::IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError; use crate::consensus::state::identity::invalid_identity_contract_nonce_error::InvalidIdentityNonceError; use crate::consensus::state::identity::missing_transfer_key_error::MissingTransferKeyError; @@ -209,6 +210,18 @@ pub enum StateError { #[error(transparent)] UnauthorizedTokenActionError(UnauthorizedTokenActionError), + + #[error(transparent)] + IdentityNotMemberOfGroupError(IdentityNotMemberOfGroupError), + + #[error(transparent)] + GroupActionDoesNotExistError(GroupActionDoesNotExistError), + + #[error(transparent)] + GroupActionAlreadyCompletedError(GroupActionAlreadyCompletedError), + + #[error(transparent)] + GroupActionAlreadySignedByIdentityError(GroupActionAlreadySignedByIdentityError), } impl From for ConsensusError { diff --git a/packages/rs-dpp/src/group/mod.rs b/packages/rs-dpp/src/group/mod.rs index e0ec3861d76..1915d41c212 100644 --- a/packages/rs-dpp/src/group/mod.rs +++ b/packages/rs-dpp/src/group/mod.rs @@ -8,6 +8,26 @@ use serde::{Deserialize, Serialize}; pub mod action_event; pub mod group_action; +#[derive(Debug, Clone, Copy, Encode, Decode, PartialEq)] +pub enum GroupStateTransitionInfoStatus { + GroupStateTransitionInfoProposer(GroupContractPosition), + GroupStateTransitionInfoOtherSigner(GroupStateTransitionInfo), +} + +impl From for GroupStateTransitionInfo { + fn from(value: GroupStateTransitionInfoStatus) -> Self { + match value { + GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer( + group_contract_position, + ) => GroupStateTransitionInfo { + group_contract_position, + action_id: Default::default(), + action_is_proposer: true, + }, + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner(info) => info, + } + } +} #[derive(Debug, Clone, Copy, Encode, Decode, Default, PartialEq, Display)] #[cfg_attr( diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs index f085488fc08..559708b8735 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs @@ -1,7 +1,7 @@ mod v0; use std::slice::Iter; -use crate::state_transition::batch_transition::batched_transition::{BatchedTransition, BatchedTransitionRef}; +use crate::state_transition::batch_transition::batched_transition::{BatchedTransition, BatchedTransitionMutRef, BatchedTransitionRef}; use crate::state_transition::batch_transition::BatchTransition; pub use v0::*; use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransition; @@ -82,4 +82,17 @@ impl DocumentsBatchTransitionAccessorsV0 for BatchTransition { .map(|batch_transition| batch_transition.borrow_as_ref()), } } + + fn first_transition_mut(&mut self) -> Option { + match self { + BatchTransition::V0(v0) => v0 + .transitions + .first_mut() + .map(|document_transition| BatchedTransitionMutRef::Document(document_transition)), + BatchTransition::V1(v1) => v1 + .transitions + .first_mut() + .map(|batch_transition| batch_transition.borrow_as_mut()), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/v0/mod.rs index 267a95bff65..767cff29930 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/v0/mod.rs @@ -1,4 +1,6 @@ -use crate::state_transition::batch_transition::batched_transition::BatchedTransitionRef; +use crate::state_transition::batch_transition::batched_transition::{ + BatchedTransitionMutRef, BatchedTransitionRef, +}; pub trait DocumentsBatchTransitionAccessorsV0 { /// Associated type for the iterator. type IterType<'a>: Iterator> @@ -12,4 +14,6 @@ pub trait DocumentsBatchTransitionAccessorsV0 { fn transitions_are_empty(&self) -> bool; fn first_transition(&self) -> Option; + + fn first_transition_mut(&mut self) -> Option; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs index f89836c8c9a..8c7d0cf7041 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs @@ -57,6 +57,14 @@ pub enum BatchedTransitionRef<'a> { Token(&'a TokenTransition), } +#[derive(Debug, From, PartialEq, Display)] +pub enum BatchedTransitionMutRef<'a> { + #[display("DocumentTransition({})", "_0")] + Document(&'a mut DocumentTransition), + #[display("TokenTransition({})", "_0")] + Token(&'a mut TokenTransition), +} + impl<'a> BatchedTransitionRef<'a> { pub fn to_owned_transition(&self) -> BatchedTransition { match self { @@ -102,6 +110,19 @@ impl BatchedTransition { } } + pub fn borrow_as_mut(&mut self) -> BatchedTransitionMutRef { + match self { + BatchedTransition::Document(doc) => { + // Create a reference to a DocumentTransition + BatchedTransitionMutRef::Document(doc) + } + BatchedTransition::Token(tok) => { + // Create a reference to a TokenTransition + BatchedTransitionMutRef::Token(tok) + } + } + } + pub fn set_identity_contract_nonce(&mut self, identity_contract_nonce: IdentityNonce) { match self { BatchedTransition::Document(document_transition) => { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs index f82156f1317..5e0119507dd 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs @@ -4,7 +4,7 @@ use crate::state_transition::batch_transition::token_base_transition::token_base use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; -use crate::util::hash::hash_double; +use crate::state_transition::batch_transition::TokenMintTransition; impl TokenBaseTransitionAccessors for TokenMintTransitionV0 { fn base(&self) -> &TokenBaseTransition { @@ -76,12 +76,11 @@ impl AllowedAsMultiPartyAction for TokenMintTransitionV0 { fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { let TokenMintTransitionV0 { base, amount, .. } = self; - let mut bytes = b"action_token_mint".to_vec(); - bytes.extend_from_slice(base.token_id().as_bytes()); - bytes.extend_from_slice(owner_id.as_bytes()); - bytes.extend_from_slice(&base.identity_contract_nonce().to_be_bytes()); - bytes.extend_from_slice(&amount.to_be_bytes()); - - hash_double(bytes).into() + TokenMintTransition::calculate_action_id_with_fields( + base.token_id().as_bytes(), + owner_id.as_bytes(), + base.identity_contract_nonce(), + *amount, + ) } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0_methods.rs index 9af7d32aac2..245242e452d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0_methods.rs @@ -1,9 +1,12 @@ use platform_value::Identifier; +use crate::balances::credits::TokenAmount; +use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransition; use crate::state_transition::batch_transition::token_mint_transition::v0::v0_methods::TokenMintTransitionV0Methods; +use crate::util::hash::hash_double; impl TokenBaseTransitionAccessors for TokenMintTransition { fn base(&self) -> &TokenBaseTransition { @@ -76,3 +79,20 @@ impl AllowedAsMultiPartyAction for TokenMintTransition { } } } + +impl TokenMintTransition { + pub fn calculate_action_id_with_fields( + token_id: &[u8; 32], + owner_id: &[u8; 32], + identity_contract_nonce: IdentityNonce, + mint_amount: TokenAmount, + ) -> Identifier { + let mut bytes = b"action_token_mint".to_vec(); + bytes.extend_from_slice(token_id); + bytes.extend_from_slice(owner_id); + bytes.extend_from_slice(&identity_contract_nonce.to_be_bytes()); + bytes.extend_from_slice(&mint_amount.to_be_bytes()); + + hash_double(bytes).into() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs index a4203feee1f..ec31b70b1c5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0/v0_methods.rs @@ -1,11 +1,8 @@ use platform_value::Identifier; use crate::prelude::{DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; -use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::batched_transition::token_transfer_transition::TokenTransferTransitionV0; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; -use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; -use crate::util::hash::hash_double; impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { fn base(&self) -> &TokenBaseTransition { @@ -21,9 +18,7 @@ impl TokenBaseTransitionAccessors for TokenTransferTransitionV0 { } } -pub trait TokenTransferTransitionV0Methods: - TokenBaseTransitionAccessors + AllowedAsMultiPartyAction -{ +pub trait TokenTransferTransitionV0Methods: TokenBaseTransitionAccessors { /// Returns the `amount` field of the `TokenTransferTransitionV0`. fn amount(&self) -> u64; @@ -198,23 +193,3 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransitionV0 { ) } } - -impl AllowedAsMultiPartyAction for TokenTransferTransitionV0 { - fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { - let TokenTransferTransitionV0 { - base, - amount, - recipient_id, - .. - } = self; - - let mut bytes = b"action_token_transfer".to_vec(); - bytes.extend_from_slice(base.token_id().as_bytes()); - bytes.extend_from_slice(owner_id.as_bytes()); - bytes.extend_from_slice(recipient_id.as_bytes()); - bytes.extend_from_slice(&base.identity_contract_nonce().to_be_bytes()); - bytes.extend_from_slice(&amount.to_be_bytes()); - - hash_double(bytes).into() - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs index 45c05094d4d..414e53f5d42 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transfer_transition/v0_methods.rs @@ -1,6 +1,5 @@ use platform_value::Identifier; use crate::prelude::{DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; -use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::batched_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::TokenTransferTransition; @@ -155,11 +154,3 @@ impl TokenTransferTransitionV0Methods for TokenTransferTransition { } } } - -impl AllowedAsMultiPartyAction for TokenTransferTransition { - fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { - match self { - TokenTransferTransition::V0(v0) => v0.calculate_action_id(owner_id), - } - } -} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs index 9eee0c41536..8bfa654d0c5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs @@ -91,7 +91,9 @@ pub trait TokenTransitionV0Methods { /// sets identity contract nonce fn set_identity_contract_nonce(&mut self, nonce: IdentityNonce); - fn calculate_action_id(&self, owner_id: Identifier) -> Identifier; + fn calculate_action_id(&self, owner_id: Identifier) -> Option; + + fn can_calculate_action_id(&self) -> bool; } impl TokenTransitionV0Methods for TokenTransition { @@ -115,11 +117,18 @@ impl TokenTransitionV0Methods for TokenTransition { self.base().data_contract_id() } - fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + fn calculate_action_id(&self, owner_id: Identifier) -> Option { + match self { + TokenTransition::Burn(t) => Some(t.calculate_action_id(owner_id)), + TokenTransition::Mint(t) => Some(t.calculate_action_id(owner_id)), + TokenTransition::Transfer(t) => None, + } + } + + fn can_calculate_action_id(&self) -> bool { match self { - TokenTransition::Burn(t) => t.calculate_action_id(owner_id), - TokenTransition::Mint(t) => t.calculate_action_id(owner_id), - TokenTransition::Transfer(t) => t.calculate_action_id(owner_id), + TokenTransition::Burn(_) | TokenTransition::Mint(_) => true, + TokenTransition::Transfer(_) => false, } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs index 613660dc745..9695299f115 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs @@ -1,3 +1,4 @@ +use std::fmt; use crate::state_transition::state_transitions::document::batch_transition::batched_transition::token_transition::TokenTransition; use crate::ProtocolError; @@ -5,10 +6,21 @@ use crate::ProtocolError; #[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)] pub enum TokenTransitionActionType { Burn, - Issuance, + Mint, Transfer, } +impl fmt::Display for TokenTransitionActionType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let action_str = match self { + TokenTransitionActionType::Burn => "Burn", + TokenTransitionActionType::Mint => "Mint", + TokenTransitionActionType::Transfer => "Transfer", + }; + write!(f, "{}", action_str) + } +} + pub trait TransitionActionTypeGetter { fn action_type(&self) -> TokenTransitionActionType; } @@ -17,7 +29,7 @@ impl TransitionActionTypeGetter for TokenTransition { fn action_type(&self) -> TokenTransitionActionType { match self { TokenTransition::Burn(_) => TokenTransitionActionType::Burn, - TokenTransition::Mint(_) => TokenTransitionActionType::Issuance, + TokenTransition::Mint(_) => TokenTransitionActionType::Mint, TokenTransition::Transfer(_) => TokenTransitionActionType::Transfer, } } @@ -29,7 +41,7 @@ impl TryFrom<&str> for TokenTransitionActionType { fn try_from(value: &str) -> Result { match value { "burn" => Ok(TokenTransitionActionType::Burn), - "issuance" => Ok(TokenTransitionActionType::Issuance), + "issuance" => Ok(TokenTransitionActionType::Mint), "transfer" => Ok(TokenTransitionActionType::Transfer), action_type => Err(ProtocolError::Generic(format!( "unknown token transition action type {action_type}" diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs index a3ecf2b33ba..5734aab90a2 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs @@ -5,7 +5,8 @@ use crate::data_contract::TokenContractPosition; #[cfg(feature = "state-transition-signing")] use crate::document::Document; use crate::fee::Credits; -use crate::group::GroupStateTransitionInfo; +#[cfg(feature = "state-transition-signing")] +use crate::group::GroupStateTransitionInfoStatus; #[cfg(feature = "state-transition-signing")] use crate::identity::signer::Signer; #[cfg(feature = "state-transition-signing")] @@ -425,6 +426,7 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransition { } impl DocumentsBatchTransitionMethodsV1 for BatchTransition { + #[cfg(feature = "state-transition-signing")] fn new_token_mint_transition( token_id: Identifier, owner_id: Identifier, @@ -433,7 +435,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { amount: TokenAmount, issued_to_identity_id: Option, public_note: Option, - using_group_info: Option, + using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -485,6 +487,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } } + #[cfg(feature = "state-transition-signing")] fn new_token_burn_transition( token_id: Identifier, owner_id: Identifier, @@ -492,7 +495,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { token_contract_position: u16, amount: TokenAmount, public_note: Option, - using_group_info: Option, + using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -543,6 +546,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } } + #[cfg(feature = "state-transition-signing")] fn new_token_transfer_transition( token_id: Identifier, owner_id: Identifier, @@ -557,7 +561,6 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { DerivationEncryptionKeyIndex, Vec, )>, - using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -593,7 +596,6 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { public_note, shared_encrypted_note, private_encrypted_note, - using_group_info, identity_public_key, identity_contract_nonce, user_fee_increase, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs index 7d8641377ff..5f1f58e7084 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs @@ -1,5 +1,5 @@ use crate::balances::credits::TokenAmount; -use crate::group::GroupStateTransitionInfo; +use crate::group::GroupStateTransitionInfoStatus; use crate::identity::signer::Signer; use crate::identity::IdentityPublicKey; use crate::prelude::{ @@ -23,7 +23,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 amount: TokenAmount, issued_to_identity_id: Option, public_note: Option, - using_group_info: Option, + using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -42,7 +42,7 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 token_contract_position: u16, amount: TokenAmount, public_note: Option, - using_group_info: Option, + using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -68,7 +68,6 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 DerivationEncryptionKeyIndex, Vec, )>, - using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs index 1833ee2d1fa..aeb895201e3 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs @@ -16,7 +16,7 @@ use crate::prelude::UserFeeIncrease; use crate::state_transition::batch_transition::accessors::{DocumentsBatchTransitionAccessorsV0}; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::document_create_transition::DocumentCreateTransition; -use crate::state_transition::batch_transition::batched_transition::{BatchedTransition, BatchedTransitionRef}; +use crate::state_transition::batch_transition::batched_transition::{BatchedTransition, BatchedTransitionMutRef, BatchedTransitionRef}; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::batched_transition::{ DocumentPurchaseTransition, DocumentReplaceTransition, DocumentTransferTransition, DocumentUpdatePriceTransition, @@ -64,6 +64,12 @@ impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV0 { fn first_transition(&self) -> Option { self.transitions.first().map(BatchedTransitionRef::Document) } + + fn first_transition_mut(&mut self) -> Option { + self.transitions + .first_mut() + .map(BatchedTransitionMutRef::Document) + } } impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV0 { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index 1b38ea8e714..67c7057151d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -17,7 +17,7 @@ use crate::prelude::{ }; use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use crate::state_transition::batch_transition::batched_transition::{ - BatchedTransition, BatchedTransitionRef, + BatchedTransition, BatchedTransitionMutRef, BatchedTransitionRef, }; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::batched_transition::{ @@ -40,16 +40,20 @@ use crate::state_transition::StateTransition; use crate::ProtocolError; #[cfg(feature = "state-transition-signing")] use platform_value::Identifier; +use platform_value::string_encoding::Encoding; #[cfg(feature = "state-transition-signing")] use platform_version::version::{FeatureVersion, PlatformVersion}; use crate::balances::credits::TokenAmount; -use crate::group::GroupStateTransitionInfo; +use crate::group::{GroupStateTransitionInfo, GroupStateTransitionInfoStatus}; use crate::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::methods::v1::DocumentsBatchTransitionMethodsV1; use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::batch_transition::token_burn_transition::TokenBurnTransitionV0; use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; use crate::state_transition::batch_transition::token_transfer_transition::TokenTransferTransitionV0; @@ -82,6 +86,13 @@ impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV1 { .first() .map(|transition| transition.borrow_as_ref()) } + + /// Returns the first transition, if it exists, as a `BatchedTransitionMutRef`. + fn first_transition_mut(&mut self) -> Option { + self.transitions + .first_mut() + .map(|transition| transition.borrow_as_mut()) + } } impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { @@ -403,7 +414,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { amount: TokenAmount, issued_to_identity_id: Option, public_note: Option, - using_group_info: Option, + using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -413,18 +424,40 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { _delete_feature_version: Option, _base_feature_version: Option, ) -> Result { - let mint_transition = TokenMintTransition::V0(TokenMintTransitionV0 { + let mut mint_transition = TokenMintTransition::V0(TokenMintTransitionV0 { base: TokenBaseTransition::V0(TokenBaseTransitionV0 { identity_contract_nonce, token_contract_position, data_contract_id, token_id, - using_group_info, + using_group_info: None, }), issued_to_identity_id, amount, public_note, }); + + if let Some(using_group_info_status) = using_group_info { + match using_group_info_status { + GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer( + group_contract_position, + ) => { + let action_id = mint_transition.calculate_action_id(owner_id); + println!("using action id {}", action_id.to_string(Encoding::Hex)); + mint_transition.base_mut().set_using_group_info(Some( + GroupStateTransitionInfo { + group_contract_position, + action_id, + action_is_proposer: true, + }, + )) + } + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner(info) => { + mint_transition.base_mut().set_using_group_info(Some(info)) + } + } + } + let documents_batch_transition: BatchTransition = BatchTransitionV1 { owner_id, transitions: vec![BatchedTransition::Token(mint_transition.into())], @@ -449,7 +482,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { token_contract_position: u16, amount: TokenAmount, public_note: Option, - using_group_info: Option, + using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -459,18 +492,38 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { _delete_feature_version: Option, _base_feature_version: Option, ) -> Result { - let burn_transition = TokenBurnTransition::V0(TokenBurnTransitionV0 { + let mut burn_transition = TokenBurnTransition::V0(TokenBurnTransitionV0 { base: TokenBaseTransition::V0(TokenBaseTransitionV0 { identity_contract_nonce, token_contract_position, data_contract_id, token_id, - using_group_info, + using_group_info: None, }), burn_amount: amount, public_note, }); + if let Some(using_group_info_status) = using_group_info { + match using_group_info_status { + GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer( + group_contract_position, + ) => { + let action_id = burn_transition.calculate_action_id(owner_id); + burn_transition.base_mut().set_using_group_info(Some( + GroupStateTransitionInfo { + group_contract_position, + action_id, + action_is_proposer: true, + }, + )) + } + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner(info) => { + burn_transition.base_mut().set_using_group_info(Some(info)) + } + } + } + // Wrap in a batch transition let documents_batch_transition: BatchTransition = BatchTransitionV1 { owner_id, @@ -506,7 +559,6 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { DerivationEncryptionKeyIndex, Vec, )>, - using_group_info: Option, identity_public_key: &IdentityPublicKey, identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, @@ -523,7 +575,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { token_contract_position, data_contract_id, token_id, - using_group_info, + using_group_info: None, }), recipient_id, amount, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs index c87e4f26b66..354c402e376 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs @@ -15,9 +15,11 @@ use platform_value::Identifier; use platform_version::version::PlatformVersion; use std::collections::btree_map::Entry; use std::collections::BTreeMap; +use crate::consensus::basic::group::GroupActionNotAllowedOnTransitionError; use crate::consensus::basic::token::{InvalidActionIdError, InvalidTokenIdError}; use crate::state_transition::batch_transition::batched_transition::BatchedTransitionRef; use crate::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; +use crate::state_transition::batch_transition::batched_transition::token_transition_action_type::TransitionActionTypeGetter; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; use crate::state_transition::StateTransitionLike; @@ -135,15 +137,30 @@ impl BatchTransition { // But only if we are the proposer if let Some(group_state_transition_info) = transition.base().using_group_info() { if group_state_transition_info.action_is_proposer { - let calculated_action_id = transition.calculate_action_id(self.owner_id()); - if group_state_transition_info.action_id != calculated_action_id { - result.add_error(BasicError::InvalidActionIdError( - InvalidActionIdError::new( - calculated_action_id, - group_state_transition_info.action_id, + if let Some(calculated_action_id) = + transition.calculate_action_id(self.owner_id()) + { + if group_state_transition_info.action_id != calculated_action_id { + result.add_error(BasicError::InvalidActionIdError( + InvalidActionIdError::new( + calculated_action_id, + group_state_transition_info.action_id, + ), + )); + } + } else { + result.add_error(BasicError::GroupActionNotAllowedOnTransitionError( + GroupActionNotAllowedOnTransitionError::new( + transition.action_type().to_string(), ), )); } + } else if !transition.can_calculate_action_id() { + result.add_error(BasicError::GroupActionNotAllowedOnTransitionError( + GroupActionNotAllowedOnTransitionError::new( + transition.action_type().to_string(), + ), + )); } } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs index 695ba8ce384..f3f9c654969 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs @@ -1,26 +1,12 @@ use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::InvalidDocumentTypeError; -use dpp::consensus::ConsensusError; -use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; -use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; -use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; -use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; -use dpp::consensus::state::state_error::StateError; use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; -use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; -use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; -use drive::error::drive::DriveError; use drive::query::TransactionArg; use crate::error::Error; -use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; -use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenBaseTransitionActionStateValidationV0 { @@ -44,7 +30,8 @@ impl TokenBaseTransitionActionStateValidationV0 for TokenBaseTransitionAction { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result { - // todo verify that minting would not break max supply + // We should start by validating that if we did not yet sign + if let Some(group_state_transition_resolved_info) = self.store_in_group() {} Ok(SimpleConsensusValidationResult::new()) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs index 8bb185f13f6..692620adcbe 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs @@ -3,7 +3,6 @@ use dpp::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTok use dpp::consensus::basic::token::InvalidTokenPositionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; -use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; use dpp::validation::{SimpleConsensusValidationResult}; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs index caea4adbf8e..abcbd3e0c7d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs @@ -1,31 +1,19 @@ use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::InvalidDocumentTypeError; use dpp::consensus::ConsensusError; -use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; -use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; -use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; -use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; use dpp::consensus::state::state_error::StateError; use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, UnauthorizedTokenActionError}; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::multi_identity_events::ActionTaker; -use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; -use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; -use drive::error::drive::DriveError; use drive::query::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; -use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenBurnTransitionActionStateValidationV0 { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs index d37f56c1a6b..41541fa7377 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs @@ -1,31 +1,21 @@ use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::InvalidDocumentTypeError; use dpp::consensus::ConsensusError; -use dpp::consensus::state::document::document_already_present_error::DocumentAlreadyPresentError; -use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; -use dpp::consensus::state::document::document_contest_identity_already_contestant::DocumentContestIdentityAlreadyContestantError; -use dpp::consensus::state::document::document_contest_not_joinable_error::DocumentContestNotJoinableError; use dpp::consensus::state::state_error::StateError; use dpp::consensus::state::token::{RecipientIdentityDoesNotExistError, UnauthorizedTokenActionError}; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; +use dpp::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; use dpp::multi_identity_events::ActionTaker; -use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; -use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; -use drive::error::drive::DriveError; use drive::query::TransactionArg; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::{RetrieveIdentityInfo, ValidationOperation}; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; -use crate::execution::validation::state_transition::batch::state::v0::fetch_contender::fetch_contender; -use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_document_with_id; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenMintTransitionActionStateValidationV0 { @@ -58,21 +48,74 @@ impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { .map(|position| contract.expected_group(position)) .transpose()?; - if !rules.can_make_change( - &contract.owner_id(), - main_control_group, - contract.groups(), - &ActionTaker::SingleIdentity(owner_id), - ) { - return Ok(SimpleConsensusValidationResult::new_with_error( - ConsensusError::StateError(StateError::UnauthorizedTokenActionError( - UnauthorizedTokenActionError::new( - owner_id, - "mint".to_string(), - rules.authorized_to_make_change_action_takers().clone(), - ), - )), - )); + if let Some(resolved_group_info) = self.base().store_in_group() { + // We are trying to do a group action + // We have already checked when converting into an action that we are a member of the Group + // Now we need to just check that the group is the actual group set by the contract + match rules.authorized_to_make_change_action_takers() { + AuthorizedActionTakers::NoOne | AuthorizedActionTakers::ContractOwner => { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + owner_id, + "mint".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )) + } + AuthorizedActionTakers::MainGroup => { + if let Some(main_control_group_contract_position) = + token_configuration.main_control_group() + { + if main_control_group_contract_position + != resolved_group_info.group_contract_position + { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError( + StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + owner_id, + "mint".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + ), + ), + )); + } + } + } + AuthorizedActionTakers::Group(group_contract_position) => { + if *group_contract_position != resolved_group_info.group_contract_position { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + owner_id, + "mint".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )); + } + } + } + } else { + if !rules.can_make_change( + &contract.owner_id(), + main_control_group, + contract.groups(), + &ActionTaker::SingleIdentity(owner_id), + ) { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + owner_id, + "mint".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )); + } } // todo verify that minting would not break max supply diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs index e7162316951..dfaddbedd25 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs @@ -17,6 +17,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; pub(super) trait TokenMintTransitionActionStructureValidationV0 { fn validate_structure_v0( @@ -29,6 +30,7 @@ impl TokenMintTransitionActionStructureValidationV0 for TokenMintTransitionActio &self, platform_version: &PlatformVersion, ) -> Result { + self.base().validate_structure(platform_version)?; let token_configuration = self.base().token_configuration()?; Ok(SimpleConsensusValidationResult::default()) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs index b491ac4b89f..f4aaa1ff8c0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs @@ -2,15 +2,11 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::state_error::StateError; use dpp::consensus::state::token::IdentityDoesNotHaveEnoughTokenBalanceError; -use dpp::prelude::{ConsensusValidationResult, Identifier}; +use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction}; use dpp::version::PlatformVersion; -use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; -use drive::error::drive::DriveError; use drive::query::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index 33599f2fd68..4202cbca96f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -5,6 +5,7 @@ use dpp::version::PlatformVersion; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; pub(super) trait TokenTransferTransitionActionStructureValidationV0 { fn validate_structure_v0( @@ -19,6 +20,7 @@ impl TokenTransferTransitionActionStructureValidationV0 for TokenTransferTransit owner_id: Identifier, platform_version: &PlatformVersion, ) -> Result { + self.base().validate_structure(platform_version)?; let token_configuration = self.base().token_configuration()?; Ok(SimpleConsensusValidationResult::default()) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index f4f822a89ec..62de40fc11a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -10227,6 +10227,8 @@ mod tests { use dpp::data_contract::change_control_rules::ChangeControlRules; use dpp::data_contract::group::v0::GroupV0; use dpp::data_contract::group::Group; + use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionInfoStatus}; + use dpp::state_transition::batch_transition::TokenMintTransition; #[test] fn test_token_mint_by_owner_sending_to_self_minting_not_allowed() { @@ -10556,6 +10558,871 @@ mod tests { .expect("expected to fetch token balance"); assert_eq!(token_balance, Some(101337)); } + + #[test] + fn test_token_mint_by_owner_requires_group_other_member() { + // We are using a group, and two members need to sign for the event to happen + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, signer2, key2) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [(identity.id(), 1), (identity_2.id(), 1)].into(), + required_power: 2, + }), + )] + .into(), + ), + platform_version, + ); + + let token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some(GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer(0)), + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_mint_serialized_transition = token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + // Now we need to get the second identity to also sign it + let action_id = TokenMintTransition::calculate_action_id_with_fields( + token_id.as_bytes(), + identity.id().as_bytes(), + 2, + 1337, + ); + let confirm_token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity_2.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some( + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner( + GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: false, + }, + ), + ), + &key2, + 2, + 0, + &signer2, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let confirm_token_mint_serialized_transition = confirm_token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![confirm_token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(101337)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + + #[test] + fn test_token_mint_by_owner_requires_group_resubmitting_causes_error() { + // We are using a group, and two members need to sign for the event to happen + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, signer2, key2) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [(identity.id(), 1), (identity_2.id(), 1)].into(), + required_power: 2, + }), + )] + .into(), + ), + platform_version, + ); + + let token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some(GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer(0)), + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_mint_serialized_transition = token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + // Now we need to get the second identity to also sign it, but we are going to resubmit with first + // This will create an error + let action_id = TokenMintTransition::calculate_action_id_with_fields( + token_id.as_bytes(), + identity.id().as_bytes(), + 2, + 1337, + ); + let confirm_token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some( + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner( + GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: false, + }, + ), + ), + &key, + 3, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let confirm_token_mint_serialized_transition = confirm_token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![confirm_token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError( + StateError::GroupActionAlreadySignedByIdentityError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(101337)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + + #[test] + fn test_token_mint_by_owner_requires_group_proposer_not_in_group() { + // We are using a group, and two members need to sign for the event to happen + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_3, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [(identity_3.id(), 1), (identity_2.id(), 1)].into(), + required_power: 2, + }), + )] + .into(), + ), + platform_version, + ); + + let token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some(GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer(0)), + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_mint_serialized_transition = token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::IdentityNotMemberOfGroupError( + _ + )), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + } + + #[test] + fn test_token_mint_by_owner_requires_group_other_signer_not_part_of_group() { + // We are using a group, and two members need to sign for the event to happen + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, signer2, key2) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_3, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [(identity.id(), 1), (identity_3.id(), 1)].into(), + required_power: 2, + }), + )] + .into(), + ), + platform_version, + ); + + let token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some(GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer(0)), + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_mint_serialized_transition = token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + // Now we need to get the second identity to also sign it + let action_id = TokenMintTransition::calculate_action_id_with_fields( + token_id.as_bytes(), + identity.id().as_bytes(), + 2, + 1337, + ); + let confirm_token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity_2.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some( + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner( + GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: false, + }, + ), + ), + &key2, + 2, + 0, + &signer2, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let confirm_token_mint_serialized_transition = confirm_token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![confirm_token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::IdentityNotMemberOfGroupError( + _ + )), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + + #[test] + fn test_token_mint_other_signer_going_first_causes_error() { + // We are using a group, and the second member gets a bit hasty and signs first + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, signer2, key2) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [(identity.id(), 1), (identity_2.id(), 1)].into(), + required_power: 2, + }), + )] + .into(), + ), + platform_version, + ); + + // The second identity to also sign it + let action_id = TokenMintTransition::calculate_action_id_with_fields( + token_id.as_bytes(), + identity.id().as_bytes(), + 2, + 1337, + ); + let confirm_token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity_2.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some( + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner( + GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: false, + }, + ), + ), + &key2, + 2, + 0, + &signer2, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let confirm_token_mint_serialized_transition = confirm_token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![confirm_token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::GroupActionDoesNotExistError(_)), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } } } @@ -10845,6 +11712,20 @@ mod tests { } mod token_transfer_tests { + use dpp::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; + use dpp::data_contract::change_control_rules::ChangeControlRules; + use dpp::data_contract::change_control_rules::v0::ChangeControlRulesV0; + use dpp::data_contract::group::Group; + use dpp::state_transition::batch_transition::TokenMintTransition; + use dpp::data_contract::group::v0::GroupV0; + use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionInfoStatus}; + use dpp::identity::SecurityLevel; + use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; + use dpp::state_transition::batch_transition::batched_transition::token_transition::TokenTransition; + use dpp::state_transition::StateTransition; + use dpp::state_transition::batch_transition::batched_transition::BatchedTransitionMutRef; + use dpp::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; + use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use super::*; #[test] @@ -10883,7 +11764,6 @@ mod tests { None, None, None, - None, &key, 2, 0, @@ -10987,7 +11867,6 @@ mod tests { None, None, None, - None, &key, 2, 0, @@ -11056,7 +11935,217 @@ mod tests { platform_version, ) .expect("expected to fetch token balance"); - let expected_amount = 1337; + assert_eq!(token_balance, None); + } + + #[test] + fn test_token_transfer_adding_group_info_causes_error() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (recipient, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + // let's start by creating a real action + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [(identity.id(), 1), (recipient.id(), 1)].into(), + required_power: 2, + }), + )] + .into(), + ), + platform_version, + ); + + let token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some(GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer(0)), + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_mint_serialized_transition = token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let action_id = TokenMintTransition::calculate_action_id_with_fields( + token_id.as_bytes(), + identity.id().as_bytes(), + 2, + 1337, + ); + + let mut token_transfer_transition = BatchTransition::new_token_transfer_transition( + token_id, + identity.id(), + contract.id(), + 0, + 200000, + recipient.id(), + None, + None, + None, + &key, + 3, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + // here we add fake info + match &mut token_transfer_transition { + StateTransition::Batch(batch) => { + let first_transition = batch + .first_transition_mut() + .expect("expected_first_transition"); + match first_transition { + BatchedTransitionMutRef::Token(token) => match token { + TokenTransition::Transfer(transfer) => transfer + .base_mut() + .set_using_group_info(Some(GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: true, + })), + _ => {} + }, + _ => {} + } + } + _ => {} + } + + token_transfer_transition + .sign_external(&key, &signer, Some(|_, _| Ok(SecurityLevel::HIGH))) + .expect("expected to resign transaction"); + + let token_transfer_serialized_transition = token_transfer_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_transfer_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::UnpaidConsensusError( + ConsensusError::BasicError( + BasicError::GroupActionNotAllowedOnTransitionError(_) + ) + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 100000; + assert_eq!(token_balance, Some(expected_amount)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + recipient.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); assert_eq!(token_balance, None); } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index 01bf85774c3..6bc5415c97a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -21,7 +21,7 @@ use dpp::document::property_names::PRICE; use dpp::document::{Document, DocumentV0Getters}; use dpp::fee::Credits; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; -use dpp::prelude::Revision; +use dpp::prelude::{Revision, UserFeeIncrease}; use dpp::validation::SimpleConsensusValidationResult; use dpp::{consensus::ConsensusError, prelude::Identifier, ProtocolError, validation::ConsensusValidationResult}; use dpp::fee::fee_result::FeeResult; @@ -105,6 +105,7 @@ trait BatchTransitionInternalTransformerV0 { validate_against_state: bool, owner_id: Identifier, token_transitions: &Vec<&TokenTransition>, + user_fee_increase: UserFeeIncrease, transaction: TransactionArg, execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, @@ -118,6 +119,7 @@ trait BatchTransitionInternalTransformerV0 { data_contract_fetch_info: Arc, transition: &TokenTransition, owner_id: Identifier, + user_fee_increase: UserFeeIncrease, execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, ) -> Result, Error>; @@ -231,6 +233,8 @@ impl BatchTransitionTransformerV0 for BatchTransition { .collect::>>, Error>>( )?; + let user_fee_increase = self.user_fee_increase(); + let mut validation_result_tokens = token_transitions_by_contracts .iter() .map(|(data_contract_id, token_transitions)| { @@ -241,6 +245,7 @@ impl BatchTransitionTransformerV0 for BatchTransition { validate_against_state, owner_id, token_transitions, + user_fee_increase, transaction, execution_context, platform_version, @@ -283,6 +288,7 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { validate_against_state: bool, owner_id: Identifier, token_transitions: &Vec<&TokenTransition>, + user_fee_increase: UserFeeIncrease, transaction: TransactionArg, execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, @@ -318,6 +324,7 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { data_contract_fetch_info.clone(), token_transition, owner_id, + user_fee_increase, execution_context, platform_version, ) @@ -489,26 +496,24 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { data_contract_fetch_info: Arc, transition: &TokenTransition, owner_id: Identifier, + user_fee_increase: UserFeeIncrease, execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, ) -> Result, Error> { let approximate_for_costs = !validate_against_state; match transition { TokenTransition::Burn(token_burn_transition) => { - let (token_burn_action, fee_result) = TokenBurnTransitionAction::try_from_borrowed_token_burn_transition_with_contract_lookup(drive, owner_id, token_burn_transition, approximate_for_costs, transaction, block_info, |_identifier| { + let (batched_action, fee_result) = TokenBurnTransitionAction::try_from_borrowed_token_burn_transition_with_contract_lookup(drive, owner_id, token_burn_transition, approximate_for_costs, transaction, block_info,user_fee_increase, |_identifier| { Ok(data_contract_fetch_info.clone()) }, platform_version)?; execution_context .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); - let batched_action = BatchedTransitionAction::TokenAction( - TokenTransitionAction::BurnAction(token_burn_action), - ); - Ok(batched_action.into()) + Ok(batched_action) } TokenTransition::Mint(token_mint_transition) => { - let (batched_action, fee_result) = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(drive, owner_id, token_mint_transition, approximate_for_costs, transaction, block_info, |_identifier| { + let (batched_action, fee_result) = TokenMintTransitionAction::try_from_borrowed_token_mint_transition_with_contract_lookup(drive, owner_id, token_mint_transition, approximate_for_costs, transaction, block_info, user_fee_increase, |_identifier| { Ok(data_contract_fetch_info.clone()) }, platform_version)?; diff --git a/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/mod.rs b/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/mod.rs new file mode 100644 index 00000000000..efef30d2dfe --- /dev/null +++ b/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/mod.rs @@ -0,0 +1,79 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use dpp::data_contract::GroupContractPosition; +use dpp::version::drive_versions::DriveVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerInformation; +use std::collections::HashMap; + +impl Drive { + /// Adds estimation costs for adding a group action based on the specified contract and version. + /// + /// This function selects the appropriate version of cost estimation for adding a group action, depending on the + /// `drive_version` provided. It then delegates the cost estimation to the relevant method for that version. + /// + /// Currently, it supports version `0` which uses the `add_estimation_costs_for_add_group_action_v0` method to estimate + /// the computational costs associated with adding a group action. If an unsupported version is passed in the `drive_version`, + /// the function will return an error indicating a version mismatch. + /// + /// # Parameters + /// + /// - `contract_id`: The unique identifier of the contract for which the group action is being added. + /// This is used to form paths and calculate relevant costs. + /// - `group_contract_position`: The position of the group contract within the system, influencing the paths used for cost estimation. + /// - `action_id`: An optional identifier for the specific action being added. If provided, the estimation for this action and its signers is included. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to a `HashMap` where the estimated costs for updating + /// the group action and its associated data will be stored. The keys in the map represent paths to the trees, + /// and the values represent the estimated computational costs for those trees. + /// - `drive_version`: The version of the drive being used. It determines which method to use for cost estimation. + /// This is a versioned API, so different versions may have different cost estimation methods. + /// + /// # Return Value + /// + /// - Returns `Ok(())` if the version of the `drive_version` matches the supported versions and the estimation is successfully added. + /// - Returns an error (`Error::Drive(DriveError::UnknownVersionMismatch)`) if the version is not supported. + /// + /// # Logic Breakdown + /// + /// - **Version Selection**: The function first checks the version provided in `drive_version`. If the version is `0`, + /// it uses the `add_estimation_costs_for_add_group_action_v0` method for cost estimation. + /// - **Version Mismatch**: If the version does not match the supported versions, an error is returned with details + /// about the expected versions and the received version. + /// + /// # Errors + /// + /// - `Error::Drive(DriveError::UnknownVersionMismatch)` will be returned if the `drive_version` does not match the + /// known versions supported for this method (currently only version `0`). + pub(crate) fn add_estimation_costs_for_add_group_action( + contract_id: [u8; 32], + group_contract_position: GroupContractPosition, + action_id: Option<[u8; 32]>, + estimated_costs_only_with_layer_info: &mut HashMap, + drive_version: &DriveVersion, + ) -> Result<(), Error> { + match drive_version + .methods + .group + .cost_estimation + .for_add_group_action + { + 0 => { + Self::add_estimation_costs_for_add_group_action_v0( + contract_id, + group_contract_position, + action_id, + estimated_costs_only_with_layer_info, + ); + Ok(()) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_estimation_costs_for_add_group_action".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs new file mode 100644 index 00000000000..c1faf370de5 --- /dev/null +++ b/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs @@ -0,0 +1,170 @@ +use crate::drive::Drive; + +use crate::drive::group::{ + group_action_path, group_action_root_path, group_action_signers_path, group_contract_path, + group_path, group_root_path, +}; +use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; +use dpp::data_contract::GroupContractPosition; +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerCount::EstimatedLevel; +use grovedb::EstimatedLayerInformation; +use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees, Mix}; +use grovedb::EstimatedSumTrees::{AllSumTrees, NoSumTrees, SomeSumTrees}; +use std::collections::HashMap; + +impl Drive { + /// Adds estimated costs for the layer information of group action updates in a contract. + /// + /// This function updates the `estimated_costs_only_with_layer_info` map with the layer information for + /// the trees involved in adding or updating a group action in the context of a contract. The trees are + /// organized hierarchically based on their role in the system, such as "Group Actions", "Withdrawal Transactions", + /// "Balances", and "Contract/Documents". This estimation is used to determine the computational costs associated + /// with updating these trees, considering whether they are sum trees or normal trees and their expected layer counts. + /// + /// The function breaks down the tree layers and their corresponding costs as follows: + /// 1. **Group Actions Tree**: A normal tree that holds information about group actions in the contract. + /// 2. **Withdrawal Transactions Tree**: A normal tree that holds withdrawal transaction data. + /// 3. **Balances Tree**: A sum tree that holds balance information, which is crucial for cost estimation. + /// 4. **Contract/Documents Tree**: A normal tree that holds contract and document-related data. + /// + /// Each tree's cost is estimated based on its depth and whether it's a sum tree or not. The function inserts the + /// estimated layer information for each relevant tree in the `estimated_costs_only_with_layer_info` map, where + /// the key represents the path to the specific tree and the value represents its estimated layer information. + /// + /// # Parameters + /// + /// - `contract_id`: The unique identifier of the contract being updated. Used to construct paths for the trees. + /// - `group_contract_position`: The position of the group contract in the system, used to further specify paths. + /// - `action_id`: An optional identifier for the specific action being added. If provided, additional paths for + /// the action and its associated signers will be included. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to a `HashMap` where the estimated layer information + /// will be inserted. The keys represent paths to the trees, and the values represent their estimated layer information. + /// + /// # Logic Breakdown + /// + /// - **Top Layer (Contract/Documents)**: The contract and documents tree is at the top level, with a weight of 2. + /// - **Balance Tree (Sum Tree)**: The balance tree is a sum tree with a weight of 1. + /// - **Withdrawal Transactions**: This tree is a normal tree, and it is expected to have a weight of 2. + /// - **Group Action Tree**: The group action tree is also a normal tree, with an expected weight of 2. + /// - **Additional Layer Costs**: For specific paths related to actions, signers, etc., further estimations are added with + /// appropriate layer counts and subtree size estimations. + /// + /// The function constructs the paths based on the contract ID, group contract position, and action ID (if provided). + /// It then populates the `estimated_costs_only_with_layer_info` map with the estimated costs for each relevant tree + /// involved in the group action update. + + pub(super) fn add_estimation_costs_for_add_group_action_v0( + contract_id: [u8; 32], + group_contract_position: GroupContractPosition, + action_id: Option<[u8; 32]>, + estimated_costs_only_with_layer_info: &mut HashMap, + ) { + // DataContract_Documents 64 + // / \ + // Identities 32 Balances 96 + // / \ / \ + // Token_Balances 16 Pools 48 WithdrawalTransactions 80 Votes 112 + // / \ / \ / \ / \ + // NUPKH->I 8 UPKH->I 24 PreFundedSpecializedBalances 40 Masternode Lists 56 (reserved) SpentAssetLockTransactions 72 GroupActions 88 Misc 104 Versions 120 + + // we have constructed the top layer so contract/documents tree are at the top + // since balance will be on layer 3 (level 2 on left then left) + // updating will mean we will update: + // 1 normal tree (group actions) + // 1 normal tree (withdrawal transactions) + // 1 sum tree (balances) + // 1 normal tree (contract/documents) + // hence we should give an equal weight to both + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path([]), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(3, false), + estimated_layer_sizes: AllSubtrees( + 1, + SomeSumTrees { + sum_trees_weight: 1, + non_sum_trees_weight: 2, + }, + None, + ), + }, + ); + + // there is one tree for the root path + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(group_root_path()), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(10, false), // We estimate that on average we need to update 10 nodes + estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), + }, + ); + + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(group_contract_path(contract_id.as_slice())), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(1, false), + estimated_layer_sizes: AllSubtrees(2, NoSumTrees, None), + }, + ); + + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(group_path( + contract_id.as_slice(), + &group_contract_position.to_be_bytes(), + )), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(1, false), + estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), + }, + ); + + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(group_action_root_path( + contract_id.as_slice(), + &group_contract_position.to_be_bytes(), + )), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(10, false), + estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), + }, + ); + + if let Some(action_id) = action_id { + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(group_action_path( + contract_id.as_slice(), + &group_contract_position.to_be_bytes(), + action_id.as_slice(), + )), + EstimatedLayerInformation { + is_sum_tree: false, + estimated_layer_count: EstimatedLevel(1, false), + estimated_layer_sizes: Mix { + subtrees_size: Some((1, AllSumTrees, None, 1)), + items_size: Some((1, 8, Some(36), 1)), + references_size: None, + }, + }, + ); + + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(group_action_signers_path( + contract_id.as_slice(), + &group_contract_position.to_be_bytes(), + action_id.as_slice(), + )), + EstimatedLayerInformation { + is_sum_tree: true, + estimated_layer_count: EstimatedLevel(1, false), + estimated_layer_sizes: AllItems(8, 1, None), + }, + ); + } + } +} diff --git a/packages/rs-drive/src/drive/group/estimated_costs/mod.rs b/packages/rs-drive/src/drive/group/estimated_costs/mod.rs new file mode 100644 index 00000000000..ef47daecce4 --- /dev/null +++ b/packages/rs-drive/src/drive/group/estimated_costs/mod.rs @@ -0,0 +1 @@ +mod for_add_group_action; diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/mod.rs new file mode 100644 index 00000000000..6fbe9f0a983 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/mod.rs @@ -0,0 +1,78 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::group::GroupSumPower; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use grovedb::TransactionArg; +use platform_version::version::PlatformVersion; + +mod v0; + +impl Drive { + /// Fetches the action id signers power + pub fn fetch_action_id_has_signer( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_has_signer + { + 0 => self.fetch_action_id_has_signer_v0( + contract_id, + group_contract_position, + action_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_signers_power".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + pub(crate) fn fetch_action_id_signers_power_and_add_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + estimate_costs_only: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_signers_power + { + 0 => self.fetch_action_id_signers_power_and_add_operations_v0( + contract_id, + group_contract_position, + action_id, + estimate_costs_only, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_signers_and_add_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs new file mode 100644 index 00000000000..af88918a8fa --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs @@ -0,0 +1,132 @@ +use crate::drive::group::{group_action_path, ACTION_SIGNERS_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::data_contract::group::GroupSumPower; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// v0 implementation of fetching the signers' power for a given action ID within a group contract. + /// + /// This function retrieves the signers' power associated with a specific action ID in a group contract. + /// It constructs the appropriate GroveDB path, fetches the relevant data, deserializes it, and + /// calculates any applicable fees based on the provided epoch. + /// + /// # Parameters + /// * `contract_id` - The identifier of the contract. + /// * `group_contract_position` - The position of the group contract within the data contract. + /// * `action_id` - The identifier of the action whose signers' power is to be fetched. + /// * `apply` - A boolean flag indicating whether to apply certain operations during the fetch. + /// * `transaction` - The GroveDB transaction argument for executing the fetch operation. + /// * `platform_version` - The current platform version, used to ensure compatibility. + /// + /// # Returns + /// * `Ok(Some(Arc))` if the signers' power is successfully fetched. + /// * `Ok(None)` if the signers' power does not exist. + /// * `Err(Error)` if an error occurs during the fetch operation. + /// + /// # Errors + /// * `Error::Drive(DriveError::CorruptedContractPath)` if the fetched path does not refer to a valid sum item. + /// * `Error::Drive(DriveError::CorruptedCodeExecution)` if the element type is unexpected. + /// * `Error::GroveDB` for any underlying GroveDB errors. + pub(super) fn fetch_action_id_signers_power_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_action_path( + contract_id.as_ref(), + &group_contract_position_bytes, + action_id.as_ref(), + ); + + let value = self + .grove_get_optional_sum_tree_total_value( + (&path).into(), + ACTION_SIGNERS_KEY, + DirectQueryType::StatefulDirectQuery, + transaction, + &mut vec![], + &platform_version.drive, + )? + .map(|v| v as GroupSumPower); + + Ok(value) + } + + /// v0 implementation of fetching the signers' power for a given action ID within a group contract and adding related operations. + /// + /// This function not only fetches the signers' power but also appends necessary low-level drive operations based on the provided epoch. + /// It ensures that fees are calculated and added to the `drive_operations` vector when applicable. + /// + /// # Parameters + /// * `contract_id` - The identifier of the contract. + /// * `group_contract_position` - The position of the group contract within the data contract. + /// * `action_id` - The identifier of the action whose signers' power is to be fetched. + /// * `epoch` - An optional reference to an `Epoch` object. If provided, fees will be calculated based on the epoch. + /// * `transaction` - The GroveDB transaction argument for executing the fetch operation. + /// * `drive_operations` - A mutable reference to a vector where low-level drive operations and fees will be appended. + /// * `platform_version` - The current platform version, used to ensure compatibility. + /// + /// # Returns + /// * `Ok(Some(Arc))` if the signers' power is successfully fetched. + /// * `Ok(None)` if the signers' power does not exist. + /// * `Err(Error)` if an error occurs during the fetch operation. + /// + /// # Errors + /// * `Error::Drive(DriveError::CorruptedContractPath)` if the fetched path does not refer to a valid sum item. + /// * `Error::Drive(DriveError::CorruptedCodeExecution)` if the element type is unexpected. + /// * `Error::Drive(DriveError::NotSupportedPrivate)` if stateful batch insertions are attempted. + /// * `Error::GroveDB` for any underlying GroveDB errors. + pub(super) fn fetch_action_id_signers_power_and_add_operations_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + estimate_costs_only: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_action_path( + contract_id.as_ref(), + &group_contract_position_bytes, + action_id.as_ref(), + ); + + // no estimated_costs_only_with_layer_info, means we want to apply to state + let direct_query_type = if estimate_costs_only { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums: false, + query_target: QueryTargetValue(8), + } + } else { + DirectQueryType::StatefulDirectQuery + }; + + let value = self + .grove_get_optional_sum_tree_total_value( + (&path).into(), + ACTION_SIGNERS_KEY, + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + )? + .map(|v| v as GroupSumPower); + + Ok(value) + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs index 05f4805b733..12684997430 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/mod.rs @@ -19,7 +19,7 @@ impl Drive { action_id: Identifier, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { match platform_version .drive .methods @@ -51,7 +51,7 @@ impl Drive { transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { match platform_version .drive .methods diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs index 7e276144002..af88918a8fa 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs @@ -41,7 +41,7 @@ impl Drive { action_id: Identifier, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); // Construct the GroveDB path for the action signers let path = group_action_path( @@ -50,16 +50,18 @@ impl Drive { action_id.as_ref(), ); - let value = self.grove_get_sum_tree_total_value( - (&path).into(), - ACTION_SIGNERS_KEY, - DirectQueryType::StatefulDirectQuery, - transaction, - &mut vec![], - &platform_version.drive, - )?; + let value = self + .grove_get_optional_sum_tree_total_value( + (&path).into(), + ACTION_SIGNERS_KEY, + DirectQueryType::StatefulDirectQuery, + transaction, + &mut vec![], + &platform_version.drive, + )? + .map(|v| v as GroupSumPower); - Ok(value as GroupSumPower) + Ok(value) } /// v0 implementation of fetching the signers' power for a given action ID within a group contract and adding related operations. @@ -95,7 +97,7 @@ impl Drive { transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); // Construct the GroveDB path for the action signers let path = group_action_path( @@ -114,15 +116,17 @@ impl Drive { DirectQueryType::StatefulDirectQuery }; - let value = self.grove_get_sum_tree_total_value( - (&path).into(), - ACTION_SIGNERS_KEY, - direct_query_type, - transaction, - drive_operations, - &platform_version.drive, - )?; + let value = self + .grove_get_optional_sum_tree_total_value( + (&path).into(), + ACTION_SIGNERS_KEY, + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + )? + .map(|v| v as GroupSumPower); - Ok(value as GroupSumPower) + Ok(value) } } diff --git a/packages/rs-drive/src/drive/group/fetch/mod.rs b/packages/rs-drive/src/drive/group/fetch/mod.rs index 696d6c21d08..11fa39cbcef 100644 --- a/packages/rs-drive/src/drive/group/fetch/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/mod.rs @@ -1,3 +1,4 @@ +mod fetch_action_id_has_signer; mod fetch_action_id_info; mod fetch_action_id_info_keep_serialized; mod fetch_action_id_signers_power; diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs index ea331ece925..8273acfa7f2 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -122,6 +122,16 @@ impl Drive { ) -> Result, Error> { let mut batch_operations: Vec = vec![]; + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { + Drive::add_estimation_costs_for_add_group_action( + contract_id.to_buffer(), + group_contract_position, + Some(action_id.to_buffer()), + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + } + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); let group_action_root_path = group_action_root_path( contract_id.as_slice(), diff --git a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs index c5b55d607fd..9e489c31c2a 100644 --- a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs @@ -1,9 +1,11 @@ -use crate::drive::group::{group_contract_path, group_path_vec, group_root_path, GROUP_INFO_KEY}; +use crate::drive::group::{ + group_contract_path, group_path, group_root_path, GROUP_ACTIONS_KEY, GROUP_INFO_KEY, +}; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use crate::util::grove_operations::BatchInsertTreeApplyType; -use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKey; +use crate::util::object_size_info::PathKeyInfo::{PathFixedSizeKey, PathFixedSizeKeyRef}; use crate::util::object_size_info::{DriveKeyInfo, PathKeyElementInfo}; use dpp::block::block_info::BlockInfo; use dpp::data_contract::group::Group; @@ -128,26 +130,34 @@ impl Drive { &mut batch_operations, &platform_version.drive, )?; - let group_path = group_path_vec(contract_id.as_slice(), *group_pos); + let group_path = group_path(contract_id.as_slice(), group_pos_bytes.as_slice()); let serialized_group_info = group.serialize_to_bytes()?; let info_item = Element::Item(serialized_group_info, None); self.batch_insert( - PathKeyElementInfo::PathKeyElement::<0>(( + PathKeyElementInfo::PathFixedSizeKeyRefElement::<3>(( group_path, - GROUP_INFO_KEY.to_vec(), + GROUP_INFO_KEY, info_item, )), &mut batch_operations, &platform_version.drive, )?; + + self.batch_insert_empty_tree( + group_path, + DriveKeyInfo::KeyRef(GROUP_ACTIONS_KEY), + None, + &mut batch_operations, + &platform_version.drive, + )?; } } else { for (group_pos, group) in groups { let group_pos_bytes = group_pos.to_be_bytes().to_vec(); let path = group_contract_path(contract_id.as_slice()); let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey((path, group_pos_bytes)), + PathFixedSizeKeyRef((path, group_pos_bytes.as_slice())), false, None, apply_type, @@ -158,19 +168,27 @@ impl Drive { )?; if inserted { - let group_path = group_path_vec(contract_id.as_slice(), *group_pos); + let group_path = group_path(contract_id.as_slice(), group_pos_bytes.as_slice()); let serialized_group_info = group.serialize_to_bytes()?; let info_item = Element::Item(serialized_group_info, None); self.batch_insert( - PathKeyElementInfo::PathKeyElement::<0>(( + PathKeyElementInfo::PathFixedSizeKeyRefElement::<3>(( group_path, - GROUP_INFO_KEY.to_vec(), + GROUP_INFO_KEY, info_item, )), &mut batch_operations, &platform_version.drive, )?; + + self.batch_insert_empty_tree( + group_path, + DriveKeyInfo::KeyRef(GROUP_ACTIONS_KEY), + None, + &mut batch_operations, + &platform_version.drive, + )?; } } } diff --git a/packages/rs-drive/src/drive/group/mod.rs b/packages/rs-drive/src/drive/group/mod.rs index 7a134413c62..d283c314a97 100644 --- a/packages/rs-drive/src/drive/group/mod.rs +++ b/packages/rs-drive/src/drive/group/mod.rs @@ -1,6 +1,7 @@ use crate::drive::RootTree; use dpp::data_contract::GroupContractPosition; +mod estimated_costs; mod fetch; mod insert; diff --git a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs index 97abd31e189..3aa28799baa 100644 --- a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs @@ -1,7 +1,4 @@ -use crate::drive::balances::{ - total_token_supply_path, total_token_supply_path_vec, total_tokens_root_supply_path, - total_tokens_root_supply_path_vec, -}; +use crate::drive::balances::{total_tokens_root_supply_path, total_tokens_root_supply_path_vec}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; diff --git a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs index fa9c5bd3eaf..311c3254c8d 100644 --- a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs @@ -1,7 +1,4 @@ -use crate::drive::balances::{ - total_token_supply_path, total_token_supply_path_vec, total_tokens_root_supply_path, - total_tokens_root_supply_path_vec, -}; +use crate::drive::balances::{total_tokens_root_supply_path, total_tokens_root_supply_path_vec}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs similarity index 96% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs index 0ef3b467b43..d0534eb779b 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/batch_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; use crate::util::batch::DriveOperation; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_create_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs similarity index 99% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_create_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs index 96c16ed9e36..5b376c10fa5 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_create_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::util::batch::DriveOperation::{ DocumentOperation, IdentityOperation, PrefundedSpecializedBalanceOperation, }; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_delete_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_delete_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs index 799f5857784..cfaa9295314 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_delete_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs @@ -1,4 +1,4 @@ -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_purchase_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_purchase_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs index 3634442c282..2b255b09207 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_purchase_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_replace_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_replace_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs index 19fb9febacf..59339d16480 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_replace_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transfer_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs index 67ea0f3bd1d..991370d6716 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs similarity index 97% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs index 3967e050f0f..e8aacd5a148 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_update_price_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_update_price_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs index abea0ffa630..14d33c2ea85 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/document_update_price_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/documents_batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs similarity index 97% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/documents_batch_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs index 5630245ff14..cff9b3ffe7c 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/documents_batch_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs @@ -1,6 +1,6 @@ use crate::error::drive::DriveError; use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; use crate::state_transition_action::document::documents_batch::BatchTransitionAction; use crate::util::batch::DriveOperation; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/mod.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs index af8b7a9c017..32d0ddf03a6 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs @@ -9,7 +9,7 @@ use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs new file mode 100644 index 00000000000..8e8464a3aac --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs @@ -0,0 +1,109 @@ +use dpp::block::epoch::Epoch; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::group::action_event::GroupActionEvent; +use dpp::group::group_action::GroupAction; +use dpp::group::group_action::v0::GroupActionV0; +use dpp::group::GroupStateTransitionResolvedInfo; +use dpp::identifier::Identifier; +use dpp::tokens::token_event::TokenEvent; +use platform_version::version::PlatformVersion; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use crate::util::batch::{DriveOperation, IdentityOperationType}; +use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; +use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; + +impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { + fn into_high_level_document_drive_operations<'b>( + self, + _epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .state_transitions + .convert_to_high_level_operations + .token_mint_transition + { + 0 => { + let data_contract_id = self.base().data_contract_id(); + + let identity_contract_nonce = self.base().identity_contract_nonce(); + + let mut ops = vec![IdentityOperation( + IdentityOperationType::UpdateIdentityContractNonce { + identity_id: owner_id.into_buffer(), + contract_id: data_contract_id.into_buffer(), + nonce: identity_contract_nonce, + }, + )]; + + if self.base().perform_action() { + ops.push(TokenOperation(TokenOperationType::TokenMint { + token_id: self.token_id(), + identity_balance_holder_id: self.identity_balance_holder_id(), + mint_amount: self.mint_amount(), + allow_first_mint: false, + })); + + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Mint( + self.mint_amount(), + self.identity_balance_holder_id(), + self.public_note_owned(), + ), + })); + } + } else if let Some(GroupStateTransitionResolvedInfo { + group_contract_position, + action_id, + action_is_proposer, + signer_power, + .. + }) = self.base().store_in_group() + { + let event = TokenEvent::Mint( + self.mint_amount(), + self.identity_balance_holder_id(), + self.public_note().cloned(), + ); + + let initialize_with_insert_action_info = if *action_is_proposer { + Some(GroupAction::V0(GroupActionV0 { + event: GroupActionEvent::TokenEvent(event), + })) + } else { + None + }; + + ops.push(GroupOperation(GroupOperationType::AddGroupAction { + contract_id: data_contract_id, + group_contract_position: *group_contract_position, + initialize_with_insert_action_info, + action_id: *action_id, + signer_identity_id: owner_id, + signer_power: *signer_power, + })); + } + + Ok(ops) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "TokenMintTransitionAction::into_high_level_document_drive_operations" + .to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs index 61bd9db796b..9b62d28c0d6 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs @@ -5,7 +5,7 @@ use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs similarity index 96% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs index 5ecd40d75f8..1399a63d74a 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::TokenTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_mint_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_mint_transition.rs deleted file mode 100644 index deb56e4851a..00000000000 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/document/token_mint_transition.rs +++ /dev/null @@ -1,73 +0,0 @@ -use dpp::block::epoch::Epoch; -use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; -use dpp::identifier::Identifier; -use dpp::tokens::token_event::TokenEvent; -use platform_version::version::PlatformVersion; -use crate::error::drive::DriveError; -use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::document::DriveHighLevelDocumentOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; -use crate::util::batch::{DriveOperation, IdentityOperationType}; -use crate::util::batch::drive_op_batch::TokenOperationType; -use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; - -impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { - fn into_high_level_document_drive_operations<'b>( - self, - _epoch: &Epoch, - owner_id: Identifier, - platform_version: &PlatformVersion, - ) -> Result>, Error> { - match platform_version - .drive - .methods - .state_transitions - .convert_to_high_level_operations - .token_mint_transition - { - 0 => { - let data_contract_id = self.base().data_contract_id(); - - let identity_contract_nonce = self.base().identity_contract_nonce(); - - let mut ops = vec![IdentityOperation( - IdentityOperationType::UpdateIdentityContractNonce { - identity_id: owner_id.into_buffer(), - contract_id: data_contract_id.into_buffer(), - nonce: identity_contract_nonce, - }, - )]; - - ops.push(TokenOperation(TokenOperationType::TokenMint { - token_id: self.token_id(), - identity_balance_holder_id: self.identity_balance_holder_id(), - mint_amount: self.mint_amount(), - allow_first_mint: false, - })); - - let token_configuration = self.base().token_configuration()?; - if token_configuration.keeps_history() { - ops.push(TokenOperation(TokenOperationType::TokenHistory { - token_id: self.token_id(), - owner_id, - nonce: identity_contract_nonce, - event: TokenEvent::Mint( - self.mint_amount(), - self.identity_balance_holder_id(), - self.public_note_owned(), - ), - })); - } - - Ok(ops) - } - version => Err(Error::Drive(DriveError::UnknownVersionMismatch { - method: "TokenMintTransitionAction::into_high_level_document_drive_operations" - .to_string(), - known_versions: vec![0], - received: version, - })), - } - } -} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/mod.rs index 345b823df3e..28c69e3f883 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/mod.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/mod.rs @@ -3,8 +3,8 @@ //! This module defines general, commonly used functions in Drive. //! +mod batch; mod contract; -mod document; mod identity; mod system; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs index 88734b37285..7d52c7ab2a5 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs @@ -1,6 +1,7 @@ use dpp::platform_value::Identifier; use std::sync::Arc; use grovedb::TransactionArg; +use dpp::prelude::ConsensusValidationResult; use dpp::ProtocolError; use dpp::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use platform_version::version::PlatformVersion; @@ -21,7 +22,7 @@ impl TokenBaseTransitionAction { drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { match value { TokenBaseTransition::V0(v0) => Ok( TokenBaseTransitionActionV0::try_from_base_transition_with_contract_lookup( @@ -34,7 +35,7 @@ impl TokenBaseTransitionAction { get_data_contract, platform_version, )? - .into(), + .map(|v0| v0.into()), ), } } @@ -49,7 +50,7 @@ impl TokenBaseTransitionAction { drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { match value { TokenBaseTransition::V0(v0) => Ok( TokenBaseTransitionActionV0::try_from_borrowed_base_transition_with_contract_lookup( @@ -61,8 +62,7 @@ impl TokenBaseTransitionAction { drive_operations, get_data_contract, platform_version, - )? - .into(), + )?.map(|v0| v0.into()) ), } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index 9a039451429..bfd5ee4e976 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -2,8 +2,12 @@ use dpp::group::{GroupStateTransitionInfo, GroupStateTransitionResolvedInfo}; use dpp::platform_value::Identifier; use grovedb::TransactionArg; use std::sync::Arc; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::group::{GroupActionDoesNotExistError, IdentityNotMemberOfGroupError}; +use dpp::consensus::state::state_error::StateError; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::group::accessors::v0::GroupV0Getters; +use dpp::prelude::ConsensusValidationResult; use dpp::ProtocolError; use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use platform_version::version::PlatformVersion; @@ -24,7 +28,7 @@ impl TokenBaseTransitionActionV0 { drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { let TokenBaseTransitionV0 { token_contract_position, data_contract_id, @@ -43,17 +47,50 @@ impl TokenBaseTransitionActionV0 { action_is_proposer, }) => { let group = data_contract.contract.group(group_contract_position)?; - let signer_power = group.member_power(owner_id)?; + let signer_power = match group.member_power(owner_id) { + Ok(signer_power) => signer_power, + Err(ProtocolError::GroupMemberNotFound(_)) => { + return Ok(ConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::IdentityNotMemberOfGroupError( + IdentityNotMemberOfGroupError::new( + owner_id, + data_contract_id, + group_contract_position, + ), + )), + )); + } + Err(e) => return Err(e.into()), + }; let required_power = group.required_power(); - let current_power = drive.fetch_action_id_signers_power_and_add_operations( - data_contract_id, - group_contract_position, - action_id, - approximate_without_state_for_costs, - transaction, - drive_operations, - platform_version, - )?; + let current_power = if action_is_proposer { + 0 + } else { + match drive.fetch_action_id_signers_power_and_add_operations( + data_contract_id, + group_contract_position, + action_id, + approximate_without_state_for_costs, + transaction, + drive_operations, + platform_version, + )? { + None => { + return Ok(ConsensusValidationResult::new_with_error( + ConsensusError::StateError( + StateError::GroupActionDoesNotExistError( + GroupActionDoesNotExistError::new( + data_contract_id, + group_contract_position, + action_id, + ), + ), + ), + )); + } + Some(power) => power, + } + }; let perform_action = if approximate_without_state_for_costs { // most expensive case is that we perform action true @@ -77,7 +114,8 @@ impl TokenBaseTransitionActionV0 { data_contract, store_in_group, perform_action, - }) + } + .into()) } /// try from borrowed base transition with contract lookup @@ -90,7 +128,7 @@ impl TokenBaseTransitionActionV0 { drive_operations: &mut Vec, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { let TokenBaseTransitionV0 { token_contract_position, data_contract_id, @@ -109,17 +147,50 @@ impl TokenBaseTransitionActionV0 { action_is_proposer, }) => { let group = data_contract.contract.group(*group_contract_position)?; - let signer_power = group.member_power(owner_id)?; + let signer_power = match group.member_power(owner_id) { + Ok(signer_power) => signer_power, + Err(ProtocolError::GroupMemberNotFound(_)) => { + return Ok(ConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::IdentityNotMemberOfGroupError( + IdentityNotMemberOfGroupError::new( + owner_id, + *data_contract_id, + *group_contract_position, + ), + )), + )); + } + Err(e) => return Err(e.into()), + }; let required_power = group.required_power(); - let current_power = drive.fetch_action_id_signers_power_and_add_operations( - *data_contract_id, - *group_contract_position, - *action_id, - approximate_without_state_for_costs, - transaction, - drive_operations, - platform_version, - )?; + let current_power = if *action_is_proposer { + 0 + } else { + match drive.fetch_action_id_signers_power_and_add_operations( + *data_contract_id, + *group_contract_position, + *action_id, + approximate_without_state_for_costs, + transaction, + drive_operations, + platform_version, + )? { + None => { + return Ok(ConsensusValidationResult::new_with_error( + ConsensusError::StateError( + StateError::GroupActionDoesNotExistError( + GroupActionDoesNotExistError::new( + *data_contract_id, + *group_contract_position, + *action_id, + ), + ), + ), + )); + } + Some(power) => power, + } + }; let perform_action = if approximate_without_state_for_costs { // most expensive case is that we perform action true @@ -143,6 +214,7 @@ impl TokenBaseTransitionActionV0 { data_contract, store_in_group, perform_action, - }) + } + .into()) } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs index 56882c931c0..2828e045410 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs @@ -4,6 +4,7 @@ use grovedb::TransactionArg; use std::sync::Arc; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{ TokenBurnTransitionAction, TokenBurnTransitionActionV0, @@ -12,6 +13,7 @@ use dpp::state_transition::batch_transition::token_burn_transition::TokenBurnTra use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; +use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; /// Implement methods to transform a `TokenBurnTransition` into a `TokenBurnTransitionAction`. impl TokenBurnTransitionAction { @@ -41,22 +43,29 @@ impl TokenBurnTransitionAction { approximate_without_state_for_costs: bool, transaction: TransactionArg, block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result<(Self, FeeResult), Error> { + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { match value { TokenBurnTransition::V0(v0) => { - let (v0, fee) = TokenBurnTransitionActionV0::try_from_token_burn_transition_with_contract_lookup( + TokenBurnTransitionActionV0::try_from_token_burn_transition_with_contract_lookup( drive, owner_id, v0, approximate_without_state_for_costs, transaction, block_info, + user_fee_increase, get_data_contract, platform_version, - )?; - Ok((v0.into(), fee)) + ) } } } @@ -87,22 +96,29 @@ impl TokenBurnTransitionAction { approximate_without_state_for_costs: bool, transaction: TransactionArg, block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result<(Self, FeeResult), Error> { + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { match value { TokenBurnTransition::V0(v0) => { - let (v0, fee) = TokenBurnTransitionActionV0::try_from_borrowed_token_burn_transition_with_contract_lookup( + TokenBurnTransitionActionV0::try_from_borrowed_token_burn_transition_with_contract_lookup( drive, owner_id, v0, approximate_without_state_for_costs, transaction, block_info, + user_fee_increase, get_data_contract, platform_version, - )?; - Ok((v0.into(), fee)) + ) } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index 0261872631a..3480d668457 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -5,12 +5,18 @@ use grovedb::TransactionArg; use std::sync::Arc; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; +use dpp::prelude::UserFeeIncrease; +use dpp::validation::ConsensusValidationResult; use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; +use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionActionV0; +use crate::state_transition_action::StateTransitionAction; +use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; impl TokenBurnTransitionActionV0 { /// Attempts to create a `TokenBurnTransitionActionV0` from the given `TokenBurnTransitionV0` value. @@ -43,9 +49,16 @@ impl TokenBurnTransitionActionV0 { approximate_without_state_for_costs: bool, transaction: TransactionArg, block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result<(Self, FeeResult), Error> { + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { let TokenBurnTransitionV0 { base, burn_amount, @@ -54,16 +67,17 @@ impl TokenBurnTransitionActionV0 { let mut drive_operations = vec![]; - let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( - drive, - owner_id, - base, - approximate_without_state_for_costs, - transaction, - &mut drive_operations, - get_data_contract, - platform_version, - )?; + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + &base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; let fee_result = Drive::calculate_fee( None, @@ -74,12 +88,37 @@ impl TokenBurnTransitionActionV0 { None, )?; + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = BumpIdentityDataContractNonceAction::from_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + Ok(( - TokenBurnTransitionActionV0 { - base: base_action, - burn_amount, - public_note, - }, + BatchedTransitionAction::TokenAction(TokenTransitionAction::BurnAction( + TokenBurnTransitionActionV0 { + base: base_action, + burn_amount, + public_note, + } + .into(), + )) + .into(), fee_result, )) } @@ -114,9 +153,16 @@ impl TokenBurnTransitionActionV0 { approximate_without_state_for_costs: bool, transaction: TransactionArg, block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, - ) -> Result<(Self, FeeResult), Error> { + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { let TokenBurnTransitionV0 { base, burn_amount, @@ -125,7 +171,7 @@ impl TokenBurnTransitionActionV0 { let mut drive_operations = vec![]; - let base_action = + let base_action_validation_result = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( drive, owner_id, @@ -146,12 +192,38 @@ impl TokenBurnTransitionActionV0 { None, )?; + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + Ok(( - TokenBurnTransitionActionV0 { - base: base_action, - burn_amount: *burn_amount, - public_note: public_note.clone(), - }, + BatchedTransitionAction::TokenAction(TokenTransitionAction::BurnAction( + TokenBurnTransitionActionV0 { + base: base_action, + burn_amount: *burn_amount, + public_note: public_note.clone(), + } + .into(), + )) + .into(), fee_result, )) } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs index 91b79f56bba..4a408a94577 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs @@ -4,7 +4,7 @@ use grovedb::TransactionArg; use std::sync::Arc; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; -use dpp::prelude::ConsensusValidationResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionActionV0, TokenMintTransitionAction}; use dpp::state_transition::batch_transition::token_mint_transition::TokenMintTransition; @@ -38,6 +38,7 @@ impl TokenMintTransitionAction { approximate_without_state_for_costs: bool, transaction: TransactionArg, block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, ) -> Result< @@ -56,6 +57,7 @@ impl TokenMintTransitionAction { approximate_without_state_for_costs, transaction, block_info, + user_fee_increase, get_data_contract, platform_version, ) @@ -86,6 +88,7 @@ impl TokenMintTransitionAction { approximate_without_state_for_costs: bool, transaction: TransactionArg, block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, ) -> Result< @@ -104,6 +107,7 @@ impl TokenMintTransitionAction { approximate_without_state_for_costs, transaction, block_info, + user_fee_increase, get_data_contract, platform_version, ) diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs index 0c7e0643e43..1ff995248b2 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs @@ -13,7 +13,7 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::v0::TokenMintTransitionActionV0; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::fee::fee_result::FeeResult; -use dpp::prelude::ConsensusValidationResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; @@ -51,6 +51,7 @@ impl TokenMintTransitionActionV0 { approximate_without_state_for_costs: bool, transaction: TransactionArg, block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, ) -> Result< @@ -71,16 +72,17 @@ impl TokenMintTransitionActionV0 { let mut drive_operations = vec![]; - let base_action = TokenBaseTransitionAction::try_from_base_transition_with_contract_lookup( - drive, - owner_id, - base, - approximate_without_state_for_costs, - transaction, - &mut drive_operations, - get_data_contract, - platform_version, - )?; + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + &base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; let fee_result = Drive::calculate_fee( None, @@ -91,6 +93,27 @@ impl TokenMintTransitionActionV0 { None, )?; + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = BumpIdentityDataContractNonceAction::from_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + if !base_action .token_configuration()? .minting_allow_choosing_destination() @@ -100,7 +123,7 @@ impl TokenMintTransitionActionV0 { BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action( &base_action, owner_id, - 0, + user_fee_increase, ); let batched_action = BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); @@ -202,6 +225,7 @@ impl TokenMintTransitionActionV0 { approximate_without_state_for_costs: bool, transaction: TransactionArg, block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, platform_version: &PlatformVersion, ) -> Result< @@ -220,7 +244,7 @@ impl TokenMintTransitionActionV0 { let mut drive_operations = vec![]; - let base_action = + let base_action_validation_result = TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( drive, owner_id, @@ -241,6 +265,28 @@ impl TokenMintTransitionActionV0 { None, )?; + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + if !base_action .token_configuration()? .minting_allow_choosing_destination() @@ -250,7 +296,7 @@ impl TokenMintTransitionActionV0 { BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action( &base_action, owner_id, - 0, + user_fee_increase, ); let batched_action = BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs index 5a6e083615c..ac6820da0b9 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs @@ -67,7 +67,8 @@ impl TokenTransferTransitionActionV0 { &mut drive_operations, get_data_contract, platform_version, - )?; + )? + .into_data()?; let fee_result = Drive::calculate_fee( None, @@ -148,7 +149,8 @@ impl TokenTransferTransitionActionV0 { &mut drive_operations, get_data_contract, platform_version, - )?; + )? + .into_data()?; let fee_result = Drive::calculate_fee( None, diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/mod.rs new file mode 100644 index 00000000000..2be6d7a68e9 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/mod.rs @@ -0,0 +1,58 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use dpp::version::drive_versions::DriveVersion; +use grovedb::TransactionArg; +use grovedb_path::SubtreePath; + +impl Drive { + /// Retrieves the total value from a sum tree within groveDB at the specified path and key. + /// The cost of the operation is then appended to `drive_operations` for later processing. + /// + /// # Parameters + /// * `path`: The groveDB hierarchical authenticated structure path where the sum tree is located. + /// * `key`: The key where the sum tree resides within the subtree. + /// * `query_type`: The type of query to perform, either `StatelessDirectQuery` or `StatefulDirectQuery`. + /// * `transaction`: The groveDB transaction associated with this operation. + /// * `drive_operations`: A vector to collect the costs of operations for later computation. + /// * `platform_version`: The platform version to select the correct function version to run. + /// + /// # Returns + /// * `Ok(Option)` if the operation was successful, returning the total value of the sum tree if it exists. + /// * `Err(DriveError::UnknownVersionMismatch)` if the platform version does not match known versions. + /// * `Err(DriveError::CorruptedBalancePath)` if the balance path does not refer to a sum tree. + /// * `Err(DriveError::CorruptedCodeExecution)` if trying to query a non-tree element. + pub fn grove_get_optional_sum_tree_total_value>( + &self, + path: SubtreePath<'_, B>, + key: &[u8], + query_type: DirectQueryType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result, Error> { + match drive_version + .grove_methods + .basic + .grove_get_optional_sum_tree_total_value + { + 0 => self.grove_get_optional_sum_tree_total_value_v0( + path, + key, + query_type, + transaction, + drive_operations, + drive_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "grove_get_optional_sum_tree_total_value".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/v0/mod.rs new file mode 100644 index 00000000000..fb117ea7a37 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/v0/mod.rs @@ -0,0 +1,72 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::fees::op::LowLevelDriveOperation::CalculatedCostOperation; +use crate::util::grove_operations::{DirectQueryType, QueryTarget}; +use grovedb::batch::key_info::KeyInfo; +use grovedb::batch::KeyInfoPath; +use grovedb::{Element, GroveDb, TransactionArg}; +use grovedb_costs::CostContext; +use grovedb_path::SubtreePath; +use platform_version::version::drive_versions::DriveVersion; + +impl Drive { + /// Gets the element at the given path from groveDB. + /// Pushes the `OperationCost` of getting the element to `drive_operations`. + pub(super) fn grove_get_optional_sum_tree_total_value_v0>( + &self, + path: SubtreePath<'_, B>, + key: &[u8], + query_type: DirectQueryType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result, Error> { + match query_type { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums, + query_target, + } => { + let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); + let key_info = KeyInfo::KnownKey(key.to_vec()); + let cost = match query_target { + QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + Ok(GroveDb::average_case_for_get_tree( + &key_info_path, + &key_info, + flags_size, + is_sum_tree, + in_tree_using_sums, + &drive_version.grove_version, + )?) + } + _ => Err(Error::Drive(DriveError::CorruptedCodeExecution( + "can not query a non tree", + ))), + }?; + + drive_operations.push(CalculatedCostOperation(cost)); + Ok(Some(0)) + } + DirectQueryType::StatefulDirectQuery => { + let CostContext { value, cost } = self.grove.get_raw_optional( + path, + key, + transaction, + &drive_version.grove_version, + ); + drive_operations.push(CalculatedCostOperation(cost)); + let Some(element) = value.map_err(Error::GroveDB)? else { + return Ok(None); + }; + match element { + Element::SumTree(_, value, _) => Ok(Some(value)), + _ => Err(Error::Drive(DriveError::CorruptedBalancePath( + "balance path does not refer to a sum tree", + ))), + } + } + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/mod.rs b/packages/rs-drive/src/util/grove_operations/mod.rs index 9e75d2f59aa..20cea07f6c7 100644 --- a/packages/rs-drive/src/util/grove_operations/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/mod.rs @@ -137,6 +137,9 @@ pub mod batch_insert_sum_item_if_not_exists; /// Moved items that are found in a path query to a new path. pub mod batch_move_items_in_path_query; +/// Get total value from sum tree in grove if it exists +pub mod grove_get_optional_sum_tree_total_value; + use grovedb_costs::CostContext; use grovedb::EstimatedLayerInformation; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs index 95bf59680f0..01359a50255 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs @@ -15,6 +15,7 @@ pub struct DriveGroupFetchMethodVersions { pub fetch_action_id_signers_power: FeatureVersion, pub fetch_action_id_info: FeatureVersion, pub fetch_action_id_info_keep_serialized: FeatureVersion, + pub fetch_action_id_has_signer: FeatureVersion, } #[derive(Clone, Debug, Default)] @@ -27,4 +28,6 @@ pub struct DriveGroupInsertMethodVersions { } #[derive(Clone, Debug, Default)] -pub struct DriveGroupCostEstimationMethodVersions {} +pub struct DriveGroupCostEstimationMethodVersions { + pub for_add_group_action: FeatureVersion, +} diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs index 4bd631f3115..4daae181c72 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs @@ -14,5 +14,7 @@ pub const DRIVE_GROUP_METHOD_VERSIONS_V1: DriveGroupMethodVersions = DriveGroupM add_new_groups: 0, add_group_action: 0, }, - cost_estimation: DriveGroupCostEstimationMethodVersions {}, + cost_estimation: DriveGroupCostEstimationMethodVersions { + for_add_group_action: 0, + }, }; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs index 9746e504599..f624d94fd15 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs @@ -34,6 +34,7 @@ pub struct DriveGroveBasicMethodVersions { pub grove_get_sum_tree_total_value: FeatureVersion, pub grove_has_raw: FeatureVersion, pub grove_get_raw_item: FeatureVersion, + pub grove_get_optional_sum_tree_total_value: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs index 76800ee0c88..df572a2cf2a 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs @@ -27,6 +27,7 @@ pub const DRIVE_GROVE_METHOD_VERSIONS_V1: DriveGroveMethodVersions = DriveGroveM grove_get_sum_tree_total_value: 0, grove_has_raw: 0, grove_get_raw_item: 0, + grove_get_optional_sum_tree_total_value: 0, }, batch: DriveGroveBatchMethodVersions { batch_insert_empty_tree: 0, From 22814b02843a337bf6715574d2ab0300b307494c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 5 Jan 2025 12:52:12 +0700 Subject: [PATCH 39/61] group actions working --- packages/rs-dpp/src/errors/consensus/codes.rs | 1 + .../state_v0/mod.rs | 32 +- .../state_v0/mod.rs | 13 + .../structure_v0/mod.rs | 6 +- .../state_v0/mod.rs | 13 + .../structure_v0/mod.rs | 6 +- .../state_v0/mod.rs | 13 + .../structure_v0/mod.rs | 6 +- .../state_transitions/batch/mod.rs | 296 +++++++++++++++++- .../fetch/fetch_action_id_has_signer/mod.rs | 58 +++- .../fetch_action_id_has_signer/v0/mod.rs | 100 ++++-- .../grove_operations/grove_has_raw/v0/mod.rs | 2 +- .../drive_group_method_versions/v1.rs | 1 + 13 files changed, 496 insertions(+), 51 deletions(-) diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index 34142db436c..e8b767156fa 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -277,6 +277,7 @@ impl ErrorWithCode for StateError { Self::IdentityNotMemberOfGroupError(_) => 40800, Self::GroupActionDoesNotExistError(_) => 40801, Self::GroupActionAlreadyCompletedError(_) => 40802, + Self::GroupActionAlreadySignedByIdentityError(_) => 40803, } } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs index f3f9c654969..3518ad233ab 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs @@ -1,4 +1,7 @@ use dpp::block::block_info::BlockInfo; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::group::GroupActionAlreadySignedByIdentityError; +use dpp::consensus::state::state_error::StateError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; @@ -6,6 +9,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; +use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; use crate::platform_types::platform::PlatformStateRef; @@ -31,7 +35,33 @@ impl TokenBaseTransitionActionStateValidationV0 for TokenBaseTransitionAction { platform_version: &PlatformVersion, ) -> Result { // We should start by validating that if we did not yet sign - if let Some(group_state_transition_resolved_info) = self.store_in_group() {} + if let Some(group_state_transition_resolved_info) = self.store_in_group() { + let (already_signed, cost) = platform.drive.fetch_action_id_has_signer_with_costs( + self.data_contract_id(), + group_state_transition_resolved_info.group_contract_position, + group_state_transition_resolved_info.action_id, + owner_id, + block_info, + transaction, + platform_version, + )?; + execution_context.add_operation(ValidationOperation::PrecalculatedOperation(cost)); + if already_signed { + // We already have signed this state transition group action + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError( + StateError::GroupActionAlreadySignedByIdentityError( + GroupActionAlreadySignedByIdentityError::new( + owner_id, + self.data_contract_id(), + group_state_transition_resolved_info.group_contract_position, + group_state_transition_resolved_info.action_id, + ), + ), + ), + )); + } + } Ok(SimpleConsensusValidationResult::new()) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs index abcbd3e0c7d..bea78369c2e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs @@ -14,6 +14,7 @@ use drive::query::TransactionArg; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenBurnTransitionActionStateValidationV0 { @@ -37,6 +38,18 @@ impl TokenBurnTransitionActionStateValidationV0 for TokenBurnTransitionAction { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result { + let validation_result = self.base().validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + // Let's first check to see if we are authorized to perform this action let contract = &self.data_contract_fetch_info_ref().contract; let token_configuration = contract.expected_token_configuration(self.token_position())?; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs index 22fed53d193..52862d7dc75 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs @@ -28,8 +28,10 @@ impl TokenBurnTransitionActionStructureValidationV0 for TokenBurnTransitionActio &self, platform_version: &PlatformVersion, ) -> Result { - self.base().validate_structure(platform_version)?; - let token_configuration = self.base().token_configuration()?; + let validation_result = self.base().validate_structure(platform_version)?; + if !validation_result.is_valid() { + return Ok(validation_result); + } Ok(SimpleConsensusValidationResult::default()) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs index 41541fa7377..60504136f25 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs @@ -16,6 +16,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use crate::error::Error; use crate::execution::types::execution_operation::{RetrieveIdentityInfo, ValidationOperation}; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenMintTransitionActionStateValidationV0 { @@ -39,6 +40,18 @@ impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result { + let validation_result = self.base().validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + // Let's first check to see if we are authorized to perform this action let contract = &self.data_contract_fetch_info_ref().contract; let token_configuration = contract.expected_token_configuration(self.token_position())?; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs index dfaddbedd25..21d592898fa 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs @@ -30,8 +30,10 @@ impl TokenMintTransitionActionStructureValidationV0 for TokenMintTransitionActio &self, platform_version: &PlatformVersion, ) -> Result { - self.base().validate_structure(platform_version)?; - let token_configuration = self.base().token_configuration()?; + let validation_result = self.base().validate_structure(platform_version)?; + if !validation_result.is_valid() { + return Ok(validation_result); + } Ok(SimpleConsensusValidationResult::default()) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs index f4aaa1ff8c0..52d40495ad8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs @@ -11,6 +11,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; use crate::platform_types::platform::PlatformStateRef; pub(super) trait TokenTransferTransitionActionStateValidationV0 { @@ -34,6 +35,18 @@ impl TokenTransferTransitionActionStateValidationV0 for TokenTransferTransitionA transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result { + let validation_result = self.base().validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + // We need to verify that we have enough of the token let balance = platform .drive diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index 4202cbca96f..4a52e66d1fc 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -20,8 +20,10 @@ impl TokenTransferTransitionActionStructureValidationV0 for TokenTransferTransit owner_id: Identifier, platform_version: &PlatformVersion, ) -> Result { - self.base().validate_structure(platform_version)?; - let token_configuration = self.base().token_configuration()?; + let validation_result = self.base().validate_structure(platform_version)?; + if !validation_result.is_valid() { + return Ok(validation_result); + } Ok(SimpleConsensusValidationResult::default()) } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index 62de40fc11a..b790d788e60 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -10947,7 +10947,301 @@ mod tests { platform_version, ) .expect("expected to fetch token balance"); - assert_eq!(token_balance, Some(101337)); + assert_eq!(token_balance, Some(100000)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + + #[test] + fn test_token_mint_by_owner_requires_group_other_member_resubmitting_causes_error() + { + // We are using a group, and two members need to sign for the event to happen + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, signer2, key2) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_3, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [ + (identity.id(), 1), + (identity_2.id(), 1), + (identity_3.id(), 1), + ] + .into(), + required_power: 3, + }), + )] + .into(), + ), + platform_version, + ); + + let token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some(GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer(0)), + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_mint_serialized_transition = token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + // Now we need to get the second identity to also sign it + let action_id = TokenMintTransition::calculate_action_id_with_fields( + token_id.as_bytes(), + identity.id().as_bytes(), + 2, + 1337, + ); + let confirm_token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity_2.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some( + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner( + GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: false, + }, + ), + ), + &key2, + 2, + 0, + &signer2, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let confirm_token_mint_serialized_transition = confirm_token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![confirm_token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + + // Now we need to get the second identity to sign it again to cause the error + let confirm_token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity_2.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some( + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner( + GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: false, + }, + ), + ), + &key2, + 3, + 0, + &signer2, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let confirm_token_mint_serialized_transition = confirm_token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![confirm_token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError( + StateError::GroupActionAlreadySignedByIdentityError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); let token_balance = platform .drive diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/mod.rs index 6fbe9f0a983..1aa5d30a107 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/mod.rs @@ -2,8 +2,9 @@ use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; -use dpp::data_contract::group::GroupSumPower; +use dpp::block::block_info::BlockInfo; use dpp::data_contract::GroupContractPosition; +use dpp::fee::fee_result::FeeResult; use dpp::identifier::Identifier; use grovedb::TransactionArg; use platform_version::version::PlatformVersion; @@ -11,15 +12,16 @@ use platform_version::version::PlatformVersion; mod v0; impl Drive { - /// Fetches the action id signers power + /// Fetches if an identity has already signed in an action pub fn fetch_action_id_has_signer( &self, contract_id: Identifier, group_contract_position: GroupContractPosition, action_id: Identifier, + signer_id: Identifier, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result, Error> { + ) -> Result { match platform_version .drive .methods @@ -31,45 +33,83 @@ impl Drive { contract_id, group_contract_position, action_id, + signer_id, transaction, platform_version, ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { - method: "fetch_action_id_signers_power".to_string(), + method: "fetch_action_id_has_signer".to_string(), known_versions: vec![0], received: version, })), } } + /// Fetches if an identity has already signed in an action with costs - pub(crate) fn fetch_action_id_signers_power_and_add_operations( + pub fn fetch_action_id_has_signer_with_costs( &self, contract_id: Identifier, group_contract_position: GroupContractPosition, action_id: Identifier, + signer_id: Identifier, + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(bool, FeeResult), Error> { + match platform_version + .drive + .methods + .group + .fetch + .fetch_action_id_has_signer + { + 0 => self.fetch_action_id_has_signer_with_costs_v0( + contract_id, + group_contract_position, + action_id, + signer_id, + block_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_action_id_has_signer_with_costs".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + pub(crate) fn fetch_action_id_has_signer_and_add_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + signer_id: Identifier, estimate_costs_only: bool, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result, Error> { + ) -> Result { match platform_version .drive .methods .group .fetch - .fetch_action_id_signers_power + .fetch_action_id_has_signer { - 0 => self.fetch_action_id_signers_power_and_add_operations_v0( + 0 => self.fetch_action_id_has_signer_and_add_operations_v0( contract_id, group_contract_position, action_id, + signer_id, estimate_costs_only, transaction, drive_operations, platform_version, ), version => Err(Error::Drive(DriveError::UnknownVersionMismatch { - method: "fetch_action_id_signers_and_add_operations".to_string(), + method: "fetch_action_id_has_signer_and_add_operations".to_string(), known_versions: vec![0], received: version, })), diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs index af88918a8fa..1e60604353e 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs @@ -1,11 +1,13 @@ -use crate::drive::group::{group_action_path, ACTION_SIGNERS_KEY}; +use crate::drive::group::group_action_signers_path; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use crate::util::grove_operations::DirectQueryType; use crate::util::grove_operations::QueryTarget::QueryTargetValue; -use dpp::data_contract::group::GroupSumPower; +use dpp::block::block_info::BlockInfo; use dpp::data_contract::GroupContractPosition; +use dpp::fee::fee_result::FeeResult; +use dpp::fee::Credits; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; use grovedb::TransactionArg; @@ -34,36 +36,69 @@ impl Drive { /// * `Error::Drive(DriveError::CorruptedContractPath)` if the fetched path does not refer to a valid sum item. /// * `Error::Drive(DriveError::CorruptedCodeExecution)` if the element type is unexpected. /// * `Error::GroveDB` for any underlying GroveDB errors. - pub(super) fn fetch_action_id_signers_power_v0( + pub(super) fn fetch_action_id_has_signer_v0( &self, contract_id: Identifier, group_contract_position: GroupContractPosition, action_id: Identifier, + signer_id: Identifier, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result, Error> { + ) -> Result { let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); // Construct the GroveDB path for the action signers - let path = group_action_path( - contract_id.as_ref(), + let path = group_action_signers_path( + contract_id.as_slice(), &group_contract_position_bytes, - action_id.as_ref(), + action_id.as_slice(), ); - let value = self - .grove_get_optional_sum_tree_total_value( - (&path).into(), - ACTION_SIGNERS_KEY, - DirectQueryType::StatefulDirectQuery, - transaction, - &mut vec![], - &platform_version.drive, - )? - .map(|v| v as GroupSumPower); + let value = self.grove_has_raw( + (&path).into(), + signer_id.as_slice(), + DirectQueryType::StatefulDirectQuery, + transaction, + &mut vec![], + &platform_version.drive, + )?; Ok(value) } + /// Fetches the Identity's balance from the backing store + /// Passing apply as false get the estimated cost instead + pub(super) fn fetch_action_id_has_signer_with_costs_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + action_id: Identifier, + signer_id: Identifier, + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(bool, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_action_id_has_signer_and_add_operations_v0( + contract_id, + group_contract_position, + action_id, + signer_id, + false, + transaction, + &mut drive_operations, + platform_version, + )?; + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + Ok((value, fees)) + } + /// v0 implementation of fetching the signers' power for a given action ID within a group contract and adding related operations. /// /// This function not only fetches the signers' power but also appends necessary low-level drive operations based on the provided epoch. @@ -88,44 +123,43 @@ impl Drive { /// * `Error::Drive(DriveError::CorruptedCodeExecution)` if the element type is unexpected. /// * `Error::Drive(DriveError::NotSupportedPrivate)` if stateful batch insertions are attempted. /// * `Error::GroveDB` for any underlying GroveDB errors. - pub(super) fn fetch_action_id_signers_power_and_add_operations_v0( + pub(super) fn fetch_action_id_has_signer_and_add_operations_v0( &self, contract_id: Identifier, group_contract_position: GroupContractPosition, action_id: Identifier, + signer_id: Identifier, estimate_costs_only: bool, transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result, Error> { + ) -> Result { let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); // Construct the GroveDB path for the action signers - let path = group_action_path( - contract_id.as_ref(), + let path = group_action_signers_path( + contract_id.as_slice(), &group_contract_position_bytes, - action_id.as_ref(), + action_id.as_slice(), ); // no estimated_costs_only_with_layer_info, means we want to apply to state let direct_query_type = if estimate_costs_only { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_using_sums: true, query_target: QueryTargetValue(8), } } else { DirectQueryType::StatefulDirectQuery }; - let value = self - .grove_get_optional_sum_tree_total_value( - (&path).into(), - ACTION_SIGNERS_KEY, - direct_query_type, - transaction, - drive_operations, - &platform_version.drive, - )? - .map(|v| v as GroupSumPower); + let value = self.grove_has_raw( + (&path).into(), + signer_id.as_slice(), + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + )?; Ok(value) } diff --git a/packages/rs-drive/src/util/grove_operations/grove_has_raw/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_has_raw/v0/mod.rs index 52b3eaaa969..5b15c0a73c1 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_has_raw/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_has_raw/v0/mod.rs @@ -14,7 +14,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Gets the return value and the cost of a groveDB `has_raw` operation. /// Pushes the cost to `drive_operations` and returns the return value. - pub(crate) fn grove_has_raw_v0>( + pub(super) fn grove_has_raw_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs index 4daae181c72..a28f8f1d788 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs @@ -8,6 +8,7 @@ pub const DRIVE_GROUP_METHOD_VERSIONS_V1: DriveGroupMethodVersions = DriveGroupM fetch_action_id_signers_power: 0, fetch_action_id_info: 0, fetch_action_id_info_keep_serialized: 0, + fetch_action_id_has_signer: 0, }, prove: DriveGroupProveMethodVersions {}, insert: DriveGroupInsertMethodVersions { From e5e361a60525f0c7e56b5d76aebf8b7b68d663bc Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 5 Jan 2025 13:02:05 +0700 Subject: [PATCH 40/61] more tests --- .../batch_transition/v1/v0_methods.rs | 1 - .../state_transitions/batch/mod.rs | 294 ++++++++++++++++++ .../batch/token_burn_transition.rs | 36 ++- .../batch/token_mint_transition.rs | 46 +-- .../v0/transformer.rs | 24 +- 5 files changed, 360 insertions(+), 41 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index 67c7057151d..b15db66ecb8 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -443,7 +443,6 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { group_contract_position, ) => { let action_id = mint_transition.calculate_action_id(owner_id); - println!("using action id {}", action_id.to_string(Encoding::Hex)); mint_transition.base_mut().set_using_group_info(Some( GroupStateTransitionInfo { group_contract_position, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index b790d788e60..daba9407763 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -11255,6 +11255,300 @@ mod tests { assert_eq!(token_balance, None); } + #[test] + fn test_token_mint_by_owner_requires_group_other_member_submitting_after_completion_causes_error( + ) { + // We are using a group, and two members need to sign for the event to happen + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, signer2, key2) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_3, signer3, key3) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_manual_minting_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::Group(0), + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: + false, + }, + )); + }), + Some( + [( + 0, + Group::V0(GroupV0 { + members: [ + (identity.id(), 1), + (identity_2.id(), 1), + (identity_3.id(), 1), + ] + .into(), + required_power: 2, + }), + )] + .into(), + ), + platform_version, + ); + + let token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some(GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer(0)), + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_mint_serialized_transition = token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + + // Now we need to get the second identity to also sign it + let action_id = TokenMintTransition::calculate_action_id_with_fields( + token_id.as_bytes(), + identity.id().as_bytes(), + 2, + 1337, + ); + let confirm_token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity_2.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some( + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner( + GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: false, + }, + ), + ), + &key2, + 2, + 0, + &signer2, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let confirm_token_mint_serialized_transition = confirm_token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![confirm_token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(101337)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + + // Now we need to get the second identity to sign it again to cause the error + let confirm_token_mint_transition = BatchTransition::new_token_mint_transition( + token_id, + identity_3.id(), + contract.id(), + 0, + 1337, + Some(identity.id()), + None, + Some( + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner( + GroupStateTransitionInfo { + group_contract_position: 0, + action_id, + action_is_proposer: false, + }, + ), + ), + &key3, + 2, + 0, + &signer3, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let confirm_token_mint_serialized_transition = confirm_token_mint_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![confirm_token_mint_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError( + StateError::GroupActionAlreadyCompletedError(_) + ), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(101337)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, None); + } + #[test] fn test_token_mint_by_owner_requires_group_proposer_not_in_group() { // We are using a group, and two members need to sign for the event to happen diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs index 32d0ddf03a6..d2aa44d2d4b 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs @@ -43,23 +43,7 @@ impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { }, )]; - if self.base().perform_action() { - ops.push(TokenOperation(TokenOperationType::TokenBurn { - token_id: self.token_id(), - identity_balance_holder_id: owner_id, - burn_amount: self.burn_amount(), - })); - - let token_configuration = self.base().token_configuration()?; - if token_configuration.keeps_history() { - ops.push(TokenOperation(TokenOperationType::TokenHistory { - token_id: self.token_id(), - owner_id, - nonce: identity_contract_nonce, - event: TokenEvent::Burn(self.burn_amount(), self.public_note_owned()), - })); - } - } else if let Some(GroupStateTransitionResolvedInfo { + if let Some(GroupStateTransitionResolvedInfo { group_contract_position, action_id, action_is_proposer, @@ -87,6 +71,24 @@ impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { })); } + if self.base().perform_action() { + ops.push(TokenOperation(TokenOperationType::TokenBurn { + token_id: self.token_id(), + identity_balance_holder_id: owner_id, + burn_amount: self.burn_amount(), + })); + + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Burn(self.burn_amount(), self.public_note_owned()), + })); + } + } + Ok(ops) } version => Err(Error::Drive(DriveError::UnknownVersionMismatch { diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs index 8e8464a3aac..632cba76a33 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs @@ -43,28 +43,7 @@ impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { }, )]; - if self.base().perform_action() { - ops.push(TokenOperation(TokenOperationType::TokenMint { - token_id: self.token_id(), - identity_balance_holder_id: self.identity_balance_holder_id(), - mint_amount: self.mint_amount(), - allow_first_mint: false, - })); - - let token_configuration = self.base().token_configuration()?; - if token_configuration.keeps_history() { - ops.push(TokenOperation(TokenOperationType::TokenHistory { - token_id: self.token_id(), - owner_id, - nonce: identity_contract_nonce, - event: TokenEvent::Mint( - self.mint_amount(), - self.identity_balance_holder_id(), - self.public_note_owned(), - ), - })); - } - } else if let Some(GroupStateTransitionResolvedInfo { + if let Some(GroupStateTransitionResolvedInfo { group_contract_position, action_id, action_is_proposer, @@ -96,6 +75,29 @@ impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { })); } + if self.base().perform_action() { + ops.push(TokenOperation(TokenOperationType::TokenMint { + token_id: self.token_id(), + identity_balance_holder_id: self.identity_balance_holder_id(), + mint_amount: self.mint_amount(), + allow_first_mint: false, + })); + + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Mint( + self.mint_amount(), + self.identity_balance_holder_id(), + self.public_note_owned(), + ), + })); + } + } + Ok(ops) } version => Err(Error::Drive(DriveError::UnknownVersionMismatch { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs index bfd5ee4e976..7dc2337281b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs @@ -3,7 +3,7 @@ use dpp::platform_value::Identifier; use grovedb::TransactionArg; use std::sync::Arc; use dpp::consensus::ConsensusError; -use dpp::consensus::state::group::{GroupActionDoesNotExistError, IdentityNotMemberOfGroupError}; +use dpp::consensus::state::group::{GroupActionAlreadyCompletedError, GroupActionDoesNotExistError, IdentityNotMemberOfGroupError}; use dpp::consensus::state::state_error::StateError; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::group::accessors::v0::GroupV0Getters; @@ -91,6 +91,17 @@ impl TokenBaseTransitionActionV0 { Some(power) => power, } }; + if current_power >= required_power { + return Ok(ConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::GroupActionAlreadyCompletedError( + GroupActionAlreadyCompletedError::new( + data_contract_id, + group_contract_position, + action_id, + ), + )), + )); + } let perform_action = if approximate_without_state_for_costs { // most expensive case is that we perform action true @@ -191,6 +202,17 @@ impl TokenBaseTransitionActionV0 { Some(power) => power, } }; + if current_power >= required_power { + return Ok(ConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::GroupActionAlreadyCompletedError( + GroupActionAlreadyCompletedError::new( + *data_contract_id, + *group_contract_position, + *action_id, + ), + )), + )); + } let perform_action = if approximate_without_state_for_costs { // most expensive case is that we perform action true From 2d224a1eb4ae60d3245450da2b2842f58d23648e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 5 Jan 2025 15:53:40 +0700 Subject: [PATCH 41/61] its cold --- packages/rs-dpp/src/state_transition/mod.rs | 6 +- .../batched_transition/document_transition.rs | 10 ++- .../batched_transition/mod.rs | 2 + .../batched_transition/resolvers.rs | 31 ++++++- .../token_freeze_transition/mod.rs | 24 ++++++ .../token_freeze_transition/v0/mod.rs | 45 ++++++++++ .../token_freeze_transition/v0/v0_methods.rs | 78 +++++++++++++++++ .../token_freeze_transition/v0_methods.rs | 85 +++++++++++++++++++ .../token_mint_transition/v0/mod.rs | 2 +- .../token_mint_transition/v0/v0_methods.rs | 10 +-- .../batched_transition/token_transition.rs | 38 ++++++++- .../token_transition_action_type.rs | 8 ++ .../token_unfreeze_transition/mod.rs | 24 ++++++ .../token_unfreeze_transition/v0/mod.rs | 45 ++++++++++ .../v0/v0_methods.rs | 78 +++++++++++++++++ .../token_unfreeze_transition/v0_methods.rs | 85 +++++++++++++++++++ .../document/batch_transition/mod.rs | 6 +- .../batch_transition/resolvers/v0/mod.rs | 5 +- .../batch_transition/v1/v0_methods.rs | 1 - .../state_v0/mod.rs | 1 - .../structure_v0/mod.rs | 13 --- .../token_mint_transition_action/mod.rs | 1 - .../structure_v0/mod.rs | 15 ---- .../token_transfer_transition_action/mod.rs | 1 - .../structure_v0/mod.rs | 1 - .../batch/transformer/v0/mod.rs | 23 ++++- .../fetch_action_id_has_signer/v0/mod.rs | 1 - .../v0/transformer.rs | 2 - 28 files changed, 588 insertions(+), 53 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0_methods.rs diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 793bdf0fe78..514b4aa2739 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -367,8 +367,12 @@ impl StateTransition { BatchedTransitionRef::Token(TokenTransition::Transfer(_)) => { "TokenTransfer" } - BatchedTransitionRef::Token(TokenTransition::Mint(_)) => "TokenIssuance", + BatchedTransitionRef::Token(TokenTransition::Mint(_)) => "TokenMint", BatchedTransitionRef::Token(TokenTransition::Burn(_)) => "TokenBurn", + BatchedTransitionRef::Token(TokenTransition::Freeze(_)) => "TokenFreeze", + BatchedTransitionRef::Token(TokenTransition::Unfreeze(_)) => { + "TokenUnfreeze" + } }; document_transition_types.push(document_transition_name); } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs index a9f5f1ecdb2..9b9a2ec0d88 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs @@ -5,7 +5,7 @@ use derive_more::{Display, From}; use serde::{Deserialize, Serialize}; use bincode::{Encode, Decode}; use crate::prelude::{IdentityNonce, Revision}; -use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenMintTransition, TokenTransferTransition}; +use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, TokenUnfreezeTransition}; use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition}; use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use crate::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; @@ -93,6 +93,14 @@ impl BatchTransitionResolversV0 for DocumentTransition { fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition> { None } + + fn as_transition_token_freeze(&self) -> Option<&TokenFreezeTransition> { + None + } + + fn as_transition_token_unfreeze(&self) -> Option<&TokenUnfreezeTransition> { + None + } } pub trait DocumentTransitionV0Methods { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs index 8c7d0cf7041..8342f635ff4 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs @@ -16,10 +16,12 @@ pub mod multi_party_action; mod resolvers; pub mod token_base_transition; pub mod token_burn_transition; +pub mod token_freeze_transition; pub mod token_mint_transition; pub mod token_transfer_transition; pub mod token_transition; pub mod token_transition_action_type; +pub mod token_unfreeze_transition; use crate::prelude::IdentityNonce; use crate::state_transition::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs index 4939084539c..eaaa4cc2c76 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs @@ -4,7 +4,8 @@ use crate::state_transition::batch_transition::batched_transition::{ use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; use crate::state_transition::batch_transition::{ DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, - TokenBurnTransition, TokenMintTransition, TokenTransferTransition, + TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, + TokenUnfreezeTransition, }; impl BatchTransitionResolversV0 for BatchedTransition { @@ -63,6 +64,20 @@ impl BatchTransitionResolversV0 for BatchedTransition { BatchedTransition::Token(token) => token.as_transition_token_transfer(), } } + + fn as_transition_token_freeze(&self) -> Option<&TokenFreezeTransition> { + match self { + BatchedTransition::Document(_) => None, + BatchedTransition::Token(token) => token.as_transition_token_freeze(), + } + } + + fn as_transition_token_unfreeze(&self) -> Option<&TokenUnfreezeTransition> { + match self { + BatchedTransition::Document(_) => None, + BatchedTransition::Token(token) => token.as_transition_token_unfreeze(), + } + } } impl<'a> BatchTransitionResolversV0 for BatchedTransitionRef<'a> { @@ -121,4 +136,18 @@ impl<'a> BatchTransitionResolversV0 for BatchedTransitionRef<'a> { BatchedTransitionRef::Token(token) => token.as_transition_token_transfer(), } } + + fn as_transition_token_freeze(&self) -> Option<&TokenFreezeTransition> { + match self { + BatchedTransitionRef::Document(_) => None, + BatchedTransitionRef::Token(token) => token.as_transition_token_freeze(), + } + } + + fn as_transition_token_unfreeze(&self) -> Option<&TokenUnfreezeTransition> { + match self { + BatchedTransitionRef::Document(_) => None, + BatchedTransitionRef::Token(token) => token.as_transition_token_unfreeze(), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/mod.rs new file mode 100644 index 00000000000..844454a6610 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/mod.rs @@ -0,0 +1,24 @@ +pub mod v0; +mod v0_methods; + +use bincode::{Decode, Encode}; +use derive_more::{Display, From}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +pub use v0::TokenFreezeTransitionV0; + +#[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenFreezeTransition { + #[display("V0({})", "_0")] + V0(TokenFreezeTransitionV0), +} + +impl Default for TokenFreezeTransition { + fn default() -> Self { + TokenFreezeTransition::V0(TokenFreezeTransitionV0::default()) // since only v0 + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/mod.rs new file mode 100644 index 00000000000..c27da679746 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/mod.rs @@ -0,0 +1,45 @@ +pub mod v0_methods; + +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use bincode::{Decode, Encode}; +use platform_value::Identifier; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +use std::fmt; + +mod property_names { + pub const AMOUNT: &str = "$amount"; +} +/// The Identifier fields in [`TokenFreezeTransition`] +pub use super::super::document_base_transition::IDENTIFIER_FIELDS; + +#[derive(Debug, Clone, Default, Encode, Decode, PartialEq)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +pub struct TokenFreezeTransitionV0 { + /// Document Base Transition + #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] + pub base: TokenBaseTransition, + /// The identity that we are freezing + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "frozenIdentityId") + )] + pub frozen_identity_id: Identifier, + /// The public note + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "publicNote") + )] + pub public_note: Option, +} + +impl fmt::Display for TokenFreezeTransitionV0 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Format the base transition (assuming `TokenBaseTransition` implements Display) + write!(f, "Base: {}, Froze: {}", self.base, self.frozen_identity_id) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..bec3466b7ba --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0/v0_methods.rs @@ -0,0 +1,78 @@ +use platform_value::Identifier; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::batch_transition::token_freeze_transition::TokenFreezeTransitionV0; +use crate::state_transition::batch_transition::TokenFreezeTransition; + +impl TokenBaseTransitionAccessors for TokenFreezeTransitionV0 { + fn base(&self) -> &TokenBaseTransition { + &self.base + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + &mut self.base + } + + fn set_base(&mut self, base: TokenBaseTransition) { + self.base = base; + } +} + +pub trait TokenFreezeTransitionV0Methods: + TokenBaseTransitionAccessors + AllowedAsMultiPartyAction +{ + /// Returns the `public_note` field of the `TokenFreezeTransitionV0`. + fn public_note(&self) -> Option<&String>; + + /// Returns the owned `public_note` field of the `TokenFreezeTransitionV0`. + fn public_note_owned(self) -> Option; + + /// Sets the value of the `public_note` field in the `TokenFreezeTransitionV0`. + fn set_public_note(&mut self, public_note: Option); + + /// Returns the `frozen_identity_id` field of the `TokenFreezeTransitionV0`. + fn frozen_identity_id(&self) -> Identifier; + + /// Sets the value of the `frozen_identity_id` field in the `TokenFreezeTransitionV0`. + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier); +} + +impl TokenFreezeTransitionV0Methods for TokenFreezeTransitionV0 { + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } + + fn frozen_identity_id(&self) -> Identifier { + self.frozen_identity_id + } + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + self.frozen_identity_id = frozen_identity_id; + } +} + +impl AllowedAsMultiPartyAction for TokenFreezeTransitionV0 { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + let TokenFreezeTransitionV0 { + base, + frozen_identity_id, + .. + } = self; + + TokenFreezeTransition::calculate_action_id_with_fields( + base.token_id().as_bytes(), + owner_id.as_bytes(), + frozen_identity_id.as_bytes(), + base.identity_contract_nonce(), + ) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0_methods.rs new file mode 100644 index 00000000000..13c06dcd456 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_freeze_transition/v0_methods.rs @@ -0,0 +1,85 @@ +use platform_value::Identifier; +use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_freeze_transition::v0::v0_methods::TokenFreezeTransitionV0Methods; +use crate::state_transition::batch_transition::TokenFreezeTransition; +use crate::util::hash::hash_double; + +impl TokenBaseTransitionAccessors for TokenFreezeTransition { + fn base(&self) -> &TokenBaseTransition { + match self { + TokenFreezeTransition::V0(v0) => &v0.base, + } + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + match self { + TokenFreezeTransition::V0(v0) => &mut v0.base, + } + } + + fn set_base(&mut self, base: TokenBaseTransition) { + match self { + TokenFreezeTransition::V0(v0) => v0.base = base, + } + } +} + +impl TokenFreezeTransitionV0Methods for TokenFreezeTransition { + fn public_note(&self) -> Option<&String> { + match self { + TokenFreezeTransition::V0(v0) => v0.public_note(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenFreezeTransition::V0(v0) => v0.public_note_owned(), + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenFreezeTransition::V0(v0) => v0.set_public_note(public_note), + } + } + + fn frozen_identity_id(&self) -> Identifier { + match self { + TokenFreezeTransition::V0(v0) => v0.frozen_identity_id(), + } + } + + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + match self { + TokenFreezeTransition::V0(v0) => v0.set_frozen_identity_id(frozen_identity_id), + } + } +} + +impl AllowedAsMultiPartyAction for TokenFreezeTransition { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + match self { + TokenFreezeTransition::V0(v0) => v0.calculate_action_id(owner_id), + } + } +} + +impl TokenFreezeTransition { + pub fn calculate_action_id_with_fields( + token_id: &[u8; 32], + owner_id: &[u8; 32], + target_id: &[u8; 32], + identity_contract_nonce: IdentityNonce, + ) -> Identifier { + let mut bytes = b"action_token_freeze".to_vec(); + bytes.extend_from_slice(token_id); + bytes.extend_from_slice(owner_id); + bytes.extend_from_slice(target_id); + bytes.extend_from_slice(&identity_contract_nonce.to_be_bytes()); + + hash_double(bytes).into() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/mod.rs index 412111a65c7..da8079655a5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/mod.rs @@ -11,7 +11,7 @@ use std::fmt; mod property_names { pub const AMOUNT: &str = "$amount"; } -/// The Identifier fields in [`TokenIssuanceTransition`] +/// The Identifier fields in [`TokenMintTransition`] pub use super::super::document_base_transition::IDENTIFIER_FIELDS; #[derive(Debug, Clone, Default, Encode, Decode, PartialEq)] diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs index 5e0119507dd..9bb315fd6ef 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_mint_transition/v0/v0_methods.rs @@ -27,19 +27,19 @@ pub trait TokenMintTransitionV0Methods: fn set_amount(&mut self, amount: u64); - /// Returns the `public_note` field of the `TokenIssuanceTransitionV0`. + /// Returns the `public_note` field of the `TokenMintTransitionV0`. fn public_note(&self) -> Option<&String>; - /// Returns the owned `public_note` field of the `TokenIssuanceTransitionV0`. + /// Returns the owned `public_note` field of the `TokenMintTransitionV0`. fn public_note_owned(self) -> Option; - /// Sets the value of the `public_note` field in the `TokenIssuanceTransitionV0`. + /// Sets the value of the `public_note` field in the `TokenMintTransitionV0`. fn set_public_note(&mut self, public_note: Option); - /// Returns the `issued_to_identity_id` field of the `TokenIssuanceTransitionV0`. + /// Returns the `issued_to_identity_id` field of the `TokenMintTransitionV0`. fn issued_to_identity_id(&self) -> Option; - /// Sets the value of the `issued_to_identity_id` field in the `TokenIssuanceTransitionV0`. + /// Sets the value of the `issued_to_identity_id` field in the `TokenMintTransitionV0`. fn set_issued_to_identity_id(&mut self, issued_to_identity_id: Option); } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs index 8bfa654d0c5..2e75c5b74ab 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs @@ -4,9 +4,10 @@ use serde::{Deserialize, Serialize}; use platform_value::Identifier; use bincode::{Encode, Decode}; use crate::prelude::IdentityNonce; -use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenMintTransition, TokenTransferTransition}; +use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition}; use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition}; use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::batched_transition::token_unfreeze_transition::TokenUnfreezeTransition; use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; @@ -26,6 +27,12 @@ pub enum TokenTransition { #[display("TokenTransferTransition({})", "_0")] Transfer(TokenTransferTransition), + + #[display("TokenFreezeTransition({})", "_0")] + Freeze(TokenFreezeTransition), + + #[display("TokenUnfreezeTransition({})", "_0")] + Unfreeze(TokenUnfreezeTransition), } impl BatchTransitionResolversV0 for TokenTransition { @@ -70,6 +77,22 @@ impl BatchTransitionResolversV0 for TokenTransition { None } } + + fn as_transition_token_freeze(&self) -> Option<&TokenFreezeTransition> { + if let Self::Freeze(ref t) = self { + Some(t) + } else { + None + } + } + + fn as_transition_token_unfreeze(&self) -> Option<&TokenUnfreezeTransition> { + if let Self::Unfreeze(ref t) = self { + Some(t) + } else { + None + } + } } pub trait TokenTransitionV0Methods { @@ -102,6 +125,8 @@ impl TokenTransitionV0Methods for TokenTransition { TokenTransition::Burn(t) => t.base(), TokenTransition::Mint(t) => t.base(), TokenTransition::Transfer(t) => t.base(), + TokenTransition::Freeze(t) => t.base(), + TokenTransition::Unfreeze(t) => t.base(), } } @@ -110,6 +135,8 @@ impl TokenTransitionV0Methods for TokenTransition { TokenTransition::Burn(t) => t.base_mut(), TokenTransition::Mint(t) => t.base_mut(), TokenTransition::Transfer(t) => t.base_mut(), + TokenTransition::Freeze(t) => t.base_mut(), + TokenTransition::Unfreeze(t) => t.base_mut(), } } @@ -121,13 +148,18 @@ impl TokenTransitionV0Methods for TokenTransition { match self { TokenTransition::Burn(t) => Some(t.calculate_action_id(owner_id)), TokenTransition::Mint(t) => Some(t.calculate_action_id(owner_id)), - TokenTransition::Transfer(t) => None, + TokenTransition::Freeze(t) => Some(t.calculate_action_id(owner_id)), + TokenTransition::Unfreeze(t) => Some(t.calculate_action_id(owner_id)), + TokenTransition::Transfer(_) => None, } } fn can_calculate_action_id(&self) -> bool { match self { - TokenTransition::Burn(_) | TokenTransition::Mint(_) => true, + TokenTransition::Burn(_) + | TokenTransition::Mint(_) + | TokenTransition::Freeze(_) + | TokenTransition::Unfreeze(_) => true, TokenTransition::Transfer(_) => false, } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs index 9695299f115..1aef40ba974 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs @@ -8,6 +8,8 @@ pub enum TokenTransitionActionType { Burn, Mint, Transfer, + Freeze, + Unfreeze, } impl fmt::Display for TokenTransitionActionType { @@ -16,6 +18,8 @@ impl fmt::Display for TokenTransitionActionType { TokenTransitionActionType::Burn => "Burn", TokenTransitionActionType::Mint => "Mint", TokenTransitionActionType::Transfer => "Transfer", + TokenTransitionActionType::Freeze => "Freeze", + TokenTransitionActionType::Unfreeze => "Unfreeze", }; write!(f, "{}", action_str) } @@ -31,6 +35,8 @@ impl TransitionActionTypeGetter for TokenTransition { TokenTransition::Burn(_) => TokenTransitionActionType::Burn, TokenTransition::Mint(_) => TokenTransitionActionType::Mint, TokenTransition::Transfer(_) => TokenTransitionActionType::Transfer, + TokenTransition::Freeze(_) => TokenTransitionActionType::Freeze, + TokenTransition::Unfreeze(_) => TokenTransitionActionType::Unfreeze, } } } @@ -43,6 +49,8 @@ impl TryFrom<&str> for TokenTransitionActionType { "burn" => Ok(TokenTransitionActionType::Burn), "issuance" => Ok(TokenTransitionActionType::Mint), "transfer" => Ok(TokenTransitionActionType::Transfer), + "freeze" => Ok(TokenTransitionActionType::Freeze), + "unfreeze" => Ok(TokenTransitionActionType::Unfreeze), action_type => Err(ProtocolError::Generic(format!( "unknown token transition action type {action_type}" ))), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/mod.rs new file mode 100644 index 00000000000..4cefde0effb --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/mod.rs @@ -0,0 +1,24 @@ +pub mod v0; +mod v0_methods; + +use bincode::{Decode, Encode}; +use derive_more::{Display, From}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +pub use v0::TokenUnfreezeTransitionV0; + +#[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenUnfreezeTransition { + #[display("V0({})", "_0")] + V0(TokenUnfreezeTransitionV0), +} + +impl Default for TokenUnfreezeTransition { + fn default() -> Self { + TokenUnfreezeTransition::V0(TokenUnfreezeTransitionV0::default()) // since only v0 + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/mod.rs new file mode 100644 index 00000000000..abdf7892c53 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/mod.rs @@ -0,0 +1,45 @@ +pub mod v0_methods; + +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use bincode::{Decode, Encode}; +use platform_value::Identifier; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +use std::fmt; + +mod property_names { + pub const AMOUNT: &str = "$amount"; +} +/// The Identifier fields in [`TokenUnfreezeTransition`] +pub use super::super::document_base_transition::IDENTIFIER_FIELDS; + +#[derive(Debug, Clone, Default, Encode, Decode, PartialEq)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +pub struct TokenUnfreezeTransitionV0 { + /// Document Base Transition + #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] + pub base: TokenBaseTransition, + /// The identity that we are freezing + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "frozenIdentityId") + )] + pub frozen_identity_id: Identifier, + /// The public note + #[cfg_attr( + feature = "state-transition-serde-conversion", + serde(rename = "publicNote") + )] + pub public_note: Option, +} + +impl fmt::Display for TokenUnfreezeTransitionV0 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Format the base transition (assuming `TokenBaseTransition` implements Display) + write!(f, "Base: {}, Froze: {}", self.base, self.frozen_identity_id) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..d386f30bd66 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0/v0_methods.rs @@ -0,0 +1,78 @@ +use platform_value::Identifier; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::batched_transition::token_unfreeze_transition::TokenUnfreezeTransitionV0; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::batch_transition::TokenUnfreezeTransition; + +impl TokenBaseTransitionAccessors for TokenUnfreezeTransitionV0 { + fn base(&self) -> &TokenBaseTransition { + &self.base + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + &mut self.base + } + + fn set_base(&mut self, base: TokenBaseTransition) { + self.base = base; + } +} + +pub trait TokenUnfreezeTransitionV0Methods: + TokenBaseTransitionAccessors + AllowedAsMultiPartyAction +{ + /// Returns the `public_note` field of the `TokenUnfreezeTransitionV0`. + fn public_note(&self) -> Option<&String>; + + /// Returns the owned `public_note` field of the `TokenUnfreezeTransitionV0`. + fn public_note_owned(self) -> Option; + + /// Sets the value of the `public_note` field in the `TokenUnfreezeTransitionV0`. + fn set_public_note(&mut self, public_note: Option); + + /// Returns the `frozen_identity_id` field of the `TokenUnfreezeTransitionV0`. + fn frozen_identity_id(&self) -> Identifier; + + /// Sets the value of the `frozen_identity_id` field in the `TokenUnfreezeTransitionV0`. + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier); +} + +impl TokenUnfreezeTransitionV0Methods for TokenUnfreezeTransitionV0 { + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } + + fn frozen_identity_id(&self) -> Identifier { + self.frozen_identity_id + } + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + self.frozen_identity_id = frozen_identity_id; + } +} + +impl AllowedAsMultiPartyAction for TokenUnfreezeTransitionV0 { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + let TokenUnfreezeTransitionV0 { + base, + frozen_identity_id, + .. + } = self; + + TokenUnfreezeTransition::calculate_action_id_with_fields( + base.token_id().as_bytes(), + owner_id.as_bytes(), + frozen_identity_id.as_bytes(), + base.identity_contract_nonce(), + ) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0_methods.rs new file mode 100644 index 00000000000..2f660df7167 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_unfreeze_transition/v0_methods.rs @@ -0,0 +1,85 @@ +use platform_value::Identifier; +use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_unfreeze_transition::v0::v0_methods::TokenUnfreezeTransitionV0Methods; +use crate::state_transition::batch_transition::TokenUnfreezeTransition; +use crate::util::hash::hash_double; + +impl TokenBaseTransitionAccessors for TokenUnfreezeTransition { + fn base(&self) -> &TokenBaseTransition { + match self { + TokenUnfreezeTransition::V0(v0) => &v0.base, + } + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + match self { + TokenUnfreezeTransition::V0(v0) => &mut v0.base, + } + } + + fn set_base(&mut self, base: TokenBaseTransition) { + match self { + TokenUnfreezeTransition::V0(v0) => v0.base = base, + } + } +} + +impl TokenUnfreezeTransitionV0Methods for TokenUnfreezeTransition { + fn public_note(&self) -> Option<&String> { + match self { + TokenUnfreezeTransition::V0(v0) => v0.public_note(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenUnfreezeTransition::V0(v0) => v0.public_note_owned(), + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenUnfreezeTransition::V0(v0) => v0.set_public_note(public_note), + } + } + + fn frozen_identity_id(&self) -> Identifier { + match self { + TokenUnfreezeTransition::V0(v0) => v0.frozen_identity_id(), + } + } + + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + match self { + TokenUnfreezeTransition::V0(v0) => v0.set_frozen_identity_id(frozen_identity_id), + } + } +} + +impl AllowedAsMultiPartyAction for TokenUnfreezeTransition { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + match self { + TokenUnfreezeTransition::V0(v0) => v0.calculate_action_id(owner_id), + } + } +} + +impl TokenUnfreezeTransition { + pub fn calculate_action_id_with_fields( + token_id: &[u8; 32], + owner_id: &[u8; 32], + target_id: &[u8; 32], + identity_contract_nonce: IdentityNonce, + ) -> Identifier { + let mut bytes = b"action_token_unfreeze".to_vec(); + bytes.extend_from_slice(token_id); + bytes.extend_from_slice(owner_id); + bytes.extend_from_slice(target_id); + bytes.extend_from_slice(&identity_contract_nonce.to_be_bytes()); + + hash_double(bytes).into() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs index fe45ab58c3d..68fed9a5143 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs @@ -16,9 +16,11 @@ pub use self::batched_transition::{ document_create_transition::DocumentCreateTransition, document_delete_transition, document_delete_transition::DocumentDeleteTransition, document_replace_transition, document_replace_transition::DocumentReplaceTransition, token_base_transition, - token_burn_transition, token_burn_transition::TokenBurnTransition, token_mint_transition, + token_burn_transition, token_burn_transition::TokenBurnTransition, token_freeze_transition, + token_freeze_transition::TokenFreezeTransition, token_mint_transition, token_mint_transition::TokenMintTransition, token_transfer_transition, - token_transfer_transition::TokenTransferTransition, + token_transfer_transition::TokenTransferTransition, token_unfreeze_transition, + token_unfreeze_transition::TokenUnfreezeTransition, }; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize, PlatformSignable}; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs index 87015c97fcd..2db30dae0de 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs @@ -1,9 +1,10 @@ +use crate::state_transition::batch_transition::batched_transition::token_unfreeze_transition::TokenUnfreezeTransition; use crate::state_transition::batch_transition::batched_transition::{ DocumentPurchaseTransition, DocumentTransferTransition, }; use crate::state_transition::batch_transition::{ DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, - TokenBurnTransition, TokenMintTransition, TokenTransferTransition, + TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, }; pub trait BatchTransitionResolversV0 { @@ -15,4 +16,6 @@ pub trait BatchTransitionResolversV0 { fn as_transition_token_burn(&self) -> Option<&TokenBurnTransition>; fn as_transition_token_mint(&self) -> Option<&TokenMintTransition>; fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition>; + fn as_transition_token_freeze(&self) -> Option<&TokenFreezeTransition>; + fn as_transition_token_unfreeze(&self) -> Option<&TokenUnfreezeTransition>; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index b15db66ecb8..0ef9f18d301 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -40,7 +40,6 @@ use crate::state_transition::StateTransition; use crate::ProtocolError; #[cfg(feature = "state-transition-signing")] use platform_value::Identifier; -use platform_value::string_encoding::Encoding; #[cfg(feature = "state-transition-signing")] use platform_version::version::{FeatureVersion, PlatformVersion}; use crate::balances::credits::TokenAmount; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs index 3518ad233ab..8c777f109c5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs @@ -2,7 +2,6 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::group::GroupActionAlreadySignedByIdentityError; use dpp::consensus::state::state_error::StateError; -use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs index 52862d7dc75..8c331162f4b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs @@ -1,19 +1,6 @@ -use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::{DocumentCreationNotAllowedError, InvalidDocumentTypeError}; -use dpp::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError; -use dpp::dashcore::Network; -use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::data_contract::accessors::v1::DataContractV1Getters; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; -use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; -use dpp::data_contract::document_type::restricted_creation::CreationRestrictionMode; -use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; -use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs index 2821fcbdd36..9da0f53e2b0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs @@ -1,4 +1,3 @@ -use dashcore_rpc::dashcore::Network; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs index 21d592898fa..db057244666 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs @@ -1,21 +1,6 @@ -use dpp::block::block_info::BlockInfo; -use dpp::consensus::basic::document::{DocumentCreationNotAllowedError, InvalidDocumentTypeError}; -use dpp::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError; -use dpp::dashcore::Network; -use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::data_contract::accessors::v1::DataContractV1Getters; -use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; -use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; -use dpp::data_contract::document_type::restricted_creation::CreationRestrictionMode; -use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; -use dpp::identifier::Identifier; -use dpp::ProtocolError; -use dpp::tokens::errors::TokenError; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs index c79c3fef5d8..744f2f0e00f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs @@ -1,4 +1,3 @@ -use dashcore_rpc::dashcore::Network; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index 4a52e66d1fc..7daa9970f24 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -2,7 +2,6 @@ use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index 6bc5415c97a..38d47abed30 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -23,8 +23,7 @@ use dpp::fee::Credits; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::prelude::{Revision, UserFeeIncrease}; use dpp::validation::SimpleConsensusValidationResult; -use dpp::{consensus::ConsensusError, prelude::Identifier, ProtocolError, validation::ConsensusValidationResult}; -use dpp::fee::fee_result::FeeResult; +use dpp::{consensus::ConsensusError, prelude::Identifier, validation::ConsensusValidationResult}; use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use dpp::state_transition::batch_transition::batched_transition::BatchedTransitionRef; use dpp::state_transition::batch_transition::BatchTransition; @@ -535,6 +534,26 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { ); Ok(batched_action.into()) } + TokenTransition::Freeze(token_freeze_transition) => { + let (batched_action, fee_result) = TokenFreezeTransitionAction::try_from_borrowed_token_freeze_transition_with_contract_lookup(drive, owner_id, token_freeze_transition, approximate_for_costs, transaction, block_info, user_fee_increase, |_identifier| { + Ok(data_contract_fetch_info.clone()) + }, platform_version)?; + + execution_context + .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + Ok(batched_action) + } + TokenTransition::Unfreeze(token_unfreeze_transition) => { + let (batched_action, fee_result) = TokenUnfreezeTransitionAction::try_from_borrowed_token_unfreeze_transition_with_contract_lookup(drive, owner_id, token_unfreeze_transition, approximate_for_costs, transaction, block_info, user_fee_increase, |_identifier| { + Ok(data_contract_fetch_info.clone()) + }, platform_version)?; + + execution_context + .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + Ok(batched_action) + } } } diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs index 1e60604353e..ef6963b4d3b 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs @@ -7,7 +7,6 @@ use crate::util::grove_operations::QueryTarget::QueryTargetValue; use dpp::block::block_info::BlockInfo; use dpp::data_contract::GroupContractPosition; use dpp::fee::fee_result::FeeResult; -use dpp::fee::Credits; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; use grovedb::TransactionArg; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs index 3480d668457..b9c6d99e0aa 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs @@ -14,8 +14,6 @@ use crate::error::Error; use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionActionV0; -use crate::state_transition_action::StateTransitionAction; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; impl TokenBurnTransitionActionV0 { From 726c5241126d84cb08d94d1474674cd9b9f70a5b Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sun, 5 Jan 2025 16:22:17 +0700 Subject: [PATCH 42/61] its cold --- .../batch/transformer/v0/mod.rs | 2 + .../batch/token_transition.rs | 13 +- .../document_transition/mod.rs | 14 ++ .../token_freeze_transition_action/mod.rs | 61 +++++ .../transformer.rs | 117 +++++++++ .../token_freeze_transition_action/v0/mod.rs | 96 ++++++++ .../v0/transformer.rs | 232 ++++++++++++++++++ .../token_unfreeze_transition_action/mod.rs | 61 +++++ .../transformer.rs | 117 +++++++++ .../v0/mod.rs | 96 ++++++++ .../v0/transformer.rs | 232 ++++++++++++++++++ 11 files changed, 1034 insertions(+), 7 deletions(-) create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index 38d47abed30..df04ac19d11 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -54,8 +54,10 @@ use drive::state_transition_action::document::documents_batch::document_transiti use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::TokenBurnTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::TokenFreezeTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionAction; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs index 1399a63d74a..5753e67384f 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs @@ -16,13 +16,8 @@ impl DriveHighLevelDocumentOperationConverter for TokenTransitionAction { match self { TokenTransitionAction::BurnAction(token_burn_transition) => token_burn_transition .into_high_level_document_drive_operations(epoch, owner_id, platform_version), - TokenTransitionAction::MintAction(token_issuance_transition) => { - token_issuance_transition.into_high_level_document_drive_operations( - epoch, - owner_id, - platform_version, - ) - } + TokenTransitionAction::MintAction(token_mint_transition) => token_mint_transition + .into_high_level_document_drive_operations(epoch, owner_id, platform_version), TokenTransitionAction::TransferAction(token_transfer_transition) => { token_transfer_transition.into_high_level_document_drive_operations( epoch, @@ -30,6 +25,10 @@ impl DriveHighLevelDocumentOperationConverter for TokenTransitionAction { platform_version, ) } + TokenTransitionAction::FreezeAction(token_freeze_action) => token_freeze_action + .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + TokenTransitionAction::UnfreezeAction(token_unfreeze_action) => token_unfreeze_action + .into_high_level_document_drive_operations(epoch, owner_id, platform_version), } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs index 9c2f4c4fdeb..f15ca23d50c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs @@ -17,10 +17,14 @@ pub mod document_update_price_transition_action; pub mod token_base_transition_action; /// token_burn_transition_action pub mod token_burn_transition_action; +/// token_freeze_transition_action +pub mod token_freeze_transition_action; /// token_issuance_transition_action pub mod token_mint_transition_action; /// token_transfer_transition_action pub mod token_transfer_transition_action; +/// token_unfreeze_transition_action +pub mod token_unfreeze_transition_action; pub use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; @@ -37,6 +41,8 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::{BumpIdentityDataContractNonceAction, BumpIdentityDataContractNonceActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; @@ -96,6 +102,10 @@ pub enum TokenTransitionAction { MintAction(TokenMintTransitionAction), /// transfer TransferAction(TokenTransferTransitionAction), + /// freeze + FreezeAction(TokenFreezeTransitionAction), + /// unfreeze + UnfreezeAction(TokenUnfreezeTransitionAction), } impl TokenTransitionAction { @@ -105,6 +115,8 @@ impl TokenTransitionAction { TokenTransitionAction::BurnAction(action) => action.base(), TokenTransitionAction::MintAction(action) => action.base(), TokenTransitionAction::TransferAction(action) => action.base(), + TokenTransitionAction::FreezeAction(action) => action.base(), + TokenTransitionAction::UnfreezeAction(action) => action.base(), } } @@ -114,6 +126,8 @@ impl TokenTransitionAction { TokenTransitionAction::BurnAction(action) => action.base_owned(), TokenTransitionAction::MintAction(action) => action.base_owned(), TokenTransitionAction::TransferAction(action) => action.base_owned(), + TokenTransitionAction::FreezeAction(action) => action.base_owned(), + TokenTransitionAction::UnfreezeAction(action) => action.base_owned(), } } } diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/mod.rs new file mode 100644 index 00000000000..6efd2f4df88 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/mod.rs @@ -0,0 +1,61 @@ +use derive_more::From; +use dpp::identifier::Identifier; + +/// transformer module for token freeze transition action +pub mod transformer; +mod v0; + +pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) + +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; + +/// Token freeze transition action +#[derive(Debug, Clone, From)] +pub enum TokenFreezeTransitionAction { + /// v0 + V0(TokenFreezeTransitionActionV0), +} + +impl TokenFreezeTransitionActionAccessorsV0 for TokenFreezeTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenFreezeTransitionAction::V0(v0) => &v0.base, + } + } + + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenFreezeTransitionAction::V0(v0) => v0.base, + } + } + + fn frozen_identity_id(&self) -> Identifier { + match self { + TokenFreezeTransitionAction::V0(v0) => v0.frozen_identity_id, + } + } + + fn set_frozen_identity_id(&mut self, id: Identifier) { + match self { + TokenFreezeTransitionAction::V0(v0) => v0.frozen_identity_id = id, + } + } + + fn public_note(&self) -> Option<&String> { + match self { + TokenFreezeTransitionAction::V0(v0) => v0.public_note.as_ref(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenFreezeTransitionAction::V0(v0) => v0.public_note, + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenFreezeTransitionAction::V0(v0) => v0.public_note = public_note, + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/transformer.rs new file mode 100644 index 00000000000..acd281eb476 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/transformer.rs @@ -0,0 +1,117 @@ +use dpp::platform_value::Identifier; +use dpp::ProtocolError; +use grovedb::TransactionArg; +use std::sync::Arc; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionActionV0, TokenFreezeTransitionAction}; +use dpp::state_transition::batch_transition::token_freeze_transition::TokenFreezeTransition; +use platform_version::version::PlatformVersion; +use crate::drive::Drive; +use crate::error::Error; +use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; + +/// Implement methods to transform a `TokenFreezeTransition` into a `TokenFreezeTransitionAction`. +impl TokenFreezeTransitionAction { + /// Transform a `TokenFreezeTransition` into a `TokenFreezeTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the freeze transition. + /// * `transaction` - The transaction argument used for state changes. + /// * `value` - A `TokenFreezeTransition` instance. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// + /// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenFreezeTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_token_freeze_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: TokenFreezeTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + match value { + TokenFreezeTransition::V0(v0) => { + TokenFreezeTransitionActionV0::try_from_token_freeze_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + user_fee_increase, + get_data_contract, + platform_version, + ) + } + } + } + + /// Transform a borrowed `TokenFreezeTransition` into a `TokenFreezeTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the freeze transition. + /// * `transaction` - The transaction argument used for state changes. + /// * `value` - A reference to a `TokenFreezeTransition`. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// + /// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenFreezeTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_borrowed_token_freeze_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: &TokenFreezeTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + match value { + TokenFreezeTransition::V0(v0) => { + TokenFreezeTransitionActionV0::try_from_borrowed_token_freeze_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + user_fee_increase, + get_data_contract, + platform_version, + ) + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/mod.rs new file mode 100644 index 00000000000..02e40882ce3 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/mod.rs @@ -0,0 +1,96 @@ +mod transformer; + +use std::sync::Arc; +use dpp::identifier::Identifier; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; + +/// Token issuance transition action v0 +#[derive(Debug, Clone)] +pub struct TokenFreezeTransitionActionV0 { + /// Base token transition action + pub base: TokenBaseTransitionAction, + /// The identity to credit the token to + pub frozen_identity_id: Identifier, + /// A public note + pub public_note: Option, +} + +/// Accessors for `TokenIssuanceTransitionActionV0` +pub trait TokenFreezeTransitionActionAccessorsV0 { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Consumes self and returns the base token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + + /// Consumes self and returns the identity balance holder ID + fn frozen_identity_id(&self) -> Identifier; + + /// Sets the identity balance holder ID + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier); + + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } + + /// Returns the token ID + fn token_id(&self) -> Identifier { + self.base().token_id() + } + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + /// Returns the public note (optional) + fn public_note(&self) -> Option<&String>; + + /// Returns the public note (owned) + fn public_note_owned(self) -> Option; + + /// Sets the public note + fn set_public_note(&mut self, public_note: Option); +} + +impl TokenFreezeTransitionActionAccessorsV0 for TokenFreezeTransitionActionV0 { + fn base(&self) -> &TokenBaseTransitionAction { + &self.base + } + + fn base_owned(self) -> TokenBaseTransitionAction { + self.base + } + + fn frozen_identity_id(&self) -> Identifier { + self.frozen_identity_id + } + + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + self.frozen_identity_id = frozen_identity_id; + } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs new file mode 100644 index 00000000000..56e360d3d35 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs @@ -0,0 +1,232 @@ +use std::sync::Arc; +use grovedb::TransactionArg; +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::state_transition::batch_transition::token_freeze_transition::v0::TokenFreezeTransitionV0; +use dpp::ProtocolError; +use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::v0::TokenFreezeTransitionActionV0; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use platform_version::version::PlatformVersion; +use crate::drive::Drive; +use crate::error::Error; +use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; +use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; + +impl TokenFreezeTransitionActionV0 { + /// Converts a `TokenFreezeTransitionV0` into a `TokenFreezeTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token freezeing transition and returns the corresponding transition action + /// while looking up necessary data contracts and applying the relevant logic for freezeing. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the freezeing transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `transaction` - A transaction context that includes the necessary state and other details for the transition. + /// * `value` - The `TokenFreezeTransitionV0` struct containing the transition data, including token amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. Useful for optimizing the transaction cost calculations. + /// * `block_info` - Information about the current block to calculate fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version, ensuring the transition respects version-specific logic. + /// + /// # Returns + /// + /// * `Result, Error>` - Returns the constructed `TokenFreezeTransitionActionV0` if successful, + /// or an error if any issue arises, such as missing data or an invalid state transition. + pub fn try_from_token_freeze_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: TokenFreezeTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + let TokenFreezeTransitionV0 { + base, + frozen_identity_id, + public_note, + } = value; + + let mut drive_operations = vec![]; + + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + &base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; + + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = BumpIdentityDataContractNonceAction::from_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + + Ok(( + BatchedTransitionAction::TokenAction(TokenTransitionAction::FreezeAction( + TokenFreezeTransitionActionV0 { + base: base_action, + frozen_identity_id, + public_note, + } + .into(), + )) + .into(), + fee_result, + )) + } + + /// Converts a borrowed `TokenFreezeTransitionV0` into a `TokenFreezeTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token freezeing transition and constructs the corresponding transition action while + /// looking up necessary data contracts and applying the relevant freezeing logic. It does not require `drive_operations` + /// to be passed as a parameter, but it manages them internally. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance that handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the freezeing transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `value` - A reference to the `TokenFreezeTransitionV0` struct containing the transition data, including token + /// amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to indicate whether costs should be approximated without full + /// state consideration. Useful for optimizing transaction cost calculations in scenarios where full state is not needed. + /// * `transaction` - The transaction context, which includes the necessary state and other details for the transition. + /// * `block_info` - Information about the current block (e.g., epoch) to help calculate transaction fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version to ensure the transition respects version-specific logic. + /// + //// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - Returns a tuple containing the constructed + /// `TokenFreezeTransitionActionV0` and a `FeeResult` if successful. If an error occurs (e.g., missing data or + /// invalid state transition), it returns an `Error`. + /// + pub fn try_from_borrowed_token_freeze_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: &TokenFreezeTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + let TokenFreezeTransitionV0 { + base, + frozen_identity_id, + public_note, + } = value; + + let mut drive_operations = vec![]; + + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; + + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + + Ok(( + BatchedTransitionAction::TokenAction(TokenTransitionAction::FreezeAction( + TokenFreezeTransitionActionV0 { + base: base_action, + frozen_identity_id: *frozen_identity_id, + public_note: public_note.clone(), + } + .into(), + )) + .into(), + fee_result, + )) + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/mod.rs new file mode 100644 index 00000000000..0608aad98cd --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/mod.rs @@ -0,0 +1,61 @@ +use derive_more::From; +use dpp::identifier::Identifier; + +/// transformer module for token freeze transition action +pub mod transformer; +mod v0; + +pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) + +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; + +/// Token freeze transition action +#[derive(Debug, Clone, From)] +pub enum TokenUnfreezeTransitionAction { + /// v0 + V0(TokenUnfreezeTransitionActionV0), +} + +impl TokenUnfreezeTransitionActionAccessorsV0 for TokenUnfreezeTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenUnfreezeTransitionAction::V0(v0) => &v0.base, + } + } + + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenUnfreezeTransitionAction::V0(v0) => v0.base, + } + } + + fn frozen_identity_id(&self) -> Identifier { + match self { + TokenUnfreezeTransitionAction::V0(v0) => v0.frozen_identity_id, + } + } + + fn set_frozen_identity_id(&mut self, id: Identifier) { + match self { + TokenUnfreezeTransitionAction::V0(v0) => v0.frozen_identity_id = id, + } + } + + fn public_note(&self) -> Option<&String> { + match self { + TokenUnfreezeTransitionAction::V0(v0) => v0.public_note.as_ref(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenUnfreezeTransitionAction::V0(v0) => v0.public_note, + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenUnfreezeTransitionAction::V0(v0) => v0.public_note = public_note, + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/transformer.rs new file mode 100644 index 00000000000..78e9630bc5f --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/transformer.rs @@ -0,0 +1,117 @@ +use dpp::platform_value::Identifier; +use dpp::ProtocolError; +use grovedb::TransactionArg; +use std::sync::Arc; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionActionV0, TokenUnfreezeTransitionAction}; +use dpp::state_transition::batch_transition::token_unfreeze_transition::TokenUnfreezeTransition; +use platform_version::version::PlatformVersion; +use crate::drive::Drive; +use crate::error::Error; +use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; + +/// Implement methods to transform a `TokenUnfreezeTransition` into a `TokenUnfreezeTransitionAction`. +impl TokenUnfreezeTransitionAction { + /// Transform a `TokenUnfreezeTransition` into a `TokenUnfreezeTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the freeze transition. + /// * `transaction` - The transaction argument used for state changes. + /// * `value` - A `TokenUnfreezeTransition` instance. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// + /// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenUnfreezeTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_token_unfreeze_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: TokenUnfreezeTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + match value { + TokenUnfreezeTransition::V0(v0) => { + TokenUnfreezeTransitionActionV0::try_from_token_unfreeze_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + user_fee_increase, + get_data_contract, + platform_version, + ) + } + } + } + + /// Transform a borrowed `TokenUnfreezeTransition` into a `TokenUnfreezeTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the freeze transition. + /// * `transaction` - The transaction argument used for state changes. + /// * `value` - A reference to a `TokenUnfreezeTransition`. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// + /// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenUnfreezeTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_borrowed_token_unfreeze_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: &TokenUnfreezeTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + match value { + TokenUnfreezeTransition::V0(v0) => { + TokenUnfreezeTransitionActionV0::try_from_borrowed_token_unfreeze_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + user_fee_increase, + get_data_contract, + platform_version, + ) + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/mod.rs new file mode 100644 index 00000000000..88d42f799ba --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/mod.rs @@ -0,0 +1,96 @@ +mod transformer; + +use std::sync::Arc; +use dpp::identifier::Identifier; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; + +/// Token issuance transition action v0 +#[derive(Debug, Clone)] +pub struct TokenUnfreezeTransitionActionV0 { + /// Base token transition action + pub base: TokenBaseTransitionAction, + /// The identity to credit the token to + pub frozen_identity_id: Identifier, + /// A public note + pub public_note: Option, +} + +/// Accessors for `TokenIssuanceTransitionActionV0` +pub trait TokenUnfreezeTransitionActionAccessorsV0 { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Consumes self and returns the base token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + + /// Consumes self and returns the identity balance holder ID + fn frozen_identity_id(&self) -> Identifier; + + /// Sets the identity balance holder ID + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier); + + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } + + /// Returns the token ID + fn token_id(&self) -> Identifier { + self.base().token_id() + } + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + /// Returns the public note (optional) + fn public_note(&self) -> Option<&String>; + + /// Returns the public note (owned) + fn public_note_owned(self) -> Option; + + /// Sets the public note + fn set_public_note(&mut self, public_note: Option); +} + +impl TokenUnfreezeTransitionActionAccessorsV0 for TokenUnfreezeTransitionActionV0 { + fn base(&self) -> &TokenBaseTransitionAction { + &self.base + } + + fn base_owned(self) -> TokenBaseTransitionAction { + self.base + } + + fn frozen_identity_id(&self) -> Identifier { + self.frozen_identity_id + } + + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + self.frozen_identity_id = frozen_identity_id; + } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs new file mode 100644 index 00000000000..328f0e44ba0 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs @@ -0,0 +1,232 @@ +use std::sync::Arc; +use grovedb::TransactionArg; +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::state_transition::batch_transition::token_unfreeze_transition::v0::TokenUnfreezeTransitionV0; +use dpp::ProtocolError; +use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::v0::TokenUnfreezeTransitionActionV0; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use platform_version::version::PlatformVersion; +use crate::drive::Drive; +use crate::error::Error; +use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; +use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; + +impl TokenUnfreezeTransitionActionV0 { + /// Converts a `TokenUnfreezeTransitionV0` into a `TokenUnfreezeTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token freezeing transition and returns the corresponding transition action + /// while looking up necessary data contracts and applying the relevant logic for freezeing. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the freezeing transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `transaction` - A transaction context that includes the necessary state and other details for the transition. + /// * `value` - The `TokenUnfreezeTransitionV0` struct containing the transition data, including token amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. Useful for optimizing the transaction cost calculations. + /// * `block_info` - Information about the current block to calculate fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version, ensuring the transition respects version-specific logic. + /// + /// # Returns + /// + /// * `Result, Error>` - Returns the constructed `TokenUnfreezeTransitionActionV0` if successful, + /// or an error if any issue arises, such as missing data or an invalid state transition. + pub fn try_from_token_unfreeze_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: TokenUnfreezeTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + let TokenUnfreezeTransitionV0 { + base, + frozen_identity_id, + public_note, + } = value; + + let mut drive_operations = vec![]; + + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + &base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; + + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = BumpIdentityDataContractNonceAction::from_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + + Ok(( + BatchedTransitionAction::TokenAction(TokenTransitionAction::UnfreezeAction( + TokenUnfreezeTransitionActionV0 { + base: base_action, + frozen_identity_id, + public_note, + } + .into(), + )) + .into(), + fee_result, + )) + } + + /// Converts a borrowed `TokenUnfreezeTransitionV0` into a `TokenUnfreezeTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token freezeing transition and constructs the corresponding transition action while + /// looking up necessary data contracts and applying the relevant freezeing logic. It does not require `drive_operations` + /// to be passed as a parameter, but it manages them internally. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance that handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the freezeing transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `value` - A reference to the `TokenUnfreezeTransitionV0` struct containing the transition data, including token + /// amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to indicate whether costs should be approximated without full + /// state consideration. Useful for optimizing transaction cost calculations in scenarios where full state is not needed. + /// * `transaction` - The transaction context, which includes the necessary state and other details for the transition. + /// * `block_info` - Information about the current block (e.g., epoch) to help calculate transaction fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version to ensure the transition respects version-specific logic. + /// + //// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - Returns a tuple containing the constructed + /// `TokenUnfreezeTransitionActionV0` and a `FeeResult` if successful. If an error occurs (e.g., missing data or + /// invalid state transition), it returns an `Error`. + /// + pub fn try_from_borrowed_token_unfreeze_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: &TokenUnfreezeTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + let TokenUnfreezeTransitionV0 { + base, + frozen_identity_id, + public_note, + } = value; + + let mut drive_operations = vec![]; + + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; + + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + + Ok(( + BatchedTransitionAction::TokenAction(TokenTransitionAction::UnfreezeAction( + TokenUnfreezeTransitionActionV0 { + base: base_action, + frozen_identity_id: *frozen_identity_id, + public_note: public_note.clone(), + } + .into(), + )) + .into(), + fee_result, + )) + } +} From bb4e761fcdd69d2d42caf764b126600691ab498e Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Jan 2025 09:07:08 +0700 Subject: [PATCH 43/61] freeze and unfreeze validation --- packages/rs-dpp/src/tokens/info/methods.rs | 16 ++ packages/rs-dpp/src/tokens/info/mod.rs | 44 ++++++ packages/rs-dpp/src/tokens/info/v0/mod.rs | 26 +++ packages/rs-dpp/src/tokens/mod.rs | 2 + packages/rs-dpp/src/tokens/token_event.rs | 3 + .../batch/action_validation/mod.rs | 2 + .../token_freeze_transition_action/mod.rs | 86 ++++++++++ .../state_v0/mod.rs | 81 ++++++++++ .../structure_v0/mod.rs | 25 +++ .../token_unfreeze_transition_action/mod.rs | 86 ++++++++++ .../state_v0/mod.rs | 80 ++++++++++ .../structure_v0/mod.rs | 25 +++ .../batch/advanced_structure/v0/mod.rs | 30 ++++ .../state_transitions/batch/state/v0/mod.rs | 20 +++ .../contract/insert/insert_contract/v1/mod.rs | 11 +- .../v0/mod.rs | 102 +++++++++++- .../rs-drive/src/drive/tokens/freeze/mod.rs | 95 +++++++++++ .../src/drive/tokens/freeze/v0/mod.rs | 148 ++++++++++++++++++ packages/rs-drive/src/drive/tokens/mod.rs | 2 + .../system/create_token_trees/v0/mod.rs | 22 ++- .../rs-drive/src/drive/tokens/unfreeze/mod.rs | 95 +++++++++++ .../src/drive/tokens/unfreeze/v0/mod.rs | 148 ++++++++++++++++++ .../batch/batch_transition.rs | 10 +- .../batch/document_create_transition.rs | 6 +- .../batch/document_delete_transition.rs | 6 +- .../batch/document_purchase_transition.rs | 6 +- .../batch/document_replace_transition.rs | 6 +- .../batch/document_transfer_transition.rs | 6 +- .../batch/document_transition.rs | 18 +-- .../batch/document_update_price_transition.rs | 6 +- .../batch/documents_batch_transition.rs | 4 +- .../action_convert_to_operations/batch/mod.rs | 6 +- .../batch/token_burn_transition.rs | 6 +- .../batch/token_freeze_transition.rs | 105 +++++++++++++ .../batch/token_mint_transition.rs | 6 +- .../batch/token_transfer_transition.rs | 6 +- .../batch/token_transition.rs | 16 +- .../batch/token_unfreeze_transition.rs | 107 +++++++++++++ .../v0/transformer.rs | 1 - .../v0/transformer.rs | 1 - .../v0/mod.rs | 2 +- .../src/util/batch/drive_op_batch/token.rs | 48 +++++- .../v0/mod.rs | 2 +- .../grove_apply_operation/v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../grove_batch_operations_costs/v0/mod.rs | 2 +- .../grove_operations/grove_clear/v0/mod.rs | 2 +- .../grove_operations/grove_delete/v0/mod.rs | 2 +- .../util/grove_operations/grove_get/v0/mod.rs | 2 +- .../grove_get_path_query/v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../grove_get_proved_path_query/v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../grove_operations/grove_get_raw/v0/mod.rs | 2 +- .../grove_get_raw_optional/v0/mod.rs | 2 +- .../grove_get_raw_optional_item/mod.rs | 59 +++++++ .../grove_get_raw_optional_item/v0/mod.rs | 84 ++++++++++ .../grove_get_raw_path_query/v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../grove_operations/grove_insert/v0/mod.rs | 2 +- .../grove_insert_empty_sum_tree/v0/mod.rs | 2 +- .../grove_insert_empty_tree/v0/mod.rs | 2 +- .../grove_insert_if_not_exists/v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../rs-drive/src/util/grove_operations/mod.rs | 2 + .../apply_batch_grovedb_operations/v0/mod.rs | 2 +- .../dpp_versions/dpp_token_versions/mod.rs | 8 + .../dpp_versions/dpp_token_versions/v1.rs | 5 + .../src/version/dpp_versions/mod.rs | 3 + .../drive_abci_validation_versions/mod.rs | 4 + .../drive_abci_validation_versions/v1.rs | 4 + .../drive_abci_validation_versions/v2.rs | 4 + .../drive_abci_validation_versions/v3.rs | 4 + .../drive_abci_validation_versions/v4.rs | 4 + .../drive_grove_method_versions/mod.rs | 1 + .../drive_grove_method_versions/v1.rs | 1 + .../mod.rs | 2 + .../v1.rs | 2 + .../drive_token_method_versions/mod.rs | 2 + .../drive_token_method_versions/v1.rs | 2 + .../src/version/mocks/v2_test.rs | 2 + .../src/version/mocks/v3_test.rs | 2 + .../rs-platform-version/src/version/v1.rs | 2 + .../rs-platform-version/src/version/v2.rs | 2 + .../rs-platform-version/src/version/v3.rs | 2 + .../rs-platform-version/src/version/v4.rs | 2 + .../rs-platform-version/src/version/v5.rs | 2 + .../rs-platform-version/src/version/v6.rs | 2 + .../rs-platform-version/src/version/v7.rs | 2 + .../rs-platform-version/src/version/v8.rs | 2 + .../v1/token-history-contract-documents.json | 17 +- 94 files changed, 1698 insertions(+), 99 deletions(-) create mode 100644 packages/rs-dpp/src/tokens/info/methods.rs create mode 100644 packages/rs-dpp/src/tokens/info/mod.rs create mode 100644 packages/rs-dpp/src/tokens/info/v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/freeze/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/unfreeze/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs create mode 100644 packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/v0/mod.rs create mode 100644 packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/mod.rs create mode 100644 packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/v1.rs diff --git a/packages/rs-dpp/src/tokens/info/methods.rs b/packages/rs-dpp/src/tokens/info/methods.rs new file mode 100644 index 00000000000..09884a8ab61 --- /dev/null +++ b/packages/rs-dpp/src/tokens/info/methods.rs @@ -0,0 +1,16 @@ +use crate::tokens::info::v0::IdentityTokenInfoV0Accessors; +use crate::tokens::info::IdentityTokenInfo; + +impl IdentityTokenInfoV0Accessors for IdentityTokenInfo { + fn frozen(&self) -> bool { + match self { + IdentityTokenInfo::V0(info) => info.frozen, + } + } + + fn set_frozen(&mut self, frozen: bool) { + match self { + IdentityTokenInfo::V0(info) => info.set_frozen(frozen), + } + } +} diff --git a/packages/rs-dpp/src/tokens/info/mod.rs b/packages/rs-dpp/src/tokens/info/mod.rs new file mode 100644 index 00000000000..ccf211d4404 --- /dev/null +++ b/packages/rs-dpp/src/tokens/info/mod.rs @@ -0,0 +1,44 @@ +use crate::tokens::info::v0::IdentityTokenInfoV0; +use crate::ProtocolError; +use bincode::Encode; +use derive_more::From; +use platform_serialization::de::Decode; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_version::version::PlatformVersion; +use platform_versioning::PlatformVersioned; + +mod methods; +pub mod v0; + +#[derive( + Debug, + Clone, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PlatformVersioned, + From, + PartialEq, +)] +#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version +pub enum IdentityTokenInfo { + V0(IdentityTokenInfoV0), +} + +impl IdentityTokenInfo { + pub fn new(frozen: bool, platform_version: &PlatformVersion) -> Result { + match platform_version + .dpp + .token_versions + .identity_token_info_default_structure_version + { + 0 => Ok(IdentityTokenInfo::V0(IdentityTokenInfoV0 { frozen })), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "IdentityTokenInfo::new".to_string(), + known_versions: vec![0], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/tokens/info/v0/mod.rs b/packages/rs-dpp/src/tokens/info/v0/mod.rs new file mode 100644 index 00000000000..2fa6f5e3106 --- /dev/null +++ b/packages/rs-dpp/src/tokens/info/v0/mod.rs @@ -0,0 +1,26 @@ +use bincode::{Decode, Encode}; +use derive_more::From; + +#[derive(Debug, Clone, Encode, Decode, From, PartialEq)] +/// Token information for an identity (version 0). +pub struct IdentityTokenInfoV0 { + pub frozen: bool, +} + +pub trait IdentityTokenInfoV0Accessors { + /// Gets the frozen state of the identity. + fn frozen(&self) -> bool; + + /// Sets the frozen state of the identity. + fn set_frozen(&mut self, frozen: bool); +} + +impl IdentityTokenInfoV0Accessors for IdentityTokenInfoV0 { + fn frozen(&self) -> bool { + self.frozen + } + + fn set_frozen(&mut self, frozen: bool) { + self.frozen = frozen; + } +} diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs index c9d7ace1187..1c0cc2094ef 100644 --- a/packages/rs-dpp/src/tokens/mod.rs +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -3,7 +3,9 @@ use crate::util::hash::hash_double; pub mod allowed_currency; pub mod errors; +pub mod info; pub mod token_event; + pub fn calculate_token_id(contract_id: &[u8; 32], token_pos: TokenContractPosition) -> [u8; 32] { let mut bytes = b"dash_token".to_vec(); bytes.extend_from_slice(contract_id); diff --git a/packages/rs-dpp/src/tokens/token_event.rs b/packages/rs-dpp/src/tokens/token_event.rs index d21734fbf05..b38f7646630 100644 --- a/packages/rs-dpp/src/tokens/token_event.rs +++ b/packages/rs-dpp/src/tokens/token_event.rs @@ -16,6 +16,7 @@ pub type TokenEventPersonalEncryptedNote = Option<( use crate::ProtocolError; pub type RecipientIdentifier = Identifier; +pub type FrozenIdentifier = Identifier; #[derive( Debug, PartialEq, PartialOrd, Clone, Eq, Encode, Decode, PlatformDeserialize, PlatformSerialize, @@ -24,6 +25,8 @@ pub type RecipientIdentifier = Identifier; pub enum TokenEvent { Mint(TokenAmount, RecipientIdentifier, TokenEventPublicNote), Burn(TokenAmount, TokenEventPublicNote), + Freeze(FrozenIdentifier, TokenEventPublicNote), + Unfreeze(FrozenIdentifier, TokenEventPublicNote), Transfer( RecipientIdentifier, TokenEventPublicNote, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs index 7e620c15723..034c8d387b3 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs @@ -6,5 +6,7 @@ pub(crate) mod document_transfer_transition_action; pub(crate) mod document_update_price_transition_action; pub(crate) mod token_base_transition_action; pub(crate) mod token_burn_transition_action; +pub(crate) mod token_freeze_transition_action; pub(crate) mod token_mint_transition_action; pub(crate) mod token_transfer_transition_action; +pub(crate) mod token_unfreeze_transition_action; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs new file mode 100644 index 00000000000..32489877b01 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs @@ -0,0 +1,86 @@ +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::TokenFreezeTransitionAction; +use dpp::version::PlatformVersion; +use drive::grovedb::TransactionArg; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::token_freeze_transition_action::state_v0::TokenFreezeTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_freeze_transition_action::structure_v0::TokenFreezeTransitionActionStructureValidationV0; +use crate::platform_types::platform::PlatformStateRef; + +mod state_v0; +mod structure_v0; + +pub trait TokenFreezeTransitionActionValidation { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result; + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} + +impl TokenFreezeTransitionActionValidation for TokenFreezeTransitionAction { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_freeze_transition_structure_validation + { + 0 => self.validate_structure_v0(platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenFreezeTransitionAction::validate_structure".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_freeze_transition_state_validation + { + 0 => self.validate_state_v0( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenFreezeTransitionAction::validate_state".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..4365b5c0ece --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs @@ -0,0 +1,81 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::state_error::StateError; +use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, UnauthorizedTokenActionError}; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::multi_identity_events::ActionTaker; +use dpp::prelude::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use drive::query::TransactionArg; +use crate::error::Error; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenFreezeTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenFreezeTransitionActionStateValidationV0 for TokenFreezeTransitionAction { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let validation_result = self.base().validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + + // Let's first check to see if we are authorized to perform this action + let contract = &self.data_contract_fetch_info_ref().contract; + let token_configuration = contract.expected_token_configuration(self.token_position())?; + let rules = token_configuration.freeze_rules(); + let main_control_group = token_configuration + .main_control_group() + .map(|position| contract.expected_group(position)) + .transpose()?; + + if !rules.can_make_change( + &contract.owner_id(), + main_control_group, + contract.groups(), + &ActionTaker::SingleIdentity(owner_id), + ) { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + owner_id, + "freeze".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )); + } + + Ok(SimpleConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs new file mode 100644 index 00000000000..e479bfb5b3f --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs @@ -0,0 +1,25 @@ +use dpp::validation::{SimpleConsensusValidationResult}; +use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use crate::error::Error; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; + +pub(super) trait TokenFreezeTransitionActionStructureValidationV0 { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenFreezeTransitionActionStructureValidationV0 for TokenFreezeTransitionAction { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result { + let validation_result = self.base().validate_structure(platform_version)?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + + Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs new file mode 100644 index 00000000000..7a645db08da --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs @@ -0,0 +1,86 @@ +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; +use dpp::version::PlatformVersion; +use drive::grovedb::TransactionArg; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::token_unfreeze_transition_action::state_v0::TokenUnfreezeTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_unfreeze_transition_action::structure_v0::TokenUnfreezeTransitionActionStructureValidationV0; +use crate::platform_types::platform::PlatformStateRef; + +mod state_v0; +mod structure_v0; + +pub trait TokenUnfreezeTransitionActionValidation { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result; + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} + +impl TokenUnfreezeTransitionActionValidation for TokenUnfreezeTransitionAction { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_unfreeze_transition_structure_validation + { + 0 => self.validate_structure_v0(platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenUnfreezeTransitionAction::validate_structure".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_unfreeze_transition_state_validation + { + 0 => self.validate_state_v0( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenUnfreezeTransitionAction::validate_state".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..7b25f1207d8 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs @@ -0,0 +1,80 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::state_error::StateError; +use dpp::consensus::state::token::UnauthorizedTokenActionError; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::multi_identity_events::ActionTaker; +use dpp::prelude::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use drive::query::TransactionArg; +use crate::error::Error; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenUnfreezeTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenUnfreezeTransitionActionStateValidationV0 for TokenUnfreezeTransitionAction { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let validation_result = self.base().validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + + // Let's first check to see if we are authorized to perform this action + let contract = &self.data_contract_fetch_info_ref().contract; + let token_configuration = contract.expected_token_configuration(self.token_position())?; + let rules = token_configuration.unfreeze_rules(); + let main_control_group = token_configuration + .main_control_group() + .map(|position| contract.expected_group(position)) + .transpose()?; + + if !rules.can_make_change( + &contract.owner_id(), + main_control_group, + contract.groups(), + &ActionTaker::SingleIdentity(owner_id), + ) { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + owner_id, + "unfreeze".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )); + } + + Ok(SimpleConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs new file mode 100644 index 00000000000..de5082315af --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs @@ -0,0 +1,25 @@ +use dpp::validation::{SimpleConsensusValidationResult}; +use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use crate::error::Error; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; + +pub(super) trait TokenUnfreezeTransitionActionStructureValidationV0 { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenUnfreezeTransitionActionStructureValidationV0 for TokenUnfreezeTransitionAction { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result { + let validation_result = self.base().validate_structure(platform_version)?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + + Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs index 418710d0e4b..f9b57453f79 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs @@ -28,8 +28,10 @@ use drive::state_transition_action::document::documents_batch::document_transiti use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentReplaceTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::TokenFreezeTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; +use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionActionAccessorsV0; use drive::state_transition_action::StateTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::execution::ExecutionError; @@ -39,8 +41,10 @@ use crate::execution::validation::state_transition::batch::action_validation::do use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_burn_transition_action::TokenBurnTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_freeze_transition_action::TokenFreezeTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_mint_transition_action::TokenMintTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_transfer_transition_action::TokenTransferTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_unfreeze_transition_action::TokenUnfreezeTransitionActionValidation; pub(in crate::execution::validation::state_transition::state_transitions::batch) trait DocumentsBatchStateTransitionStructureValidationV0 { @@ -254,6 +258,32 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(transfer_action.base(), self.owner_id(), self.user_fee_increase()), ); + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + TokenTransitionAction::FreezeAction(freeze_action) => { + let result = freeze_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(freeze_action.base(), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + TokenTransitionAction::UnfreezeAction(unfreeze_action) => { + let result = unfreeze_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(unfreeze_action.base(), self.owner_id(), self.user_fee_increase()), + ); + return Ok(ConsensusValidationResult::new_with_data_and_errors( bump_action, result.errors, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs index 0410814b376..b8433767715 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs @@ -20,8 +20,10 @@ use crate::execution::validation::state_transition::batch::action_validation::do use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_burn_transition_action::TokenBurnTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_freeze_transition_action::TokenFreezeTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_mint_transition_action::TokenMintTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_transfer_transition_action::TokenTransferTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_unfreeze_transition_action::TokenUnfreezeTransitionActionValidation; use crate::execution::validation::state_transition::batch::data_triggers::{data_trigger_bindings_list, DataTriggerExecutionContext, DataTriggerExecutor}; use crate::platform_types::platform::{PlatformStateRef}; use crate::execution::validation::state_transition::state_transitions::batch::transformer::v0::BatchTransitionTransformerV0; @@ -164,6 +166,24 @@ impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { transaction, platform_version, )?, + TokenTransitionAction::FreezeAction(freeze_action) => freeze_action + .validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, + TokenTransitionAction::UnfreezeAction(unfreeze_action) => unfreeze_action + .validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, }, BatchedTransitionAction::BumpIdentityDataContractNonce(_) => { return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs index e0f615f470f..9d5c2536108 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs @@ -12,6 +12,7 @@ use dpp::fee::fee_result::FeeResult; use crate::drive::balances::total_tokens_root_supply_path_vec; use crate::drive::tokens::{ token_balances_path_vec, token_path, tokens_root_path, TOKEN_BALANCES_KEY, + TOKEN_IDENTITY_INFO_KEY, }; use crate::error::contract::DataContractError; use crate::util::object_size_info::DriveKeyInfo; @@ -203,7 +204,7 @@ impl Drive { &platform_version.drive, )?; - self.batch_insert_empty_tree( + self.batch_insert_empty_sum_tree( token_path(&token_id_bytes), DriveKeyInfo::Key(vec![TOKEN_BALANCES_KEY]), None, @@ -211,6 +212,14 @@ impl Drive { &platform_version.drive, )?; + self.batch_insert_empty_tree( + token_path(&token_id_bytes), + DriveKeyInfo::Key(vec![TOKEN_IDENTITY_INFO_KEY]), + None, + &mut batch_operations, + &platform_version.drive, + )?; + let path_holding_total_token_supply = total_tokens_root_supply_path_vec(); if token_config.base_supply() > 0 { diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs index 185da14ed49..4e124f93405 100644 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs @@ -61,7 +61,7 @@ impl Drive { created_at_block_height: Some(block_info.height), updated_at_block_height: None, transferred_at_block_height: None, - created_at_core_block_height: Some(block_info.core_height), + created_at_core_block_height: None, updated_at_core_block_height: None, transferred_at_core_block_height: None, } @@ -109,7 +109,7 @@ impl Drive { created_at_block_height: Some(block_info.height), updated_at_block_height: None, transferred_at_block_height: None, - created_at_core_block_height: Some(block_info.core_height), + created_at_core_block_height: None, updated_at_core_block_height: None, transferred_at_core_block_height: None, } @@ -185,7 +185,103 @@ impl Drive { created_at_block_height: Some(block_info.height), updated_at_block_height: None, transferred_at_block_height: None, - created_at_core_block_height: Some(block_info.core_height), + created_at_core_block_height: None, + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + operations = self.add_document_for_contract_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentOwnedInfo((document, None)), + owner_id: Some(owner_id.to_buffer()), + }, + contract: &contract, + document_type, + }, + true, + block_info, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + } + TokenEvent::Freeze(frozen_identity_id, public_note) => { + let document_type = contract.document_type_for_name("frozen")?; + let document_id = Document::generate_document_id_v0( + &contract.id(), + &owner_id, + "frozen", + owner_nonce.to_be_bytes().as_slice(), + ); + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("frozenIdentityId".to_string(), frozen_identity_id.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + let document: Document = DocumentV0 { + id: document_id, + owner_id, + properties, + revision: None, + created_at: Some(block_info.time_ms), + updated_at: None, + transferred_at: None, + created_at_block_height: Some(block_info.height), + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: None, + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + operations = self.add_document_for_contract_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentOwnedInfo((document, None)), + owner_id: Some(owner_id.to_buffer()), + }, + contract: &contract, + document_type, + }, + true, + block_info, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + } + TokenEvent::Unfreeze(frozen_identity_id, public_note) => { + let document_type = contract.document_type_for_name("unfrozen")?; + let document_id = Document::generate_document_id_v0( + &contract.id(), + &owner_id, + "unfrozen", + owner_nonce.to_be_bytes().as_slice(), + ); + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("frozenIdentityId".to_string(), frozen_identity_id.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + let document: Document = DocumentV0 { + id: document_id, + owner_id, + properties, + revision: None, + created_at: Some(block_info.time_ms), + updated_at: None, + transferred_at: None, + created_at_block_height: Some(block_info.height), + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: None, updated_at_core_block_height: None, transferred_at_core_block_height: None, } diff --git a/packages/rs-drive/src/drive/tokens/freeze/mod.rs b/packages/rs-drive/src/drive/tokens/freeze/mod.rs new file mode 100644 index 00000000000..d2339bd4c87 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/freeze/mod.rs @@ -0,0 +1,95 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::Identifier; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Burns tokens by reducing the total supply and removing them from an identity's balance. + pub fn token_freeze( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version.drive.methods.token.update.freeze { + 0 => self.token_freeze_v0( + token_id, + frozen_identity_id, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_freeze".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds the operations to freeze tokens without calculating fees and optionally applying. + pub fn token_freeze_add_to_operations( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version.drive.methods.token.update.freeze { + 0 => self.token_freeze_add_to_operations_v0( + token_id, + frozen_identity_id, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_freeze_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Gathers the operations needed to freeze tokens. + pub fn token_freeze_operations( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.update.freeze { + 0 => self.token_freeze_operations_v0( + token_id, + frozen_identity_id, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_freeze_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs b/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs new file mode 100644 index 00000000000..5b7acf9597a --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs @@ -0,0 +1,148 @@ +use crate::drive::tokens::{token_identity_infos_path, token_identity_infos_path_vec}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::identifier::Identifier; +use dpp::serialization::{PlatformDeserializable, PlatformSerializable}; +use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; +use dpp::tokens::info::IdentityTokenInfo; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, Element, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + pub(super) fn token_freeze_v0( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations = vec![]; + + self.token_freeze_add_to_operations_v0( + token_id, + frozen_identity_id, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + pub(super) fn token_freeze_add_to_operations_v0( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + if apply { None } else { Some(HashMap::new()) }; + + let batch_operations = self.token_freeze_operations_v0( + token_id, + frozen_identity_id, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + pub(super) fn token_freeze_operations_v0( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { + Self::add_estimation_costs_for_token_balances( + token_id.to_buffer(), + true, + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + } + + // no estimated_costs_only_with_layer_info, means we want to apply to state + let direct_query_type = if estimated_costs_only_with_layer_info.is_none() { + DirectQueryType::StatefulDirectQuery + } else { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums: false, + query_target: QueryTargetValue(8), + } + }; + + let token_info_path = token_identity_infos_path(token_id.as_bytes()); + match self + .grove_get_raw_optional_item( + (&token_info_path).into(), + frozen_identity_id.as_slice(), + direct_query_type, + transaction, + &mut drive_operations, + &platform_version.drive, + )? + .map(|bytes| IdentityTokenInfo::deserialize_from_bytes(&bytes)) + .transpose()? + { + None => { + let identity_token_info_bytes = + IdentityTokenInfo::new(true, platform_version)?.serialize_consume_to_bytes()?; + drive_operations.push(LowLevelDriveOperation::insert_for_known_path_key_element( + token_info_path.iter().map(|a| a.to_vec()).collect(), + frozen_identity_id.to_vec(), + Element::new_item(identity_token_info_bytes), + )); + } + Some(mut token_info) => { + if !token_info.frozen() { + token_info.set_frozen(true); + let identity_token_info_bytes = token_info.serialize_consume_to_bytes()?; + drive_operations.push( + LowLevelDriveOperation::replace_for_known_path_key_element( + token_info_path.iter().map(|a| a.to_vec()).collect(), + frozen_identity_id.to_vec(), + Element::new_item(identity_token_info_bytes), + ), + ); + } + } + }; + + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index ea27741ade7..64c1d16914c 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -4,9 +4,11 @@ mod add_transaction_history_operations; pub mod balance; pub mod burn; pub mod estimated_costs; +pub mod freeze; pub mod mint; pub mod system; pub mod transfer; +pub mod unfreeze; pub const TOKEN_IDENTITY_INFO_KEY: u8 = 64; pub const TOKEN_BALANCES_KEY: u8 = 128; diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs index c307cba91dc..c97bf6e3319 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs @@ -1,5 +1,7 @@ use crate::drive::balances::total_tokens_root_supply_path; -use crate::drive::tokens::{token_path, tokens_root_path, TOKEN_BALANCES_KEY}; +use crate::drive::tokens::{ + token_path, tokens_root_path, TOKEN_BALANCES_KEY, TOKEN_IDENTITY_INFO_KEY, +}; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; @@ -162,6 +164,24 @@ impl Drive { ))); } + let inserted = self.batch_insert_empty_tree_if_not_exists( + PathFixedSizeKey((token_path(&token_id), vec![TOKEN_IDENTITY_INFO_KEY])), + false, + None, + non_sum_tree_apply_type, + transaction, + &mut None, + &mut batch_operations, + &platform_version.drive, + )?; + + if !inserted && !allow_already_exists { + // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. + return Err(Error::Drive(DriveError::CorruptedDriveState( + "token info tree already exists".to_string(), + ))); + } + let inserted = self.batch_insert_empty_tree_if_not_exists( PathFixedSizeKey((total_tokens_root_supply_path(), token_id.to_vec())), false, diff --git a/packages/rs-drive/src/drive/tokens/unfreeze/mod.rs b/packages/rs-drive/src/drive/tokens/unfreeze/mod.rs new file mode 100644 index 00000000000..0e483c0c244 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/unfreeze/mod.rs @@ -0,0 +1,95 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::Identifier; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Burns tokens by reducing the total supply and removing them from an identity's balance. + pub fn token_unfreeze( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version.drive.methods.token.update.unfreeze { + 0 => self.token_unfreeze_v0( + token_id, + frozen_identity_id, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_unfreeze".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds the operations to unfreeze tokens without calculating fees and optionally applying. + pub fn token_unfreeze_add_to_operations( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version.drive.methods.token.update.unfreeze { + 0 => self.token_unfreeze_add_to_operations_v0( + token_id, + frozen_identity_id, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_unfreeze_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Gathers the operations needed to unfreeze tokens. + pub fn token_unfreeze_operations( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.update.unfreeze { + 0 => self.token_unfreeze_operations_v0( + token_id, + frozen_identity_id, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_unfreeze_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs b/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs new file mode 100644 index 00000000000..9ea87b8cead --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs @@ -0,0 +1,148 @@ +use crate::drive::tokens::{token_identity_infos_path, token_identity_infos_path_vec}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::identifier::Identifier; +use dpp::serialization::{PlatformDeserializable, PlatformSerializable}; +use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; +use dpp::tokens::info::IdentityTokenInfo; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, Element, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + pub(super) fn token_unfreeze_v0( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations = vec![]; + + self.token_unfreeze_add_to_operations_v0( + token_id, + frozen_identity_id, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + pub(super) fn token_unfreeze_add_to_operations_v0( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + if apply { None } else { Some(HashMap::new()) }; + + let batch_operations = self.token_unfreeze_operations_v0( + token_id, + frozen_identity_id, + &mut estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + pub(super) fn token_unfreeze_operations_v0( + &self, + token_id: Identifier, + frozen_identity_id: Identifier, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { + Self::add_estimation_costs_for_token_balances( + token_id.to_buffer(), + true, + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + } + + // no estimated_costs_only_with_layer_info, means we want to apply to state + let direct_query_type = if estimated_costs_only_with_layer_info.is_none() { + DirectQueryType::StatefulDirectQuery + } else { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums: false, + query_target: QueryTargetValue(8), + } + }; + + let token_info_path = token_identity_infos_path(token_id.as_bytes()); + match self + .grove_get_raw_optional_item( + (&token_info_path).into(), + frozen_identity_id.as_slice(), + direct_query_type, + transaction, + &mut drive_operations, + &platform_version.drive, + )? + .map(|bytes| IdentityTokenInfo::deserialize_from_bytes(&bytes)) + .transpose()? + { + None => { + let identity_token_info_bytes = IdentityTokenInfo::new(false, platform_version)? + .serialize_consume_to_bytes()?; + drive_operations.push(LowLevelDriveOperation::insert_for_known_path_key_element( + token_info_path.iter().map(|a| a.to_vec()).collect(), + frozen_identity_id.to_vec(), + Element::new_item(identity_token_info_bytes), + )); + } + Some(mut token_info) => { + if token_info.frozen() { + token_info.set_frozen(false); + let identity_token_info_bytes = token_info.serialize_consume_to_bytes()?; + drive_operations.push( + LowLevelDriveOperation::replace_for_known_path_key_element( + token_info_path.iter().map(|a| a.to_vec()).collect(), + frozen_identity_id.to_vec(), + Element::new_item(identity_token_info_bytes), + ), + ); + } + } + }; + + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs index d0534eb779b..42446fc81fe 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; use crate::util::batch::DriveOperation; @@ -7,8 +7,8 @@ use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; use dpp::version::PlatformVersion; -impl DriveHighLevelDocumentOperationConverter for BatchedTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for BatchedTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, epoch: &Epoch, owner_id: Identifier, @@ -16,9 +16,9 @@ impl DriveHighLevelDocumentOperationConverter for BatchedTransitionAction { ) -> Result>, Error> { match self { BatchedTransitionAction::DocumentAction(document_action) => document_action - .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + .into_high_level_batch_drive_operations(epoch, owner_id, platform_version), BatchedTransitionAction::TokenAction(token_action) => token_action - .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + .into_high_level_batch_drive_operations(epoch, owner_id, platform_version), BatchedTransitionAction::BumpIdentityDataContractNonce( bump_identity_contract_nonce_action, ) => bump_identity_contract_nonce_action diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs index 5b376c10fa5..ac885195648 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::util::batch::DriveOperation::{ DocumentOperation, IdentityOperation, PrefundedSpecializedBalanceOperation, }; @@ -19,8 +19,8 @@ use crate::util::batch::drive_op_batch::PrefundedSpecializedBalanceOperationType use crate::util::object_size_info::DataContractInfo::DataContractFetchInfo; use crate::error::drive::DriveError; -impl DriveHighLevelDocumentOperationConverter for DocumentCreateTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for DocumentCreateTransitionAction { + fn into_high_level_batch_drive_operations<'b>( mut self, epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs index cfaa9295314..a650a0b6c0b 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs @@ -1,4 +1,4 @@ -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; @@ -14,8 +14,8 @@ use dpp::version::PlatformVersion; use crate::util::object_size_info::{DataContractInfo, DocumentTypeInfo}; use crate::error::drive::DriveError; -impl DriveHighLevelDocumentOperationConverter for DocumentDeleteTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for DocumentDeleteTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, _epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs index 2b255b09207..aba3423feb7 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; @@ -14,8 +14,8 @@ use crate::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use crate::error::drive::DriveError; -impl DriveHighLevelDocumentOperationConverter for DocumentPurchaseTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for DocumentPurchaseTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs index 59339d16480..ca675812585 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; @@ -15,8 +15,8 @@ use crate::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use crate::error::drive::DriveError; -impl DriveHighLevelDocumentOperationConverter for DocumentReplaceTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for DocumentReplaceTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs index 991370d6716..0c96ca675c3 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; @@ -15,8 +15,8 @@ use crate::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use crate::error::drive::DriveError; -impl DriveHighLevelDocumentOperationConverter for DocumentTransferTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for DocumentTransferTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs index e8aacd5a148..6ccfa60a2c8 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs @@ -1,13 +1,13 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; use dpp::version::PlatformVersion; -impl DriveHighLevelDocumentOperationConverter for DocumentTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for DocumentTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, epoch: &Epoch, owner_id: Identifier, @@ -15,42 +15,42 @@ impl DriveHighLevelDocumentOperationConverter for DocumentTransitionAction { ) -> Result>, Error> { match self { DocumentTransitionAction::CreateAction(document_create_transition) => { - document_create_transition.into_high_level_document_drive_operations( + document_create_transition.into_high_level_batch_drive_operations( epoch, owner_id, platform_version, ) } DocumentTransitionAction::ReplaceAction(document_replace_transition) => { - document_replace_transition.into_high_level_document_drive_operations( + document_replace_transition.into_high_level_batch_drive_operations( epoch, owner_id, platform_version, ) } DocumentTransitionAction::DeleteAction(document_delete_transition) => { - document_delete_transition.into_high_level_document_drive_operations( + document_delete_transition.into_high_level_batch_drive_operations( epoch, owner_id, platform_version, ) } DocumentTransitionAction::TransferAction(document_transfer_transition) => { - document_transfer_transition.into_high_level_document_drive_operations( + document_transfer_transition.into_high_level_batch_drive_operations( epoch, owner_id, platform_version, ) } DocumentTransitionAction::PurchaseAction(document_purchase_transition) => { - document_purchase_transition.into_high_level_document_drive_operations( + document_purchase_transition.into_high_level_batch_drive_operations( epoch, owner_id, platform_version, ) } DocumentTransitionAction::UpdatePriceAction(document_update_price_transition) => { - document_update_price_transition.into_high_level_document_drive_operations( + document_update_price_transition.into_high_level_batch_drive_operations( epoch, owner_id, platform_version, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs index 14d33c2ea85..d37c3c44579 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs @@ -1,5 +1,5 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::util::batch::DriveOperation::{DocumentOperation, IdentityOperation}; use crate::util::batch::{DocumentOperationType, DriveOperation, IdentityOperationType}; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; @@ -14,8 +14,8 @@ use crate::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use crate::error::drive::DriveError; -impl DriveHighLevelDocumentOperationConverter for DocumentUpdatePriceTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for DocumentUpdatePriceTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs index cff9b3ffe7c..ab13600847c 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs @@ -1,6 +1,6 @@ use crate::error::drive::DriveError; use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; use crate::state_transition_action::document::documents_batch::BatchTransitionAction; use crate::util::batch::DriveOperation; @@ -26,7 +26,7 @@ impl DriveHighLevelOperationConverter for BatchTransitionAction { Ok(transitions .into_iter() .map(|transition| { - transition.into_high_level_document_drive_operations( + transition.into_high_level_batch_drive_operations( epoch, owner_id, platform_version, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs index 0c46a74bd61..e678ce38ffd 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs @@ -14,14 +14,16 @@ mod document_transition; mod document_update_price_transition; mod documents_batch_transition; mod token_burn_transition; +mod token_freeze_transition; mod token_mint_transition; mod token_transfer_transition; mod token_transition; +mod token_unfreeze_transition; /// A converter that will get High Level Drive Operations from State transitions -pub trait DriveHighLevelDocumentOperationConverter { +pub trait DriveHighLevelBatchOperationConverter { /// This will get a list of atomic drive operations from a high level operations - fn into_high_level_document_drive_operations<'a>( + fn into_high_level_batch_drive_operations<'a>( self, epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs index d2aa44d2d4b..414358e6b2a 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs @@ -9,15 +9,15 @@ use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; -impl DriveHighLevelDocumentOperationConverter for TokenBurnTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for TokenBurnTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, _epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs new file mode 100644 index 00000000000..db421686b1d --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs @@ -0,0 +1,105 @@ +use dpp::block::epoch::Epoch; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::group::action_event::GroupActionEvent; +use dpp::group::group_action::GroupAction; +use dpp::group::group_action::v0::GroupActionV0; +use dpp::group::GroupStateTransitionResolvedInfo; +use dpp::identifier::Identifier; +use dpp::tokens::token_event::TokenEvent; +use platform_version::version::PlatformVersion; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use crate::util::batch::{DriveOperation, IdentityOperationType}; +use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; +use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; + +impl DriveHighLevelBatchOperationConverter for TokenFreezeTransitionAction { + fn into_high_level_batch_drive_operations<'b>( + self, + _epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .state_transitions + .convert_to_high_level_operations + .token_freeze_transition + { + 0 => { + let data_contract_id = self.base().data_contract_id(); + + let identity_contract_nonce = self.base().identity_contract_nonce(); + + let mut ops = vec![IdentityOperation( + IdentityOperationType::UpdateIdentityContractNonce { + identity_id: owner_id.into_buffer(), + contract_id: data_contract_id.into_buffer(), + nonce: identity_contract_nonce, + }, + )]; + + if let Some(GroupStateTransitionResolvedInfo { + group_contract_position, + action_id, + action_is_proposer, + signer_power, + .. + }) = self.base().store_in_group() + { + let event = + TokenEvent::Freeze(self.frozen_identity_id(), self.public_note().cloned()); + + let initialize_with_insert_action_info = if *action_is_proposer { + Some(GroupAction::V0(GroupActionV0 { + event: GroupActionEvent::TokenEvent(event), + })) + } else { + None + }; + + ops.push(GroupOperation(GroupOperationType::AddGroupAction { + contract_id: data_contract_id, + group_contract_position: *group_contract_position, + initialize_with_insert_action_info, + action_id: *action_id, + signer_identity_id: owner_id, + signer_power: *signer_power, + })); + } + + if self.base().perform_action() { + ops.push(TokenOperation(TokenOperationType::TokenFreeze { + token_id: self.token_id(), + frozen_identity_id: self.frozen_identity_id(), + })); + + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Freeze( + self.frozen_identity_id(), + self.public_note_owned(), + ), + })); + } + } + + Ok(ops) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "TokenFreezeTransitionAction::into_high_level_document_drive_operations" + .to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs index 632cba76a33..2b267bc11e1 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs @@ -9,15 +9,15 @@ use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; -impl DriveHighLevelDocumentOperationConverter for TokenMintTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for TokenMintTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, _epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs index 9b62d28c0d6..360eab00d1a 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs @@ -5,7 +5,7 @@ use dpp::tokens::token_event::TokenEvent; use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; @@ -13,8 +13,8 @@ use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::TokenOperationType; use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; -impl DriveHighLevelDocumentOperationConverter for TokenTransferTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for TokenTransferTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, _epoch: &Epoch, owner_id: Identifier, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs index 5753e67384f..7edd6280bbb 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs @@ -1,13 +1,13 @@ use crate::error::Error; -use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelDocumentOperationConverter; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::document::documents_batch::document_transition::TokenTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; use dpp::version::PlatformVersion; -impl DriveHighLevelDocumentOperationConverter for TokenTransitionAction { - fn into_high_level_document_drive_operations<'b>( +impl DriveHighLevelBatchOperationConverter for TokenTransitionAction { + fn into_high_level_batch_drive_operations<'b>( self, epoch: &Epoch, owner_id: Identifier, @@ -15,20 +15,20 @@ impl DriveHighLevelDocumentOperationConverter for TokenTransitionAction { ) -> Result>, Error> { match self { TokenTransitionAction::BurnAction(token_burn_transition) => token_burn_transition - .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + .into_high_level_batch_drive_operations(epoch, owner_id, platform_version), TokenTransitionAction::MintAction(token_mint_transition) => token_mint_transition - .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + .into_high_level_batch_drive_operations(epoch, owner_id, platform_version), TokenTransitionAction::TransferAction(token_transfer_transition) => { - token_transfer_transition.into_high_level_document_drive_operations( + token_transfer_transition.into_high_level_batch_drive_operations( epoch, owner_id, platform_version, ) } TokenTransitionAction::FreezeAction(token_freeze_action) => token_freeze_action - .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + .into_high_level_batch_drive_operations(epoch, owner_id, platform_version), TokenTransitionAction::UnfreezeAction(token_unfreeze_action) => token_unfreeze_action - .into_high_level_document_drive_operations(epoch, owner_id, platform_version), + .into_high_level_batch_drive_operations(epoch, owner_id, platform_version), } } } diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs new file mode 100644 index 00000000000..87a44c1895e --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs @@ -0,0 +1,107 @@ +use dpp::block::epoch::Epoch; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::group::action_event::GroupActionEvent; +use dpp::group::group_action::GroupAction; +use dpp::group::group_action::v0::GroupActionV0; +use dpp::group::GroupStateTransitionResolvedInfo; +use dpp::identifier::Identifier; +use dpp::tokens::token_event::TokenEvent; +use platform_version::version::PlatformVersion; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; +use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use crate::util::batch::{DriveOperation, IdentityOperationType}; +use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; +use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; + +impl DriveHighLevelBatchOperationConverter for TokenUnfreezeTransitionAction { + fn into_high_level_batch_drive_operations<'b>( + self, + _epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .state_transitions + .convert_to_high_level_operations + .token_unfreeze_transition + { + 0 => { + let data_contract_id = self.base().data_contract_id(); + + let identity_contract_nonce = self.base().identity_contract_nonce(); + + let mut ops = vec![IdentityOperation( + IdentityOperationType::UpdateIdentityContractNonce { + identity_id: owner_id.into_buffer(), + contract_id: data_contract_id.into_buffer(), + nonce: identity_contract_nonce, + }, + )]; + + if let Some(GroupStateTransitionResolvedInfo { + group_contract_position, + action_id, + action_is_proposer, + signer_power, + .. + }) = self.base().store_in_group() + { + let event = TokenEvent::Unfreeze( + self.frozen_identity_id(), + self.public_note().cloned(), + ); + + let initialize_with_insert_action_info = if *action_is_proposer { + Some(GroupAction::V0(GroupActionV0 { + event: GroupActionEvent::TokenEvent(event), + })) + } else { + None + }; + + ops.push(GroupOperation(GroupOperationType::AddGroupAction { + contract_id: data_contract_id, + group_contract_position: *group_contract_position, + initialize_with_insert_action_info, + action_id: *action_id, + signer_identity_id: owner_id, + signer_power: *signer_power, + })); + } + + if self.base().perform_action() { + ops.push(TokenOperation(TokenOperationType::TokenUnfreeze { + token_id: self.token_id(), + frozen_identity_id: self.frozen_identity_id(), + })); + + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::Freeze( + self.frozen_identity_id(), + self.public_note_owned(), + ), + })); + } + } + + Ok(ops) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "TokenUnfreezeTransitionAction::into_high_level_document_drive_operations" + .to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs index 56e360d3d35..737d800cfb2 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs @@ -4,7 +4,6 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_freeze_transition::v0::TokenFreezeTransitionV0; use dpp::ProtocolError; -use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::v0::TokenFreezeTransitionActionV0; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs index 328f0e44ba0..f3842553426 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs @@ -4,7 +4,6 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_unfreeze_transition::v0::TokenUnfreezeTransitionV0; use dpp::ProtocolError; -use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::v0::TokenUnfreezeTransitionActionV0; diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/drive_methods/convert_drive_operations_to_grove_operations/v0/mod.rs b/packages/rs-drive/src/util/batch/drive_op_batch/drive_methods/convert_drive_operations_to_grove_operations/v0/mod.rs index de4fecc4c41..0b719f85d48 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/drive_methods/convert_drive_operations_to_grove_operations/v0/mod.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/drive_methods/convert_drive_operations_to_grove_operations/v0/mod.rs @@ -30,7 +30,7 @@ impl Drive { /// Returns a `Result` containing a `GroveDbOpBatch` with transformed grove database operations, /// or an error if any step in the conversion process fails. #[inline(always)] - pub(crate) fn convert_drive_operations_to_grove_operations_v0( + pub(super) fn convert_drive_operations_to_grove_operations_v0( &self, drive_batch_operations: Vec, block_info: &BlockInfo, diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index 3c45712d71e..b0357018ad2 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -15,7 +15,7 @@ use std::collections::HashMap; /// Operations on Tokens #[derive(Clone, Debug)] pub enum TokenOperationType { - /// Burns token from the account issuing the . + /// Burns token from the account issuing the action. TokenBurn { /// The token id token_id: Identifier, @@ -24,7 +24,7 @@ pub enum TokenOperationType { /// The amount to burn burn_amount: TokenAmount, }, - /// Adds a document to a contract matching the desired info. + /// Mints tokens TokenMint { /// The token id token_id: Identifier, @@ -35,7 +35,7 @@ pub enum TokenOperationType { /// Should we allow this to be the first ever mint allow_first_mint: bool, }, - /// Adds a document to a contract matching the desired info. + /// Performs a token transfer TokenTransfer { /// The token id token_id: Identifier, @@ -46,7 +46,21 @@ pub enum TokenOperationType { /// The amount to transfer amount: TokenAmount, }, - /// Adds a document to a contract matching the desired info. + /// Freezes an identity's token balance so money can no longer be sent out. + TokenFreeze { + /// The token id + token_id: Identifier, + /// The frozen identity id + frozen_identity_id: Identifier, + }, + /// Unfreezes an identity's token balance so money can be sent out again. + TokenUnfreeze { + /// The token id + token_id: Identifier, + /// The frozen identity id + frozen_identity_id: Identifier, + }, + /// Adds a historical document explaining a token action. TokenHistory { /// The token id token_id: Identifier, @@ -146,6 +160,32 @@ impl DriveLowLevelOperationConverter for TokenOperationType { )?; Ok(batch_operations) } + TokenOperationType::TokenFreeze { + token_id, + frozen_identity_id, + } => { + let batch_operations = drive.token_freeze_operations( + token_id, + frozen_identity_id, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + Ok(batch_operations) + } + TokenOperationType::TokenUnfreeze { + token_id, + frozen_identity_id, + } => { + let batch_operations = drive.token_unfreeze_operations( + token_id, + frozen_identity_id, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + Ok(batch_operations) + } } } } diff --git a/packages/rs-drive/src/util/grove_operations/grove_apply_batch_with_add_costs/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_apply_batch_with_add_costs/v0/mod.rs index c0afbdaa794..3c212ba5440 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_apply_batch_with_add_costs/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_apply_batch_with_add_costs/v0/mod.rs @@ -13,7 +13,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Applies the given groveDB operations batch and gets and passes the costs to `push_drive_operation_result`. - pub(crate) fn grove_apply_batch_with_add_costs_v0( + pub(super) fn grove_apply_batch_with_add_costs_v0( &self, ops: GroveDbOpBatch, validate: bool, diff --git a/packages/rs-drive/src/util/grove_operations/grove_apply_operation/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_apply_operation/v0/mod.rs index dbbb7613493..9bb4ab95c48 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_apply_operation/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_apply_operation/v0/mod.rs @@ -7,7 +7,7 @@ use grovedb::TransactionArg; impl Drive { /// Applies the given groveDB operation - pub(crate) fn grove_apply_operation_v0( + pub(super) fn grove_apply_operation_v0( &self, operation: QualifiedGroveDbOp, validate: bool, diff --git a/packages/rs-drive/src/util/grove_operations/grove_apply_partial_batch_with_add_costs/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_apply_partial_batch_with_add_costs/v0/mod.rs index a734e406dba..9d7a6bc8eba 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_apply_partial_batch_with_add_costs/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_apply_partial_batch_with_add_costs/v0/mod.rs @@ -16,7 +16,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Applies the given groveDB operations batch and gets and passes the costs to `push_drive_operation_result`. - pub(crate) fn grove_apply_partial_batch_with_add_costs_v0( + pub(super) fn grove_apply_partial_batch_with_add_costs_v0( &self, ops: GroveDbOpBatch, validate: bool, diff --git a/packages/rs-drive/src/util/grove_operations/grove_batch_operations_costs/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_batch_operations_costs/v0/mod.rs index 146db3487e4..fb1f867e8d0 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_batch_operations_costs/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_batch_operations_costs/v0/mod.rs @@ -12,7 +12,7 @@ use std::collections::HashMap; impl Drive { /// Gets the costs for the given groveDB op batch and passes them to `push_drive_operation_result`. - pub(crate) fn grove_batch_operations_costs_v0( + pub(super) fn grove_batch_operations_costs_v0( &self, ops: GroveDbOpBatch, estimated_layer_info: HashMap, diff --git a/packages/rs-drive/src/util/grove_operations/grove_clear/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_clear/v0/mod.rs index ad3152f8957..e1de93ec3a9 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_clear/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_clear/v0/mod.rs @@ -7,7 +7,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Pushes the `OperationCost` of deleting an element in groveDB to `drive_operations`. - pub(crate) fn grove_clear_v0>( + pub(super) fn grove_clear_v0>( &self, path: SubtreePath<'_, B>, transaction: TransactionArg, diff --git a/packages/rs-drive/src/util/grove_operations/grove_delete/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_delete/v0/mod.rs index 13c8a0776eb..d5e0c2ab1e2 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_delete/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_delete/v0/mod.rs @@ -9,7 +9,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Pushes the `OperationCost` of deleting an element in groveDB to `drive_operations`. - pub(crate) fn grove_delete_v0>( + pub(super) fn grove_delete_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_get/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get/v0/mod.rs index c5d473ea6d2..9171ff9b9a1 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get/v0/mod.rs @@ -13,7 +13,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Gets the element at the given path from groveDB. /// Pushes the `OperationCost` of getting the element to `drive_operations`. - pub(crate) fn grove_get_v0>( + pub(super) fn grove_get_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_path_query/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_path_query/v0/mod.rs index 9997184f5fa..80a48f05095 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_path_query/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_path_query/v0/mod.rs @@ -10,7 +10,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Gets the return value and the cost of a groveDB path query. /// Pushes the cost to `drive_operations` and returns the return value. - pub(crate) fn grove_get_path_query_v0( + pub(super) fn grove_get_path_query_v0( &self, path_query: &PathQuery, transaction: TransactionArg, diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_path_query_serialized_or_sum_results/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_path_query_serialized_or_sum_results/v0/mod.rs index 18753f813b3..56625e4b2fb 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_path_query_serialized_or_sum_results/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_path_query_serialized_or_sum_results/v0/mod.rs @@ -10,7 +10,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Gets the return value and the cost of a groveDB path query. /// Pushes the cost to `drive_operations` and returns the return value. - pub(crate) fn grove_get_path_query_serialized_or_sum_results_v0( + pub(super) fn grove_get_path_query_serialized_or_sum_results_v0( &self, path_query: &PathQuery, transaction: TransactionArg, diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_path_query_serialized_results/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_path_query_serialized_results/v0/mod.rs index 584f36d4d63..cb584854876 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_path_query_serialized_results/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_path_query_serialized_results/v0/mod.rs @@ -9,7 +9,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Gets the return value and the cost of a groveDB path query. /// Pushes the cost to `drive_operations` and returns the return value. - pub(crate) fn grove_get_path_query_serialized_results_v0( + pub(super) fn grove_get_path_query_serialized_results_v0( &self, path_query: &PathQuery, transaction: TransactionArg, diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_path_query_with_optional/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_path_query_with_optional/v0/mod.rs index bd914b73b8d..4ee57d66e8d 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_path_query_with_optional/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_path_query_with_optional/v0/mod.rs @@ -10,7 +10,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Gets the return value and the cost of a groveDB path query. /// Pushes the cost to `drive_operations` and returns the return value. - pub(crate) fn grove_get_path_query_with_optional_v0( + pub(super) fn grove_get_path_query_with_optional_v0( &self, path_query: &PathQuery, transaction: TransactionArg, diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_proved_path_query/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_proved_path_query/v0/mod.rs index 3b9a9614a5f..ecc4d49907d 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_proved_path_query/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_proved_path_query/v0/mod.rs @@ -11,7 +11,7 @@ impl Drive { /// Pushes the cost to `drive_operations` and returns the return value. /// Verbose should be generally set to false unless one needs to prove /// subsets of a proof. - pub(crate) fn grove_get_proved_path_query_v0( + pub(super) fn grove_get_proved_path_query_v0( &self, path_query: &PathQuery, transaction: TransactionArg, diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_proved_path_query_with_conditional/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_proved_path_query_with_conditional/v0/mod.rs index 3d3d4aad5d2..40a47aa901a 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_proved_path_query_with_conditional/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_proved_path_query_with_conditional/v0/mod.rs @@ -12,7 +12,7 @@ impl Drive { /// Pushes the cost to `drive_operations` and returns the return value. /// Verbose should be generally set to false unless one needs to prove /// subsets of a proof. - pub(crate) fn grove_get_proved_path_query_with_conditional_v0>( + pub(super) fn grove_get_proved_path_query_with_conditional_v0>( &self, root_path: SubtreePath, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw/v0/mod.rs index a564abc2730..4a84959eb1c 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw/v0/mod.rs @@ -13,7 +13,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// grove_get_raw basically means that there are no reference hops, this only matters /// when calculating worst case costs - pub(crate) fn grove_get_raw_v0>( + pub(super) fn grove_get_raw_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional/v0/mod.rs index 9b9a5be3bbb..9c8f567fa9a 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional/v0/mod.rs @@ -13,7 +13,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// grove_get_raw basically means that there are no reference hops, this only matters /// when calculating worst case costs - pub(crate) fn grove_get_raw_optional_v0>( + pub(super) fn grove_get_raw_optional_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/mod.rs new file mode 100644 index 00000000000..667e956ce9b --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/mod.rs @@ -0,0 +1,59 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; + +use dpp::version::drive_versions::DriveVersion; + +use grovedb::TransactionArg; +use grovedb_path::SubtreePath; + +impl Drive { + /// Handles the retrieval of a raw element from GroveDB at the specified path and key. + /// The operation cost is added to `drive_operations` for later processing. + /// + /// # Parameters + /// * `path`: The groveDB hierarchical authenticated structure path from where the element is to be retrieved. + /// * `key`: The key of the element to be retrieved from the subtree. + /// * `direct_query_type`: The type of query to perform, whether stateless or stateful. + /// * `transaction`: The groveDB transaction associated with this operation. + /// * `drive_operations`: A vector to collect the costs of operations for later computation. + /// * `platform_version`: The platform version to select the correct function version to run. + /// + /// # Returns + /// * `Ok(Some(Element))` if the operation was successful and the element was found. + /// * `Ok(None)` if the operation was successful but the element was not found. + /// * `Err(DriveError::UnknownVersionMismatch)` if the platform version does not match known versions. + pub fn grove_get_raw_optional_item>( + &self, + path: SubtreePath<'_, B>, + key: &[u8], + direct_query_type: DirectQueryType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result>, Error> { + match drive_version + .grove_methods + .basic + .grove_get_raw_optional_item + { + 0 => self.grove_get_raw_optional_item_v0( + path, + key, + direct_query_type, + transaction, + drive_operations, + drive_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "grove_get_raw_optional_item".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/v0/mod.rs new file mode 100644 index 00000000000..4e17e9b0931 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/v0/mod.rs @@ -0,0 +1,84 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::fees::op::LowLevelDriveOperation::CalculatedCostOperation; +use crate::util::grove_operations::{DirectQueryType, QueryTarget}; +use grovedb::batch::key_info::KeyInfo; +use grovedb::batch::KeyInfoPath; +use grovedb::{Element, GroveDb, TransactionArg}; +use grovedb_costs::CostContext; +use grovedb_path::SubtreePath; +use itertools::Itertools; +use platform_version::version::drive_versions::DriveVersion; + +impl Drive { + /// grove_get_raw_item basically means that there are no reference hops, this only matters + /// when calculating worst case costs + pub(super) fn grove_get_raw_optional_item_v0>( + &self, + path: SubtreePath<'_, B>, + key: &[u8], + direct_query_type: DirectQueryType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result>, Error> { + match direct_query_type { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums, + query_target, + } => { + let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); + let key_info = KeyInfo::KnownKey(key.to_vec()); + let cost = match query_target { + QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + GroveDb::average_case_for_get_tree( + &key_info_path, + &key_info, + flags_size, + is_sum_tree, + in_tree_using_sums, + &drive_version.grove_version, + ) + } + QueryTarget::QueryTargetValue(estimated_value_size) => { + GroveDb::average_case_for_get_raw( + &key_info_path, + &key_info, + estimated_value_size, + in_tree_using_sums, + &drive_version.grove_version, + ) + } + }?; + + drive_operations.push(CalculatedCostOperation(cost)); + Ok(None) + } + DirectQueryType::StatefulDirectQuery => { + //todo remove path clone + let CostContext { value, cost } = self.grove.get_raw_optional( + path.clone(), + key, + transaction, + &drive_version.grove_version, + ); + drive_operations.push(CalculatedCostOperation(cost)); + let element = value.map_err(Error::GroveDB)?; + match element { + Some(Element::Item(value, _)) => Ok(Some(value)), + None => Ok(None), + _ => Err(Error::Drive(DriveError::CorruptedDriveState(format!( + "path {}/0x{} does not refer to an item", + path.to_vec() + .iter() + .map(|bytes| format!("0x{}", hex::encode(bytes))) + .join("/"), + hex::encode(key) + )))), + } + } + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_path_query/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_path_query/v0/mod.rs index eebeb4b5241..2deec8ba8b7 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw_path_query/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_path_query/v0/mod.rs @@ -10,7 +10,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Gets the return value and the cost of a groveDB raw path query. /// Pushes the cost to `drive_operations` and returns the return value. - pub(crate) fn grove_get_raw_path_query_v0( + pub(super) fn grove_get_raw_path_query_v0( &self, path_query: &PathQuery, transaction: TransactionArg, diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_path_query_with_optional/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_path_query_with_optional/v0/mod.rs index add7c65d917..1e852fcb775 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw_path_query_with_optional/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_path_query_with_optional/v0/mod.rs @@ -10,7 +10,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Gets the return value and the cost of a groveDB path query. /// Pushes the cost to `drive_operations` and returns the return value. - pub(crate) fn grove_get_raw_path_query_with_optional_v0( + pub(super) fn grove_get_raw_path_query_with_optional_v0( &self, path_query: &PathQuery, error_if_intermediate_path_tree_not_present: bool, diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_value_u64_from_encoded_var_vec/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_value_u64_from_encoded_var_vec/v0/mod.rs index 368a7d29330..07418407bbb 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw_value_u64_from_encoded_var_vec/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_value_u64_from_encoded_var_vec/v0/mod.rs @@ -10,7 +10,7 @@ use integer_encoding::VarInt; impl Drive { /// grove_get_direct_u64 is a helper function to get a - pub(crate) fn grove_get_raw_value_u64_from_encoded_var_vec_v0>( + pub(super) fn grove_get_raw_value_u64_from_encoded_var_vec_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_insert/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_insert/v0/mod.rs index f9c81c65c7c..f949ecc605b 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_insert/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_insert/v0/mod.rs @@ -9,7 +9,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Pushes the `OperationCost` of inserting an element in groveDB to `drive_operations`. - pub(crate) fn grove_insert_v0>( + pub(super) fn grove_insert_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_insert_empty_sum_tree/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_insert_empty_sum_tree/v0/mod.rs index a025023bf33..2ea0ae20d8e 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_insert_empty_sum_tree/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_insert_empty_sum_tree/v0/mod.rs @@ -9,7 +9,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Pushes the `OperationCost` of inserting an empty sum tree in groveDB to `drive_operations`. - pub fn grove_insert_empty_sum_tree_v0>( + pub(super) fn grove_insert_empty_sum_tree_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_insert_empty_tree/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_insert_empty_tree/v0/mod.rs index 6628036899f..4a0a2d34880 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_insert_empty_tree/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_insert_empty_tree/v0/mod.rs @@ -9,7 +9,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Pushes the `OperationCost` of inserting an empty tree in groveDB to `drive_operations`. - pub(crate) fn grove_insert_empty_tree_v0>( + pub(super) fn grove_insert_empty_tree_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_insert_if_not_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_insert_if_not_exists/v0/mod.rs index b03297457cd..4d27e254599 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_insert_if_not_exists/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_insert_if_not_exists/v0/mod.rs @@ -9,7 +9,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Pushes the `OperationCost` of inserting an element in groveDB where the path key does not yet exist /// to `drive_operations`. - pub(crate) fn grove_insert_if_not_exists_v0>( + pub(super) fn grove_insert_if_not_exists_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/grove_insert_if_not_exists_return_existing_element/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_insert_if_not_exists_return_existing_element/v0/mod.rs index 69b55ba2d76..86bb679a397 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_insert_if_not_exists_return_existing_element/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_insert_if_not_exists_return_existing_element/v0/mod.rs @@ -9,7 +9,7 @@ use platform_version::version::drive_versions::DriveVersion; impl Drive { /// Pushes the `OperationCost` of inserting an element in groveDB where the path key does not yet exist /// to `drive_operations`. - pub(crate) fn grove_insert_if_not_exists_return_existing_element_v0>( + pub(super) fn grove_insert_if_not_exists_return_existing_element_v0>( &self, path: SubtreePath<'_, B>, key: &[u8], diff --git a/packages/rs-drive/src/util/grove_operations/mod.rs b/packages/rs-drive/src/util/grove_operations/mod.rs index 20cea07f6c7..ee07d5c1ff4 100644 --- a/packages/rs-drive/src/util/grove_operations/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/mod.rs @@ -139,6 +139,8 @@ pub mod batch_move_items_in_path_query; /// Get total value from sum tree in grove if it exists pub mod grove_get_optional_sum_tree_total_value; +/// Fetch raw grove data if it exists, None otherwise +pub mod grove_get_raw_optional_item; use grovedb_costs::CostContext; diff --git a/packages/rs-drive/src/util/operations/apply_batch_grovedb_operations/v0/mod.rs b/packages/rs-drive/src/util/operations/apply_batch_grovedb_operations/v0/mod.rs index af240c94907..22622d5adf1 100644 --- a/packages/rs-drive/src/util/operations/apply_batch_grovedb_operations/v0/mod.rs +++ b/packages/rs-drive/src/util/operations/apply_batch_grovedb_operations/v0/mod.rs @@ -9,7 +9,7 @@ use std::collections::HashMap; impl Drive { /// Applies a batch of groveDB operations if apply is True, otherwise gets the cost of the operations. - pub(crate) fn apply_batch_grovedb_operations_v0( + pub(super) fn apply_batch_grovedb_operations_v0( &self, estimated_costs_only_with_layer_info: Option< HashMap, diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/mod.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/mod.rs new file mode 100644 index 00000000000..a964e80e059 --- /dev/null +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/mod.rs @@ -0,0 +1,8 @@ +pub mod v1; + +use versioned_feature_core::FeatureVersion; + +#[derive(Clone, Debug, Default)] +pub struct DPPTokenVersions { + pub identity_token_info_default_structure_version: FeatureVersion, +} diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/v1.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/v1.rs new file mode 100644 index 00000000000..ff0cef29c3e --- /dev/null +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/v1.rs @@ -0,0 +1,5 @@ +use crate::version::dpp_versions::dpp_token_versions::DPPTokenVersions; + +pub const TOKEN_VERSIONS_V1: DPPTokenVersions = DPPTokenVersions { + identity_token_info_default_structure_version: 0, +}; diff --git a/packages/rs-platform-version/src/version/dpp_versions/mod.rs b/packages/rs-platform-version/src/version/dpp_versions/mod.rs index e51203512c0..c58be60aec4 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/mod.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/mod.rs @@ -9,6 +9,7 @@ pub mod dpp_state_transition_conversion_versions; pub mod dpp_state_transition_method_versions; pub mod dpp_state_transition_serialization_versions; pub mod dpp_state_transition_versions; +pub mod dpp_token_versions; pub mod dpp_validation_versions; pub mod dpp_voting_versions; @@ -23,6 +24,7 @@ use dpp_state_transition_conversion_versions::DPPStateTransitionConversionVersio use dpp_state_transition_method_versions::DPPStateTransitionMethodVersions; use dpp_state_transition_serialization_versions::DPPStateTransitionSerializationVersions; use dpp_state_transition_versions::DPPStateTransitionVersions; +use dpp_token_versions::DPPTokenVersions; use dpp_validation_versions::DPPValidationVersions; use dpp_voting_versions::DPPVotingVersions; @@ -39,6 +41,7 @@ pub struct DPPVersion { pub document_versions: DPPDocumentVersions, pub identity_versions: DPPIdentityVersions, pub voting_versions: DPPVotingVersions, + pub token_versions: DPPTokenVersions, pub asset_lock_versions: DPPAssetLockVersions, pub methods: DPPMethodVersions, pub factory_versions: DPPFactoryVersions, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs index 3a20be18a85..04379b5d6eb 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs @@ -104,6 +104,10 @@ pub struct DriveAbciDocumentsStateTransitionValidationVersions { pub token_burn_transition_state_validation: FeatureVersion, pub token_transfer_transition_state_validation: FeatureVersion, pub token_base_transition_structure_validation: FeatureVersion, + pub token_freeze_transition_structure_validation: FeatureVersion, + pub token_unfreeze_transition_structure_validation: FeatureVersion, + pub token_freeze_transition_state_validation: FeatureVersion, + pub token_unfreeze_transition_state_validation: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs index bc3ff85bd0f..93f10ebed12 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs @@ -136,6 +136,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V1: DriveAbciValidationVersions = token_burn_transition_state_validation: 0, token_transfer_transition_state_validation: 0, token_base_transition_structure_validation: 0, + token_freeze_transition_structure_validation: 0, + token_unfreeze_transition_structure_validation: 0, + token_freeze_transition_state_validation: 0, + token_unfreeze_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs index c11c3ef29c0..63a3e254a49 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs @@ -136,6 +136,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V2: DriveAbciValidationVersions = token_burn_transition_state_validation: 0, token_transfer_transition_state_validation: 0, token_base_transition_structure_validation: 0, + token_freeze_transition_structure_validation: 0, + token_unfreeze_transition_structure_validation: 0, + token_freeze_transition_state_validation: 0, + token_unfreeze_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs index 95f3bcef537..ba2c6d601f6 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs @@ -136,6 +136,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V3: DriveAbciValidationVersions = token_burn_transition_state_validation: 0, token_transfer_transition_state_validation: 0, token_base_transition_structure_validation: 0, + token_freeze_transition_structure_validation: 0, + token_unfreeze_transition_structure_validation: 0, + token_freeze_transition_state_validation: 0, + token_unfreeze_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs index e4c16445998..0af0d9e87e4 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs @@ -136,6 +136,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V4: DriveAbciValidationVersions = token_burn_transition_state_validation: 0, token_transfer_transition_state_validation: 0, token_base_transition_structure_validation: 0, + token_freeze_transition_structure_validation: 0, + token_unfreeze_transition_structure_validation: 0, + token_freeze_transition_state_validation: 0, + token_unfreeze_transition_state_validation: 0, }, }, has_nonce_validation: 1, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs index f624d94fd15..7b281cd6cc6 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs @@ -35,6 +35,7 @@ pub struct DriveGroveBasicMethodVersions { pub grove_has_raw: FeatureVersion, pub grove_get_raw_item: FeatureVersion, pub grove_get_optional_sum_tree_total_value: FeatureVersion, + pub grove_get_raw_optional_item: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs index df572a2cf2a..31b39cfad3e 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs @@ -28,6 +28,7 @@ pub const DRIVE_GROVE_METHOD_VERSIONS_V1: DriveGroveMethodVersions = DriveGroveM grove_has_raw: 0, grove_get_raw_item: 0, grove_get_optional_sum_tree_total_value: 0, + grove_get_raw_optional_item: 0, }, batch: DriveGroveBatchMethodVersions { batch_insert_empty_tree: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs index bb4adfbb9d9..ed9e6a59c27 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs @@ -33,6 +33,8 @@ pub struct DriveStateTransitionActionConvertToHighLevelOperationsMethodVersions pub bump_identity_data_contract_nonce: FeatureVersion, pub bump_identity_nonce: FeatureVersion, pub partially_use_asset_lock: FeatureVersion, + pub token_freeze_transition: FeatureVersion, + pub token_unfreeze_transition: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs index e12a719fdd7..e89684d70c0 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs @@ -35,5 +35,7 @@ pub const DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1: DriveStateTransitionMethodV bump_identity_data_contract_nonce: 0, bump_identity_nonce: 0, partially_use_asset_lock: 0, + token_freeze_transition: 0, + token_unfreeze_transition: 0, }, }; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 1daea28aeb3..22971a365b3 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -32,4 +32,6 @@ pub struct DriveTokenUpdateMethodVersions { pub remove_from_identity_token_balance: FeatureVersion, pub add_to_identity_token_balance: FeatureVersion, pub add_transaction_history_operations: FeatureVersion, + pub freeze: FeatureVersion, + pub unfreeze: FeatureVersion, } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index c2afcae91e9..5fc38099b7f 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -22,5 +22,7 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM remove_from_identity_token_balance: 0, add_to_identity_token_balance: 0, add_transaction_history_operations: 0, + freeze: 0, + unfreeze: 0, }, }; 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 88f8ad14365..1765d8d69ba 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v1:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v1::STATE_TRANSITION_VERSIONS_V1; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; @@ -327,6 +328,7 @@ pub const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, 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 4c54dfbfef0..caae43ccea9 100644 --- a/packages/rs-platform-version/src/version/mocks/v3_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v3_test.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v1::STATE_TRANSITION_VERSIONS_V1; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; @@ -167,6 +168,7 @@ pub const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/rs-platform-version/src/version/v1.rs b/packages/rs-platform-version/src/version/v1.rs index f7803b32c58..5f32d406fae 100644 --- a/packages/rs-platform-version/src/version/v1.rs +++ b/packages/rs-platform-version/src/version/v1.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v1:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v1::STATE_TRANSITION_VERSIONS_V1; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v1::DPP_VALIDATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_voting_versions::v1::VOTING_VERSION_V1; use crate::version::dpp_versions::DPPVersion; @@ -49,6 +50,7 @@ pub const PLATFORM_V1: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V1, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/rs-platform-version/src/version/v2.rs b/packages/rs-platform-version/src/version/v2.rs index 6e1ed400947..f97bee41394 100644 --- a/packages/rs-platform-version/src/version/v2.rs +++ b/packages/rs-platform-version/src/version/v2.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v1:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v1::STATE_TRANSITION_VERSIONS_V1; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v1::VOTING_VERSION_V1; use crate::version::dpp_versions::DPPVersion; @@ -49,6 +50,7 @@ pub const PLATFORM_V2: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V1, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/rs-platform-version/src/version/v3.rs b/packages/rs-platform-version/src/version/v3.rs index f3856bc1e6c..c92b8ab225c 100644 --- a/packages/rs-platform-version/src/version/v3.rs +++ b/packages/rs-platform-version/src/version/v3.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANSITION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; @@ -56,6 +57,7 @@ pub const PLATFORM_V3: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/rs-platform-version/src/version/v4.rs b/packages/rs-platform-version/src/version/v4.rs index d0b58943744..a6086b01ef7 100644 --- a/packages/rs-platform-version/src/version/v4.rs +++ b/packages/rs-platform-version/src/version/v4.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANSITION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; @@ -51,6 +52,7 @@ pub const PLATFORM_V4: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/rs-platform-version/src/version/v5.rs b/packages/rs-platform-version/src/version/v5.rs index 988531b3d09..1679fff28a5 100644 --- a/packages/rs-platform-version/src/version/v5.rs +++ b/packages/rs-platform-version/src/version/v5.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANSITION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; @@ -51,6 +52,7 @@ pub const PLATFORM_V5: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/rs-platform-version/src/version/v6.rs b/packages/rs-platform-version/src/version/v6.rs index b282d1b7520..3ae597d99f7 100644 --- a/packages/rs-platform-version/src/version/v6.rs +++ b/packages/rs-platform-version/src/version/v6.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANSITION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; @@ -50,6 +51,7 @@ pub const PLATFORM_V6: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/rs-platform-version/src/version/v7.rs b/packages/rs-platform-version/src/version/v7.rs index ee532689970..26a9ed6ef58 100644 --- a/packages/rs-platform-version/src/version/v7.rs +++ b/packages/rs-platform-version/src/version/v7.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v1::STATE_TRANSITION_SERIALIZATION_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANSITION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; @@ -51,6 +52,7 @@ pub const PLATFORM_V7: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/rs-platform-version/src/version/v8.rs b/packages/rs-platform-version/src/version/v8.rs index 068105e7292..4712c1521e6 100644 --- a/packages/rs-platform-version/src/version/v8.rs +++ b/packages/rs-platform-version/src/version/v8.rs @@ -10,6 +10,7 @@ use crate::version::dpp_versions::dpp_state_transition_conversion_versions::v2:: use crate::version::dpp_versions::dpp_state_transition_method_versions::v1::STATE_TRANSITION_METHOD_VERSIONS_V1; use crate::version::dpp_versions::dpp_state_transition_serialization_versions::v2::STATE_TRANSITION_SERIALIZATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_state_transition_versions::v2::STATE_TRANSITION_VERSIONS_V2; +use crate::version::dpp_versions::dpp_token_versions::v1::TOKEN_VERSIONS_V1; use crate::version::dpp_versions::dpp_validation_versions::v2::DPP_VALIDATION_VERSIONS_V2; use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; @@ -51,6 +52,7 @@ pub const PLATFORM_V8: PlatformVersion = PlatformVersion { document_versions: DOCUMENT_VERSIONS_V1, identity_versions: IDENTITY_VERSIONS_V1, voting_versions: VOTING_VERSION_V2, + token_versions: TOKEN_VERSIONS_V1, asset_lock_versions: DPP_ASSET_LOCK_VERSIONS_V1, methods: DPP_METHOD_VERSIONS_V1, factory_versions: DPP_FACTORY_VERSIONS_V1, diff --git a/packages/token-history-contract/schema/v1/token-history-contract-documents.json b/packages/token-history-contract/schema/v1/token-history-contract-documents.json index 7bc7732d124..d4880f2f718 100644 --- a/packages/token-history-contract/schema/v1/token-history-contract-documents.json +++ b/packages/token-history-contract/schema/v1/token-history-contract-documents.json @@ -68,8 +68,7 @@ "tokenId", "amount", "$createdAt", - "$createdAtBlockHeight", - "$createdAtCoreBlockHeight" + "$createdAtBlockHeight" ], "additionalProperties": false }, @@ -165,8 +164,7 @@ "amount", "recipientId", "$createdAt", - "$createdAtBlockHeight", - "$createdAtCoreBlockHeight" + "$createdAtBlockHeight" ], "additionalProperties": false }, @@ -302,8 +300,7 @@ "amount", "toIdentityId", "$createdAt", - "$createdAtBlockHeight", - "$createdAtCoreBlockHeight" + "$createdAtBlockHeight" ], "additionalProperties": false }, @@ -389,13 +386,13 @@ ] }, { - "name": "byUnfrozenIdentityId", + "name": "byFrozenIdentityId", "properties": [ { "tokenId": "asc" }, { - "unfrozenIdentityId": "asc" + "frozenIdentityId": "asc" }, { "$createdAt": "asc" @@ -412,7 +409,7 @@ "description": "The token ID", "position": 0 }, - "unfrozenIdentityId": { + "frozenIdentityId": { "type": "array", "byteArray": true, "minItems": 32, @@ -423,7 +420,7 @@ }, "required": [ "tokenId", - "unfrozenIdentityId", + "frozenIdentityId", "$createdAt", "$createdAtBlockHeight" ], From 7a6202a34a3b538daafc9c8c300b20fe0bbb8301 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Jan 2025 12:37:33 +0700 Subject: [PATCH 44/61] added info queries --- packages/dapi-grpc/build.rs | 12 +- .../protos/platform/v0/platform.proto | 78 ++++ packages/rs-dpp/src/errors/consensus/codes.rs | 1 - .../document/batch_transition/methods/mod.rs | 127 ++++++- .../batch_transition/methods/v1/mod.rs | 38 ++ .../batch_transition/v1/v0_methods.rs | 146 +++++++- .../state_transitions/batch/mod.rs | 92 +++++ packages/rs-drive-abci/src/query/service.rs | 30 +- .../identities_token_infos/mod.rs | 62 +++ .../identities_token_infos/v0/mod.rs | 94 +++++ .../token_queries/identity_token_infos/mod.rs | 62 +++ .../identity_token_infos/v0/mod.rs | 89 +++++ .../src/query/token_queries/mod.rs | 2 + packages/rs-drive/Cargo.toml | 1 + .../rs-drive/src/drive/document/delete/mod.rs | 13 +- .../rs-drive/src/drive/document/insert/mod.rs | 20 +- .../rs-drive/src/drive/document/update/mod.rs | 44 ++- .../fetch_identities_token_balances/mod.rs | 4 +- .../prove_identities_token_balances/mod.rs | 4 +- .../src/drive/tokens/freeze/v0/mod.rs | 2 +- .../info/fetch_identities_token_infos/mod.rs | 151 ++++++++ .../fetch_identities_token_infos/v0/mod.rs | 66 ++++ .../info/fetch_identity_token_infos/mod.rs | 151 ++++++++ .../info/fetch_identity_token_infos/v0/mod.rs | 87 +++++ .../rs-drive/src/drive/tokens/info/mod.rs | 9 + .../info/prove_identities_token_infos/mod.rs | 149 ++++++++ .../prove_identities_token_infos/v0/mod.rs | 353 ++++++++++++++++++ .../info/prove_identity_token_infos/mod.rs | 149 ++++++++ .../info/prove_identity_token_infos/v0/mod.rs | 55 +++ .../rs-drive/src/drive/tokens/info/queries.rs | 72 ++++ packages/rs-drive/src/drive/tokens/mod.rs | 1 + .../src/drive/tokens/unfreeze/v0/mod.rs | 2 +- .../src/util/batch/drive_op_batch/mod.rs | 10 +- packages/rs-drive/src/verify/tokens/mod.rs | 1 + .../v0/mod.rs | 3 +- .../mod.rs | 79 ++++ .../v0/mod.rs | 65 ++++ .../drive_abci_query_versions/mod.rs | 2 + .../drive_abci_query_versions/v1.rs | 10 + .../drive_token_method_versions/mod.rs | 8 + .../drive_token_method_versions/v1.rs | 8 + .../drive_verify_method_versions/mod.rs | 1 + .../drive_verify_method_versions/v1.rs | 1 + .../src/version/mocks/v2_test.rs | 10 + 44 files changed, 2320 insertions(+), 44 deletions(-) create mode 100644 packages/rs-drive-abci/src/query/token_queries/identities_token_infos/mod.rs create mode 100644 packages/rs-drive-abci/src/query/token_queries/identities_token_infos/v0/mod.rs create mode 100644 packages/rs-drive-abci/src/query/token_queries/identity_token_infos/mod.rs create mode 100644 packages/rs-drive-abci/src/query/token_queries/identity_token_infos/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/fetch_identities_token_infos/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/fetch_identities_token_infos/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/prove_identities_token_infos/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/prove_identities_token_infos/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/prove_identity_token_infos/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/prove_identity_token_infos/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/queries.rs create mode 100644 packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/mod.rs create mode 100644 packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/v0/mod.rs diff --git a/packages/dapi-grpc/build.rs b/packages/dapi-grpc/build.rs index 642b614ab90..49b9c29032d 100644 --- a/packages/dapi-grpc/build.rs +++ b/packages/dapi-grpc/build.rs @@ -47,7 +47,7 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig { // Derive features for versioned messages // // "GetConsensusParamsRequest" is excluded as this message does not support proofs - const VERSIONED_REQUESTS: [&str; 30] = [ + const VERSIONED_REQUESTS: [&str; 34] = [ "GetDataContractHistoryRequest", "GetDataContractRequest", "GetDataContractsRequest", @@ -78,6 +78,10 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig { "GetEvonodesProposedEpochBlocksByIdsRequest", "GetEvonodesProposedEpochBlocksByRangeRequest", "GetStatusRequest", + "GetIdentityTokenBalancesRequest", + "GetIdentitiesTokenBalancesRequest", + "GetIdentityTokenInfosRequest", + "GetIdentitiesTokenInfosRequest", ]; // The following responses are excluded as they don't support proofs: @@ -85,7 +89,7 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig { // - "GetStatusResponse" // // "GetEvonodesProposedEpochBlocksResponse" is used for 2 Requests - const VERSIONED_RESPONSES: [&str; 29] = [ + const VERSIONED_RESPONSES: [&str; 33] = [ "GetDataContractHistoryResponse", "GetDataContractResponse", "GetDataContractsResponse", @@ -115,6 +119,10 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig { "GetVotePollsByEndDateResponse", "GetTotalCreditsInPlatformResponse", "GetEvonodesProposedEpochBlocksResponse", + "GetIdentityTokenBalancesResponse", + "GetIdentitiesTokenBalancesResponse", + "GetIdentityTokenInfosResponse", + "GetIdentitiesTokenInfosResponse", ]; check_unique(&VERSIONED_REQUESTS).expect("VERSIONED_REQUESTS"); diff --git a/packages/dapi-grpc/protos/platform/v0/platform.proto b/packages/dapi-grpc/protos/platform/v0/platform.proto index 73146769665..f31f4658eb1 100644 --- a/packages/dapi-grpc/protos/platform/v0/platform.proto +++ b/packages/dapi-grpc/protos/platform/v0/platform.proto @@ -57,6 +57,8 @@ service Platform { rpc getCurrentQuorumsInfo(GetCurrentQuorumsInfoRequest) returns (GetCurrentQuorumsInfoResponse); rpc getIdentityTokenBalances(GetIdentityTokenBalancesRequest) returns (GetIdentityTokenBalancesResponse); rpc getIdentitiesTokenBalances(GetIdentitiesTokenBalancesRequest) returns (GetIdentitiesTokenBalancesResponse); + rpc getIdentityTokenInfos(GetIdentityTokenInfosRequest) returns (GetIdentityTokenInfosResponse); + rpc getIdentitiesTokenInfos(GetIdentitiesTokenInfosRequest) returns (GetIdentitiesTokenInfosResponse); } // Proof message includes cryptographic proofs for validating responses @@ -1283,3 +1285,79 @@ message GetIdentitiesTokenBalancesResponse { GetIdentitiesTokenBalancesResponseV0 v0 = 1; } } + + + +message GetIdentityTokenInfosRequest { + message GetIdentityTokenInfosRequestV0 { + bytes identity_id = 1; + repeated bytes token_ids = 2; + bool prove = 3; + } + oneof version { + GetIdentityTokenInfosRequestV0 v0 = 1; + } +} + +message GetIdentityTokenInfosResponse { + message GetIdentityTokenInfosResponseV0 { + message TokenIdentityInfoEntry { + bool frozen = 1; + } + + message TokenInfoEntry { + bytes token_id = 1; + optional TokenIdentityInfoEntry info = 2; + } + + message TokenInfos { + repeated TokenInfoEntry token_infos = 1; + } + + oneof result { + TokenInfos token_infos = 1; + Proof proof = 2; + } + ResponseMetadata metadata = 3; + } + oneof version { + GetIdentityTokenInfosResponseV0 v0 = 1; + } +} + +message GetIdentitiesTokenInfosRequest { + message GetIdentitiesTokenInfosRequestV0 { + bytes token_id = 1; + repeated bytes identity_ids = 2; + bool prove = 3; + } + oneof version { + GetIdentitiesTokenInfosRequestV0 v0 = 1; + } +} + +message GetIdentitiesTokenInfosResponse { + message GetIdentitiesTokenInfosResponseV0 { + message TokenIdentityInfoEntry { + bool frozen = 1; + } + + message TokenInfoEntry { + bytes identity_id = 1; + optional TokenIdentityInfoEntry info = 2; + } + + message IdentityTokenInfos { + repeated TokenInfoEntry token_infos = 1; + } + + oneof result { + IdentityTokenInfos identity_token_infos = 1; + Proof proof = 2; + } + ResponseMetadata metadata = 3; + } + oneof version { + GetIdentitiesTokenInfosResponseV0 v0 = 1; + } +} \ No newline at end of file diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index e8b767156fa..e9d36bacc12 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -273,7 +273,6 @@ impl ErrorWithCode for StateError { Self::DataTriggerError(ref e) => e.code(), // Group errors: 40800-40899 - #[cfg(feature = "state-transition-validation")] Self::IdentityNotMemberOfGroupError(_) => 40800, Self::GroupActionDoesNotExistError(_) => 40801, Self::GroupActionAlreadyCompletedError(_) => 40802, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs index 5734aab90a2..31f82c1ce9a 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs @@ -1,6 +1,8 @@ +#[cfg(feature = "state-transition-signing")] use crate::balances::credits::TokenAmount; #[cfg(feature = "state-transition-signing")] use crate::data_contract::document_type::DocumentTypeRef; +#[cfg(feature = "state-transition-signing")] use crate::data_contract::TokenContractPosition; #[cfg(feature = "state-transition-signing")] use crate::document::Document; @@ -11,11 +13,12 @@ use crate::group::GroupStateTransitionInfoStatus; use crate::identity::signer::Signer; #[cfg(feature = "state-transition-signing")] use crate::identity::IdentityPublicKey; +use crate::prelude::IdentityNonce; #[cfg(feature = "state-transition-signing")] use crate::prelude::UserFeeIncrease; +#[cfg(feature = "state-transition-signing")] use crate::prelude::{ - DerivationEncryptionKeyIndex, IdentityNonce, RecipientKeyIndex, RootEncryptionKeyIndex, - SenderKeyIndex, + DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex, }; use crate::state_transition::batch_transition::batched_transition::BatchedTransition; use crate::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; @@ -613,4 +616,124 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { }), } } + + #[cfg(feature = "state-transition-signing")] + fn new_token_freeze_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + freeze_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + match batch_feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .default_current_version, + ) { + 1 | 0 + if platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .max_version + >= 1 => + { + // Create the freeze transition for batch version 1 + BatchTransitionV1::new_token_freeze_transition( + token_id, + owner_id, + data_contract_id, + token_contract_position, + freeze_identity_id, + public_note, + using_group_info, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + delete_feature_version, + base_feature_version, + ) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DocumentsBatchTransition::new_token_freeze_transition".to_string(), + known_versions: vec![1], + received: version, + }), + } + } + + #[cfg(feature = "state-transition-signing")] + fn new_token_unfreeze_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + unfreeze_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + match batch_feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .default_current_version, + ) { + 1 | 0 + if platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .max_version + >= 1 => + { + // Create the freeze transition for batch version 1 + BatchTransitionV1::new_token_unfreeze_transition( + token_id, + owner_id, + data_contract_id, + token_contract_position, + unfreeze_identity_id, + public_note, + using_group_info, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + delete_feature_version, + base_feature_version, + ) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DocumentsBatchTransition::new_token_unfreeze_transition".to_string(), + known_versions: vec![1], + received: version, + }), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs index 5f1f58e7084..38b593d7360 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs @@ -77,4 +77,42 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 delete_feature_version: Option, base_feature_version: Option, ) -> Result; + + #[cfg(feature = "state-transition-signing")] + fn new_token_freeze_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + frozen_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result; + + #[cfg(feature = "state-transition-signing")] + fn new_token_unfreeze_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + frozen_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index 0ef9f18d301..1d2abd28c3b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -30,7 +30,7 @@ use crate::state_transition::batch_transition::methods::v0::DocumentsBatchTransi use std::iter::Map; use std::slice::Iter; -use crate::state_transition::batch_transition::{BatchTransitionV1, TokenBurnTransition, TokenMintTransition, TokenTransferTransition}; +use crate::state_transition::batch_transition::{BatchTransitionV1, TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, TokenUnfreezeTransition}; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::{ BatchTransition, DocumentDeleteTransition, @@ -54,8 +54,10 @@ use crate::state_transition::batch_transition::token_base_transition::TokenBaseT use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::batch_transition::token_burn_transition::TokenBurnTransitionV0; +use crate::state_transition::batch_transition::token_freeze_transition::TokenFreezeTransitionV0; use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; use crate::state_transition::batch_transition::token_transfer_transition::TokenTransferTransitionV0; +use crate::state_transition::batch_transition::token_unfreeze_transition::TokenUnfreezeTransitionV0; impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV1 { type IterType<'a> = Map, fn(&'a BatchedTransition) -> BatchedTransitionRef<'a>> @@ -405,6 +407,7 @@ impl DocumentsBatchTransitionMethodsV0 for BatchTransitionV1 { } impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { + #[cfg(feature = "state-transition-signing")] fn new_token_mint_transition( token_id: Identifier, owner_id: Identifier, @@ -473,6 +476,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { Ok(state_transition) } + #[cfg(feature = "state-transition-signing")] fn new_token_burn_transition( token_id: Identifier, owner_id: Identifier, @@ -542,7 +546,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { Ok(state_transition) } - + #[cfg(feature = "state-transition-signing")] fn new_token_transfer_transition( token_id: Identifier, owner_id: Identifier, @@ -602,4 +606,142 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { Ok(state_transition) } + + #[cfg(feature = "state-transition-signing")] + fn new_token_freeze_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + frozen_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let mut freeze_transition = TokenFreezeTransition::V0(TokenFreezeTransitionV0 { + base: TokenBaseTransition::V0(TokenBaseTransitionV0 { + identity_contract_nonce, + token_contract_position, + data_contract_id, + token_id, + using_group_info: None, + }), + frozen_identity_id, + public_note, + }); + + if let Some(using_group_info_status) = using_group_info { + match using_group_info_status { + GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer( + group_contract_position, + ) => { + let action_id = freeze_transition.calculate_action_id(owner_id); + freeze_transition.base_mut().set_using_group_info(Some( + GroupStateTransitionInfo { + group_contract_position, + action_id, + action_is_proposer: true, + }, + )) + } + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner(info) => { + freeze_transition + .base_mut() + .set_using_group_info(Some(info)) + } + } + } + + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Token(freeze_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + #[cfg(feature = "state-transition-signing")] + fn new_token_unfreeze_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + frozen_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let mut unfreeze_transition = TokenUnfreezeTransition::V0(TokenUnfreezeTransitionV0 { + base: TokenBaseTransition::V0(TokenBaseTransitionV0 { + identity_contract_nonce, + token_contract_position, + data_contract_id, + token_id, + using_group_info: None, + }), + frozen_identity_id, + public_note, + }); + + if let Some(using_group_info_status) = using_group_info { + match using_group_info_status { + GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer( + group_contract_position, + ) => { + let action_id = unfreeze_transition.calculate_action_id(owner_id); + unfreeze_transition.base_mut().set_using_group_info(Some( + GroupStateTransitionInfo { + group_contract_position, + action_id, + action_is_proposer: true, + }, + )) + } + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner(info) => { + unfreeze_transition + .base_mut() + .set_using_group_info(Some(info)) + } + } + } + + let documents_batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Token(unfreeze_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = documents_batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index daba9407763..c492b653016 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -12737,5 +12737,97 @@ mod tests { assert_eq!(token_balance, None); } } + + mod token_freeze_tests { + use super::*; + + #[test] + fn test_token_freeze_and_unfreeze() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, signer_2, key_2) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + None, + platform_version, + ); + + let freeze_transition = BatchTransition::new_token_freeze_transition( + token_id, + identity.id(), + contract.id(), + 0, + identity_2.id(), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let freeze_serialized_transition = freeze_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![freeze_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + assert_eq!(token_balance, Some(100000)); + } + } } } diff --git a/packages/rs-drive-abci/src/query/service.rs b/packages/rs-drive-abci/src/query/service.rs index 039a33a1319..3847b7d1bb4 100644 --- a/packages/rs-drive-abci/src/query/service.rs +++ b/packages/rs-drive-abci/src/query/service.rs @@ -23,13 +23,15 @@ use dapi_grpc::platform::v0::{ GetEvonodesProposedEpochBlocksResponse, GetIdentitiesBalancesRequest, GetIdentitiesBalancesResponse, GetIdentitiesContractKeysRequest, GetIdentitiesContractKeysResponse, GetIdentitiesTokenBalancesRequest, - GetIdentitiesTokenBalancesResponse, GetIdentityBalanceAndRevisionRequest, + GetIdentitiesTokenBalancesResponse, GetIdentitiesTokenInfosRequest, + GetIdentitiesTokenInfosResponse, GetIdentityBalanceAndRevisionRequest, GetIdentityBalanceAndRevisionResponse, GetIdentityBalanceRequest, GetIdentityBalanceResponse, GetIdentityByPublicKeyHashRequest, GetIdentityByPublicKeyHashResponse, GetIdentityContractNonceRequest, GetIdentityContractNonceResponse, GetIdentityKeysRequest, GetIdentityKeysResponse, GetIdentityNonceRequest, GetIdentityNonceResponse, GetIdentityRequest, GetIdentityResponse, GetIdentityTokenBalancesRequest, GetIdentityTokenBalancesResponse, - GetPathElementsRequest, GetPathElementsResponse, GetPrefundedSpecializedBalanceRequest, + GetIdentityTokenInfosRequest, GetIdentityTokenInfosResponse, GetPathElementsRequest, + GetPathElementsResponse, GetPrefundedSpecializedBalanceRequest, GetPrefundedSpecializedBalanceResponse, GetProofsRequest, GetProofsResponse, GetProtocolVersionUpgradeStateRequest, GetProtocolVersionUpgradeStateResponse, GetProtocolVersionUpgradeVoteStatusRequest, GetProtocolVersionUpgradeVoteStatusResponse, @@ -634,6 +636,30 @@ impl PlatformService for QueryService { ) .await } + + async fn get_identity_token_infos( + &self, + request: Request, + ) -> Result, Status> { + self.handle_blocking_query( + request, + Platform::::query_identity_token_infos, + "query_identity_token_infos", + ) + .await + } + + async fn get_identities_token_infos( + &self, + request: Request, + ) -> Result, Status> { + self.handle_blocking_query( + request, + Platform::::query_identities_token_infos, + "query_identities_token_infos", + ) + .await + } } fn query_error_into_status(error: QueryError) -> Status { diff --git a/packages/rs-drive-abci/src/query/token_queries/identities_token_infos/mod.rs b/packages/rs-drive-abci/src/query/token_queries/identities_token_infos/mod.rs new file mode 100644 index 00000000000..a1746ff1a0c --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/identities_token_infos/mod.rs @@ -0,0 +1,62 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_identities_token_infos_request::Version as RequestVersion; +use dapi_grpc::platform::v0::get_identities_token_infos_response::Version as ResponseVersion; +use dapi_grpc::platform::v0::{GetIdentitiesTokenInfosRequest, GetIdentitiesTokenInfosResponse}; +use dpp::version::PlatformVersion; +mod v0; + +impl Platform { + /// Querying of an identity's token infos by a public key hash + pub fn query_identities_token_infos( + &self, + GetIdentitiesTokenInfosRequest { version }: GetIdentitiesTokenInfosRequest, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let Some(version) = version else { + return Ok(QueryValidationResult::new_with_error( + QueryError::DecodingError( + "could not decode identity token infos query".to_string(), + ), + )); + }; + + let feature_version_bounds = &platform_version + .drive_abci + .query + .token_queries + .identities_token_infos; + + let feature_version = match &version { + RequestVersion::V0(_) => 0, + }; + if !feature_version_bounds.check_version(feature_version) { + return Ok(QueryValidationResult::new_with_error( + QueryError::UnsupportedQueryVersion( + "identities_token_infos".to_string(), + feature_version_bounds.min_version, + feature_version_bounds.max_version, + platform_version.protocol_version, + feature_version, + ), + )); + } + + match version { + RequestVersion::V0(request_v0) => { + let result = self.query_identities_token_infos_v0( + request_v0, + platform_state, + platform_version, + )?; + Ok(result.map(|response_v0| GetIdentitiesTokenInfosResponse { + version: Some(ResponseVersion::V0(response_v0)), + })) + } + } + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/identities_token_infos/v0/mod.rs b/packages/rs-drive-abci/src/query/token_queries/identities_token_infos/v0/mod.rs new file mode 100644 index 00000000000..e6a0786e78d --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/identities_token_infos/v0/mod.rs @@ -0,0 +1,94 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_identities_token_infos_request::GetIdentitiesTokenInfosRequestV0; +use dapi_grpc::platform::v0::get_identities_token_infos_response::{get_identities_token_infos_response_v0, GetIdentitiesTokenInfosResponseV0}; +use dapi_grpc::platform::v0::get_identities_token_infos_response::get_identities_token_infos_response_v0::{IdentityTokenInfos, TokenIdentityInfoEntry, TokenInfoEntry}; +use dpp::check_validation_result_with_data; +use dpp::identifier::Identifier; +use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; +use dpp::validation::ValidationResult; +use dpp::version::PlatformVersion; + +impl Platform { + pub(super) fn query_identities_token_infos_v0( + &self, + GetIdentitiesTokenInfosRequestV0 { + token_id, + identity_ids, + prove, + }: GetIdentitiesTokenInfosRequestV0, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let token_id: Identifier = + check_validation_result_with_data!(token_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "token_id must be a valid identifier (32 bytes long)".to_string(), + ) + })); + + let identity_ids: Vec<[u8; 32]> = check_validation_result_with_data!(identity_ids + .into_iter() + .map(|identity_id| { + identity_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "identity_id must be a valid identifier (32 bytes long)".to_string(), + ) + }) + }) + .collect::, QueryError>>()); + + let response = if prove { + let proof = + check_validation_result_with_data!(self.drive.prove_identities_token_infos( + token_id.into_buffer(), + identity_ids.as_slice(), + None, + platform_version, + )); + + GetIdentitiesTokenInfosResponseV0 { + result: Some(get_identities_token_infos_response_v0::Result::Proof( + self.response_proof_v0(platform_state, proof), + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + } else { + let identity_token_infos = self + .drive + .fetch_identities_token_infos( + token_id.into_buffer(), + identity_ids.as_slice(), + None, + platform_version, + )? + .into_iter() + .map(|(identity_id, info)| { + let info = info.map(|identity_token_info| TokenIdentityInfoEntry { + frozen: identity_token_info.frozen(), + }); + TokenInfoEntry { + identity_id: identity_id.to_vec(), + info, + } + }) + .collect(); + + GetIdentitiesTokenInfosResponseV0 { + result: Some( + get_identities_token_infos_response_v0::Result::IdentityTokenInfos( + IdentityTokenInfos { + token_infos: identity_token_infos, + }, + ), + ), + metadata: Some(self.response_metadata_v0(platform_state)), + } + }; + + Ok(QueryValidationResult::new_with_data(response)) + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/identity_token_infos/mod.rs b/packages/rs-drive-abci/src/query/token_queries/identity_token_infos/mod.rs new file mode 100644 index 00000000000..c0abc1a21e6 --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/identity_token_infos/mod.rs @@ -0,0 +1,62 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_identity_token_infos_request::Version as RequestVersion; +use dapi_grpc::platform::v0::get_identity_token_infos_response::Version as ResponseVersion; +use dapi_grpc::platform::v0::{GetIdentityTokenInfosRequest, GetIdentityTokenInfosResponse}; +use dpp::version::PlatformVersion; +mod v0; + +impl Platform { + /// Querying of an identity's token infos by a public key hash + pub fn query_identity_token_infos( + &self, + GetIdentityTokenInfosRequest { version }: GetIdentityTokenInfosRequest, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let Some(version) = version else { + return Ok(QueryValidationResult::new_with_error( + QueryError::DecodingError( + "could not decode identity token infos query".to_string(), + ), + )); + }; + + let feature_version_bounds = &platform_version + .drive_abci + .query + .token_queries + .identity_token_infos; + + let feature_version = match &version { + RequestVersion::V0(_) => 0, + }; + if !feature_version_bounds.check_version(feature_version) { + return Ok(QueryValidationResult::new_with_error( + QueryError::UnsupportedQueryVersion( + "identity_token_infos".to_string(), + feature_version_bounds.min_version, + feature_version_bounds.max_version, + platform_version.protocol_version, + feature_version, + ), + )); + } + + match version { + RequestVersion::V0(request_v0) => { + let result = self.query_identity_token_infos_v0( + request_v0, + platform_state, + platform_version, + )?; + Ok(result.map(|response_v0| GetIdentityTokenInfosResponse { + version: Some(ResponseVersion::V0(response_v0)), + })) + } + } + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/identity_token_infos/v0/mod.rs b/packages/rs-drive-abci/src/query/token_queries/identity_token_infos/v0/mod.rs new file mode 100644 index 00000000000..c013f8e9d9c --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/identity_token_infos/v0/mod.rs @@ -0,0 +1,89 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_identity_token_infos_request::GetIdentityTokenInfosRequestV0; +use dapi_grpc::platform::v0::get_identity_token_infos_response::{get_identity_token_infos_response_v0, GetIdentityTokenInfosResponseV0}; +use dapi_grpc::platform::v0::get_identity_token_infos_response::get_identity_token_infos_response_v0::{TokenIdentityInfoEntry, TokenInfoEntry, TokenInfos}; +use dpp::check_validation_result_with_data; +use dpp::identifier::Identifier; +use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; +use dpp::validation::ValidationResult; +use dpp::version::PlatformVersion; + +impl Platform { + pub(super) fn query_identity_token_infos_v0( + &self, + GetIdentityTokenInfosRequestV0 { + identity_id, + token_ids, + prove, + }: GetIdentityTokenInfosRequestV0, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let identity_id: Identifier = + check_validation_result_with_data!(identity_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "identity_id must be a valid identifier (32 bytes long)".to_string(), + ) + })); + + let token_ids: Vec<[u8; 32]> = check_validation_result_with_data!(token_ids + .into_iter() + .map(|token_id| { + token_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "token_id must be a valid identifier (32 bytes long)".to_string(), + ) + }) + }) + .collect::, QueryError>>()); + + let response = if prove { + let proof = check_validation_result_with_data!(self.drive.prove_identity_token_infos( + token_ids.as_slice(), + identity_id.into_buffer(), + None, + platform_version, + )); + + GetIdentityTokenInfosResponseV0 { + result: Some(get_identity_token_infos_response_v0::Result::Proof( + self.response_proof_v0(platform_state, proof), + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + } else { + let token_infos = self + .drive + .fetch_identity_token_infos( + token_ids.as_slice(), + identity_id.into_buffer(), + None, + platform_version, + )? + .into_iter() + .map(|(token_id, info)| { + let info = info.map(|identity_token_info| TokenIdentityInfoEntry { + frozen: identity_token_info.frozen(), + }); + TokenInfoEntry { + token_id: token_id.to_vec(), + info, + } + }) + .collect(); + + GetIdentityTokenInfosResponseV0 { + result: Some(get_identity_token_infos_response_v0::Result::TokenInfos( + TokenInfos { token_infos }, + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + }; + + Ok(QueryValidationResult::new_with_data(response)) + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/mod.rs b/packages/rs-drive-abci/src/query/token_queries/mod.rs index 80ed054e11b..3ffa5ac53f7 100644 --- a/packages/rs-drive-abci/src/query/token_queries/mod.rs +++ b/packages/rs-drive-abci/src/query/token_queries/mod.rs @@ -1,2 +1,4 @@ mod identities_token_balances; +mod identities_token_infos; mod identity_token_balances; +mod identity_token_infos; diff --git a/packages/rs-drive/Cargo.toml b/packages/rs-drive/Cargo.toml index 26ec8c66e18..98af1c8e18a 100644 --- a/packages/rs-drive/Cargo.toml +++ b/packages/rs-drive/Cargo.toml @@ -100,6 +100,7 @@ server = [ "parking_lot", "arc-swap", "moka", + "dpp/validation", "dpp/platform-value-json", "dpp/system_contracts", "dpp/state-transitions", diff --git a/packages/rs-drive/src/drive/document/delete/mod.rs b/packages/rs-drive/src/drive/document/delete/mod.rs index 04b780b6d5d..7edbfa42a27 100644 --- a/packages/rs-drive/src/drive/document/delete/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/mod.rs @@ -69,6 +69,7 @@ mod tests { use crate::query::DriveDocumentQuery; use dpp::block::epoch::Epoch; use dpp::data_contract::accessors::v0::DataContractV0Getters; + use dpp::data_contract::DataContract; use dpp::document::serialization_traits::DocumentPlatformConversionMethodsV0; use dpp::document::Document; use dpp::fee::default_costs::KnownCostItem::StorageDiskUsageCreditPerByte; @@ -99,7 +100,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-reduced.json", None, None, - None, + None::, None, None, ); @@ -196,7 +197,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-reduced.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -340,7 +341,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-reduced.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -527,7 +528,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-reduced.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -805,7 +806,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -908,7 +909,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); diff --git a/packages/rs-drive/src/drive/document/insert/mod.rs b/packages/rs-drive/src/drive/document/insert/mod.rs index a351a305ccf..7db26e9df2c 100644 --- a/packages/rs-drive/src/drive/document/insert/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/mod.rs @@ -51,11 +51,11 @@ mod tests { use once_cell::sync::Lazy; use std::collections::BTreeMap; - use dpp::block::epoch::Epoch; - use dpp::data_contract::accessors::v0::DataContractV0Getters; - use crate::util::object_size_info::DocumentInfo::DocumentRefInfo; use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; + use dpp::block::epoch::Epoch; + use dpp::data_contract::accessors::v0::DataContractV0Getters; + use dpp::data_contract::DataContract; use dpp::fee::default_costs::KnownCostItem::StorageDiskUsageCreditPerByte; use dpp::fee::default_costs::{CachedEpochIndexFeeVersions, EpochCosts}; use dpp::fee::fee_result::FeeResult; @@ -166,7 +166,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -265,7 +265,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -333,7 +333,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -401,7 +401,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -469,7 +469,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -548,7 +548,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-all-mutable.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -644,7 +644,7 @@ mod tests { "tests/supporting_files/contract/dpns/dpns-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); diff --git a/packages/rs-drive/src/drive/document/update/mod.rs b/packages/rs-drive/src/drive/document/update/mod.rs index 793594a31f0..cd5ef18a076 100644 --- a/packages/rs-drive/src/drive/document/update/mod.rs +++ b/packages/rs-drive/src/drive/document/update/mod.rs @@ -685,7 +685,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -777,7 +777,7 @@ mod tests { "tests/supporting_files/contract/dashpay/dashpay-contract-with-profile-history.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -871,7 +871,15 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, None, None, transaction.as_ref(), None); + let contract = setup_contract( + &drive, + path, + None, + None, + None::, + transaction.as_ref(), + None, + ); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1166,7 +1174,15 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, None, None, transaction.as_ref(), None); + let contract = setup_contract( + &drive, + path, + None, + None, + None::, + transaction.as_ref(), + None, + ); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1365,7 +1381,15 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, None, None, transaction.as_ref(), None); + let contract = setup_contract( + &drive, + path, + None, + None, + None::, + transaction.as_ref(), + None, + ); let id = Identifier::from([1u8; 32]); let owner_id = Identifier::from([2u8; 32]); @@ -1700,7 +1724,15 @@ mod tests { }; // setup code - let contract = setup_contract(&drive, path, None, None, None, transaction.as_ref(), None); + let contract = setup_contract( + &drive, + path, + None, + None, + None::, + transaction.as_ref(), + None, + ); let person_0_original = Person { id: Identifier::from([0u8; 32]), diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs index aca14dbbac5..3a41cda8be5 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs @@ -40,7 +40,7 @@ impl Drive { .methods .token .fetch - .identity_token_balances + .identities_token_balances { 0 => self.fetch_identities_token_balances_v0( token_id, @@ -132,7 +132,7 @@ impl Drive { .methods .token .fetch - .identity_token_balances + .identities_token_balances { 0 => self.fetch_identities_token_balances_operations_v0( token_id, diff --git a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/mod.rs index 969fd63690b..4549f680a08 100644 --- a/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/prove_identities_token_balances/mod.rs @@ -38,7 +38,7 @@ impl Drive { .methods .token .prove - .identity_token_balances + .identities_token_balances { 0 => self.prove_identities_token_balances_v0( token_id, @@ -130,7 +130,7 @@ impl Drive { .methods .token .prove - .identity_token_balances + .identities_token_balances { 0 => self.prove_identities_token_balances_operations_v0( token_id, diff --git a/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs b/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs index 5b7acf9597a..8b1210d7e07 100644 --- a/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs @@ -1,4 +1,4 @@ -use crate::drive::tokens::{token_identity_infos_path, token_identity_infos_path_vec}; +use crate::drive::tokens::token_identity_infos_path; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; diff --git a/packages/rs-drive/src/drive/tokens/info/fetch_identities_token_infos/mod.rs b/packages/rs-drive/src/drive/tokens/info/fetch_identities_token_infos/mod.rs new file mode 100644 index 00000000000..33fac51df92 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/fetch_identities_token_infos/mod.rs @@ -0,0 +1,151 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::tokens::info::IdentityTokenInfo; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; +use std::collections::BTreeMap; + +impl Drive { + /// Fetches the token infos of an identity from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose infos are to be fetched. + /// * `identity_id` - The ID of the identity whose token infos are being queried. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding infos, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identities_token_infos( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identities_token_infos + { + 0 => self.fetch_identities_token_infos_v0( + token_id, + identity_ids, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_infos".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the identity's token infos with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to fetch the infos for. + /// * `identity_id` - The identity's ID whose infos are being queried. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result<((BTreeMap<[u8; 32], Option>), FeeResult), Error>` - A tuple containing a map of token infos and the associated fee result. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identities_token_infos_with_costs( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(BTreeMap<[u8; 32], Option>, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_identities_token_infos_operations( + token_id, + identity_ids, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to fetch the identity's token infos from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the infos for. + /// * `identity_id` - The ID of the identity whose token infos are being queried. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding infos, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identities_token_infos_operations( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identities_token_infos + { + 0 => self.fetch_identities_token_infos_operations_v0( + token_id, + identity_ids, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identities_token_infos_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/fetch_identities_token_infos/v0/mod.rs b/packages/rs-drive/src/drive/tokens/info/fetch_identities_token_infos/v0/mod.rs new file mode 100644 index 00000000000..e892dcd7aaf --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/fetch_identities_token_infos/v0/mod.rs @@ -0,0 +1,66 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::serialization::PlatformDeserializable; +use dpp::tokens::info::IdentityTokenInfo; +use dpp::version::PlatformVersion; +use grovedb::Element::Item; +use grovedb::TransactionArg; +use std::collections::BTreeMap; + +impl Drive { + pub(super) fn fetch_identities_token_infos_v0( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + self.fetch_identities_token_infos_operations_v0( + token_id, + identity_ids, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_identities_token_infos_operations_v0( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + let path_query = Self::token_infos_for_identity_ids_query(token_id, identity_ids); + + self.grove_get_raw_path_query_with_optional( + &path_query, + false, + transaction, + drive_operations, + &platform_version.drive, + )? + .into_iter() + .map(|(_, key, element)| { + let identity_id: [u8; 32] = key.try_into().map_err(|_| { + Error::Drive(DriveError::CorruptedDriveState( + "identity id not 32 bytes".to_string(), + )) + })?; + match element { + Some(Item(value, ..)) => Ok(( + identity_id, + Some(IdentityTokenInfo::deserialize_from_bytes(&value)?), + )), + None => Ok((identity_id, None)), + _ => Err(Error::Drive(DriveError::CorruptedDriveState( + "token tree for infos should contain only items".to_string(), + ))), + } + }) + .collect() + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/mod.rs b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/mod.rs new file mode 100644 index 00000000000..a8335427f8a --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/mod.rs @@ -0,0 +1,151 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::tokens::info::IdentityTokenInfo; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; +use std::collections::BTreeMap; + +impl Drive { + /// Fetches the token infos of an identity from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose infos are to be fetched. + /// * `identity_id` - The ID of the identity whose token infos are being queried. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding infos, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identity_token_infos( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_infos + { + 0 => self.fetch_identity_token_infos_v0( + token_ids, + identity_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_infos".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the identity's token infos with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to fetch the infos for. + /// * `identity_id` - The identity's ID whose infos are being queried. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result<((BTreeMap<[u8; 32], Option>), FeeResult), Error>` - A tuple containing a map of token infos and the associated fee result. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identity_token_infos_with_costs( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(BTreeMap<[u8; 32], Option>, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_identity_token_infos_operations( + token_ids, + identity_id, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to fetch the identity's token infos from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the infos for. + /// * `identity_id` - The ID of the identity whose token infos are being queried. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding infos, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_identity_token_infos_operations( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_infos + { + 0 => self.fetch_identity_token_infos_operations_v0( + token_ids, + identity_id, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_infos_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/v0/mod.rs b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/v0/mod.rs new file mode 100644 index 00000000000..798f2bd3d8c --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/v0/mod.rs @@ -0,0 +1,87 @@ +use crate::drive::tokens::{tokens_root_path_vec, TOKEN_IDENTITY_INFO_KEY}; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::serialization::PlatformDeserializable; +use dpp::tokens::info::IdentityTokenInfo; +use dpp::version::PlatformVersion; +use grovedb::Element::Item; +use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; +use std::collections::BTreeMap; + +impl Drive { + pub(super) fn fetch_identity_token_infos_v0( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + self.fetch_identity_token_infos_operations_v0( + token_ids, + identity_id, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_identity_token_infos_operations_v0( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + let tokens_root = tokens_root_path_vec(); + + let mut query = Query::new(); + + for token_id in token_ids { + query.insert_key(token_id.to_vec()); + } + + query.set_subquery_path(vec![vec![TOKEN_IDENTITY_INFO_KEY], identity_id.to_vec()]); + + let path_query = PathQuery::new( + tokens_root, + SizedQuery::new(query, Some(token_ids.len() as u16), None), + ); + + self.grove_get_raw_path_query_with_optional( + &path_query, + false, + transaction, + drive_operations, + &platform_version.drive, + )? + .into_iter() + .map(|(path, _, element)| { + let token_id: [u8; 32] = path + .get(1) + .ok_or(Error::Drive(DriveError::CorruptedDriveState( + "returned path item should always have a second part at index 1".to_string(), + )))? + .clone() + .try_into() + .map_err(|_| { + Error::Drive(DriveError::CorruptedDriveState( + "token id not 32 bytes".to_string(), + )) + })?; + match element { + Some(Item(value, ..)) => Ok(( + identity_id, + Some(IdentityTokenInfo::deserialize_from_bytes(&value)?), + )), + None => Ok((token_id, None)), + _ => Err(Error::Drive(DriveError::CorruptedDriveState( + "token tree for infos should contain only items".to_string(), + ))), + } + }) + .collect() + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/mod.rs b/packages/rs-drive/src/drive/tokens/info/mod.rs new file mode 100644 index 00000000000..71786d1fd42 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/mod.rs @@ -0,0 +1,9 @@ +#[cfg(feature = "server")] +mod fetch_identities_token_infos; +#[cfg(feature = "server")] +mod fetch_identity_token_infos; +#[cfg(feature = "server")] +mod prove_identities_token_infos; +#[cfg(feature = "server")] +mod prove_identity_token_infos; +mod queries; diff --git a/packages/rs-drive/src/drive/tokens/info/prove_identities_token_infos/mod.rs b/packages/rs-drive/src/drive/tokens/info/prove_identities_token_infos/mod.rs new file mode 100644 index 00000000000..918eeafe949 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/prove_identities_token_infos/mod.rs @@ -0,0 +1,149 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Proves the token infos of an identity from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose infos are to be proveed. + /// * `identity_id` - The ID of the identity whose token infos are being queried. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identities_token_infos( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .prove + .identity_token_infos + { + 0 => self.prove_identities_token_infos_v0( + token_id, + identity_ids, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_identity_token_infos".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Proves the identity's token infos with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to prove the infos for. + /// * `identity_id` - The identity's ID whose infos are being queried. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identities_token_infos_with_costs( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(Vec, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.prove_identities_token_infos_operations( + token_id, + identity_ids, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to prove the identity's token infos from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the infos for. + /// * `identity_id` - The ID of the identity whose token infos are being queried. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identities_token_infos_operations( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .prove + .identity_token_infos + { + 0 => self.prove_identities_token_infos_operations_v0( + token_id, + identity_ids, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_identities_token_infos_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/prove_identities_token_infos/v0/mod.rs b/packages/rs-drive/src/drive/tokens/info/prove_identities_token_infos/v0/mod.rs new file mode 100644 index 00000000000..d74ae92a503 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/prove_identities_token_infos/v0/mod.rs @@ -0,0 +1,353 @@ +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + pub(super) fn prove_identities_token_infos_v0( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.prove_identities_token_infos_operations_v0( + token_id, + identity_ids, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn prove_identities_token_infos_operations_v0( + &self, + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let path_query = Self::token_infos_for_identity_ids_query(token_id, identity_ids); + + self.grove_get_proved_path_query( + &path_query, + transaction, + drive_operations, + &platform_version.drive, + ) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::util::test_helpers::setup::setup_drive_with_initial_state_structure; + use dpp::block::block_info::BlockInfo; + use dpp::data_contract::accessors::v1::DataContractV1Getters; + use dpp::data_contract::associated_token::token_configuration::v0::TokenConfigurationV0; + use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; + use dpp::data_contract::config::v0::DataContractConfigV0; + use dpp::data_contract::config::DataContractConfig; + use dpp::data_contract::v1::DataContractV1; + use dpp::identity::Identity; + use std::collections::BTreeMap; + + use dpp::identity::accessors::IdentityGettersV0; + use dpp::prelude::DataContract; + use dpp::tokens::info::IdentityTokenInfo; + use dpp::version::PlatformVersion; + + #[test] + fn should_prove_a_single_identity_token_info() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = Identity::random_identity(3, Some(14), platform_version) + .expect("expected a platform identity"); + + let identity_id = identity.id().to_buffer(); + + let contract = DataContract::V1(DataContractV1 { + id: Default::default(), + version: 0, + owner_id: Default::default(), + document_types: Default::default(), + metadata: None, + config: DataContractConfig::V0(DataContractConfigV0 { + can_be_deleted: false, + readonly: false, + keeps_history: false, + documents_keep_history_contract_default: false, + documents_mutable_contract_default: false, + documents_can_be_deleted_contract_default: false, + requires_identity_encryption_bounded_key: None, + requires_identity_decryption_bounded_key: None, + }), + schema_defs: None, + groups: Default::default(), + tokens: BTreeMap::from([( + 0, + TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()), + )]), + }); + let token_id = contract.token_id(0).expect("expected token at position 0"); + drive + .add_new_identity( + identity.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + + drive + .insert_contract( + &contract, + BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert contract"); + + drive + .token_freeze( + token_id, + identity.id(), + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to mint token"); + let proof = drive + .prove_identities_token_infos_v0( + token_id.to_buffer(), + &vec![identity.id().to_buffer()], + None, + platform_version, + ) + .expect("should not error when proving an identity"); + + let proved_identity_info: BTreeMap<[u8; 32], Option> = + Drive::verify_token_infos_for_identity_ids( + proof.as_slice(), + token_id.to_buffer(), + &vec![identity.id().to_buffer()], + false, + platform_version, + ) + .expect("expect that this be verified") + .1; + + assert_eq!( + proved_identity_info, + BTreeMap::from([( + identity_id, + Some(IdentityTokenInfo::new(true, platform_version).expect("expected token info")) + )]) + ); + } + + #[test] + fn should_prove_a_single_identity_token_info_does_not_exist() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity = Identity::random_identity(3, Some(14), platform_version) + .expect("expected a platform identity"); + + let identity_id = identity.id().to_buffer(); + + let contract = DataContract::V1(DataContractV1 { + id: Default::default(), + version: 0, + owner_id: Default::default(), + document_types: Default::default(), + metadata: None, + config: DataContractConfig::V0(DataContractConfigV0 { + can_be_deleted: false, + readonly: false, + keeps_history: false, + documents_keep_history_contract_default: false, + documents_mutable_contract_default: false, + documents_can_be_deleted_contract_default: false, + requires_identity_encryption_bounded_key: None, + requires_identity_decryption_bounded_key: None, + }), + schema_defs: None, + groups: Default::default(), + tokens: BTreeMap::from([( + 0, + TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()), + )]), + }); + let token_id = contract.token_id(0).expect("expected token at position 0"); + drive + .add_new_identity( + identity.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + + drive + .insert_contract( + &contract, + BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert contract"); + + let proof = drive + .prove_identities_token_infos_v0( + token_id.to_buffer(), + &vec![identity.id().to_buffer()], + None, + platform_version, + ) + .expect("should not error when proving an identity"); + + let proved_identity_info: BTreeMap<[u8; 32], Option> = + Drive::verify_token_infos_for_identity_ids( + proof.as_slice(), + token_id.to_buffer(), + &vec![identity.id().to_buffer()], + false, + platform_version, + ) + .expect("expect that this be verified") + .1; + + assert_eq!(proved_identity_info, BTreeMap::from([(identity_id, None)])); + } + + #[test] + fn should_prove_multiple_identity_single_token_infos() { + let drive = setup_drive_with_initial_state_structure(None); + + let platform_version = PlatformVersion::latest(); + + let identity_1 = Identity::random_identity(3, Some(14), platform_version) + .expect("expected a platform identity"); + + let identity_1_id = identity_1.id().to_buffer(); + + let identity_2 = Identity::random_identity(3, Some(15), platform_version) + .expect("expected a platform identity"); + + let identity_2_id = identity_2.id().to_buffer(); + + let contract = DataContract::V1(DataContractV1 { + id: Default::default(), + version: 0, + owner_id: Default::default(), + document_types: Default::default(), + metadata: None, + config: DataContractConfig::V0(DataContractConfigV0 { + can_be_deleted: false, + readonly: false, + keeps_history: false, + documents_keep_history_contract_default: false, + documents_mutable_contract_default: false, + documents_can_be_deleted_contract_default: false, + requires_identity_encryption_bounded_key: None, + requires_identity_decryption_bounded_key: None, + }), + schema_defs: None, + groups: Default::default(), + tokens: BTreeMap::from([( + 0, + TokenConfiguration::V0(TokenConfigurationV0::default_most_restrictive()), + )]), + }); + let token_id = contract.token_id(0).expect("expected token at position 0"); + drive + .add_new_identity( + identity_1.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + + drive + .add_new_identity( + identity_2.clone(), + false, + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to add an identity"); + + drive + .insert_contract( + &contract, + BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to insert contract"); + + drive + .token_freeze( + token_id, + identity_1.id(), + &BlockInfo::default(), + true, + None, + platform_version, + ) + .expect("expected to mint token"); + + let proof = drive + .prove_identities_token_infos_v0( + token_id.to_buffer(), + &vec![identity_1.id().to_buffer(), identity_2.id().to_buffer()], + None, + platform_version, + ) + .expect("should not error when proving an identity"); + + let proved_identity_info: BTreeMap<[u8; 32], Option> = + Drive::verify_token_infos_for_identity_ids( + proof.as_slice(), + token_id.to_buffer(), + &vec![identity_1.id().to_buffer(), identity_2.id().to_buffer()], + false, + platform_version, + ) + .expect("expect that this be verified") + .1; + + assert_eq!( + proved_identity_info, + BTreeMap::from([ + ( + identity_1_id, + Some( + IdentityTokenInfo::new(true, platform_version) + .expect("expected token info") + ) + ), + (identity_2_id, None) + ]) + ); + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/prove_identity_token_infos/mod.rs b/packages/rs-drive/src/drive/tokens/info/prove_identity_token_infos/mod.rs new file mode 100644 index 00000000000..a43d6083acb --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/prove_identity_token_infos/mod.rs @@ -0,0 +1,149 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Fetches the token infos of an identity from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose infos are to be proveed. + /// * `identity_id` - The ID of the identity whose token infos are being queried. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identity_token_infos( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .prove + .identity_token_infos + { + 0 => self.prove_identity_token_infos_v0( + token_ids, + identity_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_identity_token_infos".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the identity's token infos with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to prove the infos for. + /// * `identity_id` - The identity's ID whose infos are being queried. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identity_token_infos_with_costs( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(Vec, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.prove_identity_token_infos_operations( + token_ids, + identity_id, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to prove the identity's token infos from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the infos for. + /// * `identity_id` - The ID of the identity whose token infos are being queried. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_identity_token_infos_operations( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .prove + .identity_token_infos + { + 0 => self.prove_identity_token_infos_operations_v0( + token_ids, + identity_id, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_identity_token_infos_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/prove_identity_token_infos/v0/mod.rs b/packages/rs-drive/src/drive/tokens/info/prove_identity_token_infos/v0/mod.rs new file mode 100644 index 00000000000..15e32ac2098 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/prove_identity_token_infos/v0/mod.rs @@ -0,0 +1,55 @@ +use crate::drive::tokens::{tokens_root_path_vec, TOKEN_IDENTITY_INFO_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::version::PlatformVersion; +use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; + +impl Drive { + pub(super) fn prove_identity_token_infos_v0( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.prove_identity_token_infos_operations_v0( + token_ids, + identity_id, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn prove_identity_token_infos_operations_v0( + &self, + token_ids: &[[u8; 32]], + identity_id: [u8; 32], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let tokens_root = tokens_root_path_vec(); + + let mut query = Query::new(); + + for token_id in token_ids { + query.insert_key(token_id.to_vec()); + } + + query.set_subquery_path(vec![vec![TOKEN_IDENTITY_INFO_KEY], identity_id.to_vec()]); + + let path_query = PathQuery::new( + tokens_root, + SizedQuery::new(query, Some(token_ids.len() as u16), None), + ); + + self.grove_get_proved_path_query( + &path_query, + transaction, + drive_operations, + &platform_version.drive, + ) + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/queries.rs b/packages/rs-drive/src/drive/tokens/info/queries.rs new file mode 100644 index 00000000000..8ace79a45a2 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/queries.rs @@ -0,0 +1,72 @@ +use crate::drive::tokens::token_identity_infos_path_vec; +use crate::drive::Drive; +use crate::query::{Query, QueryItem}; +use grovedb::{PathQuery, SizedQuery}; +use std::ops::RangeFull; + +impl Drive { + /// The query for proving the identities info of a token from an identity id. + pub fn token_info_for_identity_id_query( + token_id: [u8; 32], + identity_id: [u8; 32], + ) -> PathQuery { + let info_path = token_identity_infos_path_vec(token_id); + PathQuery::new_single_key(info_path, identity_id.to_vec()) + } + + /// The query getting a token info for many identities + pub fn token_infos_for_identity_ids_query( + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + ) -> PathQuery { + let info_path = token_identity_infos_path_vec(token_id); + let mut query = Query::new(); + query.insert_keys(identity_ids.iter().map(|key| key.to_vec()).collect()); + PathQuery { + path: info_path, + query: SizedQuery { + query, + limit: Some(identity_ids.len() as u16), + offset: None, + }, + } + } + + /// The query getting token infos for identities in a range + pub fn token_infos_for_range_query( + token_id: [u8; 32], + start_at: Option<([u8; 32], bool)>, + ascending: bool, + limit: u16, + ) -> PathQuery { + let info_path = token_identity_infos_path_vec(token_id); + let mut query = Query::new_with_direction(ascending); + if ascending { + if let Some((start_at, start_at_included)) = start_at { + if start_at_included { + query.insert_item(QueryItem::RangeFrom(start_at.to_vec()..)) + } else { + query.insert_item(QueryItem::RangeAfter(start_at.to_vec()..)) + } + } else { + query.insert_item(QueryItem::RangeFull(RangeFull)) + } + } else if let Some((start_at, start_at_included)) = start_at { + if start_at_included { + query.insert_item(QueryItem::RangeToInclusive(..=start_at.to_vec())) + } else { + query.insert_item(QueryItem::RangeTo(..start_at.to_vec())) + } + } else { + query.insert_item(QueryItem::RangeFull(RangeFull)) + } + PathQuery { + path: info_path, + query: SizedQuery { + query, + limit: Some(limit), + offset: None, + }, + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index 64c1d16914c..3b8c5541694 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -5,6 +5,7 @@ pub mod balance; pub mod burn; pub mod estimated_costs; pub mod freeze; +mod info; pub mod mint; pub mod system; pub mod transfer; diff --git a/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs b/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs index 9ea87b8cead..da0524e1ce1 100644 --- a/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs @@ -1,4 +1,4 @@ -use crate::drive::tokens::{token_identity_infos_path, token_identity_infos_path_vec}; +use crate::drive::tokens::token_identity_infos_path; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs index ba7d64ad56f..8ccfc485785 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/mod.rs @@ -223,16 +223,16 @@ mod tests { use super::*; + use crate::util::test_helpers::setup_contract; use dpp::block::block_info::BlockInfo; use dpp::data_contract::accessors::v0::DataContractV0Getters; + use dpp::data_contract::DataContract; use dpp::serialization::PlatformSerializableWithPlatformVersion; use dpp::tests::json_document::{json_document_to_contract, json_document_to_document}; use dpp::util::cbor_serializer; use rand::Rng; use serde_json::json; - use crate::util::test_helpers::setup_contract; - use crate::util::batch::drive_op_batch::document::DocumentOperation::{ AddOperation, UpdateOperation, }; @@ -604,7 +604,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -718,7 +718,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-only-age-index.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -938,7 +938,7 @@ mod tests { "tests/supporting_files/contract/family/family-contract-only-age-index.json", None, None, - None, + None::, Some(&db_transaction), None, ); diff --git a/packages/rs-drive/src/verify/tokens/mod.rs b/packages/rs-drive/src/verify/tokens/mod.rs index 7f169cda4e2..9110a47eed3 100644 --- a/packages/rs-drive/src/verify/tokens/mod.rs +++ b/packages/rs-drive/src/verify/tokens/mod.rs @@ -1 +1,2 @@ mod verify_token_balances_for_identity_ids; +mod verify_token_infos_for_identity_ids; diff --git a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs index 96d3f2ecabe..3bfa94f7a91 100644 --- a/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs +++ b/packages/rs-drive/src/verify/tokens/verify_token_balances_for_identity_ids/v0/mod.rs @@ -6,7 +6,6 @@ use crate::error::Error; use crate::verify::RootHash; use dpp::balances::credits::TokenAmount; -use dpp::fee::Credits; use grovedb::GroveDb; use platform_version::version::PlatformVersion; @@ -47,7 +46,7 @@ impl Drive { match maybe_element { None => Ok((key.into(), None)), Some(element) => { - let balance: Credits = element + let balance: TokenAmount = element .as_sum_item_value() .map_err(Error::GroveDB)? .try_into() diff --git a/packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/mod.rs new file mode 100644 index 00000000000..b936762a97d --- /dev/null +++ b/packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/mod.rs @@ -0,0 +1,79 @@ +mod v0; + +use crate::drive::Drive; +use dpp::tokens::info::IdentityTokenInfo; + +use crate::error::drive::DriveError; + +use crate::error::Error; + +use crate::verify::RootHash; + +use dpp::version::PlatformVersion; + +impl Drive { + /// Verifies the token infos for a set of identity IDs. + /// + /// This function checks the token infos of multiple identities by verifying the provided + /// proof against the specified token ID and identity IDs. It also supports verifying a subset + /// of a larger proof if necessary. + /// + /// # Parameters + /// + /// - `proof`: A byte slice representing the proof of authentication from the user. This is used + /// to verify the validity of the identity and its associated info. + /// - `token_id`: A 32-byte array representing the unique identifier for the token whose info + /// is being verified. + /// - `identity_ids`: A slice of 32-byte arrays, each representing a unique identity ID. These + /// are the identities whose token infos are being verified. + /// - `verify_subset_of_proof`: A boolean flag indicating whether the proof being verified is a + /// subset of a larger proof. If `true`, the verification will consider only a part of the proof. + /// - `platform_version`: The version of the platform against which the identity token infos are + /// being verified. This ensures compatibility with the correct API version. + /// + /// # Returns + /// + /// - `Result<(RootHash, BTreeMap<[u8; 32], Option>), Error>`: If the verification is successful: + /// - `RootHash`: The root hash of the GroveDB, representing the state of the database. + /// - `BTreeMap<[u8; 32], Option>`: A map of identity IDs to their associated token infos. + /// + /// # Errors + /// + /// The function will return an `Error` if any of the following occur: + /// + /// - The provided authentication proof is invalid. + /// - The provided identity ID does not correspond to a valid info. + /// - The provided platform version is unknown or unsupported. + /// + pub fn verify_token_infos_for_identity_ids< + T: FromIterator<(I, Option)>, + I: From<[u8; 32]>, + >( + proof: &[u8], + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + verify_subset_of_proof: bool, + platform_version: &PlatformVersion, + ) -> Result<(RootHash, T), Error> { + match platform_version + .drive + .methods + .verify + .token + .verify_token_infos_for_identity_ids + { + 0 => Self::verify_token_infos_for_identity_ids_v0( + proof, + token_id, + identity_ids, + verify_subset_of_proof, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "verify_token_infos_for_identity_ids".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/v0/mod.rs b/packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/v0/mod.rs new file mode 100644 index 00000000000..4c4a6092e47 --- /dev/null +++ b/packages/rs-drive/src/verify/tokens/verify_token_infos_for_identity_ids/v0/mod.rs @@ -0,0 +1,65 @@ +use crate::drive::Drive; + +use crate::error::proof::ProofError; +use crate::error::Error; + +use crate::verify::RootHash; + +use dpp::serialization::PlatformDeserializable; +use dpp::tokens::info::IdentityTokenInfo; +use grovedb::GroveDb; +use platform_version::version::PlatformVersion; + +impl Drive { + pub(super) fn verify_token_infos_for_identity_ids_v0< + T: FromIterator<(I, Option)>, + I: From<[u8; 32]>, + >( + proof: &[u8], + token_id: [u8; 32], + identity_ids: &[[u8; 32]], + verify_subset_of_proof: bool, + platform_version: &PlatformVersion, + ) -> Result<(RootHash, T), Error> { + let path_query = Self::token_infos_for_identity_ids_query(token_id, identity_ids); + let (root_hash, proved_key_values) = if verify_subset_of_proof { + GroveDb::verify_subset_query_with_absence_proof( + proof, + &path_query, + &platform_version.drive.grove_version, + )? + } else { + GroveDb::verify_query_with_absence_proof( + proof, + &path_query, + &platform_version.drive.grove_version, + )? + }; + if proved_key_values.len() == identity_ids.len() { + let values = proved_key_values + .into_iter() + .map(|proved_key_value| { + let key: [u8; 32] = proved_key_value + .1 + .try_into() + .map_err(|_| Error::Proof(ProofError::IncorrectValueSize("value size")))?; + let maybe_element = proved_key_value.2; + match maybe_element { + None => Ok((key.into(), None)), + Some(element) => { + let info_bytes = element.as_item_bytes().map_err(Error::GroveDB)?; + let info = IdentityTokenInfo::deserialize_from_bytes(info_bytes)?; + Ok((key.into(), Some(info))) + } + } + }) + .collect::>()?; + Ok((root_hash, values)) + } else { + Err(Error::Proof(ProofError::WrongElementCount { + expected: identity_ids.len(), + got: proved_key_values.len(), + })) + } + } +} diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs index 9597fc72b25..4283f8314c0 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs @@ -26,6 +26,8 @@ pub struct DriveAbciQueryPrefundedSpecializedBalancesVersions { pub struct DriveAbciQueryTokenVersions { pub identity_token_balances: FeatureVersionBounds, pub identities_token_balances: FeatureVersionBounds, + pub identities_token_infos: FeatureVersionBounds, + pub identity_token_infos: FeatureVersionBounds, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs index 69a05a0ae7e..abfd943ca29 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs @@ -84,6 +84,16 @@ pub const DRIVE_ABCI_QUERY_VERSIONS_V1: DriveAbciQueryVersions = DriveAbciQueryV max_version: 0, default_current_version: 0, }, + identities_token_infos: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identity_token_infos: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, }, validator_queries: DriveAbciQueryValidatorVersions { proposed_block_counts_by_evonode_ids: FeatureVersionBounds { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 22971a365b3..7fd86fe126f 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -13,12 +13,20 @@ pub struct DriveTokenMethodVersions { pub struct DriveTokenFetchMethodVersions { pub identity_token_balance: FeatureVersion, pub identity_token_balances: FeatureVersion, + pub identities_token_balances: FeatureVersion, + pub identity_token_info: FeatureVersion, + pub identity_token_infos: FeatureVersion, + pub identities_token_infos: FeatureVersion, } #[derive(Clone, Debug, Default)] pub struct DriveTokenProveMethodVersions { pub identity_token_balance: FeatureVersion, pub identity_token_balances: FeatureVersion, + pub identities_token_balances: FeatureVersion, + pub identity_token_info: FeatureVersion, + pub identity_token_infos: FeatureVersion, + pub identities_token_infos: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index 5fc38099b7f..2e12260ad6f 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -7,10 +7,18 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM fetch: DriveTokenFetchMethodVersions { identity_token_balance: 0, identity_token_balances: 0, + identities_token_balances: 0, + identity_token_info: 0, + identity_token_infos: 0, + identities_token_infos: 0, }, prove: DriveTokenProveMethodVersions { identity_token_balance: 0, identity_token_balances: 0, + identities_token_balances: 0, + identity_token_info: 0, + identity_token_infos: 0, + identities_token_infos: 0, }, update: DriveTokenUpdateMethodVersions { create_token_trees: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs index f42756e4d5e..e23fd54276e 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/mod.rs @@ -47,6 +47,7 @@ pub struct DriveVerifyIdentityMethodVersions { pub struct DriveVerifyTokenMethodVersions { pub verify_token_balances_for_identity_ids: FeatureVersion, pub verify_token_balances_for_identity_id: FeatureVersion, + pub verify_token_infos_for_identity_ids: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs index d012f3e6acf..56813f3b0b0 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_verify_method_versions/v1.rs @@ -32,6 +32,7 @@ pub const DRIVE_VERIFY_METHOD_VERSIONS_V1: DriveVerifyMethodVersions = DriveVeri token: DriveVerifyTokenMethodVersions { verify_token_balances_for_identity_ids: 0, verify_token_balances_for_identity_id: 0, + verify_token_infos_for_identity_ids: 0, }, single_document: DriveVerifySingleDocumentMethodVersions { verify_proof: 0, 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 1765d8d69ba..99513147dea 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -221,6 +221,16 @@ pub const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { max_version: 0, default_current_version: 0, }, + identities_token_infos: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + identity_token_infos: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, }, validator_queries: DriveAbciQueryValidatorVersions { proposed_block_counts_by_evonode_ids: FeatureVersionBounds { From 239c2cb95dfdfe64669e69cbe460a82a61a302c7 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Jan 2025 13:52:49 +0700 Subject: [PATCH 45/61] more work --- .../src/errors/consensus/basic/basic_error.rs | 10 +- .../src/errors/consensus/basic/token/mod.rs | 17 +- .../token_transfer_to_ourselves_error.rs | 44 ++ packages/rs-dpp/src/errors/consensus/codes.rs | 8 +- .../errors/consensus/state/identity/mod.rs | 3 + ...recipient_identity_does_not_exist_error.rs | 0 .../src/errors/consensus/state/state_error.rs | 9 +- ...oes_not_have_enough_token_balance_error.rs | 9 +- .../identity_token_account_frozen_error.rs | 51 ++ .../src/errors/consensus/state/token/mod.rs | 4 +- .../token/unauthorized_token_action_error.rs | 10 +- .../validate_basic_structure/v0/mod.rs | 21 +- .../structure_v0/mod.rs | 2 +- .../state_v0/mod.rs | 2 + .../state_v0/mod.rs | 6 +- .../state_v0/mod.rs | 7 +- .../state_v0/mod.rs | 28 +- .../state_v0/mod.rs | 1 + .../state_transitions/batch/mod.rs | 695 +++++++++++++++++- .../batch/transformer/v0/mod.rs | 2 - .../mod.rs | 0 .../v0/mod.rs | 0 .../rs-drive/src/drive/tokens/balance/mod.rs | 4 +- .../info/fetch_identity_token_info/mod.rs | 134 ++++ .../info/fetch_identity_token_info/v0/mod.rs | 73 ++ .../rs-drive/src/drive/tokens/info/mod.rs | 3 + 26 files changed, 1103 insertions(+), 40 deletions(-) create mode 100644 packages/rs-dpp/src/errors/consensus/basic/token/token_transfer_to_ourselves_error.rs rename packages/rs-dpp/src/errors/consensus/state/{token => identity}/recipient_identity_does_not_exist_error.rs (100%) create mode 100644 packages/rs-dpp/src/errors/consensus/state/token/identity_token_account_frozen_error.rs rename packages/rs-drive/src/drive/tokens/balance/{fetch => fetch_identity_token_balance}/mod.rs (100%) rename packages/rs-drive/src/drive/tokens/balance/{fetch => fetch_identity_token_balance}/v0/mod.rs (100%) create mode 100644 packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/v0/mod.rs diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index 6ddfc332366..1fed4bda6fe 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -69,11 +69,10 @@ use crate::consensus::ConsensusError; use crate::consensus::basic::group::GroupActionNotAllowedOnTransitionError; use crate::consensus::basic::overflow_error::OverflowError; -use crate::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTokensError; use crate::consensus::basic::token::{ - ChoosingTokenMintRecipientNotAllowedError, DestinationIdentityForTokenMintingNotSetError, - InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, - InvalidTokenPositionError, + ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError, + DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidGroupPositionError, + InvalidTokenIdError, InvalidTokenPositionError, TokenTransferToOurselfError, }; use crate::consensus::basic::unsupported_version_error::UnsupportedVersionError; use crate::consensus::basic::value_error::ValueError; @@ -431,6 +430,9 @@ pub enum BasicError { #[error(transparent)] InvalidTokenPositionError(InvalidTokenPositionError), + #[error(transparent)] + TokenTransferToOurselfError(TokenTransferToOurselfError), + #[error(transparent)] ContractHasNoTokensError(ContractHasNoTokensError), diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs index ff2432f254c..efdcadc77af 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/token/mod.rs @@ -1,14 +1,17 @@ -pub mod choosing_token_mint_recipient_not_allowed_error; -pub mod contract_has_no_tokens_error; -pub mod destination_identity_for_token_minting_not_set_error; -pub mod invalid_action_id_error; -pub mod invalid_group_position_error; -pub mod invalid_token_id_error; -pub mod invalid_token_position_error; +mod choosing_token_mint_recipient_not_allowed_error; +mod contract_has_no_tokens_error; +mod destination_identity_for_token_minting_not_set_error; +mod invalid_action_id_error; +mod invalid_group_position_error; +mod invalid_token_id_error; +mod invalid_token_position_error; +mod token_transfer_to_ourselves_error; pub use choosing_token_mint_recipient_not_allowed_error::*; +pub use contract_has_no_tokens_error::*; pub use destination_identity_for_token_minting_not_set_error::*; pub use invalid_action_id_error::*; pub use invalid_group_position_error::*; pub use invalid_token_id_error::*; pub use invalid_token_position_error::*; +pub use token_transfer_to_ourselves_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/basic/token/token_transfer_to_ourselves_error.rs b/packages/rs-dpp/src/errors/consensus/basic/token/token_transfer_to_ourselves_error.rs new file mode 100644 index 00000000000..dbd1ee747c1 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/token/token_transfer_to_ourselves_error.rs @@ -0,0 +1,44 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Token transfer to the same identity is not allowed. Token ID: {}, Identity ID: {}", + token_id, + identity_id +)] +#[platform_serialize(unversioned)] +pub struct TokenTransferToOurselfError { + token_id: Identifier, + identity_id: Identifier, +} + +impl TokenTransferToOurselfError { + pub fn new(token_id: Identifier, identity_id: Identifier) -> Self { + Self { + token_id, + identity_id, + } + } + + pub fn token_id(&self) -> &Identifier { + &self.token_id + } + + pub fn identity_id(&self) -> &Identifier { + &self.identity_id + } +} + +impl From for ConsensusError { + fn from(err: TokenTransferToOurselfError) -> Self { + Self::BasicError(BasicError::TokenTransferToOurselfError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index e9d36bacc12..cf7571cfbf5 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -132,6 +132,7 @@ impl ErrorWithCode for BasicError { Self::ContractHasNoTokensError(_) => 10454, Self::DestinationIdentityForTokenMintingNotSetError(_) => 10455, Self::ChoosingTokenMintRecipientNotAllowedError(_) => 10456, + Self::TokenTransferToOurselfError(_) => 10457, // Identity Errors: 10500-10599 Self::DuplicatedIdentityPublicKeyBasicError(_) => 10500, @@ -233,9 +234,9 @@ impl ErrorWithCode for StateError { Self::DocumentContestNotPaidForError(_) => 40114, // Token errors: 40150-40199 - Self::RecipientIdentityDoesNotExistError(_) => 40150, - Self::IdentityDoesNotHaveEnoughTokenBalanceError(_) => 40151, - Self::UnauthorizedTokenActionError(_) => 40152, + Self::IdentityDoesNotHaveEnoughTokenBalanceError(_) => 40150, + Self::UnauthorizedTokenActionError(_) => 40151, + Self::IdentityTokenAccountFrozenError(_) => 40152, // Identity Errors: 40200-40299 Self::IdentityAlreadyExistsError(_) => 40200, @@ -254,6 +255,7 @@ impl ErrorWithCode for StateError { Self::DataContractUpdatePermissionError(_) => 40213, Self::MissingTransferKeyError(_) => 40214, Self::NoTransferKeyForCoreWithdrawalAvailableError(_) => 40215, + Self::RecipientIdentityDoesNotExistError(_) => 40216, // Voting Errors: 40300-40399 Self::MasternodeNotFoundError(_) => 40300, diff --git a/packages/rs-dpp/src/errors/consensus/state/identity/mod.rs b/packages/rs-dpp/src/errors/consensus/state/identity/mod.rs index 35e6f7f79a8..072bbda4ac3 100644 --- a/packages/rs-dpp/src/errors/consensus/state/identity/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/state/identity/mod.rs @@ -16,3 +16,6 @@ pub mod max_identity_public_key_limit_reached_error; pub mod missing_identity_public_key_ids_error; pub mod missing_transfer_key_error; pub mod no_transfer_key_for_core_withdrawal_available_error; + +mod recipient_identity_does_not_exist_error; +pub use recipient_identity_does_not_exist_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/state/token/recipient_identity_does_not_exist_error.rs b/packages/rs-dpp/src/errors/consensus/state/identity/recipient_identity_does_not_exist_error.rs similarity index 100% rename from packages/rs-dpp/src/errors/consensus/state/token/recipient_identity_does_not_exist_error.rs rename to packages/rs-dpp/src/errors/consensus/state/identity/recipient_identity_does_not_exist_error.rs diff --git a/packages/rs-dpp/src/errors/consensus/state/state_error.rs b/packages/rs-dpp/src/errors/consensus/state/state_error.rs index 620d794b329..9ab79f5e844 100644 --- a/packages/rs-dpp/src/errors/consensus/state/state_error.rs +++ b/packages/rs-dpp/src/errors/consensus/state/state_error.rs @@ -23,9 +23,7 @@ use crate::consensus::state::identity::invalid_identity_public_key_id_error::Inv use crate::consensus::state::identity::invalid_identity_revision_error::InvalidIdentityRevisionError; use crate::consensus::state::identity::max_identity_public_key_limit_reached_error::MaxIdentityPublicKeyLimitReachedError; use crate::consensus::state::identity::missing_identity_public_key_ids_error::MissingIdentityPublicKeyIdsError; -use crate::consensus::state::identity::{ - IdentityAlreadyExistsError, IdentityInsufficientBalanceError, -}; +use crate::consensus::state::identity::{IdentityAlreadyExistsError, IdentityInsufficientBalanceError, RecipientIdentityDoesNotExistError}; use crate::consensus::ConsensusError; use crate::consensus::state::data_contract::data_contract_update_permission_error::DataContractUpdatePermissionError; use crate::consensus::state::data_contract::document_type_update_error::DocumentTypeUpdateError; @@ -43,7 +41,7 @@ use crate::consensus::state::identity::missing_transfer_key_error::MissingTransf use crate::consensus::state::identity::no_transfer_key_for_core_withdrawal_available_error::NoTransferKeyForCoreWithdrawalAvailableError; use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_insufficient_error::PrefundedSpecializedBalanceInsufficientError; use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_not_found_error::PrefundedSpecializedBalanceNotFoundError; -use crate::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, RecipientIdentityDoesNotExistError, UnauthorizedTokenActionError}; +use crate::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountFrozenError, UnauthorizedTokenActionError}; use crate::consensus::state::voting::masternode_incorrect_voter_identity_id_error::MasternodeIncorrectVoterIdentityIdError; use crate::consensus::state::voting::masternode_incorrect_voting_address_error::MasternodeIncorrectVotingAddressError; use crate::consensus::state::voting::masternode_not_found_error::MasternodeNotFoundError; @@ -211,6 +209,9 @@ pub enum StateError { #[error(transparent)] UnauthorizedTokenActionError(UnauthorizedTokenActionError), + #[error(transparent)] + IdentityTokenAccountFrozenError(IdentityTokenAccountFrozenError), + #[error(transparent)] IdentityNotMemberOfGroupError(IdentityNotMemberOfGroupError), diff --git a/packages/rs-dpp/src/errors/consensus/state/token/identity_does_not_have_enough_token_balance_error.rs b/packages/rs-dpp/src/errors/consensus/state/token/identity_does_not_have_enough_token_balance_error.rs index ada238196e6..ba1c5b7fd61 100644 --- a/packages/rs-dpp/src/errors/consensus/state/token/identity_does_not_have_enough_token_balance_error.rs +++ b/packages/rs-dpp/src/errors/consensus/state/token/identity_does_not_have_enough_token_balance_error.rs @@ -10,14 +10,16 @@ use thiserror::Error; Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, )] #[error( - "Identity {} does not have enough token balance: required {}, actual {}, action: {}", + "Identity {} does not have enough balance for token {}: required {}, actual {}, action: {}", identity_id, + token_id, required_balance, actual_balance, action )] #[platform_serialize(unversioned)] pub struct IdentityDoesNotHaveEnoughTokenBalanceError { + token_id: Identifier, identity_id: Identifier, required_balance: u64, actual_balance: u64, @@ -26,18 +28,23 @@ pub struct IdentityDoesNotHaveEnoughTokenBalanceError { impl IdentityDoesNotHaveEnoughTokenBalanceError { pub fn new( + token_id: Identifier, identity_id: Identifier, required_balance: u64, actual_balance: u64, action: String, ) -> Self { Self { + token_id, identity_id, required_balance, actual_balance, action, } } + pub fn token_id(&self) -> &Identifier { + &self.token_id + } pub fn identity_id(&self) -> &Identifier { &self.identity_id diff --git a/packages/rs-dpp/src/errors/consensus/state/token/identity_token_account_frozen_error.rs b/packages/rs-dpp/src/errors/consensus/state/token/identity_token_account_frozen_error.rs new file mode 100644 index 00000000000..6d4a55e6092 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/token/identity_token_account_frozen_error.rs @@ -0,0 +1,51 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Identity {} account is frozen for token {}. Action attempted: {}", + identity_id, + token_id, + action +)] +#[platform_serialize(unversioned)] +pub struct IdentityTokenAccountFrozenError { + token_id: Identifier, + identity_id: Identifier, + action: String, +} + +impl IdentityTokenAccountFrozenError { + pub fn new(token_id: Identifier, identity_id: Identifier, action: String) -> Self { + Self { + token_id, + identity_id, + action, + } + } + + pub fn token_id(&self) -> &Identifier { + &self.token_id + } + + pub fn identity_id(&self) -> &Identifier { + &self.identity_id + } + + pub fn action(&self) -> &str { + &self.action + } +} + +impl From for ConsensusError { + fn from(err: IdentityTokenAccountFrozenError) -> Self { + Self::StateError(StateError::IdentityTokenAccountFrozenError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/state/token/mod.rs b/packages/rs-dpp/src/errors/consensus/state/token/mod.rs index 2a4e3ce701f..9d084d981b1 100644 --- a/packages/rs-dpp/src/errors/consensus/state/token/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/state/token/mod.rs @@ -1,7 +1,7 @@ mod identity_does_not_have_enough_token_balance_error; -mod recipient_identity_does_not_exist_error; +mod identity_token_account_frozen_error; mod unauthorized_token_action_error; pub use identity_does_not_have_enough_token_balance_error::*; -pub use recipient_identity_does_not_exist_error::*; +pub use identity_token_account_frozen_error::*; pub use unauthorized_token_action_error::*; diff --git a/packages/rs-dpp/src/errors/consensus/state/token/unauthorized_token_action_error.rs b/packages/rs-dpp/src/errors/consensus/state/token/unauthorized_token_action_error.rs index c71df7267a6..a1275eb7fdf 100644 --- a/packages/rs-dpp/src/errors/consensus/state/token/unauthorized_token_action_error.rs +++ b/packages/rs-dpp/src/errors/consensus/state/token/unauthorized_token_action_error.rs @@ -11,13 +11,15 @@ use thiserror::Error; Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, )] #[error( - "Identity {} is not authorized to perform action: {}. Authorized action takers: {:?}", + "Identity {} is not authorized to perform action: {} on token: {}. Authorized action takers: {:?}", identity_id, + token_id, action, authorized_action_takers )] #[platform_serialize(unversioned)] pub struct UnauthorizedTokenActionError { + token_id: Identifier, identity_id: Identifier, action: String, authorized_action_takers: AuthorizedActionTakers, @@ -25,17 +27,23 @@ pub struct UnauthorizedTokenActionError { impl UnauthorizedTokenActionError { pub fn new( + token_id: Identifier, identity_id: Identifier, action: String, authorized_action_takers: AuthorizedActionTakers, ) -> Self { Self { + token_id, identity_id, action, authorized_action_takers, } } + pub fn token_id(&self) -> &Identifier { + &self.token_id + } + pub fn identity_id(&self) -> &Identifier { &self.identity_id } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs index 354c402e376..8159c383345 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs @@ -16,11 +16,12 @@ use platform_version::version::PlatformVersion; use std::collections::btree_map::Entry; use std::collections::BTreeMap; use crate::consensus::basic::group::GroupActionNotAllowedOnTransitionError; -use crate::consensus::basic::token::{InvalidActionIdError, InvalidTokenIdError}; +use crate::consensus::basic::token::{InvalidActionIdError, InvalidTokenIdError, TokenTransferToOurselfError}; use crate::state_transition::batch_transition::batched_transition::BatchedTransitionRef; use crate::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; use crate::state_transition::batch_transition::batched_transition::token_transition_action_type::TransitionActionTypeGetter; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::batch_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; use crate::state_transition::StateTransitionLike; @@ -133,6 +134,24 @@ impl BatchTransition { ))); } + match transition { + TokenTransition::Burn(_) => {} + TokenTransition::Mint(_) => {} + TokenTransition::Transfer(transfer) => { + if transfer.recipient_id() == self.owner_id() { + // We can not transfer to ourselves + result.add_error(BasicError::TokenTransferToOurselfError( + TokenTransferToOurselfError::new( + transition.token_id(), + self.owner_id(), + ), + )); + } + } + TokenTransition::Freeze(_) => {} + TokenTransition::Unfreeze(_) => {} + } + // We need to verify that the action id given matches the expected action id // But only if we are the proposer if let Some(group_state_transition_info) = transition.base().using_group_info() { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs index 692620adcbe..57aca07ce92 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::consensus::basic::BasicError; -use dpp::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTokensError; +use dpp::consensus::basic::token::ContractHasNoTokensError; use dpp::consensus::basic::token::InvalidTokenPositionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs index bea78369c2e..da21b680fe8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs @@ -68,6 +68,7 @@ impl TokenBurnTransitionActionStateValidationV0 for TokenBurnTransitionAction { return Ok(SimpleConsensusValidationResult::new_with_error( ConsensusError::StateError(StateError::UnauthorizedTokenActionError( UnauthorizedTokenActionError::new( + self.token_id(), owner_id, "burn".to_string(), rules.authorized_to_make_change_action_takers().clone(), @@ -92,6 +93,7 @@ impl TokenBurnTransitionActionStateValidationV0 for TokenBurnTransitionAction { return Ok(SimpleConsensusValidationResult::new_with_error( ConsensusError::StateError(StateError::IdentityDoesNotHaveEnoughTokenBalanceError( IdentityDoesNotHaveEnoughTokenBalanceError::new( + self.token_id(), owner_id, self.burn_amount(), balance, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs index 4365b5c0ece..b33ebf5fcdc 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, UnauthorizedTokenActionError}; +use dpp::consensus::state::token::UnauthorizedTokenActionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; @@ -12,8 +12,7 @@ use drive::state_transition_action::document::documents_batch::document_transiti use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; -use crate::execution::types::execution_operation::ValidationOperation; -use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; use crate::platform_types::platform::PlatformStateRef; @@ -68,6 +67,7 @@ impl TokenFreezeTransitionActionStateValidationV0 for TokenFreezeTransitionActio return Ok(SimpleConsensusValidationResult::new_with_error( ConsensusError::StateError(StateError::UnauthorizedTokenActionError( UnauthorizedTokenActionError::new( + self.token_id(), owner_id, "freeze".to_string(), rules.authorized_to_make_change_action_takers().clone(), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs index 60504136f25..a4e0b36c8e7 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs @@ -1,7 +1,8 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; +use dpp::consensus::state::identity::RecipientIdentityDoesNotExistError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::{RecipientIdentityDoesNotExistError, UnauthorizedTokenActionError}; +use dpp::consensus::state::token::UnauthorizedTokenActionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; @@ -70,6 +71,7 @@ impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { return Ok(SimpleConsensusValidationResult::new_with_error( ConsensusError::StateError(StateError::UnauthorizedTokenActionError( UnauthorizedTokenActionError::new( + self.token_id(), owner_id, "mint".to_string(), rules.authorized_to_make_change_action_takers().clone(), @@ -88,6 +90,7 @@ impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { ConsensusError::StateError( StateError::UnauthorizedTokenActionError( UnauthorizedTokenActionError::new( + self.token_id(), owner_id, "mint".to_string(), rules.authorized_to_make_change_action_takers().clone(), @@ -103,6 +106,7 @@ impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { return Ok(SimpleConsensusValidationResult::new_with_error( ConsensusError::StateError(StateError::UnauthorizedTokenActionError( UnauthorizedTokenActionError::new( + self.token_id(), owner_id, "mint".to_string(), rules.authorized_to_make_change_action_takers().clone(), @@ -122,6 +126,7 @@ impl TokenMintTransitionActionStateValidationV0 for TokenMintTransitionAction { return Ok(SimpleConsensusValidationResult::new_with_error( ConsensusError::StateError(StateError::UnauthorizedTokenActionError( UnauthorizedTokenActionError::new( + self.token_id(), owner_id, "mint".to_string(), rules.authorized_to_make_change_action_takers().clone(), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs index 52d40495ad8..8ef5fa0a86a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs @@ -1,8 +1,9 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::IdentityDoesNotHaveEnoughTokenBalanceError; +use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountFrozenError}; use dpp::prelude::Identifier; +use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; use dpp::validation::SimpleConsensusValidationResult; use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction}; use dpp::version::PlatformVersion; @@ -63,6 +64,7 @@ impl TokenTransferTransitionActionStateValidationV0 for TokenTransferTransitionA return Ok(SimpleConsensusValidationResult::new_with_error( ConsensusError::StateError(StateError::IdentityDoesNotHaveEnoughTokenBalanceError( IdentityDoesNotHaveEnoughTokenBalanceError::new( + self.token_id(), owner_id, self.amount(), balance, @@ -72,6 +74,30 @@ impl TokenTransferTransitionActionStateValidationV0 for TokenTransferTransitionA )); } + // We need to verify that our token account is not frozen + + // We need to verify that we have enough of the token + let info = platform.drive.fetch_identity_token_info( + self.token_id().to_buffer(), + owner_id.to_buffer(), + transaction, + platform_version, + )?; + if let Some(info) = info { + // We have an info, we need to check that we are not frozen + if info.frozen() == true { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::IdentityTokenAccountFrozenError( + IdentityTokenAccountFrozenError::new( + self.token_id(), + owner_id, + "transfer".to_string(), + ), + )), + )); + } + }; + Ok(SimpleConsensusValidationResult::new()) } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs index 7b25f1207d8..50245570e78 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs @@ -67,6 +67,7 @@ impl TokenUnfreezeTransitionActionStateValidationV0 for TokenUnfreezeTransitionA return Ok(SimpleConsensusValidationResult::new_with_error( ConsensusError::StateError(StateError::UnauthorizedTokenActionError( UnauthorizedTokenActionError::new( + self.token_id(), owner_id, "unfreeze".to_string(), rules.authorized_to_make_change_action_takers().clone(), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index c492b653016..94686f58bac 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -9282,6 +9282,9 @@ mod tests { use crate::execution::validation::state_transition::tests::create_token_contract_with_owner_identity; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Setters; use dpp::data_contract::associated_token::token_configuration::TokenConfiguration; + use dpp::data_contract::change_control_rules::authorized_action_takers::AuthorizedActionTakers; + use dpp::data_contract::change_control_rules::v0::ChangeControlRulesV0; + use dpp::data_contract::change_control_rules::ChangeControlRules; use dpp::state_transition::batch_transition::methods::v1::DocumentsBatchTransitionMethodsV1; mod token_mint_tests { use super::*; @@ -12419,6 +12422,96 @@ mod tests { assert_eq!(token_balance, Some(expected_amount)); } + #[test] + fn test_token_transfer_to_ourself_should_fail() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + None::, + None, + platform_version, + ); + + let token_transfer_transition = BatchTransition::new_token_transfer_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + identity.id(), + None, + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_transfer_serialized_transition = token_transfer_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_transfer_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::UnpaidConsensusError( + ConsensusError::BasicError(BasicError::TokenTransferToOurselfError(_)) + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 100000 - 1337; + assert_eq!(token_balance, Some(100000)); + } + #[test] fn test_token_transfer_trying_to_send_more_than_we_have() { let platform_version = PlatformVersion::latest(); @@ -12740,6 +12833,106 @@ mod tests { mod token_freeze_tests { use super::*; + use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; + + #[test] + fn test_token_freeze() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (identity_2, _, _) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_freeze_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::ContractOwner, + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }, + )); + }), + None, + platform_version, + ); + + let freeze_transition = BatchTransition::new_token_freeze_transition( + token_id, + identity.id(), + contract.id(), + 0, + identity_2.id(), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let freeze_serialized_transition = freeze_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![freeze_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_frozen = platform + .drive + .fetch_identity_token_info( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token info") + .map(|info| info.frozen()); + assert_eq!(token_frozen, Some(true)); + } #[test] fn test_token_freeze_and_unfreeze() { @@ -12756,13 +12949,32 @@ mod tests { let (identity, signer, key) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); - let (identity_2, signer_2, key_2) = + let (identity_2, _, _) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); let (contract, token_id) = create_token_contract_with_owner_identity( &mut platform, identity.id(), - None::, + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_freeze_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::ContractOwner, + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }, + )); + token_configuration.set_unfreeze_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::ContractOwner, + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }, + )); + }), None, platform_version, ); @@ -12817,16 +13029,485 @@ mod tests { .unwrap() .expect("expected to commit transaction"); - let token_balance = platform + let token_frozen = platform .drive - .fetch_identity_token_balance( + .fetch_identity_token_info( token_id.to_buffer(), - identity.id().to_buffer(), + identity_2.id().to_buffer(), None, platform_version, ) - .expect("expected to fetch token balance"); - assert_eq!(token_balance, Some(100000)); + .expect("expected to fetch token info") + .map(|info| info.frozen()); + assert_eq!(token_frozen, Some(true)); + + let unfreeze_transition = BatchTransition::new_token_unfreeze_transition( + token_id, + identity.id(), + contract.id(), + 0, + identity_2.id(), + None, + None, + &key, + 3, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let unfreeze_serialized_transition = unfreeze_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![unfreeze_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_frozen = platform + .drive + .fetch_identity_token_info( + token_id.to_buffer(), + identity_2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token info") + .map(|info| info.frozen()); + assert_eq!(token_frozen, Some(false)); + } + + #[test] + fn test_token_frozen_receive_balance_allowed_sending_not_allowed_till_unfrozen() { + let platform_version = PlatformVersion::latest(); + let mut platform = TestPlatformBuilder::new() + .with_latest_protocol_version() + .build_with_mock_rpc() + .set_genesis_state(); + + let mut rng = StdRng::seed_from_u64(49853); + + let platform_state = platform.state.load(); + + let (identity, signer, key) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (recipient, signer2, key2) = + setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); + + let (contract, token_id) = create_token_contract_with_owner_identity( + &mut platform, + identity.id(), + Some(|token_configuration: &mut TokenConfiguration| { + token_configuration.set_freeze_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::ContractOwner, + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }, + )); + token_configuration.set_unfreeze_rules(ChangeControlRules::V0( + ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::ContractOwner, + authorized_to_change_authorized_action_takers: + AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + }, + )); + }), + None, + platform_version, + ); + + let freeze_transition = BatchTransition::new_token_freeze_transition( + token_id, + identity.id(), + contract.id(), + 0, + recipient.id(), + None, + None, + &key, + 2, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let freeze_serialized_transition = freeze_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![freeze_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_frozen = platform + .drive + .fetch_identity_token_info( + token_id.to_buffer(), + recipient.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token info") + .map(|info| info.frozen()); + assert_eq!(token_frozen, Some(true)); + + let token_transfer_transition = BatchTransition::new_token_transfer_transition( + token_id, + identity.id(), + contract.id(), + 0, + 1337, + recipient.id(), + None, + None, + None, + &key, + 3, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_transfer_serialized_transition = token_transfer_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_transfer_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 100000 - 1337; + assert_eq!(token_balance, Some(expected_amount)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + recipient.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 1337; + assert_eq!(token_balance, Some(expected_amount)); + + //now let's try sending our balance + + let token_transfer_back_transition = + BatchTransition::new_token_transfer_transition( + token_id, + recipient.id(), + contract.id(), + 0, + 300, + identity.id(), + None, + None, + None, + &key2, + 2, + 0, + &signer2, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_transfer_back_serialized_transition = token_transfer_back_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_transfer_back_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::PaidConsensusError( + ConsensusError::StateError(StateError::IdentityTokenAccountFrozenError(_)), + _ + )] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + // We expect no change + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 100000 - 1337; + assert_eq!(token_balance, Some(expected_amount)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + recipient.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 1337; + assert_eq!(token_balance, Some(expected_amount)); + + let unfreeze_transition = BatchTransition::new_token_unfreeze_transition( + token_id, + identity.id(), + contract.id(), + 0, + recipient.id(), + None, + None, + &key, + 4, + 0, + &signer, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let unfreeze_serialized_transition = unfreeze_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![unfreeze_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_frozen = platform + .drive + .fetch_identity_token_info( + token_id.to_buffer(), + recipient.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token info") + .map(|info| info.frozen()); + assert_eq!(token_frozen, Some(false)); + + let token_transfer_transition = BatchTransition::new_token_transfer_transition( + token_id, + recipient.id(), + contract.id(), + 0, + 300, + identity.id(), + None, + None, + None, + &key2, + 3, + 0, + &signer2, + platform_version, + None, + None, + None, + ) + .expect("expect to create documents batch transition"); + + let token_transfer_serialized_transition = token_transfer_transition + .serialize_to_bytes() + .expect("expected documents batch serialized state transition"); + + let transaction = platform.drive.grove.start_transaction(); + + let processing_result = platform + .platform + .process_raw_state_transitions( + &vec![token_transfer_serialized_transition.clone()], + &platform_state, + &BlockInfo::default(), + &transaction, + platform_version, + false, + None, + ) + .expect("expected to process state transition"); + + assert_matches!( + processing_result.execution_results().as_slice(), + [StateTransitionExecutionResult::SuccessfulExecution(_, _)] + ); + + platform + .drive + .grove + .commit_transaction(transaction) + .unwrap() + .expect("expected to commit transaction"); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 100000 - 1337 + 300; + assert_eq!(token_balance, Some(expected_amount)); + + let token_balance = platform + .drive + .fetch_identity_token_balance( + token_id.to_buffer(), + recipient.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch token balance"); + let expected_amount = 1337 - 300; + assert_eq!(token_balance, Some(expected_amount)); } } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index df04ac19d11..a08af4dd3ad 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -234,8 +234,6 @@ impl BatchTransitionTransformerV0 for BatchTransition { .collect::>>, Error>>( )?; - let user_fee_increase = self.user_fee_increase(); - let mut validation_result_tokens = token_transitions_by_contracts .iter() .map(|(data_contract_id, token_transitions)| { diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balance/mod.rs similarity index 100% rename from packages/rs-drive/src/drive/tokens/balance/fetch/mod.rs rename to packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balance/mod.rs diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balance/v0/mod.rs similarity index 100% rename from packages/rs-drive/src/drive/tokens/balance/fetch/v0/mod.rs rename to packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balance/v0/mod.rs diff --git a/packages/rs-drive/src/drive/tokens/balance/mod.rs b/packages/rs-drive/src/drive/tokens/balance/mod.rs index bc7bfa588f0..33d22088c30 100644 --- a/packages/rs-drive/src/drive/tokens/balance/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/mod.rs @@ -1,10 +1,10 @@ #[cfg(feature = "server")] mod add_to_previous_token_balance; #[cfg(feature = "server")] -mod fetch; -#[cfg(feature = "server")] mod fetch_identities_token_balances; #[cfg(feature = "server")] +mod fetch_identity_token_balance; +#[cfg(feature = "server")] mod fetch_identity_token_balances; #[cfg(feature = "server")] mod prove_identities_token_balances; diff --git a/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/mod.rs b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/mod.rs new file mode 100644 index 00000000000..3fa1a5dad03 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/mod.rs @@ -0,0 +1,134 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::tokens::info::IdentityTokenInfo; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Fetches the Identity's token info from the backing store. + /// Passing `apply = false` will return estimated costs (0 or Some(0) in place of actual values). + /// + /// # Arguments + /// + /// * `token_id` - The ID of the token. + /// * `identity_id` - The ID of the Identity whose token info is to be fetched. + /// * `apply` - Whether to actually fetch from state (true) or estimate costs (false). + /// * `transaction` - The current transaction. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - The token info of the Identity if successful, or an error. + pub fn fetch_identity_token_info( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_info + { + 0 => self.fetch_identity_token_info_v0( + token_id, + identity_id, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_info".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the Identity's token info with costs (if `apply = true`) and returns associated fee result. + pub fn fetch_identity_token_info_with_costs( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(Option, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_identity_token_info_operations( + token_id, + identity_id, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the operations to get Identity's token info from the backing store. + /// If `apply` is false, the operations are stateless and only used for cost estimation. + /// + /// # Arguments + /// + /// * `token_id` - The ID of the token. + /// * `identity_id` - The ID of the Identity whose token info is to be fetched. + /// * `apply` - Whether to fetch actual stateful data (true) or just estimate costs (false). + /// * `transaction` - The current transaction. + /// * `drive_operations` - The drive operations vector to populate. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - The token info of the Identity if successful, or an error. + pub fn fetch_identity_token_info_operations( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version + .drive + .methods + .token + .fetch + .identity_token_info + { + 0 => self.fetch_identity_token_info_operations_v0( + token_id, + identity_id, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_identity_token_info_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/v0/mod.rs b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/v0/mod.rs new file mode 100644 index 00000000000..102811581f5 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/v0/mod.rs @@ -0,0 +1,73 @@ +use crate::drive::tokens::token_identity_infos_path; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::serialization::PlatformDeserializable; +use dpp::tokens::info::IdentityTokenInfo; +use dpp::version::PlatformVersion; +use grovedb::Element::Item; +use grovedb::TransactionArg; + +impl Drive { + pub(super) fn fetch_identity_token_info_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.fetch_identity_token_info_operations_v0( + token_id, + identity_id, + true, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_identity_token_info_operations_v0( + &self, + token_id: [u8; 32], + identity_id: [u8; 32], + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let direct_query_type = if apply { + DirectQueryType::StatefulDirectQuery + } else { + DirectQueryType::StatelessDirectQuery { + in_tree_using_sums: false, + query_target: QueryTargetValue(8), + } + }; + + let info_path = token_identity_infos_path(&token_id); + + match self.grove_get_raw_optional( + (&info_path).into(), + identity_id.as_slice(), + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + ) { + Ok(Some(Item(info, _))) => Ok(Some(IdentityTokenInfo::deserialize_from_bytes( + info.as_slice(), + )?)), + + Ok(None) | Err(Error::GroveDB(grovedb::Error::PathKeyNotFound(_))) => Ok(None), + + Ok(Some(_)) => Err(Error::Drive(DriveError::CorruptedElementType( + "identity token info was present but was not an item", + ))), + + Err(e) => Err(e), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/info/mod.rs b/packages/rs-drive/src/drive/tokens/info/mod.rs index 71786d1fd42..f446d8668d7 100644 --- a/packages/rs-drive/src/drive/tokens/info/mod.rs +++ b/packages/rs-drive/src/drive/tokens/info/mod.rs @@ -7,3 +7,6 @@ mod prove_identities_token_infos; #[cfg(feature = "server")] mod prove_identity_token_infos; mod queries; + +#[cfg(feature = "server")] +mod fetch_identity_token_info; From da5d87ad4d2b8b6f2e5788de5ded7c47ad0d3fcf Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 6 Jan 2025 16:32:38 +0700 Subject: [PATCH 46/61] fixes for wasm --- .../batch_transition/accessors/mod.rs | 3 +- .../batch_transition/v0/v0_methods.rs | 6 ++- .../batch_transition/v1/v0_methods.rs | 3 +- .../v0/for_saving_v1.rs | 3 +- .../drive_abci_validation_versions/v5.rs | 13 ++++- .../state_transition/batch_transition/mod.rs | 2 - .../src/errors/consensus/consensus_error.rs | 54 +++++++++++++++++-- 7 files changed, 73 insertions(+), 11 deletions(-) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs index 559708b8735..fe3a6bef7e0 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/accessors/mod.rs @@ -42,7 +42,8 @@ impl<'a> Iterator for DocumentBatchIterator<'a> { } impl DocumentsBatchTransitionAccessorsV0 for BatchTransition { - type IterType<'a> = DocumentBatchIterator<'a> + type IterType<'a> + = DocumentBatchIterator<'a> where Self: 'a; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs index aeb895201e3..17b7c8df12b 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v0/v0_methods.rs @@ -41,7 +41,11 @@ use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionRes use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::DocumentTransitionV0Methods; impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV0 { - type IterType<'a> = std::iter::Map, fn(&'a DocumentTransition) -> BatchedTransitionRef<'a>> + type IterType<'a> + = std::iter::Map< + Iter<'a, DocumentTransition>, + fn(&'a DocumentTransition) -> BatchedTransitionRef<'a>, + > where Self: 'a; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index 1d2abd28c3b..22622fd189d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -60,7 +60,8 @@ use crate::state_transition::batch_transition::token_transfer_transition::TokenT use crate::state_transition::batch_transition::token_unfreeze_transition::TokenUnfreezeTransitionV0; impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV1 { - type IterType<'a> = Map, fn(&'a BatchedTransition) -> BatchedTransitionRef<'a>> + type IterType<'a> + = Map, fn(&'a BatchedTransition) -> BatchedTransitionRef<'a>> where Self: 'a; diff --git a/packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving_v1.rs b/packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving_v1.rs index bfb596e451b..b06d75eacca 100644 --- a/packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving_v1.rs +++ b/packages/rs-drive-abci/src/platform_types/signature_verification_quorum_set/v0/for_saving_v1.rs @@ -5,11 +5,10 @@ use crate::platform_types::signature_verification_quorum_set::{ Quorums, SignatureVerificationQuorumSetForSaving, SignatureVerificationQuorumSetV0, ThresholdBlsPublicKey, VerificationQuorum, }; +use bincode::{Decode, Encode}; use dashcore_rpc::dashcore::hashes::Hash; use dashcore_rpc::dashcore::QuorumHash; use dpp::bls_signatures::Bls12381G2Impl; -use dpp::identity::state_transition::asset_lock_proof::Encode; -use dpp::platform_serialization::de::Decode; use dpp::platform_value::Bytes32; #[derive(Debug, Clone, Encode, Decode)] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rs index d48857faba9..896e442aa7f 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rs @@ -101,7 +101,7 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V5: DriveAbciValidationVersions = state: 0, transform_into_action: 0, }, - documents_batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { + batch_state_transition: DriveAbciDocumentsStateTransitionValidationVersions { balance_pre_check: 0, basic_structure: 0, advanced_structure: 0, @@ -133,6 +133,17 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V5: DriveAbciValidationVersions = document_transfer_transition_state_validation: 0, document_purchase_transition_state_validation: 0, document_update_price_transition_state_validation: 0, + token_mint_transition_structure_validation: 0, + token_burn_transition_structure_validation: 0, + token_transfer_transition_structure_validation: 0, + token_issuance_transition_state_validation: 0, + token_burn_transition_state_validation: 0, + token_transfer_transition_state_validation: 0, + token_base_transition_structure_validation: 0, + token_freeze_transition_structure_validation: 0, + token_unfreeze_transition_structure_validation: 0, + token_freeze_transition_state_validation: 0, + token_unfreeze_transition_state_validation: 0, }, }, has_nonce_validation: 1, diff --git a/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs index 30396e17fc9..6dfadbf9852 100644 --- a/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/batch_transition/mod.rs @@ -13,7 +13,6 @@ use dpp::consensus::ConsensusError; use dpp::platform_value::BinaryData; use dpp::serialization::PlatformSerializable; use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; -use dpp::state_transition::batch_transition::batched_transition::document_transition::DocumentTransition; use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::StateTransition; use wasm_bindgen::prelude::*; @@ -26,7 +25,6 @@ use crate::{ IdentityPublicKeyWasm, }; -use document_transition::DocumentTransitionWasm; use dpp::ed25519_dalek::ed25519::signature::SignerMut; use dpp::state_transition::batch_transition::batched_transition::BatchedTransition; use dpp::state_transition::batch_transition::methods::v0::DocumentsBatchTransitionMethodsV0; diff --git a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs index 392b15ebb0d..2301255352b 100644 --- a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs @@ -61,12 +61,12 @@ use dpp::consensus::state::data_trigger::DataTriggerError::{ DataTriggerConditionError, DataTriggerExecutionError, DataTriggerInvalidResultError, }; use wasm_bindgen::{JsError, JsValue}; -use dpp::consensus::basic::data_contract::{ContestedUniqueIndexOnMutableDocumentTypeError, ContestedUniqueIndexWithUniqueIndexError, DataContractTokenConfigurationUpdateError, InvalidDocumentTypeRequiredSecurityLevelError, UnknownDocumentCreationRestrictionModeError, UnknownSecurityLevelError, UnknownStorageKeyRequirementsError, UnknownTradeModeError, UnknownTransferableTypeError}; +use dpp::consensus::basic::data_contract::{ContestedUniqueIndexOnMutableDocumentTypeError, ContestedUniqueIndexWithUniqueIndexError, DataContractTokenConfigurationUpdateError, InvalidDocumentTypeRequiredSecurityLevelError, InvalidTokenBaseSupplyError, NonContiguousContractGroupPositionsError, NonContiguousContractTokenPositionsError, UnknownDocumentCreationRestrictionModeError, UnknownSecurityLevelError, UnknownStorageKeyRequirementsError, UnknownTradeModeError, UnknownTransferableTypeError}; use dpp::consensus::basic::document::{ContestedDocumentsTemporarilyNotAllowedError, DocumentCreationNotAllowedError, DocumentFieldMaxSizeExceededError, MaxDocumentsTransitionsExceededError, MissingPositionsInDocumentTypePropertiesError}; +use dpp::consensus::basic::group::GroupActionNotAllowedOnTransitionError; use dpp::consensus::basic::identity::{DataContractBoundsNotPresentError, DisablingKeyIdAlsoBeingAddedInSameTransitionError, InvalidIdentityCreditWithdrawalTransitionAmountError, InvalidIdentityUpdateTransitionDisableKeysError, InvalidIdentityUpdateTransitionEmptyError, TooManyMasterPublicKeyError, WithdrawalOutputScriptNotAllowedWhenSigningWithOwnerKeyError}; use dpp::consensus::basic::overflow_error::OverflowError; -use dpp::consensus::basic::token::{InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, InvalidTokenPositionError}; -use dpp::consensus::basic::token::contract_has_no_tokens_error::ContractHasNoTokensError; +use dpp::consensus::basic::token::{ChoosingTokenMintRecipientNotAllowedError, ContractHasNoTokensError, DestinationIdentityForTokenMintingNotSetError, InvalidActionIdError, InvalidGroupPositionError, InvalidTokenIdError, InvalidTokenPositionError, TokenTransferToOurselfError}; use dpp::consensus::state::data_contract::document_type_update_error::DocumentTypeUpdateError; use dpp::consensus::state::document::document_contest_currently_locked_error::DocumentContestCurrentlyLockedError; use dpp::consensus::state::document::document_contest_document_with_same_id_already_present_error::DocumentContestDocumentWithSameIdAlreadyPresentError; @@ -75,12 +75,15 @@ use dpp::consensus::state::document::document_contest_not_joinable_error::Docume use dpp::consensus::state::document::document_contest_not_paid_for_error::DocumentContestNotPaidForError; use dpp::consensus::state::document::document_incorrect_purchase_price_error::DocumentIncorrectPurchasePriceError; use dpp::consensus::state::document::document_not_for_sale_error::DocumentNotForSaleError; +use dpp::consensus::state::group::{GroupActionAlreadyCompletedError, GroupActionAlreadySignedByIdentityError, GroupActionDoesNotExistError, IdentityNotMemberOfGroupError}; use dpp::consensus::state::identity::identity_public_key_already_exists_for_unique_contract_bounds_error::IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError; use dpp::consensus::state::identity::master_public_key_update_error::MasterPublicKeyUpdateError; use dpp::consensus::state::identity::missing_transfer_key_error::MissingTransferKeyError; use dpp::consensus::state::identity::no_transfer_key_for_core_withdrawal_available_error::NoTransferKeyForCoreWithdrawalAvailableError; +use dpp::consensus::state::identity::RecipientIdentityDoesNotExistError; use dpp::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_insufficient_error::PrefundedSpecializedBalanceInsufficientError; use dpp::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_not_found_error::PrefundedSpecializedBalanceNotFoundError; +use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountFrozenError, UnauthorizedTokenActionError}; use dpp::consensus::state::voting::masternode_incorrect_voter_identity_id_error::MasternodeIncorrectVoterIdentityIdError; use dpp::consensus::state::voting::masternode_incorrect_voting_address_error::MasternodeIncorrectVotingAddressError; use dpp::consensus::state::voting::masternode_not_found_error::MasternodeNotFoundError; @@ -310,6 +313,30 @@ pub fn from_state_error(state_error: &StateError) -> JsValue { StateError::DocumentContestNotPaidForError(e) => { generic_consensus_error!(DocumentContestNotPaidForError, e).into() } + StateError::RecipientIdentityDoesNotExistError(e) => { + generic_consensus_error!(RecipientIdentityDoesNotExistError, e).into() + } + StateError::IdentityDoesNotHaveEnoughTokenBalanceError(e) => { + generic_consensus_error!(IdentityDoesNotHaveEnoughTokenBalanceError, e).into() + } + StateError::UnauthorizedTokenActionError(e) => { + generic_consensus_error!(UnauthorizedTokenActionError, e).into() + } + StateError::IdentityTokenAccountFrozenError(e) => { + generic_consensus_error!(IdentityTokenAccountFrozenError, e).into() + } + StateError::IdentityNotMemberOfGroupError(e) => { + generic_consensus_error!(IdentityNotMemberOfGroupError, e).into() + } + StateError::GroupActionDoesNotExistError(e) => { + generic_consensus_error!(GroupActionDoesNotExistError, e).into() + } + StateError::GroupActionAlreadyCompletedError(e) => { + generic_consensus_error!(GroupActionAlreadyCompletedError, e).into() + } + StateError::GroupActionAlreadySignedByIdentityError(e) => { + generic_consensus_error!(GroupActionAlreadySignedByIdentityError, e).into() + } } } @@ -595,6 +622,27 @@ fn from_basic_error(basic_error: &BasicError) -> JsValue { BasicError::InvalidActionIdError(e) => { generic_consensus_error!(InvalidActionIdError, e).into() } + BasicError::NonContiguousContractTokenPositionsError(e) => { + generic_consensus_error!(NonContiguousContractTokenPositionsError, e).into() + } + BasicError::NonContiguousContractGroupPositionsError(e) => { + generic_consensus_error!(NonContiguousContractGroupPositionsError, e).into() + } + BasicError::InvalidTokenBaseSupplyError(e) => { + generic_consensus_error!(InvalidTokenBaseSupplyError, e).into() + } + BasicError::TokenTransferToOurselfError(e) => { + generic_consensus_error!(TokenTransferToOurselfError, e).into() + } + BasicError::DestinationIdentityForTokenMintingNotSetError(e) => { + generic_consensus_error!(DestinationIdentityForTokenMintingNotSetError, e).into() + } + BasicError::ChoosingTokenMintRecipientNotAllowedError(e) => { + generic_consensus_error!(ChoosingTokenMintRecipientNotAllowedError, e).into() + } + BasicError::GroupActionNotAllowedOnTransitionError(e) => { + generic_consensus_error!(GroupActionNotAllowedOnTransitionError, e).into() + } } } From e70100857fdc4bbf22314308b7944df823be74ca Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Jan 2025 07:26:54 +0700 Subject: [PATCH 47/61] more state transitions --- packages/rs-dpp/src/state_transition/mod.rs | 6 + .../batched_transition/document_transition.rs | 12 +- .../document_transition_action_type.rs | 4 +- .../batched_transition/mod.rs | 2 + .../batched_transition/resolvers.rs | 36 ++- .../mod.rs | 25 ++ .../v0/mod.rs | 25 ++ .../v0/v0_methods.rs | 78 ++++++ .../v0_methods.rs | 87 +++++++ .../token_emergency_action_transition/mod.rs | 25 ++ .../v0/mod.rs | 30 +++ .../v0/v0_methods.rs | 80 ++++++ .../v0_methods.rs | 86 +++++++ .../batched_transition/token_transition.rs | 36 ++- .../token_transition_action_type.rs | 16 +- .../document/batch_transition/methods/mod.rs | 121 +++++++++ .../batch_transition/methods/v1/mod.rs | 39 +++ .../document/batch_transition/mod.rs | 6 +- .../batch_transition/resolvers/v0/mod.rs | 7 +- .../batch_transition/v1/v0_methods.rs | 153 +++++++++++- .../validate_basic_structure/v0/mod.rs | 4 +- .../rs-dpp/src/tokens/emergency_action.rs | 15 ++ packages/rs-dpp/src/tokens/mod.rs | 1 + .../document_create_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../state_v1/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../document_delete_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 6 +- .../structure_v0/mod.rs | 6 +- .../mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../document_replace_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../token_base_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 2 +- .../structure_v0/mod.rs | 2 +- .../token_burn_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 2 +- .../structure_v0/mod.rs | 2 +- .../token_freeze_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 2 +- .../structure_v0/mod.rs | 2 +- .../token_mint_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 2 +- .../token_transfer_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../token_unfreeze_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 2 +- .../structure_v0/mod.rs | 2 +- .../batch/advanced_structure/v0/mod.rs | 22 +- .../bindings/data_trigger_binding/mod.rs | 2 +- .../bindings/data_trigger_binding/v0/mod.rs | 2 +- .../data_triggers/bindings/list/v0/mod.rs | 2 +- .../batch/data_triggers/executor.rs | 6 +- .../batch/data_triggers/mod.rs | 2 +- .../data_triggers/triggers/dashpay/mod.rs | 2 +- .../data_triggers/triggers/dashpay/v0/mod.rs | 10 +- .../batch/data_triggers/triggers/dpns/mod.rs | 2 +- .../data_triggers/triggers/dpns/v0/mod.rs | 10 +- .../triggers/feature_flags/mod.rs | 2 +- .../triggers/feature_flags/v0/mod.rs | 6 +- .../data_triggers/triggers/reject/mod.rs | 2 +- .../data_triggers/triggers/reject/v0/mod.rs | 4 +- .../data_triggers/triggers/withdrawals/mod.rs | 2 +- .../triggers/withdrawals/v0/mod.rs | 12 +- .../batch/state/v0/data_triggers.rs | 2 +- .../state_transitions/batch/state/v0/mod.rs | 4 +- .../batch/transformer/v0/mod.rs | 30 +-- .../verify_state_transitions.rs | 14 +- .../mod.rs | 2 +- .../v0/mod.rs | 4 +- .../mod.rs | 2 +- .../v0/mod.rs | 4 +- .../mod.rs | 2 +- .../v0/mod.rs | 4 +- .../mod.rs | 2 +- .../v0/mod.rs | 4 +- .../mod.rs | 2 +- .../v0/mod.rs | 4 +- .../batch/batch_transition.rs | 2 +- .../batch/document_create_transition.rs | 4 +- .../batch/document_delete_transition.rs | 6 +- .../batch/document_purchase_transition.rs | 4 +- .../batch/document_replace_transition.rs | 4 +- .../batch/document_transfer_transition.rs | 4 +- .../batch/document_transition.rs | 2 +- .../batch/document_update_price_transition.rs | 4 +- .../batch/documents_batch_transition.rs | 2 +- .../batch/token_burn_transition.rs | 4 +- .../batch/token_freeze_transition.rs | 4 +- .../batch/token_mint_transition.rs | 4 +- .../batch/token_transfer_transition.rs | 6 +- .../batch/token_transition.rs | 16 +- .../batch/token_unfreeze_transition.rs | 4 +- .../document_base_transition_action/mod.rs | 0 .../transformer.rs | 2 +- .../document_base_transition_action/v0/mod.rs | 0 .../v0/transformer.rs | 2 +- .../document_create_transition_action/mod.rs | 2 +- .../transformer.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 4 +- .../document_delete_transition_action/mod.rs | 4 +- .../transformer.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 4 +- .../mod.rs | 2 +- .../transformer.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 4 +- .../document_replace_transition_action/mod.rs | 2 +- .../transformer.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 4 +- .../mod.rs | 2 +- .../transformer.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 4 +- .../document_transition_action_type.rs | 6 +- .../mod.rs | 2 +- .../transformer.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 4 +- .../document_transition/mod.rs | 73 ++++++ .../batch/batched_transition/mod.rs | 40 +++ .../token_transition/mod.rs | 79 ++++++ .../token_base_transition_action/mod.rs | 0 .../transformer.rs | 2 +- .../token_base_transition_action/v0/mod.rs | 0 .../v0/transformer.rs | 2 +- .../token_burn_transition_action/mod.rs | 2 +- .../transformer.rs | 4 +- .../token_burn_transition_action/v0/mod.rs | 2 +- .../v0/transformer.rs | 7 +- .../mod.rs | 63 +++++ .../transformer.rs | 117 +++++++++ .../v0/mod.rs | 98 ++++++++ .../v0/transformer.rs | 232 ++++++++++++++++++ .../mod.rs | 63 +++++ .../transformer.rs | 117 +++++++++ .../v0/mod.rs | 97 ++++++++ .../v0/transformer.rs | 232 ++++++++++++++++++ .../token_freeze_transition_action/mod.rs | 2 +- .../transformer.rs | 4 +- .../token_freeze_transition_action/v0/mod.rs | 2 +- .../v0/transformer.rs | 7 +- .../token_mint_transition_action/mod.rs | 2 +- .../transformer.rs | 4 +- .../token_mint_transition_action/v0/mod.rs | 2 +- .../v0/transformer.rs | 7 +- .../token_transfer_transition_action/mod.rs | 7 +- .../transformer.rs | 4 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 4 +- .../token_transition_action_type.rs | 22 ++ .../token_unfreeze_transition_action/mod.rs | 2 +- .../transformer.rs | 4 +- .../v0/mod.rs | 2 +- .../v0/transformer.rs | 7 +- .../documents_batch => batch}/mod.rs | 12 +- .../documents_batch => batch}/v0/mod.rs | 21 +- .../document_transition/mod.rs | 161 ------------ .../token_transition_action_type.rs | 22 -- .../state_transition_action/document/mod.rs | 2 - .../src/state_transition_action/mod.rs | 6 +- .../transformer.rs | 6 +- .../v0/transformer.rs | 4 +- .../errors/invalid_document_action_error.rs | 2 +- .../document_transition/mod.rs | 2 +- 180 files changed, 2398 insertions(+), 468 deletions(-) create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/mod.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/v0_methods.rs create mode 100644 packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0_methods.rs create mode 100644 packages/rs-dpp/src/tokens/emergency_action.rs rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_base_transition_action/mod.rs (100%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_base_transition_action/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_base_transition_action/v0/mod.rs (100%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_base_transition_action/v0/transformer.rs (96%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_create_transition_action/mod.rs (98%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_create_transition_action/transformer.rs (97%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_create_transition_action/v0/mod.rs (99%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_create_transition_action/v0/transformer.rs (98%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_delete_transition_action/mod.rs (87%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_delete_transition_action/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_delete_transition_action/v0/mod.rs (89%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_delete_transition_action/v0/transformer.rs (92%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_purchase_transition_action/mod.rs (97%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_purchase_transition_action/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_purchase_transition_action/v0/mod.rs (94%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_purchase_transition_action/v0/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_replace_transition_action/mod.rs (98%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_replace_transition_action/transformer.rs (96%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_replace_transition_action/v0/mod.rs (99%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_replace_transition_action/v0/transformer.rs (96%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_transfer_transition_action/mod.rs (97%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_transfer_transition_action/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_transfer_transition_action/v0/mod.rs (92%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_transfer_transition_action/v0/transformer.rs (94%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_transition_action_type.rs (80%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_update_price_transition_action/mod.rs (97%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_update_price_transition_action/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_update_price_transition_action/v0/mod.rs (93%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch/batched_transition}/document_transition/document_update_price_transition_action/v0/transformer.rs (94%) create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_base_transition_action/mod.rs (100%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_base_transition_action/transformer.rs (93%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_base_transition_action/v0/mod.rs (100%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_base_transition_action/v0/transformer.rs (98%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_burn_transition_action/mod.rs (91%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_burn_transition_action/transformer.rs (96%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_burn_transition_action/v0/mod.rs (94%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_burn_transition_action/v0/transformer.rs (95%) create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/transformer.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/v0/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/v0/transformer.rs rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_freeze_transition_action/mod.rs (91%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_freeze_transition_action/transformer.rs (94%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_freeze_transition_action/v0/mod.rs (93%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_freeze_transition_action/v0/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_mint_transition_action/mod.rs (93%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_mint_transition_action/transformer.rs (94%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_mint_transition_action/v0/mod.rs (94%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_mint_transition_action/v0/transformer.rs (96%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_transfer_transition_action/mod.rs (91%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_transfer_transition_action/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_transfer_transition_action/v0/mod.rs (98%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_transfer_transition_action/v0/transformer.rs (96%) create mode 100644 packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transition_action_type.rs rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_unfreeze_transition_action/mod.rs (92%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_unfreeze_transition_action/transformer.rs (94%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_unfreeze_transition_action/v0/mod.rs (93%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch/document_transition => batch/batched_transition/token_transition}/token_unfreeze_transition_action/v0/transformer.rs (95%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch}/mod.rs (94%) rename packages/rs-drive/src/state_transition_action/{document/documents_batch => batch}/v0/mod.rs (81%) delete mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs delete mode 100644 packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transition_action_type.rs delete mode 100644 packages/rs-drive/src/state_transition_action/document/mod.rs diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 514b4aa2739..da4c0042874 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -373,6 +373,12 @@ impl StateTransition { BatchedTransitionRef::Token(TokenTransition::Unfreeze(_)) => { "TokenUnfreeze" } + BatchedTransitionRef::Token(TokenTransition::DestroyFrozenFunds(_)) => { + "TokenDestroyFrozenFunds" + } + BatchedTransitionRef::Token(TokenTransition::EmergencyAction(_)) => { + "TokenEmergencyAction" + } }; document_transition_types.push(document_transition_name); } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs index 9b9a2ec0d88..535f79932ee 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition.rs @@ -5,7 +5,7 @@ use derive_more::{Display, From}; use serde::{Deserialize, Serialize}; use bincode::{Encode, Decode}; use crate::prelude::{IdentityNonce, Revision}; -use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, TokenUnfreezeTransition}; +use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenDestroyFrozenFundsTransition, TokenEmergencyActionTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, TokenUnfreezeTransition}; use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition, DocumentUpdatePriceTransition}; use crate::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use crate::state_transition::batch_transition::batched_transition::document_transfer_transition::v0::v0_methods::DocumentTransferTransitionV0Methods; @@ -101,6 +101,16 @@ impl BatchTransitionResolversV0 for DocumentTransition { fn as_transition_token_unfreeze(&self) -> Option<&TokenUnfreezeTransition> { None } + + fn as_transition_token_destroy_frozen_funds( + &self, + ) -> Option<&TokenDestroyFrozenFundsTransition> { + None + } + + fn as_transition_token_emergency_action(&self) -> Option<&TokenEmergencyActionTransition> { + None + } } pub trait DocumentTransitionV0Methods { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs index f86026f6964..2fadc908381 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/document_transition_action_type.rs @@ -13,11 +13,11 @@ pub enum DocumentTransitionActionType { IgnoreWhileBumpingRevision, } -pub trait TransitionActionTypeGetter { +pub trait DocumentTransitionActionTypeGetter { fn action_type(&self) -> DocumentTransitionActionType; } -impl TransitionActionTypeGetter for DocumentTransition { +impl DocumentTransitionActionTypeGetter for DocumentTransition { fn action_type(&self) -> DocumentTransitionActionType { match self { DocumentTransition::Create(_) => DocumentTransitionActionType::Create, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs index 8342f635ff4..cbd28a7d902 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/mod.rs @@ -16,6 +16,8 @@ pub mod multi_party_action; mod resolvers; pub mod token_base_transition; pub mod token_burn_transition; +pub mod token_destroy_frozen_funds_transition; +pub mod token_emergency_action_transition; pub mod token_freeze_transition; pub mod token_mint_transition; pub mod token_transfer_transition; diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs index eaaa4cc2c76..bf1d555544f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/resolvers.rs @@ -4,8 +4,8 @@ use crate::state_transition::batch_transition::batched_transition::{ use crate::state_transition::batch_transition::resolvers::v0::BatchTransitionResolversV0; use crate::state_transition::batch_transition::{ DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, - TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, - TokenUnfreezeTransition, + TokenBurnTransition, TokenDestroyFrozenFundsTransition, TokenEmergencyActionTransition, + TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, TokenUnfreezeTransition, }; impl BatchTransitionResolversV0 for BatchedTransition { @@ -78,6 +78,22 @@ impl BatchTransitionResolversV0 for BatchedTransition { BatchedTransition::Token(token) => token.as_transition_token_unfreeze(), } } + + fn as_transition_token_destroy_frozen_funds( + &self, + ) -> Option<&TokenDestroyFrozenFundsTransition> { + match self { + BatchedTransition::Document(_) => None, + BatchedTransition::Token(token) => token.as_transition_token_destroy_frozen_funds(), + } + } + + fn as_transition_token_emergency_action(&self) -> Option<&TokenEmergencyActionTransition> { + match self { + BatchedTransition::Document(_) => None, + BatchedTransition::Token(token) => token.as_transition_token_emergency_action(), + } + } } impl<'a> BatchTransitionResolversV0 for BatchedTransitionRef<'a> { @@ -150,4 +166,20 @@ impl<'a> BatchTransitionResolversV0 for BatchedTransitionRef<'a> { BatchedTransitionRef::Token(token) => token.as_transition_token_unfreeze(), } } + + fn as_transition_token_destroy_frozen_funds( + &self, + ) -> Option<&TokenDestroyFrozenFundsTransition> { + match self { + BatchedTransitionRef::Document(_) => None, + BatchedTransitionRef::Token(token) => token.as_transition_token_destroy_frozen_funds(), + } + } + + fn as_transition_token_emergency_action(&self) -> Option<&TokenEmergencyActionTransition> { + match self { + BatchedTransitionRef::Document(_) => None, + BatchedTransitionRef::Token(token) => token.as_transition_token_emergency_action(), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/mod.rs new file mode 100644 index 00000000000..5d1cd01d774 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/mod.rs @@ -0,0 +1,25 @@ +pub mod v0; +mod v0_methods; + +use bincode::{Decode, Encode}; +use derive_more::{Display, From}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +pub use v0::TokenDestroyFrozenFundsTransitionV0; + +#[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenDestroyFrozenFundsTransition { + #[display("V0({})", "_0")] + V0(TokenDestroyFrozenFundsTransitionV0), +} + +impl Default for TokenDestroyFrozenFundsTransition { + fn default() -> Self { + TokenDestroyFrozenFundsTransition::V0(TokenDestroyFrozenFundsTransitionV0::default()) + // since only v0 + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/mod.rs new file mode 100644 index 00000000000..251ff821914 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/mod.rs @@ -0,0 +1,25 @@ +pub mod v0_methods; + +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use bincode::{Decode, Encode}; +use derive_more::Display; +use platform_value::Identifier; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Default, Encode, Decode, PartialEq, Display)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[display("Base: {base}, Destroyed Account Identity ID: {frozen_identity_id}")] +pub struct TokenDestroyFrozenFundsTransitionV0 { + /// Document Base Transition + #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] + pub base: TokenBaseTransition, + /// The identity id of the account whose balance should be destroyed + pub frozen_identity_id: Identifier, + /// The public note + pub public_note: Option, +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..ef6015a3417 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0/v0_methods.rs @@ -0,0 +1,78 @@ +use platform_value::Identifier; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::batch_transition::token_destroy_frozen_funds_transition::TokenDestroyFrozenFundsTransitionV0; +use crate::state_transition::batch_transition::TokenDestroyFrozenFundsTransition; + +impl TokenBaseTransitionAccessors for TokenDestroyFrozenFundsTransitionV0 { + fn base(&self) -> &TokenBaseTransition { + &self.base + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + &mut self.base + } + + fn set_base(&mut self, base: TokenBaseTransition) { + self.base = base; + } +} + +pub trait TokenDestroyFrozenFundsTransitionV0Methods: + TokenBaseTransitionAccessors + AllowedAsMultiPartyAction +{ + /// Returns the `public_note` field of the `TokenDestroyFrozenFundsTransitionV0`. + fn public_note(&self) -> Option<&String>; + + /// Returns the owned `public_note` field of the `TokenDestroyFrozenFundsTransitionV0`. + fn public_note_owned(self) -> Option; + + /// Sets the `public_note` field in the `TokenDestroyFrozenFundsTransitionV0`. + fn set_public_note(&mut self, public_note: Option); + + /// Returns the `frozen_identity_id` field of the `TokenFreezeTransitionV0`. + fn frozen_identity_id(&self) -> Identifier; + + /// Sets the value of the `frozen_identity_id` field in the `TokenFreezeTransitionV0`. + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier); +} + +impl TokenDestroyFrozenFundsTransitionV0Methods for TokenDestroyFrozenFundsTransitionV0 { + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } + + fn frozen_identity_id(&self) -> Identifier { + self.frozen_identity_id + } + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + self.frozen_identity_id = frozen_identity_id; + } +} + +impl AllowedAsMultiPartyAction for TokenDestroyFrozenFundsTransitionV0 { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + let TokenDestroyFrozenFundsTransitionV0 { + base, + frozen_identity_id, + .. + } = self; + + TokenDestroyFrozenFundsTransition::calculate_action_id_with_fields( + base.token_id().as_bytes(), + owner_id.as_bytes(), + frozen_identity_id.as_bytes(), + base.identity_contract_nonce(), + ) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0_methods.rs new file mode 100644 index 00000000000..73582b9c978 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_destroy_frozen_funds_transition/v0_methods.rs @@ -0,0 +1,87 @@ +use platform_value::Identifier; +use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_destroy_frozen_funds_transition::TokenDestroyFrozenFundsTransition; +use crate::state_transition::batch_transition::token_destroy_frozen_funds_transition::v0::v0_methods::TokenDestroyFrozenFundsTransitionV0Methods; +use crate::util::hash::hash_double; + +impl TokenBaseTransitionAccessors for TokenDestroyFrozenFundsTransition { + fn base(&self) -> &TokenBaseTransition { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => &v0.base, + } + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => &mut v0.base, + } + } + + fn set_base(&mut self, base: TokenBaseTransition) { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => v0.base = base, + } + } +} + +impl TokenDestroyFrozenFundsTransitionV0Methods for TokenDestroyFrozenFundsTransition { + fn public_note(&self) -> Option<&String> { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => v0.public_note(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => v0.public_note_owned(), + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => v0.set_public_note(public_note), + } + } + + fn frozen_identity_id(&self) -> Identifier { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => v0.frozen_identity_id(), + } + } + + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => { + v0.set_frozen_identity_id(frozen_identity_id) + } + } + } +} + +impl AllowedAsMultiPartyAction for TokenDestroyFrozenFundsTransition { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + match self { + TokenDestroyFrozenFundsTransition::V0(v0) => v0.calculate_action_id(owner_id), + } + } +} + +impl TokenDestroyFrozenFundsTransition { + pub fn calculate_action_id_with_fields( + token_id: &[u8; 32], + owner_id: &[u8; 32], + target_id: &[u8; 32], + identity_contract_nonce: IdentityNonce, + ) -> Identifier { + let mut bytes = b"action_token_destroy".to_vec(); + bytes.extend_from_slice(token_id); + bytes.extend_from_slice(owner_id); + bytes.extend_from_slice(target_id); + bytes.extend_from_slice(&identity_contract_nonce.to_be_bytes()); + + hash_double(bytes).into() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/mod.rs new file mode 100644 index 00000000000..b338e9e75eb --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/mod.rs @@ -0,0 +1,25 @@ +pub mod v0; +mod v0_methods; + +use bincode::{Decode, Encode}; +use derive_more::{Display, From}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +pub use v0::TokenEmergencyActionTransitionV0; + +#[derive(Debug, Clone, Encode, Decode, PartialEq, Display, From)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize) +)] +pub enum TokenEmergencyActionTransition { + #[display("V0({})", "_0")] + V0(TokenEmergencyActionTransitionV0), +} + +impl Default for TokenEmergencyActionTransition { + fn default() -> Self { + TokenEmergencyActionTransition::V0(TokenEmergencyActionTransitionV0::default()) + // since only v0 + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/mod.rs new file mode 100644 index 00000000000..18ea3f89b6d --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/mod.rs @@ -0,0 +1,30 @@ +pub mod v0_methods; + +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::tokens::emergency_action::TokenEmergencyAction; +use bincode::{Decode, Encode}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; +use std::fmt; + +#[derive(Debug, Clone, Default, Encode, Decode, PartialEq)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +pub struct TokenEmergencyActionTransitionV0 { + /// Document Base Transition + #[cfg_attr(feature = "state-transition-serde-conversion", serde(flatten))] + pub base: TokenBaseTransition, + /// The emergency action + pub emergency_action: TokenEmergencyAction, + /// The public note + pub public_note: Option, +} + +impl fmt::Display for TokenEmergencyActionTransitionV0 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Base: {}", self.base) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/v0_methods.rs new file mode 100644 index 00000000000..4f0e17f2c44 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0/v0_methods.rs @@ -0,0 +1,80 @@ +use platform_value::Identifier; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::batched_transition::token_emergency_action_transition::TokenEmergencyActionTransitionV0; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use crate::state_transition::batch_transition::TokenEmergencyActionTransition; +use crate::tokens::emergency_action::TokenEmergencyAction; + +impl TokenBaseTransitionAccessors for TokenEmergencyActionTransitionV0 { + fn base(&self) -> &TokenBaseTransition { + &self.base + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + &mut self.base + } + + fn set_base(&mut self, base: TokenBaseTransition) { + self.base = base; + } +} + +pub trait TokenEmergencyActionTransitionV0Methods: + TokenBaseTransitionAccessors + AllowedAsMultiPartyAction +{ + /// Returns the `public_note` field of the `TokenEmergencyActionTransitionV0`. + fn public_note(&self) -> Option<&String>; + + /// Returns the owned `public_note` field of the `TokenEmergencyActionTransitionV0`. + fn public_note_owned(self) -> Option; + + /// Sets the value of the `public_note` field in the `TokenEmergencyActionTransitionV0`. + fn set_public_note(&mut self, public_note: Option); + + /// Returns the `emergency_action` field of the `TokenEmergencyActionTransitionV0`. + fn emergency_action(&self) -> TokenEmergencyAction; + + /// Sets the value of the `emergency_action` field in the `TokenEmergencyActionTransitionV0`. + fn set_emergency_action(&mut self, emergency_action: TokenEmergencyAction); +} + +impl TokenEmergencyActionTransitionV0Methods for TokenEmergencyActionTransitionV0 { + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } + + fn emergency_action(&self) -> TokenEmergencyAction { + self.emergency_action + } + + fn set_emergency_action(&mut self, emergency_action: TokenEmergencyAction) { + self.emergency_action = emergency_action; + } +} + +impl AllowedAsMultiPartyAction for TokenEmergencyActionTransitionV0 { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + let TokenEmergencyActionTransitionV0 { + base, + emergency_action, + .. + } = self; + + TokenEmergencyActionTransition::calculate_action_id_with_fields( + base.token_id().as_bytes(), + owner_id.as_bytes(), + *emergency_action, + base.identity_contract_nonce(), + ) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0_methods.rs new file mode 100644 index 00000000000..e089d2f8de8 --- /dev/null +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_emergency_action_transition/v0_methods.rs @@ -0,0 +1,86 @@ +use platform_value::Identifier; +use crate::prelude::IdentityNonce; +use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; +use crate::state_transition::batch_transition::batched_transition::token_emergency_action_transition::v0::v0_methods::TokenEmergencyActionTransitionV0Methods; +use crate::state_transition::batch_transition::token_base_transition::token_base_transition_accessors::TokenBaseTransitionAccessors; +use crate::state_transition::batch_transition::token_base_transition::TokenBaseTransition; +use crate::state_transition::batch_transition::TokenEmergencyActionTransition; +use crate::tokens::emergency_action::TokenEmergencyAction; +use crate::util::hash::hash_double; + +impl TokenBaseTransitionAccessors for TokenEmergencyActionTransition { + fn base(&self) -> &TokenBaseTransition { + match self { + TokenEmergencyActionTransition::V0(v0) => &v0.base, + } + } + + fn base_mut(&mut self) -> &mut TokenBaseTransition { + match self { + TokenEmergencyActionTransition::V0(v0) => &mut v0.base, + } + } + + fn set_base(&mut self, base: TokenBaseTransition) { + match self { + TokenEmergencyActionTransition::V0(v0) => v0.base = base, + } + } +} + +impl TokenEmergencyActionTransitionV0Methods for TokenEmergencyActionTransition { + fn public_note(&self) -> Option<&String> { + match self { + TokenEmergencyActionTransition::V0(v0) => v0.public_note(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenEmergencyActionTransition::V0(v0) => v0.public_note_owned(), + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenEmergencyActionTransition::V0(v0) => v0.set_public_note(public_note), + } + } + + fn emergency_action(&self) -> TokenEmergencyAction { + match self { + TokenEmergencyActionTransition::V0(v0) => v0.emergency_action(), + } + } + + fn set_emergency_action(&mut self, emergency_action: TokenEmergencyAction) { + match self { + TokenEmergencyActionTransition::V0(v0) => v0.set_emergency_action(emergency_action), + } + } +} + +impl AllowedAsMultiPartyAction for TokenEmergencyActionTransition { + fn calculate_action_id(&self, owner_id: Identifier) -> Identifier { + match self { + TokenEmergencyActionTransition::V0(v0) => v0.calculate_action_id(owner_id), + } + } +} + +impl TokenEmergencyActionTransition { + pub fn calculate_action_id_with_fields( + token_id: &[u8; 32], + owner_id: &[u8; 32], + emergency_action: TokenEmergencyAction, + identity_contract_nonce: IdentityNonce, + ) -> Identifier { + let mut bytes = b"action_token_emergency_action".to_vec(); + bytes.extend_from_slice(token_id); + bytes.extend_from_slice(owner_id); + bytes.extend_from_slice(&[emergency_action as u8]); + bytes.extend_from_slice(&identity_contract_nonce.to_be_bytes()); + + hash_double(bytes).into() + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs index 2e75c5b74ab..0ca461a184d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use platform_value::Identifier; use bincode::{Encode, Decode}; use crate::prelude::IdentityNonce; -use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition}; +use crate::state_transition::batch_transition::{DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, TokenBurnTransition, TokenDestroyFrozenFundsTransition, TokenEmergencyActionTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition}; use crate::state_transition::batch_transition::batched_transition::{DocumentPurchaseTransition, DocumentTransferTransition}; use crate::state_transition::batch_transition::batched_transition::multi_party_action::AllowedAsMultiPartyAction; use crate::state_transition::batch_transition::batched_transition::token_unfreeze_transition::TokenUnfreezeTransition; @@ -33,6 +33,12 @@ pub enum TokenTransition { #[display("TokenUnfreezeTransition({})", "_0")] Unfreeze(TokenUnfreezeTransition), + + #[display("TokenDestroyFrozenFundsTransition({})", "_0")] + DestroyFrozenFunds(TokenDestroyFrozenFundsTransition), + + #[display("TokenEmergencyActionTransition({})", "_0")] + EmergencyAction(TokenEmergencyActionTransition), } impl BatchTransitionResolversV0 for TokenTransition { @@ -93,6 +99,24 @@ impl BatchTransitionResolversV0 for TokenTransition { None } } + + fn as_transition_token_destroy_frozen_funds( + &self, + ) -> Option<&TokenDestroyFrozenFundsTransition> { + if let Self::DestroyFrozenFunds(ref t) = self { + Some(t) + } else { + None + } + } + + fn as_transition_token_emergency_action(&self) -> Option<&TokenEmergencyActionTransition> { + if let Self::EmergencyAction(ref t) = self { + Some(t) + } else { + None + } + } } pub trait TokenTransitionV0Methods { @@ -127,6 +151,8 @@ impl TokenTransitionV0Methods for TokenTransition { TokenTransition::Transfer(t) => t.base(), TokenTransition::Freeze(t) => t.base(), TokenTransition::Unfreeze(t) => t.base(), + TokenTransition::DestroyFrozenFunds(t) => t.base(), + TokenTransition::EmergencyAction(t) => t.base(), } } @@ -137,6 +163,8 @@ impl TokenTransitionV0Methods for TokenTransition { TokenTransition::Transfer(t) => t.base_mut(), TokenTransition::Freeze(t) => t.base_mut(), TokenTransition::Unfreeze(t) => t.base_mut(), + TokenTransition::DestroyFrozenFunds(t) => t.base_mut(), + TokenTransition::EmergencyAction(t) => t.base_mut(), } } @@ -151,6 +179,8 @@ impl TokenTransitionV0Methods for TokenTransition { TokenTransition::Freeze(t) => Some(t.calculate_action_id(owner_id)), TokenTransition::Unfreeze(t) => Some(t.calculate_action_id(owner_id)), TokenTransition::Transfer(_) => None, + TokenTransition::DestroyFrozenFunds(t) => Some(t.calculate_action_id(owner_id)), + TokenTransition::EmergencyAction(t) => Some(t.calculate_action_id(owner_id)), } } @@ -159,7 +189,9 @@ impl TokenTransitionV0Methods for TokenTransition { TokenTransition::Burn(_) | TokenTransition::Mint(_) | TokenTransition::Freeze(_) - | TokenTransition::Unfreeze(_) => true, + | TokenTransition::Unfreeze(_) + | TokenTransition::DestroyFrozenFunds(_) + | TokenTransition::EmergencyAction(_) => true, TokenTransition::Transfer(_) => false, } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs index 1aef40ba974..d196637391f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/batched_transition/token_transition_action_type.rs @@ -10,6 +10,8 @@ pub enum TokenTransitionActionType { Transfer, Freeze, Unfreeze, + DestroyFrozenFunds, + EmergencyAction, } impl fmt::Display for TokenTransitionActionType { @@ -20,16 +22,18 @@ impl fmt::Display for TokenTransitionActionType { TokenTransitionActionType::Transfer => "Transfer", TokenTransitionActionType::Freeze => "Freeze", TokenTransitionActionType::Unfreeze => "Unfreeze", + TokenTransitionActionType::DestroyFrozenFunds => "DestroyFrozenFunds", + TokenTransitionActionType::EmergencyAction => "EmergencyAction", }; write!(f, "{}", action_str) } } -pub trait TransitionActionTypeGetter { +pub trait TokenTransitionActionTypeGetter { fn action_type(&self) -> TokenTransitionActionType; } -impl TransitionActionTypeGetter for TokenTransition { +impl TokenTransitionActionTypeGetter for TokenTransition { fn action_type(&self) -> TokenTransitionActionType { match self { TokenTransition::Burn(_) => TokenTransitionActionType::Burn, @@ -37,6 +41,8 @@ impl TransitionActionTypeGetter for TokenTransition { TokenTransition::Transfer(_) => TokenTransitionActionType::Transfer, TokenTransition::Freeze(_) => TokenTransitionActionType::Freeze, TokenTransition::Unfreeze(_) => TokenTransitionActionType::Unfreeze, + TokenTransition::DestroyFrozenFunds(_) => TokenTransitionActionType::DestroyFrozenFunds, + TokenTransition::EmergencyAction(_) => TokenTransitionActionType::EmergencyAction, } } } @@ -51,6 +57,12 @@ impl TryFrom<&str> for TokenTransitionActionType { "transfer" => Ok(TokenTransitionActionType::Transfer), "freeze" => Ok(TokenTransitionActionType::Freeze), "unfreeze" => Ok(TokenTransitionActionType::Unfreeze), + "destroy_frozen_funds" | "destroyFrozenFunds" => { + Ok(TokenTransitionActionType::DestroyFrozenFunds) + } + "emergency_action" | "emergencyAction" => { + Ok(TokenTransitionActionType::EmergencyAction) + } action_type => Err(ProtocolError::Generic(format!( "unknown token transition action type {action_type}" ))), diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs index 31f82c1ce9a..8decb15b361 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs @@ -28,6 +28,7 @@ use crate::state_transition::batch_transition::BatchTransition; use crate::state_transition::batch_transition::{BatchTransitionV0, BatchTransitionV1}; #[cfg(feature = "state-transition-signing")] use crate::state_transition::StateTransition; +use crate::tokens::emergency_action::TokenEmergencyAction; use crate::ProtocolError; #[cfg(feature = "state-transition-signing")] use platform_value::Identifier; @@ -736,4 +737,124 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { }), } } + + fn new_token_destroy_frozen_funds_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + frozen_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + match batch_feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .default_current_version, + ) { + 1 | 0 + if platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .max_version + >= 1 => + { + // Create the destroy frozen funds transition for batch version 1 + BatchTransitionV1::new_token_destroy_frozen_funds_transition( + token_id, + owner_id, + data_contract_id, + token_contract_position, + frozen_identity_id, + public_note, + using_group_info, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + delete_feature_version, + base_feature_version, + ) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DocumentsBatchTransition::new_token_destroy_frozen_funds_transition" + .to_string(), + known_versions: vec![1], + received: version, + }), + } + } + + fn new_token_emergency_action_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + emergency_action: TokenEmergencyAction, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + match batch_feature_version.unwrap_or( + platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .default_current_version, + ) { + 1 | 0 + if platform_version + .dpp + .state_transition_serialization_versions + .batch_state_transition + .max_version + >= 1 => + { + // Create the emergency action transition for batch version 1 + BatchTransitionV1::new_token_emergency_action_transition( + token_id, + owner_id, + data_contract_id, + token_contract_position, + emergency_action, + public_note, + using_group_info, + identity_public_key, + identity_contract_nonce, + user_fee_increase, + signer, + platform_version, + batch_feature_version, + delete_feature_version, + base_feature_version, + ) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "DocumentsBatchTransition::new_token_emergency_action_transition" + .to_string(), + known_versions: vec![1], + received: version, + }), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs index 38b593d7360..db4e2efab74 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/v1/mod.rs @@ -8,6 +8,7 @@ use crate::prelude::{ }; use crate::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use crate::state_transition::StateTransition; +use crate::tokens::emergency_action::TokenEmergencyAction; use crate::version::FeatureVersion; use crate::ProtocolError; use platform_value::Identifier; @@ -115,4 +116,42 @@ pub trait DocumentsBatchTransitionMethodsV1: DocumentsBatchTransitionAccessorsV0 delete_feature_version: Option, base_feature_version: Option, ) -> Result; + + #[cfg(feature = "state-transition-signing")] + fn new_token_destroy_frozen_funds_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + frozen_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result; + + #[cfg(feature = "state-transition-signing")] + fn new_token_emergency_action_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + emergency_action: TokenEmergencyAction, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs index 68fed9a5143..a3600a133cd 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/mod.rs @@ -16,7 +16,11 @@ pub use self::batched_transition::{ document_create_transition::DocumentCreateTransition, document_delete_transition, document_delete_transition::DocumentDeleteTransition, document_replace_transition, document_replace_transition::DocumentReplaceTransition, token_base_transition, - token_burn_transition, token_burn_transition::TokenBurnTransition, token_freeze_transition, + token_burn_transition, token_burn_transition::TokenBurnTransition, + token_destroy_frozen_funds_transition, + token_destroy_frozen_funds_transition::TokenDestroyFrozenFundsTransition, + token_emergency_action_transition, + token_emergency_action_transition::TokenEmergencyActionTransition, token_freeze_transition, token_freeze_transition::TokenFreezeTransition, token_mint_transition, token_mint_transition::TokenMintTransition, token_transfer_transition, token_transfer_transition::TokenTransferTransition, token_unfreeze_transition, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs index 2db30dae0de..8dd6fd6ec1c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/resolvers/v0/mod.rs @@ -4,7 +4,8 @@ use crate::state_transition::batch_transition::batched_transition::{ }; use crate::state_transition::batch_transition::{ DocumentCreateTransition, DocumentDeleteTransition, DocumentReplaceTransition, - TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, + TokenBurnTransition, TokenDestroyFrozenFundsTransition, TokenEmergencyActionTransition, + TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, }; pub trait BatchTransitionResolversV0 { @@ -18,4 +19,8 @@ pub trait BatchTransitionResolversV0 { fn as_transition_token_transfer(&self) -> Option<&TokenTransferTransition>; fn as_transition_token_freeze(&self) -> Option<&TokenFreezeTransition>; fn as_transition_token_unfreeze(&self) -> Option<&TokenUnfreezeTransition>; + fn as_transition_token_destroy_frozen_funds( + &self, + ) -> Option<&TokenDestroyFrozenFundsTransition>; + fn as_transition_token_emergency_action(&self) -> Option<&TokenEmergencyActionTransition>; } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index 22622fd189d..d50ba9c4e8c 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -30,7 +30,7 @@ use crate::state_transition::batch_transition::methods::v0::DocumentsBatchTransi use std::iter::Map; use std::slice::Iter; -use crate::state_transition::batch_transition::{BatchTransitionV1, TokenBurnTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, TokenUnfreezeTransition}; +use crate::state_transition::batch_transition::{BatchTransitionV1, TokenBurnTransition, TokenDestroyFrozenFundsTransition, TokenEmergencyActionTransition, TokenFreezeTransition, TokenMintTransition, TokenTransferTransition, TokenUnfreezeTransition}; #[cfg(feature = "state-transition-signing")] use crate::state_transition::batch_transition::{ BatchTransition, DocumentDeleteTransition, @@ -54,10 +54,13 @@ use crate::state_transition::batch_transition::token_base_transition::TokenBaseT use crate::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::batch_transition::token_burn_transition::TokenBurnTransitionV0; +use crate::state_transition::batch_transition::token_destroy_frozen_funds_transition::TokenDestroyFrozenFundsTransitionV0; +use crate::state_transition::batch_transition::token_emergency_action_transition::TokenEmergencyActionTransitionV0; use crate::state_transition::batch_transition::token_freeze_transition::TokenFreezeTransitionV0; use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; use crate::state_transition::batch_transition::token_transfer_transition::TokenTransferTransitionV0; use crate::state_transition::batch_transition::token_unfreeze_transition::TokenUnfreezeTransitionV0; +use crate::tokens::emergency_action::TokenEmergencyAction; impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV1 { type IterType<'a> @@ -621,10 +624,10 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, signer: &S, - platform_version: &PlatformVersion, - batch_feature_version: Option, - delete_feature_version: Option, - base_feature_version: Option, + _platform_version: &PlatformVersion, + _batch_feature_version: Option, + _delete_feature_version: Option, + _base_feature_version: Option, ) -> Result { let mut freeze_transition = TokenFreezeTransition::V0(TokenFreezeTransitionV0 { base: TokenBaseTransition::V0(TokenBaseTransitionV0 { @@ -745,4 +748,144 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { )?; Ok(state_transition) } + + fn new_token_destroy_frozen_funds_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + frozen_identity_id: Identifier, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let mut destroy_frozen_funds_transition = + TokenDestroyFrozenFundsTransition::V0(TokenDestroyFrozenFundsTransitionV0 { + base: TokenBaseTransition::V0(TokenBaseTransitionV0 { + identity_contract_nonce, + token_contract_position, + data_contract_id, + token_id, + using_group_info: None, + }), + frozen_identity_id, + public_note, + }); + + if let Some(using_group_info_status) = using_group_info { + match using_group_info_status { + GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer( + group_contract_position, + ) => { + let action_id = destroy_frozen_funds_transition.calculate_action_id(owner_id); + destroy_frozen_funds_transition + .base_mut() + .set_using_group_info(Some(GroupStateTransitionInfo { + group_contract_position, + action_id, + action_is_proposer: true, + })) + } + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner(info) => { + destroy_frozen_funds_transition + .base_mut() + .set_using_group_info(Some(info)) + } + } + } + + let batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Token( + destroy_frozen_funds_transition.into(), + )], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } + + fn new_token_emergency_action_transition( + token_id: Identifier, + owner_id: Identifier, + data_contract_id: Identifier, + token_contract_position: u16, + emergency_action: TokenEmergencyAction, + public_note: Option, + using_group_info: Option, + identity_public_key: &IdentityPublicKey, + identity_contract_nonce: IdentityNonce, + user_fee_increase: UserFeeIncrease, + signer: &S, + platform_version: &PlatformVersion, + batch_feature_version: Option, + delete_feature_version: Option, + base_feature_version: Option, + ) -> Result { + let mut emergency_action_transition = + TokenEmergencyActionTransition::V0(TokenEmergencyActionTransitionV0 { + base: TokenBaseTransition::V0(TokenBaseTransitionV0 { + identity_contract_nonce, + token_contract_position, + data_contract_id, + token_id, + using_group_info: None, + }), + emergency_action, + public_note, + }); + + if let Some(using_group_info_status) = using_group_info { + match using_group_info_status { + GroupStateTransitionInfoStatus::GroupStateTransitionInfoProposer( + group_contract_position, + ) => { + let action_id = emergency_action_transition.calculate_action_id(owner_id); + emergency_action_transition + .base_mut() + .set_using_group_info(Some(GroupStateTransitionInfo { + group_contract_position, + action_id, + action_is_proposer: true, + })) + } + GroupStateTransitionInfoStatus::GroupStateTransitionInfoOtherSigner(info) => { + emergency_action_transition + .base_mut() + .set_using_group_info(Some(info)) + } + } + } + + let batch_transition: BatchTransition = BatchTransitionV1 { + owner_id, + transitions: vec![BatchedTransition::Token(emergency_action_transition.into())], + user_fee_increase, + signature_public_key_id: 0, + signature: Default::default(), + } + .into(); + let mut state_transition: StateTransition = batch_transition.into(); + state_transition.sign_external( + identity_public_key, + signer, + Some(|_, _| Ok(SecurityLevel::HIGH)), + )?; + Ok(state_transition) + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs index 8159c383345..c90794beb74 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/validation/validate_basic_structure/v0/mod.rs @@ -19,7 +19,7 @@ use crate::consensus::basic::group::GroupActionNotAllowedOnTransitionError; use crate::consensus::basic::token::{InvalidActionIdError, InvalidTokenIdError, TokenTransferToOurselfError}; use crate::state_transition::batch_transition::batched_transition::BatchedTransitionRef; use crate::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; -use crate::state_transition::batch_transition::batched_transition::token_transition_action_type::TransitionActionTypeGetter; +use crate::state_transition::batch_transition::batched_transition::token_transition_action_type::TokenTransitionActionTypeGetter; use crate::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::state_transition::batch_transition::token_transfer_transition::v0::v0_methods::TokenTransferTransitionV0Methods; use crate::state_transition::state_transitions::document::batch_transition::batched_transition::document_transition::{DocumentTransition, DocumentTransitionV0Methods}; @@ -150,6 +150,8 @@ impl BatchTransition { } TokenTransition::Freeze(_) => {} TokenTransition::Unfreeze(_) => {} + TokenTransition::DestroyFrozenFunds(_) => {} + TokenTransition::EmergencyAction(_) => {} } // We need to verify that the action id given matches the expected action id diff --git a/packages/rs-dpp/src/tokens/emergency_action.rs b/packages/rs-dpp/src/tokens/emergency_action.rs new file mode 100644 index 00000000000..843d0967785 --- /dev/null +++ b/packages/rs-dpp/src/tokens/emergency_action.rs @@ -0,0 +1,15 @@ +use bincode::{Decode, Encode}; +#[cfg(feature = "state-transition-serde-conversion")] +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Default, Encode, Decode, PartialEq)] +#[cfg_attr( + feature = "state-transition-serde-conversion", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +pub enum TokenEmergencyAction { + #[default] + Pause = 0, + Resume = 1, +} diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs index 1c0cc2094ef..2f40a411a1f 100644 --- a/packages/rs-dpp/src/tokens/mod.rs +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -2,6 +2,7 @@ use crate::data_contract::TokenContractPosition; use crate::util::hash::hash_double; pub mod allowed_currency; +pub mod emergency_action; pub mod errors; pub mod info; pub mod token_event; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs index 9e4a28a3988..1b08592370c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs @@ -2,7 +2,7 @@ use dashcore_rpc::dashcore::Network; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs index cf78608b9d8..d5322dfbe47 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs @@ -10,8 +10,8 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; use drive::error::drive::DriveError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs index 819d78400bf..9e5f9d97aa3 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs @@ -12,8 +12,8 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; use drive::error::drive::DriveError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs index 7ae98cf477c..a8f67dc96ff 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs @@ -9,8 +9,8 @@ use dpp::data_contract::document_type::restricted_creation::CreationRestrictionM use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs index 20ff3378e28..3f84e860283 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs index 71427308baa..17115659cd6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs @@ -9,11 +9,11 @@ use dpp::document::{Document, DocumentV0Getters}; use dpp::identifier::Identifier; use dpp::prelude::ConsensusValidationResult; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs index 3813405201c..e547eb2e946 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs @@ -2,9 +2,9 @@ use dpp::consensus::basic::document::{InvalidDocumentTransitionActionError, Inva use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs index adf8866600d..7e92cfc0254 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs @@ -2,7 +2,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs index 79e43113440..5ce257aa516 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs @@ -4,10 +4,10 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs index afbe3ae28b2..2294f56c9e1 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs @@ -4,8 +4,8 @@ use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::document::DocumentV0Getters; use dpp::nft::TradeMode; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs index 91f910ca794..1c1cc64fd3a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs @@ -2,7 +2,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs index 8fea8e28565..e354b1a4a1b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs @@ -4,10 +4,10 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs index 6f77359d1ad..b73ea074862 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs @@ -3,8 +3,8 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs index d0a545a7491..cf6d24f605e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs @@ -2,7 +2,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs index 7613df9afcd..358330e82b7 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs @@ -4,10 +4,10 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs index 3910574a615..36d52a193f2 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs @@ -2,8 +2,8 @@ use dpp::consensus::basic::document::{InvalidDocumentTransitionActionError, Inva use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs index 5c1c7dc88b7..ad44b1823b8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs @@ -4,7 +4,7 @@ use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs index 43a72d50a57..ba000144254 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs @@ -4,10 +4,10 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs index f8b66fe3746..5c162c084ea 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs @@ -2,8 +2,8 @@ use dpp::consensus::basic::document::{InvalidDocumentTransitionActionError, Inva use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs index 036fda9ca8b..fb68b51540b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_base_transition_action::TokenBaseTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs index 8c777f109c5..ace0696ec56 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs @@ -4,7 +4,7 @@ use dpp::consensus::state::group::GroupActionAlreadySignedByIdentityError; use dpp::consensus::state::state_error::StateError; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs index 57aca07ce92..adcfec8364b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs @@ -4,7 +4,7 @@ use dpp::consensus::basic::token::InvalidTokenPositionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs index 2fc4f8947a4..d5ed6209814 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::TokenBurnTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_burn_transition_action::TokenBurnTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs index da21b680fe8..d8b8f00e3e7 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs @@ -8,7 +8,7 @@ use dpp::data_contract::associated_token::token_configuration::accessors::v0::To use dpp::multi_identity_events::ActionTaker; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs index 8c331162f4b..04a1953093a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs index 32489877b01..ca1f1cde835 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::TokenFreezeTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::TokenFreezeTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs index b33ebf5fcdc..49a004f9297 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs @@ -8,7 +8,7 @@ use dpp::data_contract::associated_token::token_configuration::accessors::v0::To use dpp::multi_identity_events::ActionTaker; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs index e479bfb5b3f..774dbe37f8d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs index 9da0f53e2b0..8a3a5b14ffb 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::TokenMintTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs index a4e0b36c8e7..263d0c588a5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs @@ -10,10 +10,10 @@ use dpp::data_contract::change_control_rules::authorized_action_takers::Authoriz use dpp::multi_identity_events::ActionTaker; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::{RetrieveIdentityInfo, ValidationOperation}; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs index db057244666..618dfe80328 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs index 744f2f0e00f..aabaff973dd 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs index 8ef5fa0a86a..41058ffa369 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs @@ -5,10 +5,10 @@ use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, I use dpp::prelude::Identifier; use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index 7daa9970f24..eb4e9ef98ac 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -1,8 +1,8 @@ use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs index 7a645db08da..76145d247f6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs index 50245570e78..c2f40fbd650 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs @@ -8,7 +8,7 @@ use dpp::data_contract::associated_token::token_configuration::accessors::v0::To use dpp::multi_identity_events::ActionTaker; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs index de5082315af..66289fc23bc 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs index f9b57453f79..267fb12d381 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs @@ -17,21 +17,21 @@ use dpp::validation::ConsensusValidationResult; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::documents_batch::BatchTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; +use drive::state_transition_action::document::batch::BatchTransitionAction; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentReplaceTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::TokenFreezeTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::TokenFreezeTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionActionAccessorsV0; use drive::state_transition_action::StateTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::execution::ExecutionError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs index aff80faa5b1..8f6dc84768c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs @@ -4,7 +4,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ use derive_more::From; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::{ +use drive::state_transition_action::document::batch::batched_transition::document_transition::{ DocumentTransitionAction, DocumentTransitionActionType, }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs index 15133ad5ddf..fd27aff4a18 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs @@ -4,7 +4,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ }; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::{ +use drive::state_transition_action::document::batch::batched_transition::document_transition::{ DocumentTransitionAction, DocumentTransitionActionType, }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs index a9ffcf11eaf..f6d9362d1fe 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs @@ -7,7 +7,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::bindin 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::document::documents_batch::document_transition::DocumentTransitionActionType; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionActionType; /// Retrieves a list of data triggers binding with matching params. /// diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs index aeed94ba294..e7f024b2470 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs @@ -1,10 +1,10 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; -use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::TransitionActionTypeGetter; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionTypeGetter; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use dpp::version::PlatformVersion; use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBindingV0Getters; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs index 9920418f531..442f94318ab 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs @@ -2,7 +2,7 @@ use dpp::validation::SimpleValidationResult; /// Data triggers implement custom validation logic for state transitions /// that modifies documents in a specific data contract. /// Data triggers can be assigned based on the data contract ID, document type, and action. -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; use crate::error::Error; use dpp::consensus::state::data_trigger::DataTriggerError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs index ba3d38332a7..e9f99ad8e36 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs @@ -5,7 +5,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs index 2002e18f3d4..1c7eea3e64a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs @@ -6,9 +6,9 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::ProtocolError; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; use dpp::system_data_contracts::dashpay_contract::v1::document_types::contact_request::properties ::{TO_USER_ID}; use dpp::version::PlatformVersion; @@ -105,8 +105,8 @@ mod test { use dpp::document::{DocumentV0Getters, DocumentV0Setters}; use dpp::platform_value; use dpp::platform_value::{Bytes32}; - use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; - use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionActionType; + use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; + use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionActionType; use crate::execution::validation::state_transition::batch::data_triggers::triggers::dashpay::create_contact_request_data_trigger; use crate::platform_types::platform::PlatformStateRef; use crate::test::helpers::setup::TestPlatformBuilder; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs index 90bffcdd81a..0900bdab3cd 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs @@ -5,7 +5,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs index 8c59ca10e71..62ffea9ac57 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs @@ -15,9 +15,9 @@ use dpp::document::DocumentV0Getters; use dpp::platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueMapPathHelper}; use dpp::platform_value::Value; use dpp::ProtocolError; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::system_data_contracts::dpns_contract; use dpp::system_data_contracts::dpns_contract::v1::document_types::domain::properties::{ALLOW_SUBDOMAINS, DASH_ALIAS_IDENTITY_ID, DASH_UNIQUE_IDENTITY_ID, LABEL, NORMALIZED_LABEL, NORMALIZED_PARENT_DOMAIN_NAME, PREORDER_SALT, RECORDS}; @@ -369,8 +369,8 @@ mod test { use std::sync::Arc; use dpp::block::block_info::BlockInfo; use dpp::platform_value::Bytes32; - use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; - use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionActionType; + use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; + use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionActionType; use dpp::tests::fixtures::{get_batched_transitions_fixture, get_dpns_data_contract_fixture, get_dpns_parent_document_fixture, ParentDocumentOptions}; use dpp::tests::utils::generate_random_identifier_struct; use dpp::version::{DefaultForPlatformVersion}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs index deb0429fd91..a2394175058 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs @@ -1,4 +1,4 @@ -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::version::PlatformVersion; use crate::error::Error; use crate::error::execution::ExecutionError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs index c337e2ed761..3f30194fe97 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs @@ -6,9 +6,9 @@ use dpp::consensus::state::data_trigger::data_trigger_condition_error::DataTrigg use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::system_data_contracts::feature_flags_contract; use dpp::system_data_contracts::feature_flags_contract::v1::document_types::update_consensus_params::properties ::PROPERTY_ENABLE_AT_HEIGHT; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs index 67634d29b78..cc5e4fc47b6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs @@ -5,7 +5,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs index 0f6a2357115..851f536a133 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs @@ -1,9 +1,9 @@ use dpp::consensus::state::data_trigger::data_trigger_condition_error::DataTriggerConditionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::validation::state_transition::batch::data_triggers::DataTriggerExecutionResult; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; /// Creates a data trigger for handling document rejections. /// diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs index 5e97f176031..8b8688c2230 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs @@ -3,7 +3,7 @@ use crate::error::Error; use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::version::PlatformVersion; use crate::execution::validation::state_transition::batch::data_triggers::triggers::withdrawals::v0::delete_withdrawal_data_trigger_v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs index 8808068b781..72c479e872b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs @@ -4,7 +4,7 @@ use crate::error::Error; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::Value; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::system_data_contracts::withdrawals_contract; use dpp::version::PlatformVersion; use drive::query::{DriveDocumentQuery, InternalClauses, WhereClause, WhereOperator}; @@ -13,8 +13,8 @@ use dpp::consensus::state::data_trigger::data_trigger_condition_error::DataTrigg use dpp::{document, ProtocolError}; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::document::DocumentV0Getters; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; use dpp::system_data_contracts::withdrawals_contract::v1::document_types::withdrawal; use drive::drive::document::query::QueryDocumentsOutcomeV0Methods; use crate::execution::validation::state_transition::batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; @@ -131,9 +131,9 @@ mod tests { use dpp::document::serialization_traits::DocumentPlatformConversionMethodsV0; use dpp::document::{Document, DocumentV0Getters}; use dpp::platform_value::platform_value; - use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; - use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; - use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionV0; + use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; + use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; + use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionV0; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use dpp::tests::fixtures::{get_data_contract_fixture, get_withdrawal_document_fixture}; use dpp::version::PlatformVersion; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs index 6b0673bbdaa..f5ff3235ddd 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs @@ -5,7 +5,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ }; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; #[allow(dead_code)] #[deprecated(note = "This function is marked as unused.")] diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs index b8433767715..a6675e5b402 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs @@ -7,8 +7,8 @@ use dpp::state_transition::StateTransitionLike; use drive::state_transition_action::StateTransitionAction; use dpp::version::{DefaultForPlatformVersion, PlatformVersion}; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::documents_batch::BatchTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; +use drive::state_transition_action::document::batch::BatchTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::Error; use crate::error::execution::ExecutionError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index a08af4dd3ad..a2594a1150c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -30,12 +30,12 @@ use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; use dpp::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use dpp::state_transition::StateTransitionLike; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::documents_batch::BatchTransitionAction; -use drive::state_transition_action::document::documents_batch::v0::DocumentsBatchTransitionActionV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; +use drive::state_transition_action::document::batch::BatchTransitionAction; +use drive::state_transition_action::document::batch::v0::BatchTransitionActionV0; use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_documents_for_transitions_knowing_contract_and_document_type; use dpp::version::PlatformVersion; @@ -50,14 +50,14 @@ use dpp::state_transition::batch_transition::document_base_transition::document_ use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use drive::drive::contract::DataContractFetchInfo; use drive::drive::Drive; -use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::TokenBurnTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::TokenFreezeTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::TokenMintTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_burn_transition_action::TokenBurnTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::TokenFreezeTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::TokenMintTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; @@ -261,7 +261,7 @@ impl BatchTransitionTransformerV0 for BatchTransition { if validation_result.has_data() { let (transitions, errors) = validation_result.into_data_and_errors()?; - let batch_transition_action = DocumentsBatchTransitionActionV0 { + let batch_transition_action = BatchTransitionActionV0 { owner_id, transitions, user_fee_increase, 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 3684f2afc66..5d177b6f382 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 @@ -15,7 +15,7 @@ use dpp::version::PlatformVersion; use drive::drive::identity::key::fetch::IdentityKeysRequest; use drive::drive::Drive; use drive::query::{SingleDocumentDriveQuery, SingleDocumentDriveQueryContestedStatus}; -use drive::state_transition_action::document::documents_batch::document_transition::{ +use drive::state_transition_action::document::batch::batched_transition::document_transition::{ BatchedTransitionAction, DocumentTransitionAction, }; use drive::state_transition_action::StateTransitionAction; @@ -29,12 +29,12 @@ use dpp::voting::votes::Vote; use drive::drive::votes::resolved::vote_polls::ResolvedVotePoll; use drive::drive::votes::resolved::votes::resolved_resource_vote::accessors::v0::ResolvedResourceVoteGettersV0; use drive::drive::votes::resolved::votes::ResolvedVote; -use drive::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionActionAccessorsV0, DocumentFromCreateTransitionAction}; -use drive::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentFromReplaceTransitionAction; -use drive::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; -use drive::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionActionAccessorsV0, DocumentFromCreateTransitionAction}; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentFromReplaceTransitionAction; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; +use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; use drive_abci::abci::app::FullAbciApplication; use drive_abci::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use drive_abci::execution::validation::state_transition::ValidationMode; diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_create_transition_action_uniqueness/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_create_transition_action_uniqueness/mod.rs index 0af032f910e..8ffb92bdcc7 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_create_transition_action_uniqueness/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_create_transition_action_uniqueness/mod.rs @@ -13,7 +13,7 @@ use dpp::validation::SimpleConsensusValidationResult; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_create_transition_action_uniqueness/v0/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_create_transition_action_uniqueness/v0/mod.rs index 5f9c96d1ab5..33a1fdcc9de 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_create_transition_action_uniqueness/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_create_transition_action_uniqueness/v0/mod.rs @@ -19,8 +19,8 @@ use dpp::document::property_names::{ }; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/mod.rs index a4e3bc9d05c..75baec39ad8 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/mod.rs @@ -13,7 +13,7 @@ use dpp::validation::SimpleConsensusValidationResult; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/v0/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/v0/mod.rs index a9673724cfc..05bee3b7e1e 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_purchase_transition_action_uniqueness/v0/mod.rs @@ -14,8 +14,8 @@ use dpp::validation::SimpleConsensusValidationResult; use dpp::document::DocumentV0Getters; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_replace_transition_action_uniqueness/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_replace_transition_action_uniqueness/mod.rs index 4b16308fd41..05deb0d4877 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_replace_transition_action_uniqueness/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_replace_transition_action_uniqueness/mod.rs @@ -13,7 +13,7 @@ use dpp::validation::SimpleConsensusValidationResult; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_replace_transition_action_uniqueness/v0/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_replace_transition_action_uniqueness/v0/mod.rs index 8930e78be5c..5dbea707624 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_replace_transition_action_uniqueness/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_replace_transition_action_uniqueness/v0/mod.rs @@ -13,8 +13,8 @@ use dpp::validation::SimpleConsensusValidationResult; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_transfer_transition_action_uniqueness/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_transfer_transition_action_uniqueness/mod.rs index b72f8d55ae2..16c272b5414 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_transfer_transition_action_uniqueness/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_transfer_transition_action_uniqueness/mod.rs @@ -13,7 +13,7 @@ use dpp::validation::SimpleConsensusValidationResult; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_transfer_transition_action_uniqueness/v0/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_transfer_transition_action_uniqueness/v0/mod.rs index a4a2551716c..638fcdd852a 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_transfer_transition_action_uniqueness/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_transfer_transition_action_uniqueness/v0/mod.rs @@ -14,8 +14,8 @@ use dpp::validation::SimpleConsensusValidationResult; use dpp::document::DocumentV0Getters; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_update_price_transition_action_uniqueness/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_update_price_transition_action_uniqueness/mod.rs index 6d412a95ab8..f60019f474f 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_update_price_transition_action_uniqueness/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_update_price_transition_action_uniqueness/mod.rs @@ -13,7 +13,7 @@ use dpp::validation::SimpleConsensusValidationResult; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_update_price_transition_action_uniqueness/v0/mod.rs b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_update_price_transition_action_uniqueness/v0/mod.rs index 21b3d94564d..feb615a5046 100644 --- a/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_update_price_transition_action_uniqueness/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/index_uniqueness/validate_document_update_price_transition_action_uniqueness/v0/mod.rs @@ -14,8 +14,8 @@ use dpp::validation::SimpleConsensusValidationResult; use dpp::document::DocumentV0Getters; use grovedb::TransactionArg; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; impl Drive { diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs index 42446fc81fe..31a92022373 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/batch_transition.rs @@ -1,7 +1,7 @@ use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs index ac885195648..7a40ab8b473 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs @@ -12,8 +12,8 @@ use dpp::block::epoch::Epoch; use dpp::document::Document; use dpp::prelude::Identifier; use std::borrow::Cow; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0, DocumentFromCreateTransitionAction}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0, DocumentFromCreateTransitionAction}; use dpp::version::PlatformVersion; use crate::util::batch::drive_op_batch::PrefundedSpecializedBalanceOperationType; use crate::util::object_size_info::DataContractInfo::DataContractFetchInfo; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs index a650a0b6c0b..b1622ca4d2d 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs @@ -7,9 +7,9 @@ use crate::error::Error; use dpp::block::epoch::Epoch; use dpp::identifier::Identifier; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; use dpp::version::PlatformVersion; use crate::util::object_size_info::{DataContractInfo, DocumentTypeInfo}; use crate::error::drive::DriveError; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs index aba3423feb7..63e6f118aac 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs @@ -9,8 +9,8 @@ use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; use std::borrow::Cow; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::drive::DriveError; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs index ca675812585..8cfaafa60ef 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs @@ -10,8 +10,8 @@ use dpp::block::epoch::Epoch; use dpp::document::Document; use dpp::prelude::Identifier; use std::borrow::Cow; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::{DocumentFromReplaceTransitionAction, DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentFromReplaceTransitionAction, DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::drive::DriveError; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs index 0c96ca675c3..65521399f83 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs @@ -10,8 +10,8 @@ use dpp::block::epoch::Epoch; use dpp::document::DocumentV0Getters; use dpp::prelude::Identifier; use std::borrow::Cow; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::drive::DriveError; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs index 6ccfa60a2c8..15e0a62f2e6 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs @@ -1,6 +1,6 @@ use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs index d37c3c44579..f01e313a8a3 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs @@ -9,8 +9,8 @@ use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; use std::borrow::Cow; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::drive::DriveError; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs index ab13600847c..652b3a33764 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs @@ -2,7 +2,7 @@ use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; use crate::state_transition_action::action_convert_to_operations::DriveHighLevelOperationConverter; -use crate::state_transition_action::document::documents_batch::BatchTransitionAction; +use crate::state_transition_action::batch::BatchTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::version::PlatformVersion; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs index 414358e6b2a..b4d62088fc7 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs @@ -10,8 +10,8 @@ use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs index db421686b1d..29eb030fce9 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs @@ -10,8 +10,8 @@ use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs index 2b267bc11e1..81cb0b2e1c0 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs @@ -10,8 +10,8 @@ use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs index 360eab00d1a..cb9db8c9b8d 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs @@ -6,9 +6,9 @@ use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::TokenOperationType; use crate::util::batch::DriveOperation::{IdentityOperation, TokenOperation}; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs index 7edd6280bbb..57b786c3be3 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs @@ -1,6 +1,6 @@ use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::TokenTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; @@ -29,6 +29,20 @@ impl DriveHighLevelBatchOperationConverter for TokenTransitionAction { .into_high_level_batch_drive_operations(epoch, owner_id, platform_version), TokenTransitionAction::UnfreezeAction(token_unfreeze_action) => token_unfreeze_action .into_high_level_batch_drive_operations(epoch, owner_id, platform_version), + TokenTransitionAction::EmergencyActionAction(token_emergency_action) => { + token_emergency_action.into_high_level_batch_drive_operations( + epoch, + owner_id, + platform_version, + ) + } + TokenTransitionAction::DestroyFrozenFundsAction(token_destroy_frozen_funds) => { + token_destroy_frozen_funds.into_high_level_batch_drive_operations( + epoch, + owner_id, + platform_version, + ) + } } } } diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs index 87a44c1895e..ca853cf5641 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs @@ -10,8 +10,8 @@ use platform_version::version::PlatformVersion; use crate::error::drive::DriveError; use crate::error::Error; use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; use crate::util::batch::{DriveOperation, IdentityOperationType}; use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/mod.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/mod.rs diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/transformer.rs index 76f74cac5b5..a9bc78577fc 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/transformer.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; impl DocumentBaseTransitionAction { /// from base transition with contract lookup diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/v0/mod.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/v0/mod.rs diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/v0/transformer.rs similarity index 96% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/v0/transformer.rs index cbe3594ed3d..d64553ca355 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_base_transition_action/v0/transformer.rs @@ -5,7 +5,7 @@ use dpp::platform_value::Identifier; use dpp::ProtocolError; use dpp::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; impl DocumentBaseTransitionActionV0 { /// try from base transition with contract lookup diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/mod.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/mod.rs index 352444f8301..e529985db76 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/mod.rs @@ -14,7 +14,7 @@ use dpp::fee::Credits; use dpp::ProtocolError; pub use v0::*; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction}; use dpp::version::PlatformVersion; use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::ContestedDocumentVotePollStoredInfo; use crate::drive::votes::resolved::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePollWithContractInfo; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/transformer.rs similarity index 97% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/transformer.rs index 2eaf9f3dfa0..dab39d6d725 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/transformer.rs @@ -10,7 +10,7 @@ use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionV0}; impl DocumentCreateTransitionAction { /// from_document_create_transition_with_contract_lookup diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/v0/mod.rs similarity index 99% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/v0/mod.rs index e61fbb73c9f..e30b3948a70 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/v0/mod.rs @@ -18,7 +18,7 @@ use dpp::document::property_names::{ }; use dpp::fee::Credits; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; use crate::drive::votes::resolved::vote_polls::contested_document_resource_vote_poll::ContestedDocumentResourceVotePollWithContractInfo; use dpp::version::PlatformVersion; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/v0/transformer.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/v0/transformer.rs index eb9b06214b9..5c7540f8692 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_create_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_create_transition_action/v0/transformer.rs @@ -15,8 +15,8 @@ use crate::drive::Drive; use crate::drive::votes::resolved::vote_polls::contested_document_resource_vote_poll::resolve::ContestedDocumentResourceVotePollResolver; use crate::error::drive::DriveError; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionV0; impl DocumentCreateTransitionActionV0 { /// try from document create transition with contract lookup diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/mod.rs similarity index 87% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/mod.rs index 6ab5b5d730d..bb6a09b3817 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/mod.rs @@ -1,13 +1,13 @@ use derive_more::From; -use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::{DocumentDeleteTransitionActionAccessorsV0, DocumentDeleteTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::{DocumentDeleteTransitionActionAccessorsV0, DocumentDeleteTransitionActionV0}; /// transformer pub mod transformer; /// v0 pub mod v0; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; /// document delete transition action #[derive(Debug, Clone, From)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/transformer.rs index 0468e91eaa9..ede80bd6f0b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/transformer.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::DocumentDeleteTransition; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::{DocumentDeleteTransitionAction, DocumentDeleteTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::{DocumentDeleteTransitionAction, DocumentDeleteTransitionActionV0}; impl DocumentDeleteTransitionAction { /// from diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/v0/mod.rs similarity index 89% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/v0/mod.rs index 7df7f037443..c4e179c9623 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/v0/mod.rs @@ -1,7 +1,7 @@ /// transformer pub mod transformer; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; #[derive(Debug, Clone)] /// document delete transition action v0 diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/v0/transformer.rs similarity index 92% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/v0/transformer.rs index ee0e3d451ee..e3bbfeb2893 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_delete_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_delete_transition_action/v0/transformer.rs @@ -4,8 +4,8 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::document_delete_transition::DocumentDeleteTransitionV0; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionV0; impl DocumentDeleteTransitionActionV0 { /// try from diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/mod.rs similarity index 97% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/mod.rs index 53a84fe1a5d..e91b681f104 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/mod.rs @@ -8,7 +8,7 @@ use dpp::platform_value::Identifier; use dpp::ProtocolError; pub use v0::*; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; use dpp::version::PlatformVersion; /// transformer diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/transformer.rs index 54549dd38c0..7f591c601f6 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/transformer.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::DocumentPurchaseTransition; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionV0}; impl DocumentPurchaseTransitionAction { /// try from borrowed diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/v0/mod.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/v0/mod.rs index 785ccb32b60..dd0fe6acb8d 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/v0/mod.rs @@ -4,7 +4,7 @@ use dpp::document::Document; use dpp::fee::Credits; use dpp::identifier::Identifier; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; /// document purchase transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/v0/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/v0/transformer.rs index 429f5a61493..f6131860b2d 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_purchase_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_purchase_transition_action/v0/transformer.rs @@ -7,8 +7,8 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::document_purchase_transition::DocumentPurchaseTransitionV0; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::v0::DocumentPurchaseTransitionActionV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::v0::DocumentPurchaseTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; impl DocumentPurchaseTransitionActionV0 { /// try from borrowed diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/mod.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/mod.rs index f2dfc222e36..01d8400b382 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/mod.rs @@ -11,7 +11,7 @@ use dpp::prelude::{BlockHeight, CoreBlockHeight, Revision}; use dpp::ProtocolError; pub use v0::*; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; use dpp::version::PlatformVersion; /// transformer diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/transformer.rs similarity index 96% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/transformer.rs index f8d03908869..51f52bd4e6e 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/transformer.rs @@ -7,7 +7,7 @@ use dpp::prelude::{BlockHeight, CoreBlockHeight}; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::DocumentReplaceTransition; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionV0}; impl DocumentReplaceTransitionAction { /// try from borrowed diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/v0/mod.rs similarity index 99% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/v0/mod.rs index 299d71136f5..f8b4daa0fd6 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/v0/mod.rs @@ -8,7 +8,7 @@ use dpp::ProtocolError; use std::collections::BTreeMap; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; /// document replace transition action v0 diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/v0/transformer.rs similarity index 96% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/v0/transformer.rs index b88d09aa112..b7d9ce25ed7 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_replace_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_replace_transition_action/v0/transformer.rs @@ -8,8 +8,8 @@ use dpp::prelude::{BlockHeight, CoreBlockHeight}; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::document_replace_transition::DocumentReplaceTransitionV0; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::v0::DocumentReplaceTransitionActionV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::v0::DocumentReplaceTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; impl DocumentReplaceTransitionActionV0 { /// try from borrowed diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/mod.rs similarity index 97% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/mod.rs index d9a38534ca9..6dde44bf561 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/mod.rs @@ -7,7 +7,7 @@ use dpp::platform_value::Identifier; use dpp::ProtocolError; pub use v0::*; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; use dpp::version::PlatformVersion; /// transformer diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/transformer.rs index 5d1336731c4..736d414f17c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/transformer.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::DocumentTransferTransition; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionV0}; impl DocumentTransferTransitionAction { /// try from borrowed diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/v0/mod.rs similarity index 92% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/v0/mod.rs index d23667dd298..f87c75b6226 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/v0/mod.rs @@ -2,7 +2,7 @@ pub mod transformer; use dpp::document::Document; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; /// document transfer transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/v0/transformer.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/v0/transformer.rs index 214df9b631f..1bf629c41db 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transfer_transition_action/v0/transformer.rs @@ -7,8 +7,8 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::document_transfer_transition::DocumentTransferTransitionV0; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::v0::DocumentTransferTransitionActionV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::v0::DocumentTransferTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; impl DocumentTransferTransitionActionV0 { /// try from borrowed diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transition_action_type.rs similarity index 80% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transition_action_type.rs index bb2ad121fcd..83d41158eaf 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_transition_action_type.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_transition_action_type.rs @@ -1,9 +1,9 @@ -use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::{ - DocumentTransitionActionType, TransitionActionTypeGetter, + DocumentTransitionActionType, DocumentTransitionActionTypeGetter, }; -impl TransitionActionTypeGetter for DocumentTransitionAction { +impl DocumentTransitionActionTypeGetter for DocumentTransitionAction { fn action_type(&self) -> DocumentTransitionActionType { match self { DocumentTransitionAction::CreateAction(_) => DocumentTransitionActionType::Create, diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/mod.rs similarity index 97% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/mod.rs index c206f21da92..254e3f803bf 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/mod.rs @@ -7,7 +7,7 @@ use dpp::platform_value::Identifier; use dpp::ProtocolError; pub use v0::*; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; use dpp::version::PlatformVersion; /// transformer diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/transformer.rs index f0339b8c4f3..524ff7e6c1a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/transformer.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::DocumentUpdatePriceTransition; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionV0}; impl DocumentUpdatePriceTransitionAction { /// try from borrowed diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/v0/mod.rs similarity index 93% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/v0/mod.rs index 37f3f8100c4..493af12a6d2 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/v0/mod.rs @@ -2,7 +2,7 @@ pub mod transformer; use dpp::document::Document; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; /// document transfer transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/v0/transformer.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/v0/transformer.rs index 7f5d57629f6..c34bba6cb60 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/document_update_price_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/document_update_price_transition_action/v0/transformer.rs @@ -7,8 +7,8 @@ use std::sync::Arc; use dpp::ProtocolError; use dpp::state_transition::batch_transition::batched_transition::document_update_price_transition::DocumentUpdatePriceTransitionV0; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::v0::DocumentUpdatePriceTransitionActionV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::v0::DocumentUpdatePriceTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; impl DocumentUpdatePriceTransitionActionV0 { /// try from borrowed diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/mod.rs new file mode 100644 index 00000000000..7c40b645318 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/document_transition/mod.rs @@ -0,0 +1,73 @@ +/// document_base_transition_action +pub mod document_base_transition_action; +/// document_create_transition_action +pub mod document_create_transition_action; +/// document_delete_transition_action +pub mod document_delete_transition_action; +/// document_purchase_transition_action +pub mod document_purchase_transition_action; +/// document_replace_transition_action +pub mod document_replace_transition_action; +/// document_transfer_transition_action +pub mod document_transfer_transition_action; +mod document_transition_action_type; +/// document_update_price_transition_action +pub mod document_update_price_transition_action; + +pub use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; + +use derive_more::From; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; + +/// version +pub const DOCUMENT_TRANSITION_ACTION_VERSION: u32 = 0; + +/// action +#[derive(Debug, Clone, From)] +pub enum DocumentTransitionAction { + /// create + CreateAction(DocumentCreateTransitionAction), + /// replace + ReplaceAction(DocumentReplaceTransitionAction), + /// delete + DeleteAction(DocumentDeleteTransitionAction), + /// transfer + TransferAction(DocumentTransferTransitionAction), + /// purchase + PurchaseAction(DocumentPurchaseTransitionAction), + /// update price + UpdatePriceAction(DocumentUpdatePriceTransitionAction), +} + +impl DocumentTransitionAction { + /// base + pub fn base(&self) -> &DocumentBaseTransitionAction { + match self { + DocumentTransitionAction::CreateAction(d) => d.base(), + DocumentTransitionAction::DeleteAction(d) => d.base(), + DocumentTransitionAction::ReplaceAction(d) => d.base(), + DocumentTransitionAction::TransferAction(d) => d.base(), + DocumentTransitionAction::PurchaseAction(d) => d.base(), + DocumentTransitionAction::UpdatePriceAction(d) => d.base(), + } + } + + /// base owned + pub fn base_owned(self) -> DocumentBaseTransitionAction { + match self { + DocumentTransitionAction::CreateAction(d) => d.base_owned(), + DocumentTransitionAction::DeleteAction(d) => d.base_owned(), + DocumentTransitionAction::ReplaceAction(d) => d.base_owned(), + DocumentTransitionAction::TransferAction(d) => d.base_owned(), + DocumentTransitionAction::PurchaseAction(d) => d.base_owned(), + DocumentTransitionAction::UpdatePriceAction(d) => d.base_owned(), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/mod.rs new file mode 100644 index 00000000000..4ba839bd84f --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/mod.rs @@ -0,0 +1,40 @@ +use derive_more::From; +use dpp::identifier::Identifier; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; +use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::{BumpIdentityDataContractNonceAction, BumpIdentityDataContractNonceActionAccessorsV0}; + +/// document transition +pub mod document_transition; +/// token transition +pub mod token_transition; + +/// token action +#[derive(Debug, Clone, From)] +pub enum BatchedTransitionAction { + /// document + DocumentAction(DocumentTransitionAction), + /// token + TokenAction(TokenTransitionAction), + /// bump identity data contract nonce + BumpIdentityDataContractNonce(BumpIdentityDataContractNonceAction), +} + +impl BatchedTransitionAction { + /// Helper method to get the data contract id + pub fn data_contract_id(&self) -> Identifier { + match self { + BatchedTransitionAction::DocumentAction(document_action) => { + document_action.base().data_contract_id() + } + BatchedTransitionAction::TokenAction(token_action) => { + token_action.base().data_contract_id() + } + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action) => { + bump_action.data_contract_id() + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs new file mode 100644 index 00000000000..79defafe132 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs @@ -0,0 +1,79 @@ +mod token_transition_action_type; + +/// token_base_transition_action +pub mod token_base_transition_action; +/// token_burn_transition_action +pub mod token_burn_transition_action; +/// token_freeze_transition_action +pub mod token_freeze_transition_action; +/// token_issuance_transition_action +pub mod token_mint_transition_action; +/// token_transfer_transition_action +pub mod token_transfer_transition_action; +/// token_unfreeze_transition_action +pub mod token_unfreeze_transition_action; + +/// token_destroy_frozen_funds_transition_action +pub mod token_destroy_frozen_funds_transition_action; +/// token_emergency_action_transition_action +pub mod token_emergency_action_transition_action; + +use derive_more::From; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::TokenEmergencyActionTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::TokenEmergencyActionTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::TokenDestroyFrozenFundsTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::TokenDestroyFrozenFundsTransitionActionAccessorsV0; + +/// token action +#[derive(Debug, Clone, From)] +pub enum TokenTransitionAction { + /// burn + BurnAction(TokenBurnTransitionAction), + /// issuance + MintAction(TokenMintTransitionAction), + /// transfer + TransferAction(TokenTransferTransitionAction), + /// freeze + FreezeAction(TokenFreezeTransitionAction), + /// unfreeze + UnfreezeAction(TokenUnfreezeTransitionAction), + /// emergency action + EmergencyActionAction(TokenEmergencyActionTransitionAction), + /// destroy frozen funds action + DestroyFrozenFundsAction(TokenDestroyFrozenFundsTransitionAction), +} + +impl TokenTransitionAction { + /// Returns a reference to the base token transition action if available + pub fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenTransitionAction::BurnAction(action) => action.base(), + TokenTransitionAction::MintAction(action) => action.base(), + TokenTransitionAction::TransferAction(action) => action.base(), + TokenTransitionAction::FreezeAction(action) => action.base(), + TokenTransitionAction::UnfreezeAction(action) => action.base(), + TokenTransitionAction::EmergencyActionAction(action) => action.base(), + TokenTransitionAction::DestroyFrozenFundsAction(action) => action.base(), + } + } + + /// Consumes self and returns the base token transition action if available + pub fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenTransitionAction::BurnAction(action) => action.base_owned(), + TokenTransitionAction::MintAction(action) => action.base_owned(), + TokenTransitionAction::TransferAction(action) => action.base_owned(), + TokenTransitionAction::FreezeAction(action) => action.base_owned(), + TokenTransitionAction::UnfreezeAction(action) => action.base_owned(), + TokenTransitionAction::EmergencyActionAction(action) => action.base_owned(), + TokenTransitionAction::DestroyFrozenFundsAction(action) => action.base_owned(), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/mod.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/mod.rs diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/transformer.rs similarity index 93% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/transformer.rs index 7d52c7ab2a5..ab33951ffcc 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/transformer.rs @@ -9,7 +9,7 @@ use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionV0}; impl TokenBaseTransitionAction { /// from base transition with contract lookup diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/v0/mod.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/v0/mod.rs diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/v0/transformer.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/v0/transformer.rs index 7dc2337281b..64532238e7c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_base_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_base_transition_action/v0/transformer.rs @@ -15,7 +15,7 @@ use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionV0; impl TokenBaseTransitionActionV0 { /// try from base transition with contract lookup diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/mod.rs similarity index 91% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/mod.rs index 9d2f3cd1c73..0e24f14920b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/mod.rs @@ -6,7 +6,7 @@ mod v0; pub use v0::*; // re-export the v0 module items (including TokenBurnTransitionActionV0) -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; /// Token burn transition action #[derive(Debug, Clone, From)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/transformer.rs similarity index 96% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/transformer.rs index 2828e045410..92383d278b8 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/transformer.rs @@ -6,14 +6,14 @@ use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{ +use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{ TokenBurnTransitionAction, TokenBurnTransitionActionV0, }; use dpp::state_transition::batch_transition::token_burn_transition::TokenBurnTransition; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::BatchedTransitionAction; /// Implement methods to transform a `TokenBurnTransition` into a `TokenBurnTransitionAction`. impl TokenBurnTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/v0/mod.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/v0/mod.rs index 84f239a832b..7a6c9a51845 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/v0/mod.rs @@ -4,7 +4,7 @@ use std::sync::Arc; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; /// Token burn transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/v0/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/v0/transformer.rs index b9c6d99e0aa..1542acc0b2a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_burn_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_burn_transition_action/v0/transformer.rs @@ -11,9 +11,10 @@ use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::v0::TokenBurnTransitionActionV0; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; impl TokenBurnTransitionActionV0 { diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/mod.rs new file mode 100644 index 00000000000..15460920d97 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/mod.rs @@ -0,0 +1,63 @@ +use derive_more::From; +use dpp::identifier::Identifier; + +/// transformer module for token destroy_frozen_funds transition action +pub mod transformer; +mod v0; + +pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) + +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; + +/// Token destroy_frozen_funds transition action +#[derive(Debug, Clone, From)] +pub enum TokenDestroyFrozenFundsTransitionAction { + /// v0 + V0(TokenDestroyFrozenFundsTransitionActionV0), +} + +impl TokenDestroyFrozenFundsTransitionActionAccessorsV0 + for TokenDestroyFrozenFundsTransitionAction +{ + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => &v0.base, + } + } + + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.base, + } + } + + fn frozen_identity_id(&self) -> Identifier { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.frozen_identity_id, + } + } + + fn set_frozen_identity_id(&mut self, id: Identifier) { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.frozen_identity_id = id, + } + } + + fn public_note(&self) -> Option<&String> { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.public_note.as_ref(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.public_note, + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.public_note = public_note, + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/transformer.rs new file mode 100644 index 00000000000..6b83b6e6a34 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/transformer.rs @@ -0,0 +1,117 @@ +use dpp::platform_value::Identifier; +use dpp::ProtocolError; +use grovedb::TransactionArg; +use std::sync::Arc; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::{TokenDestroyFrozenFundsTransitionActionV0, TokenDestroyFrozenFundsTransitionAction}; +use dpp::state_transition::batch_transition::token_destroy_frozen_funds_transition::TokenDestroyFrozenFundsTransition; +use platform_version::version::PlatformVersion; +use crate::drive::Drive; +use crate::error::Error; +use crate::state_transition_action::batch::BatchedTransitionAction; + +/// Implement methods to transform a `TokenDestroyFrozenFundsTransition` into a `TokenDestroyFrozenFundsTransitionAction`. +impl TokenDestroyFrozenFundsTransitionAction { + /// Transform a `TokenDestroyFrozenFundsTransition` into a `TokenDestroyFrozenFundsTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the destroy_frozen_funds transition. + /// * `transaction` - The transaction argument used for state changes. + /// * `value` - A `TokenDestroyFrozenFundsTransition` instance. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// + /// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenDestroyFrozenFundsTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_token_destroy_frozen_funds_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: TokenDestroyFrozenFundsTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + match value { + TokenDestroyFrozenFundsTransition::V0(v0) => { + TokenDestroyFrozenFundsTransitionActionV0::try_from_token_destroy_frozen_funds_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + user_fee_increase, + get_data_contract, + platform_version, + ) + } + } + } + + /// Transform a borrowed `TokenDestroyFrozenFundsTransition` into a `TokenDestroyFrozenFundsTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the destroy_frozen_funds transition. + /// * `transaction` - The transaction argument used for state changes. + /// * `value` - A reference to a `TokenDestroyFrozenFundsTransition`. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// + /// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenDestroyFrozenFundsTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_borrowed_token_destroy_frozen_funds_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: &TokenDestroyFrozenFundsTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + match value { + TokenDestroyFrozenFundsTransition::V0(v0) => { + TokenDestroyFrozenFundsTransitionActionV0::try_from_borrowed_token_destroy_frozen_funds_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + user_fee_increase, + get_data_contract, + platform_version, + ) + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/mod.rs new file mode 100644 index 00000000000..c86d550ac63 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/mod.rs @@ -0,0 +1,98 @@ +mod transformer; + +use std::sync::Arc; +use dpp::identifier::Identifier; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; + +/// Token issuance transition action v0 +#[derive(Debug, Clone)] +pub struct TokenDestroyFrozenFundsTransitionActionV0 { + /// Base token transition action + pub base: TokenBaseTransitionAction, + /// The identity to credit the token to + pub frozen_identity_id: Identifier, + /// A public note + pub public_note: Option, +} + +/// Accessors for `TokenIssuanceTransitionActionV0` +pub trait TokenDestroyFrozenFundsTransitionActionAccessorsV0 { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Consumes self and returns the base token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + + /// Consumes self and returns the identity balance holder ID + fn frozen_identity_id(&self) -> Identifier; + + /// Sets the identity balance holder ID + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier); + + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } + + /// Returns the token ID + fn token_id(&self) -> Identifier { + self.base().token_id() + } + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + /// Returns the public note (optional) + fn public_note(&self) -> Option<&String>; + + /// Returns the public note (owned) + fn public_note_owned(self) -> Option; + + /// Sets the public note + fn set_public_note(&mut self, public_note: Option); +} + +impl TokenDestroyFrozenFundsTransitionActionAccessorsV0 + for TokenDestroyFrozenFundsTransitionActionV0 +{ + fn base(&self) -> &TokenBaseTransitionAction { + &self.base + } + + fn base_owned(self) -> TokenBaseTransitionAction { + self.base + } + + fn frozen_identity_id(&self) -> Identifier { + self.frozen_identity_id + } + + fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier) { + self.frozen_identity_id = frozen_identity_id; + } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/transformer.rs new file mode 100644 index 00000000000..311ae6d2a2d --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/transformer.rs @@ -0,0 +1,232 @@ +use std::sync::Arc; +use grovedb::TransactionArg; +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::state_transition::batch_transition::token_destroy_frozen_funds_transition::v0::TokenDestroyFrozenFundsTransitionV0; +use dpp::ProtocolError; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::v0::TokenDestroyFrozenFundsTransitionActionV0; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use platform_version::version::PlatformVersion; +use crate::drive::Drive; +use crate::error::Error; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; +use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; + +impl TokenDestroyFrozenFundsTransitionActionV0 { + /// Converts a `TokenDestroyFrozenFundsTransitionV0` into a `TokenDestroyFrozenFundsTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token destroy_frozen_fundsing transition and returns the corresponding transition action + /// while looking up necessary data contracts and applying the relevant logic for destroy_frozen_fundsing. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the destroy_frozen_fundsing transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `transaction` - A transaction context that includes the necessary state and other details for the transition. + /// * `value` - The `TokenDestroyFrozenFundsTransitionV0` struct containing the transition data, including token amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. Useful for optimizing the transaction cost calculations. + /// * `block_info` - Information about the current block to calculate fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version, ensuring the transition respects version-specific logic. + /// + /// # Returns + /// + /// * `Result, Error>` - Returns the constructed `TokenDestroyFrozenFundsTransitionActionV0` if successful, + /// or an error if any issue arises, such as missing data or an invalid state transition. + pub fn try_from_token_destroy_frozen_funds_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: TokenDestroyFrozenFundsTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + let TokenDestroyFrozenFundsTransitionV0 { + base, + frozen_identity_id, + public_note, + } = value; + + let mut drive_operations = vec![]; + + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + &base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; + + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = BumpIdentityDataContractNonceAction::from_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + + Ok(( + BatchedTransitionAction::TokenAction(TokenTransitionAction::DestroyFrozenFundsAction( + TokenDestroyFrozenFundsTransitionActionV0 { + base: base_action, + frozen_identity_id, + public_note, + } + .into(), + )) + .into(), + fee_result, + )) + } + + /// Converts a borrowed `TokenDestroyFrozenFundsTransitionV0` into a `TokenDestroyFrozenFundsTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token destroy_frozen_fundsing transition and constructs the corresponding transition action while + /// looking up necessary data contracts and applying the relevant destroy_frozen_fundsing logic. It does not require `drive_operations` + /// to be passed as a parameter, but it manages them internally. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance that handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the destroy_frozen_fundsing transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `value` - A reference to the `TokenDestroyFrozenFundsTransitionV0` struct containing the transition data, including token + /// amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to indicate whether costs should be approximated without full + /// state consideration. Useful for optimizing transaction cost calculations in scenarios where full state is not needed. + /// * `transaction` - The transaction context, which includes the necessary state and other details for the transition. + /// * `block_info` - Information about the current block (e.g., epoch) to help calculate transaction fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version to ensure the transition respects version-specific logic. + /// + //// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - Returns a tuple containing the constructed + /// `TokenDestroyFrozenFundsTransitionActionV0` and a `FeeResult` if successful. If an error occurs (e.g., missing data or + /// invalid state transition), it returns an `Error`. + /// + pub fn try_from_borrowed_token_destroy_frozen_funds_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: &TokenDestroyFrozenFundsTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + let TokenDestroyFrozenFundsTransitionV0 { + base, + frozen_identity_id, + public_note, + } = value; + + let mut drive_operations = vec![]; + + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; + + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + + Ok(( + BatchedTransitionAction::TokenAction(TokenTransitionAction::DestroyFrozenFundsAction( + TokenDestroyFrozenFundsTransitionActionV0 { + base: base_action, + frozen_identity_id: *frozen_identity_id, + public_note: public_note.clone(), + } + .into(), + )) + .into(), + fee_result, + )) + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/mod.rs new file mode 100644 index 00000000000..4cd3b96c261 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/mod.rs @@ -0,0 +1,63 @@ +use derive_more::From; +use dpp::tokens::emergency_action::TokenEmergencyAction; + +/// transformer module for token emergency_action transition action +pub mod transformer; +mod v0; + +pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) + +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; + +/// Token emergency_action transition action +#[derive(Debug, Clone, From)] +pub enum TokenEmergencyActionTransitionAction { + /// v0 + V0(TokenEmergencyActionTransitionActionV0), +} + +impl TokenEmergencyActionTransitionActionAccessorsV0 for TokenEmergencyActionTransitionAction { + fn base(&self) -> &TokenBaseTransitionAction { + match self { + TokenEmergencyActionTransitionAction::V0(v0) => &v0.base, + } + } + + fn base_owned(self) -> TokenBaseTransitionAction { + match self { + TokenEmergencyActionTransitionAction::V0(v0) => v0.base, + } + } + + fn emergency_action(&self) -> TokenEmergencyAction { + match self { + TokenEmergencyActionTransitionAction::V0(v0) => v0.emergency_action(), + } + } + + fn set_emergency_action(&mut self, emergency_action: TokenEmergencyAction) { + match self { + TokenEmergencyActionTransitionAction::V0(v0) => { + v0.set_emergency_action(emergency_action) + } + } + } + + fn public_note(&self) -> Option<&String> { + match self { + TokenEmergencyActionTransitionAction::V0(v0) => v0.public_note.as_ref(), + } + } + + fn public_note_owned(self) -> Option { + match self { + TokenEmergencyActionTransitionAction::V0(v0) => v0.public_note, + } + } + + fn set_public_note(&mut self, public_note: Option) { + match self { + TokenEmergencyActionTransitionAction::V0(v0) => v0.public_note = public_note, + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/transformer.rs new file mode 100644 index 00000000000..0e2670ed951 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/transformer.rs @@ -0,0 +1,117 @@ +use dpp::platform_value::Identifier; +use dpp::ProtocolError; +use grovedb::TransactionArg; +use std::sync::Arc; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::{TokenEmergencyActionTransitionActionV0, TokenEmergencyActionTransitionAction}; +use dpp::state_transition::batch_transition::token_emergency_action_transition::TokenEmergencyActionTransition; +use platform_version::version::PlatformVersion; +use crate::drive::Drive; +use crate::error::Error; +use crate::state_transition_action::batch::BatchedTransitionAction; + +/// Implement methods to transform a `TokenEmergencyActionTransition` into a `TokenEmergencyActionTransitionAction`. +impl TokenEmergencyActionTransitionAction { + /// Transform a `TokenEmergencyActionTransition` into a `TokenEmergencyActionTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the emergency_action transition. + /// * `transaction` - The transaction argument used for state changes. + /// * `value` - A `TokenEmergencyActionTransition` instance. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// + /// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenEmergencyActionTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_token_emergency_action_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: TokenEmergencyActionTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + match value { + TokenEmergencyActionTransition::V0(v0) => { + TokenEmergencyActionTransitionActionV0::try_from_token_emergency_action_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + user_fee_increase, + get_data_contract, + platform_version, + ) + } + } + } + + /// Transform a borrowed `TokenEmergencyActionTransition` into a `TokenEmergencyActionTransitionAction` using the provided data contract lookup. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance used for accessing the system. + /// * `owner_id` - The identifier of the owner initiating the emergency_action transition. + /// * `transaction` - The transaction argument used for state changes. + /// * `value` - A reference to a `TokenEmergencyActionTransition`. + /// * `approximate_without_state_for_costs` - A flag indicating whether to approximate state costs without full state. + /// * `drive_operations` - A mutable reference to the vector of low-level operations that need to be performed. + /// * `get_data_contract` - A closure that fetches the `DataContractFetchInfo` given a contract ID. + /// * `platform_version` - The platform version for the context in which the transition is being executed. + /// + /// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - A `TokenEmergencyActionTransitionAction` if successful, otherwise `ProtocolError`. + pub fn try_from_borrowed_token_emergency_action_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: &TokenEmergencyActionTransition, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + match value { + TokenEmergencyActionTransition::V0(v0) => { + TokenEmergencyActionTransitionActionV0::try_from_borrowed_token_emergency_action_transition_with_contract_lookup( + drive, + owner_id, + v0, + approximate_without_state_for_costs, + transaction, + block_info, + user_fee_increase, + get_data_contract, + platform_version, + ) + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/v0/mod.rs new file mode 100644 index 00000000000..12dd5babe37 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/v0/mod.rs @@ -0,0 +1,97 @@ +mod transformer; + +use std::sync::Arc; +use dpp::identifier::Identifier; +use dpp::tokens::emergency_action::TokenEmergencyAction; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; + +/// Token issuance transition action v0 +#[derive(Debug, Clone)] +pub struct TokenEmergencyActionTransitionActionV0 { + /// Base token transition action + pub base: TokenBaseTransitionAction, + /// The emergency action + pub emergency_action: TokenEmergencyAction, + /// A public note + pub public_note: Option, +} + +/// Accessors for `TokenIssuanceTransitionActionV0` +pub trait TokenEmergencyActionTransitionActionAccessorsV0 { + /// Returns a reference to the base token transition action + fn base(&self) -> &TokenBaseTransitionAction; + + /// Consumes self and returns the base token transition action + fn base_owned(self) -> TokenBaseTransitionAction; + + /// Returns the `emergency_action` field. + fn emergency_action(&self) -> TokenEmergencyAction; + + /// Sets the value of the `emergency_action` field. + fn set_emergency_action(&mut self, emergency_action: TokenEmergencyAction); + + /// Returns the token position in the contract + fn token_position(&self) -> u16 { + self.base().token_position() + } + + /// Returns the token ID + fn token_id(&self) -> Identifier { + self.base().token_id() + } + + /// Returns the data contract ID + fn data_contract_id(&self) -> Identifier { + self.base().data_contract_id() + } + + /// Returns a reference to the data contract fetch info + fn data_contract_fetch_info_ref(&self) -> &Arc { + self.base().data_contract_fetch_info_ref() + } + + /// Returns the data contract fetch info + fn data_contract_fetch_info(&self) -> Arc { + self.base().data_contract_fetch_info() + } + + /// Returns the public note (optional) + fn public_note(&self) -> Option<&String>; + + /// Returns the public note (owned) + fn public_note_owned(self) -> Option; + + /// Sets the public note + fn set_public_note(&mut self, public_note: Option); +} + +impl TokenEmergencyActionTransitionActionAccessorsV0 for TokenEmergencyActionTransitionActionV0 { + fn base(&self) -> &TokenBaseTransitionAction { + &self.base + } + + fn base_owned(self) -> TokenBaseTransitionAction { + self.base + } + + fn emergency_action(&self) -> TokenEmergencyAction { + self.emergency_action + } + + fn set_emergency_action(&mut self, emergency_action: TokenEmergencyAction) { + self.emergency_action = emergency_action; + } + + fn public_note(&self) -> Option<&String> { + self.public_note.as_ref() + } + + fn public_note_owned(self) -> Option { + self.public_note + } + + fn set_public_note(&mut self, public_note: Option) { + self.public_note = public_note; + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/v0/transformer.rs new file mode 100644 index 00000000000..b1d3b29459f --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_emergency_action_transition_action/v0/transformer.rs @@ -0,0 +1,232 @@ +use std::sync::Arc; +use grovedb::TransactionArg; +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::state_transition::batch_transition::token_emergency_action_transition::v0::TokenEmergencyActionTransitionV0; +use dpp::ProtocolError; +use crate::drive::contract::DataContractFetchInfo; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::v0::TokenEmergencyActionTransitionActionV0; +use dpp::fee::fee_result::FeeResult; +use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use platform_version::version::PlatformVersion; +use crate::drive::Drive; +use crate::error::Error; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; +use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; + +impl TokenEmergencyActionTransitionActionV0 { + /// Converts a `TokenEmergencyActionTransitionV0` into a `TokenEmergencyActionTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token emergency_actioning transition and returns the corresponding transition action + /// while looking up necessary data contracts and applying the relevant logic for emergency_actioning. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance which handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the emergency_actioning transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `transaction` - A transaction context that includes the necessary state and other details for the transition. + /// * `value` - The `TokenEmergencyActionTransitionV0` struct containing the transition data, including token amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to determine if costs should be approximated without considering + /// the full state for the operation. Useful for optimizing the transaction cost calculations. + /// * `block_info` - Information about the current block to calculate fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version, ensuring the transition respects version-specific logic. + /// + /// # Returns + /// + /// * `Result, Error>` - Returns the constructed `TokenEmergencyActionTransitionActionV0` if successful, + /// or an error if any issue arises, such as missing data or an invalid state transition. + pub fn try_from_token_emergency_action_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: TokenEmergencyActionTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + let TokenEmergencyActionTransitionV0 { + base, + emergency_action, + public_note, + } = value; + + let mut drive_operations = vec![]; + + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + &base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; + + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = BumpIdentityDataContractNonceAction::from_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + + Ok(( + BatchedTransitionAction::TokenAction(TokenTransitionAction::EmergencyActionAction( + TokenEmergencyActionTransitionActionV0 { + base: base_action, + emergency_action, + public_note, + } + .into(), + )) + .into(), + fee_result, + )) + } + + /// Converts a borrowed `TokenEmergencyActionTransitionV0` into a `TokenEmergencyActionTransitionActionV0` using the provided contract lookup. + /// + /// This method processes the token emergency_actioning transition and constructs the corresponding transition action while + /// looking up necessary data contracts and applying the relevant emergency_actioning logic. It does not require `drive_operations` + /// to be passed as a parameter, but it manages them internally. + /// + /// # Arguments + /// + /// * `drive` - A reference to the `Drive` instance that handles data storage and retrieval. + /// * `owner_id` - The identifier of the owner initiating the emergency_actioning transition. This is typically the identity + /// performing the transaction, such as the user's ID. + /// * `value` - A reference to the `TokenEmergencyActionTransitionV0` struct containing the transition data, including token + /// amount and recipient. + /// * `approximate_without_state_for_costs` - A flag to indicate whether costs should be approximated without full + /// state consideration. Useful for optimizing transaction cost calculations in scenarios where full state is not needed. + /// * `transaction` - The transaction context, which includes the necessary state and other details for the transition. + /// * `block_info` - Information about the current block (e.g., epoch) to help calculate transaction fees. + /// * `get_data_contract` - A closure function that takes a contract identifier and returns a `DataContractFetchInfo` + /// containing the data contract details, including token configurations. + /// * `platform_version` - A reference to the platform version to ensure the transition respects version-specific logic. + /// + //// # Returns + /// + /// * `Result<(ConsensusValidationResult, FeeResult), Error>` - Returns a tuple containing the constructed + /// `TokenEmergencyActionTransitionActionV0` and a `FeeResult` if successful. If an error occurs (e.g., missing data or + /// invalid state transition), it returns an `Error`. + /// + pub fn try_from_borrowed_token_emergency_action_transition_with_contract_lookup( + drive: &Drive, + owner_id: Identifier, + value: &TokenEmergencyActionTransitionV0, + approximate_without_state_for_costs: bool, + transaction: TransactionArg, + block_info: &BlockInfo, + user_fee_increase: UserFeeIncrease, + get_data_contract: impl Fn(Identifier) -> Result, ProtocolError>, + platform_version: &PlatformVersion, + ) -> Result< + ( + ConsensusValidationResult, + FeeResult, + ), + Error, + > { + let TokenEmergencyActionTransitionV0 { + base, + emergency_action, + public_note, + } = value; + + let mut drive_operations = vec![]; + + let base_action_validation_result = + TokenBaseTransitionAction::try_from_borrowed_base_transition_with_contract_lookup( + drive, + owner_id, + base, + approximate_without_state_for_costs, + transaction, + &mut drive_operations, + get_data_contract, + platform_version, + )?; + + let fee_result = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + drive.config.epochs_per_era, + platform_version, + None, + )?; + + let base_action = match base_action_validation_result.is_valid() { + true => base_action_validation_result.into_data()?, + false => { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition( + base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + base_action_validation_result.errors, + ), + fee_result, + )); + } + }; + + Ok(( + BatchedTransitionAction::TokenAction(TokenTransitionAction::EmergencyActionAction( + TokenEmergencyActionTransitionActionV0 { + base: base_action, + emergency_action: *emergency_action, + public_note: public_note.clone(), + } + .into(), + )) + .into(), + fee_result, + )) + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/mod.rs similarity index 91% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/mod.rs index 6efd2f4df88..f61d5d6d2eb 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/mod.rs @@ -7,7 +7,7 @@ mod v0; pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; /// Token freeze transition action #[derive(Debug, Clone, From)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/transformer.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/transformer.rs index acd281eb476..3347e72524b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/transformer.rs @@ -6,12 +6,12 @@ use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionActionV0, TokenFreezeTransitionAction}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionActionV0, TokenFreezeTransitionAction}; use dpp::state_transition::batch_transition::token_freeze_transition::TokenFreezeTransition; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::BatchedTransitionAction; /// Implement methods to transform a `TokenFreezeTransition` into a `TokenFreezeTransitionAction`. impl TokenFreezeTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/v0/mod.rs similarity index 93% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/v0/mod.rs index 02e40882ce3..80a912b127f 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/v0/mod.rs @@ -3,7 +3,7 @@ mod transformer; use std::sync::Arc; use dpp::identifier::Identifier; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; /// Token issuance transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/v0/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/v0/transformer.rs index 737d800cfb2..913dec97c6e 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_freeze_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_freeze_transition_action/v0/transformer.rs @@ -5,14 +5,15 @@ use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_freeze_transition::v0::TokenFreezeTransitionV0; use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::v0::TokenFreezeTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::v0::TokenFreezeTransitionActionV0; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; impl TokenFreezeTransitionActionV0 { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/mod.rs similarity index 93% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/mod.rs index 10262ce08b8..2c4b75de5e7 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/mod.rs @@ -7,7 +7,7 @@ mod v0; pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; /// Token issuance transition action #[derive(Debug, Clone, From)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/transformer.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/transformer.rs index 4a408a94577..0183d1a7fdd 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/transformer.rs @@ -6,12 +6,12 @@ use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionActionV0, TokenMintTransitionAction}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::{TokenMintTransitionActionV0, TokenMintTransitionAction}; use dpp::state_transition::batch_transition::token_mint_transition::TokenMintTransition; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::BatchedTransitionAction; /// Implement methods to transform a `TokenMintTransition` into a `TokenMintTransitionAction`. impl TokenMintTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/mod.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/mod.rs index 5af141cff4a..812949c03ca 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/mod.rs @@ -3,7 +3,7 @@ mod transformer; use std::sync::Arc; use dpp::identifier::Identifier; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; /// Token issuance transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/transformer.rs similarity index 96% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/transformer.rs index 1ff995248b2..5fba01b5e0a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_mint_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_mint_transition_action/v0/transformer.rs @@ -9,15 +9,16 @@ use dpp::ProtocolError; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::v0::TokenMintTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::v0::TokenMintTransitionActionV0; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; +use crate::state_transition_action::batch::BatchedTransitionAction; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; impl TokenMintTransitionActionV0 { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs similarity index 91% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs index c54c4cd9912..6d4c88b6b3a 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs @@ -1,9 +1,6 @@ use derive_more::From; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::{ - TokenTransferTransitionActionV0, TokenTransferTransitionActionAccessorsV0, -}; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; use dpp::identifier::Identifier; use dpp::prelude::{DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex}; @@ -12,6 +9,8 @@ pub mod transformer; /// v0 pub mod v0; +pub use v0::*; + /// TokenTransferTransitionAction #[derive(Debug, Clone, From)] pub enum TokenTransferTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/transformer.rs index efc4d7337a0..3cf42ca9107 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/transformer.rs @@ -9,8 +9,8 @@ use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionV0; /// Implement methods to transform a `TokenTransferTransition` into a `TokenTransferTransitionAction`. impl TokenTransferTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs similarity index 98% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs index e1d318d219a..af1007df8b3 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs @@ -9,7 +9,7 @@ use dpp::prelude::{ }; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{ +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{ TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0, }; diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/transformer.rs similarity index 96% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/transformer.rs index ac6820da0b9..8f652ae7d10 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transfer_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/transformer.rs @@ -9,8 +9,8 @@ use platform_version::version::PlatformVersion; use crate::drive::contract::DataContractFetchInfo; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionActionV0; impl TokenTransferTransitionActionV0 { /// Converts a `TokenTransferTransitionV0` into a `TokenTransferTransitionActionV0` using the provided contract lookup. diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transition_action_type.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transition_action_type.rs new file mode 100644 index 00000000000..69689509bc5 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transition_action_type.rs @@ -0,0 +1,22 @@ +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; +use dpp::state_transition::batch_transition::batched_transition::token_transition_action_type::{ + TokenTransitionActionType, TokenTransitionActionTypeGetter, +}; + +impl TokenTransitionActionTypeGetter for TokenTransitionAction { + fn action_type(&self) -> TokenTransitionActionType { + match self { + TokenTransitionAction::BurnAction(_) => TokenTransitionActionType::Burn, + TokenTransitionAction::MintAction(_) => TokenTransitionActionType::Mint, + TokenTransitionAction::TransferAction(_) => TokenTransitionActionType::Transfer, + TokenTransitionAction::FreezeAction(_) => TokenTransitionActionType::Freeze, + TokenTransitionAction::UnfreezeAction(_) => TokenTransitionActionType::Unfreeze, + TokenTransitionAction::EmergencyActionAction(_) => { + TokenTransitionActionType::EmergencyAction + } + TokenTransitionAction::DestroyFrozenFundsAction(_) => { + TokenTransitionActionType::DestroyFrozenFunds + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/mod.rs similarity index 92% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/mod.rs index 0608aad98cd..ec55cb2835b 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/mod.rs @@ -7,7 +7,7 @@ mod v0; pub use v0::*; // re-export the v0 module items (including TokenIssuanceTransitionActionV0) -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; /// Token freeze transition action #[derive(Debug, Clone, From)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/transformer.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/transformer.rs index 78e9630bc5f..14df0f2fdf4 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/transformer.rs @@ -6,12 +6,12 @@ use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionActionV0, TokenUnfreezeTransitionAction}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionActionV0, TokenUnfreezeTransitionAction}; use dpp::state_transition::batch_transition::token_unfreeze_transition::TokenUnfreezeTransition; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::BatchedTransitionAction; /// Implement methods to transform a `TokenUnfreezeTransition` into a `TokenUnfreezeTransitionAction`. impl TokenUnfreezeTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/v0/mod.rs similarity index 93% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/v0/mod.rs index 88d42f799ba..9dab3dfe50c 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/v0/mod.rs @@ -3,7 +3,7 @@ mod transformer; use std::sync::Arc; use dpp::identifier::Identifier; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; /// Token issuance transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/v0/transformer.rs similarity index 95% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs rename to packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/v0/transformer.rs index f3842553426..b9c2dd5ca82 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_unfreeze_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_unfreeze_transition_action/v0/transformer.rs @@ -5,14 +5,15 @@ use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_unfreeze_transition::v0::TokenUnfreezeTransitionV0; use dpp::ProtocolError; use crate::drive::contract::DataContractFetchInfo; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::v0::TokenUnfreezeTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::v0::TokenUnfreezeTransitionActionV0; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; -use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, TokenTransitionAction}; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; impl TokenUnfreezeTransitionActionV0 { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs b/packages/rs-drive/src/state_transition_action/batch/mod.rs similarity index 94% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/mod.rs index 6ac929de511..5aad18441e0 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/mod.rs @@ -1,5 +1,5 @@ -use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; -use crate::state_transition_action::document::documents_batch::v0::DocumentsBatchTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::v0::BatchTransitionActionV0; use derive_more::From; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; @@ -8,10 +8,10 @@ use dpp::identity::SecurityLevel; use dpp::platform_value::Identifier; use dpp::prelude::UserFeeIncrease; use dpp::ProtocolError; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -/// document transition -pub mod document_transition; +/// batched transition +pub mod batched_transition; /// v0 pub mod v0; @@ -19,7 +19,7 @@ pub mod v0; #[derive(Debug, Clone, From)] pub enum BatchTransitionAction { /// v0 - V0(DocumentsBatchTransitionActionV0), + V0(BatchTransitionActionV0), } impl BatchTransitionAction { diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/v0/mod.rs similarity index 81% rename from packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs rename to packages/rs-drive/src/state_transition_action/batch/v0/mod.rs index d92358ad459..380fba6af73 100644 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/v0/mod.rs @@ -1,14 +1,15 @@ use dpp::fee::Credits; -use crate::state_transition_action::document::documents_batch::document_transition::{BatchedTransitionAction, DocumentTransitionAction}; +use crate::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::identifier::Identifier; use dpp::prelude::UserFeeIncrease; use dpp::ProtocolError; -use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; /// action v0 #[derive(Default, Debug, Clone)] -pub struct DocumentsBatchTransitionActionV0 { +pub struct BatchTransitionActionV0 { /// The owner making the transitions pub owner_id: Identifier, /// The inner transitions @@ -17,8 +18,10 @@ pub struct DocumentsBatchTransitionActionV0 { pub user_fee_increase: UserFeeIncrease, } -impl DocumentsBatchTransitionActionV0 { - pub(super) fn all_used_balances(&self) -> Result, ProtocolError> { +impl BatchTransitionActionV0 { + pub(in crate::state_transition_action) fn all_used_balances( + &self, + ) -> Result, ProtocolError> { Ok(match (self.all_purchases_amount()?, self.all_conflicting_index_collateral_voting_funds()?) { (Some(all_purchases_amount), Some(all_conflicting_index_collateral_voting_funds)) => Some(all_purchases_amount.checked_add(all_conflicting_index_collateral_voting_funds).ok_or(ProtocolError::Overflow("overflow between all_purchases_amount and all_conflicting_index_collateral_voting_funds"))?), (Some(all_purchases_amount), None) => Some(all_purchases_amount), @@ -26,7 +29,9 @@ impl DocumentsBatchTransitionActionV0 { (None, None) => None, }) } - pub(super) fn all_purchases_amount(&self) -> Result, ProtocolError> { + pub(in crate::state_transition_action) fn all_purchases_amount( + &self, + ) -> Result, ProtocolError> { let (total, any_purchases): (Option, bool) = self .transitions .iter() @@ -50,7 +55,7 @@ impl DocumentsBatchTransitionActionV0 { } } - pub(super) fn all_conflicting_index_collateral_voting_funds( + pub(in crate::state_transition_action) fn all_conflicting_index_collateral_voting_funds( &self, ) -> Result, ProtocolError> { let (total, any_voting_funds): (Option, bool) = self diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs deleted file mode 100644 index f15ca23d50c..00000000000 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/mod.rs +++ /dev/null @@ -1,161 +0,0 @@ -/// document_base_transition_action -pub mod document_base_transition_action; -/// document_create_transition_action -pub mod document_create_transition_action; -/// document_delete_transition_action -pub mod document_delete_transition_action; -/// document_purchase_transition_action -pub mod document_purchase_transition_action; -/// document_replace_transition_action -pub mod document_replace_transition_action; -/// document_transfer_transition_action -pub mod document_transfer_transition_action; -mod document_transition_action_type; -/// document_update_price_transition_action -pub mod document_update_price_transition_action; -/// token_base_transition_action -pub mod token_base_transition_action; -/// token_burn_transition_action -pub mod token_burn_transition_action; -/// token_freeze_transition_action -pub mod token_freeze_transition_action; -/// token_issuance_transition_action -pub mod token_mint_transition_action; -/// token_transfer_transition_action -pub mod token_transfer_transition_action; -/// token_unfreeze_transition_action -pub mod token_unfreeze_transition_action; - -pub use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionType; - -use derive_more::From; -use dpp::identifier::Identifier; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; -use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::{BumpIdentityDataContractNonceAction, BumpIdentityDataContractNonceActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; - -/// version -pub const DOCUMENT_TRANSITION_ACTION_VERSION: u32 = 0; - -/// action -#[derive(Debug, Clone, From)] -pub enum DocumentTransitionAction { - /// create - CreateAction(DocumentCreateTransitionAction), - /// replace - ReplaceAction(DocumentReplaceTransitionAction), - /// delete - DeleteAction(DocumentDeleteTransitionAction), - /// transfer - TransferAction(DocumentTransferTransitionAction), - /// purchase - PurchaseAction(DocumentPurchaseTransitionAction), - /// update price - UpdatePriceAction(DocumentUpdatePriceTransitionAction), -} - -impl DocumentTransitionAction { - /// base - pub fn base(&self) -> &DocumentBaseTransitionAction { - match self { - DocumentTransitionAction::CreateAction(d) => d.base(), - DocumentTransitionAction::DeleteAction(d) => d.base(), - DocumentTransitionAction::ReplaceAction(d) => d.base(), - DocumentTransitionAction::TransferAction(d) => d.base(), - DocumentTransitionAction::PurchaseAction(d) => d.base(), - DocumentTransitionAction::UpdatePriceAction(d) => d.base(), - } - } - - /// base owned - pub fn base_owned(self) -> DocumentBaseTransitionAction { - match self { - DocumentTransitionAction::CreateAction(d) => d.base_owned(), - DocumentTransitionAction::DeleteAction(d) => d.base_owned(), - DocumentTransitionAction::ReplaceAction(d) => d.base_owned(), - DocumentTransitionAction::TransferAction(d) => d.base_owned(), - DocumentTransitionAction::PurchaseAction(d) => d.base_owned(), - DocumentTransitionAction::UpdatePriceAction(d) => d.base_owned(), - } - } -} - -/// token action -#[derive(Debug, Clone, From)] -pub enum TokenTransitionAction { - /// burn - BurnAction(TokenBurnTransitionAction), - /// issuance - MintAction(TokenMintTransitionAction), - /// transfer - TransferAction(TokenTransferTransitionAction), - /// freeze - FreezeAction(TokenFreezeTransitionAction), - /// unfreeze - UnfreezeAction(TokenUnfreezeTransitionAction), -} - -impl TokenTransitionAction { - /// Returns a reference to the base token transition action if available - pub fn base(&self) -> &TokenBaseTransitionAction { - match self { - TokenTransitionAction::BurnAction(action) => action.base(), - TokenTransitionAction::MintAction(action) => action.base(), - TokenTransitionAction::TransferAction(action) => action.base(), - TokenTransitionAction::FreezeAction(action) => action.base(), - TokenTransitionAction::UnfreezeAction(action) => action.base(), - } - } - - /// Consumes self and returns the base token transition action if available - pub fn base_owned(self) -> TokenBaseTransitionAction { - match self { - TokenTransitionAction::BurnAction(action) => action.base_owned(), - TokenTransitionAction::MintAction(action) => action.base_owned(), - TokenTransitionAction::TransferAction(action) => action.base_owned(), - TokenTransitionAction::FreezeAction(action) => action.base_owned(), - TokenTransitionAction::UnfreezeAction(action) => action.base_owned(), - } - } -} - -/// token action -#[derive(Debug, Clone, From)] -pub enum BatchedTransitionAction { - /// document - DocumentAction(DocumentTransitionAction), - /// token - TokenAction(TokenTransitionAction), - /// bump identity data contract nonce - BumpIdentityDataContractNonce(BumpIdentityDataContractNonceAction), -} - -impl BatchedTransitionAction { - /// Helper method to get the data contract id - pub fn data_contract_id(&self) -> Identifier { - match self { - BatchedTransitionAction::DocumentAction(document_action) => { - document_action.base().data_contract_id() - } - BatchedTransitionAction::TokenAction(token_action) => { - token_action.base().data_contract_id() - } - BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action) => { - bump_action.data_contract_id() - } - } - } -} diff --git a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transition_action_type.rs b/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transition_action_type.rs deleted file mode 100644 index de03698b223..00000000000 --- a/packages/rs-drive/src/state_transition_action/document/documents_batch/document_transition/token_transition_action_type.rs +++ /dev/null @@ -1,22 +0,0 @@ -use crate::state_transition_action::document::documents_batch::document_transition::DocumentTransitionAction; -use dpp::state_transition::documents_batch_transition::document_transition::action_type::{ - DocumentTransitionActionType, TransitionActionTypeGetter, -}; - -impl TransitionActionTypeGetter for DocumentTransitionAction { - fn action_type(&self) -> DocumentTransitionActionType { - match self { - DocumentTransitionAction::CreateAction(_) => DocumentTransitionActionType::Create, - DocumentTransitionAction::DeleteAction(_) => DocumentTransitionActionType::Delete, - DocumentTransitionAction::ReplaceAction(_) => DocumentTransitionActionType::Replace, - DocumentTransitionAction::TransferAction(_) => DocumentTransitionActionType::Transfer, - DocumentTransitionAction::PurchaseAction(_) => DocumentTransitionActionType::Purchase, - DocumentTransitionAction::UpdatePriceAction(_) => { - DocumentTransitionActionType::UpdatePrice - } - DocumentTransitionAction::BumpIdentityDataContractNonce(_) => { - DocumentTransitionActionType::IgnoreWhileBumpingRevision - } - } - } -} diff --git a/packages/rs-drive/src/state_transition_action/document/mod.rs b/packages/rs-drive/src/state_transition_action/document/mod.rs deleted file mode 100644 index 1af2727c648..00000000000 --- a/packages/rs-drive/src/state_transition_action/document/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -/// documents_batch -pub mod documents_batch; diff --git a/packages/rs-drive/src/state_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/mod.rs index 987d90d87ba..13600ca2cc0 100644 --- a/packages/rs-drive/src/state_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/mod.rs @@ -1,7 +1,5 @@ /// contract pub mod contract; -/// documents -pub mod document; /// identity pub mod identity; @@ -9,10 +7,12 @@ pub mod identity; pub mod system; // TODO: Must crate only but we need to remove of use it first pub mod action_convert_to_operations; +/// documents_batch +pub mod batch; +use crate::state_transition_action::batch::BatchTransitionAction; use crate::state_transition_action::contract::data_contract_create::DataContractCreateTransitionAction; use crate::state_transition_action::contract::data_contract_update::DataContractUpdateTransitionAction; -use crate::state_transition_action::document::documents_batch::BatchTransitionAction; use crate::state_transition_action::identity::identity_create::IdentityCreateTransitionAction; use crate::state_transition_action::identity::identity_credit_transfer::IdentityCreditTransferTransitionAction; use crate::state_transition_action::identity::identity_credit_withdrawal::IdentityCreditWithdrawalTransitionAction; diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs index fad24198bcf..e0691b16e68 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs @@ -8,10 +8,10 @@ use dpp::state_transition::data_contract_update_transition::DataContractUpdateTr use dpp::state_transition::batch_transition::document_base_transition::DocumentBaseTransition; use dpp::state_transition::batch_transition::token_base_transition::TokenBaseTransition; use crate::error::Error; +use crate::state_transition_action::batch::batched_transition::BatchedTransitionAction; use crate::state_transition_action::contract::data_contract_update::DataContractUpdateTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::BatchedTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionAction; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionAction; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::{BumpIdentityDataContractNonceAction, BumpIdentityDataContractNonceActionV0}; impl BumpIdentityDataContractNonceAction { diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs index e377f50fe02..c87a865a70c 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs @@ -6,8 +6,8 @@ use dpp::state_transition::data_contract_update_transition::DataContractUpdateTr use dpp::state_transition::batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use crate::state_transition_action::contract::data_contract_update::v0::DataContractUpdateTransitionActionV0; -use crate::state_transition_action::document::documents_batch::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; -use crate::state_transition_action::document::documents_batch::document_transition::token_base_transition_action::TokenBaseTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionV0; use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceActionV0; impl BumpIdentityDataContractNonceActionV0 { diff --git a/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs b/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs index 309a29cf802..78eb5d5d05b 100644 --- a/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs +++ b/packages/wasm-dpp/src/document/errors/invalid_document_action_error.rs @@ -3,7 +3,7 @@ use dpp::state_transition::batch_transition::batched_transition::document_transi use thiserror::Error; use super::*; -use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::TransitionActionTypeGetter; +use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionTypeGetter; #[wasm_bindgen] #[derive(Error, Debug)] diff --git a/packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/mod.rs b/packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/mod.rs index 7853a915558..d256c15c600 100644 --- a/packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/mod.rs +++ b/packages/wasm-dpp/src/document/state_transition/batch_transition/document_transition/mod.rs @@ -10,7 +10,7 @@ use dpp::platform_value::Value; use dpp::state_transition::batch_transition::batched_transition::document_transition::{ DocumentTransition, DocumentTransitionV0Methods, }; -use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::TransitionActionTypeGetter; +use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionTypeGetter; use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; use dpp::{util::json_value::JsonValueExt, ProtocolError}; use serde::Serialize; From 084f722692a41e935cc6c86e51f6113f7f03b921 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Jan 2025 08:40:50 +0700 Subject: [PATCH 48/61] more work --- .../batch_transition/v1/v0_methods.rs | 24 +-- .../rs-dpp/src/tokens/emergency_action.rs | 2 +- packages/rs-dpp/src/tokens/token_event.rs | 3 + .../v0/mod.rs | 97 ++++++++++++ .../document_create_transition.rs | 0 .../document_delete_transition.rs | 0 .../document_purchase_transition.rs | 0 .../document_replace_transition.rs | 0 .../document_transfer_transition.rs | 0 .../{ => document}/document_transition.rs | 0 .../document_update_price_transition.rs | 0 .../documents_batch_transition.rs | 0 .../batch/document/mod.rs | 8 + .../action_convert_to_operations/batch/mod.rs | 16 +- .../batch/token/mod.rs | 8 + .../{ => token}/token_burn_transition.rs | 0 .../token_destroy_frozen_funds_transition.rs | 107 +++++++++++++ .../token_emergency_action_transition.rs | 105 +++++++++++++ .../{ => token}/token_freeze_transition.rs | 0 .../{ => token}/token_mint_transition.rs | 0 .../{ => token}/token_transfer_transition.rs | 0 .../batch/{ => token}/token_transition.rs | 0 .../{ => token}/token_unfreeze_transition.rs | 0 .../mod.rs | 13 ++ .../v0/mod.rs | 17 +++ .../v0/transformer.rs | 79 ++++++++++ .../src/util/batch/drive_op_batch/token.rs | 21 +++ .../mod.rs | 2 + .../v1.rs | 2 + .../v1/token-history-contract-documents.json | 141 ++++++++++++++++++ 30 files changed, 618 insertions(+), 27 deletions(-) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => document}/document_create_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => document}/document_delete_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => document}/document_purchase_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => document}/document_replace_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => document}/document_transfer_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => document}/document_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => document}/document_update_price_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => document}/documents_batch_transition.rs (100%) create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/mod.rs create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/mod.rs rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => token}/token_burn_transition.rs (100%) create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_destroy_frozen_funds_transition.rs create mode 100644 packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_emergency_action_transition.rs rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => token}/token_freeze_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => token}/token_mint_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => token}/token_transfer_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => token}/token_transition.rs (100%) rename packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/{ => token}/token_unfreeze_transition.rs (100%) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index d50ba9c4e8c..d9d266fe10d 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -693,10 +693,10 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, signer: &S, - platform_version: &PlatformVersion, - batch_feature_version: Option, - delete_feature_version: Option, - base_feature_version: Option, + _platform_version: &PlatformVersion, + _batch_feature_version: Option, + _delete_feature_version: Option, + _base_feature_version: Option, ) -> Result { let mut unfreeze_transition = TokenUnfreezeTransition::V0(TokenUnfreezeTransitionV0 { base: TokenBaseTransition::V0(TokenBaseTransitionV0 { @@ -761,10 +761,10 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, signer: &S, - platform_version: &PlatformVersion, - batch_feature_version: Option, - delete_feature_version: Option, - base_feature_version: Option, + _platform_version: &PlatformVersion, + _batch_feature_version: Option, + _delete_feature_version: Option, + _base_feature_version: Option, ) -> Result { let mut destroy_frozen_funds_transition = TokenDestroyFrozenFundsTransition::V0(TokenDestroyFrozenFundsTransitionV0 { @@ -832,10 +832,10 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { identity_contract_nonce: IdentityNonce, user_fee_increase: UserFeeIncrease, signer: &S, - platform_version: &PlatformVersion, - batch_feature_version: Option, - delete_feature_version: Option, - base_feature_version: Option, + _platform_version: &PlatformVersion, + _batch_feature_version: Option, + _delete_feature_version: Option, + _base_feature_version: Option, ) -> Result { let mut emergency_action_transition = TokenEmergencyActionTransition::V0(TokenEmergencyActionTransitionV0 { diff --git a/packages/rs-dpp/src/tokens/emergency_action.rs b/packages/rs-dpp/src/tokens/emergency_action.rs index 843d0967785..0b96033f8b2 100644 --- a/packages/rs-dpp/src/tokens/emergency_action.rs +++ b/packages/rs-dpp/src/tokens/emergency_action.rs @@ -2,7 +2,7 @@ use bincode::{Decode, Encode}; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, Copy, Default, Encode, Decode, PartialEq)] +#[derive(Debug, Clone, Copy, Default, Encode, Decode, PartialOrd, PartialEq, Eq)] #[cfg_attr( feature = "state-transition-serde-conversion", derive(Serialize, Deserialize), diff --git a/packages/rs-dpp/src/tokens/token_event.rs b/packages/rs-dpp/src/tokens/token_event.rs index b38f7646630..632437aa3d0 100644 --- a/packages/rs-dpp/src/tokens/token_event.rs +++ b/packages/rs-dpp/src/tokens/token_event.rs @@ -13,6 +13,7 @@ pub type TokenEventPersonalEncryptedNote = Option<( DerivationEncryptionKeyIndex, Vec, )>; +use crate::tokens::emergency_action::TokenEmergencyAction; use crate::ProtocolError; pub type RecipientIdentifier = Identifier; @@ -27,6 +28,7 @@ pub enum TokenEvent { Burn(TokenAmount, TokenEventPublicNote), Freeze(FrozenIdentifier, TokenEventPublicNote), Unfreeze(FrozenIdentifier, TokenEventPublicNote), + DestroyFrozenFunds(FrozenIdentifier, TokenAmount, TokenEventPublicNote), Transfer( RecipientIdentifier, TokenEventPublicNote, @@ -34,4 +36,5 @@ pub enum TokenEvent { TokenEventPersonalEncryptedNote, TokenAmount, ), + EmergencyAction(TokenEmergencyAction, TokenEventPublicNote), } diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs index 4e124f93405..1f36ac81c7f 100644 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs @@ -303,6 +303,103 @@ impl Drive { platform_version, )?; } + TokenEvent::DestroyFrozenFunds(frozen_identity_id, amount, public_note) => { + let document_type = contract.document_type_for_name("destroyFrozenFunds")?; + let document_id = Document::generate_document_id_v0( + &contract.id(), + &owner_id, + "destroyFrozenFunds", + owner_nonce.to_be_bytes().as_slice(), + ); + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("frozenIdentityId".to_string(), frozen_identity_id.into()), + ("amount".to_string(), amount.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + let document: Document = DocumentV0 { + id: document_id, + owner_id, + properties, + revision: None, + created_at: Some(block_info.time_ms), + updated_at: None, + transferred_at: None, + created_at_block_height: Some(block_info.height), + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: None, + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + operations = self.add_document_for_contract_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentOwnedInfo((document, None)), + owner_id: Some(owner_id.to_buffer()), + }, + contract: &contract, + document_type, + }, + true, + block_info, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + } + TokenEvent::EmergencyAction(action, public_note) => { + let document_type = contract.document_type_for_name("emergencyAction")?; + let document_id = Document::generate_document_id_v0( + &contract.id(), + &owner_id, + "emergencyAction", + owner_nonce.to_be_bytes().as_slice(), + ); + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("action".to_string(), (action as u8).into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + let document: Document = DocumentV0 { + id: document_id, + owner_id, + properties, + revision: None, + created_at: Some(block_info.time_ms), + updated_at: None, + transferred_at: None, + created_at_block_height: Some(block_info.height), + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: None, + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + operations = self.add_document_for_contract_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentOwnedInfo((document, None)), + owner_id: Some(owner_id.to_buffer()), + }, + contract: &contract, + document_type, + }, + true, + block_info, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + } } Ok(operations) diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_create_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_create_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_create_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_delete_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_delete_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_delete_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_purchase_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_purchase_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_purchase_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_replace_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_replace_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_replace_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_transfer_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transfer_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_transfer_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_update_price_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document_update_price_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/document_update_price_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/documents_batch_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/documents_batch_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/documents_batch_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/mod.rs new file mode 100644 index 00000000000..a6831026e37 --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/document/mod.rs @@ -0,0 +1,8 @@ +mod document_create_transition; +mod document_delete_transition; +mod document_purchase_transition; +mod document_replace_transition; +mod document_transfer_transition; +mod document_transition; +mod document_update_price_transition; +mod documents_batch_transition; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs index e678ce38ffd..99c1c40408a 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/mod.rs @@ -5,20 +5,8 @@ use dpp::platform_value::Identifier; use dpp::version::PlatformVersion; mod batch_transition; -mod document_create_transition; -mod document_delete_transition; -mod document_purchase_transition; -mod document_replace_transition; -mod document_transfer_transition; -mod document_transition; -mod document_update_price_transition; -mod documents_batch_transition; -mod token_burn_transition; -mod token_freeze_transition; -mod token_mint_transition; -mod token_transfer_transition; -mod token_transition; -mod token_unfreeze_transition; +mod document; +mod token; /// A converter that will get High Level Drive Operations from State transitions pub trait DriveHighLevelBatchOperationConverter { diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/mod.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/mod.rs new file mode 100644 index 00000000000..f4f2e61aa8f --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/mod.rs @@ -0,0 +1,8 @@ +mod token_burn_transition; +mod token_destroy_frozen_funds_transition; +mod token_emergency_action_transition; +mod token_freeze_transition; +mod token_mint_transition; +mod token_transfer_transition; +mod token_transition; +mod token_unfreeze_transition; diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_burn_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_burn_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_burn_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_destroy_frozen_funds_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_destroy_frozen_funds_transition.rs new file mode 100644 index 00000000000..52b46800f9c --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_destroy_frozen_funds_transition.rs @@ -0,0 +1,107 @@ +use dpp::block::epoch::Epoch; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::group::action_event::GroupActionEvent; +use dpp::group::group_action::GroupAction; +use dpp::group::group_action::v0::GroupActionV0; +use dpp::group::GroupStateTransitionResolvedInfo; +use dpp::identifier::Identifier; +use dpp::tokens::token_event::TokenEvent; +use platform_version::version::PlatformVersion; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::{TokenDestroyFrozenFundsTransitionAction, TokenDestroyFrozenFundsTransitionActionAccessorsV0}; +use crate::util::batch::{DriveOperation, IdentityOperationType}; +use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; +use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; + +impl DriveHighLevelBatchOperationConverter for TokenDestroyFrozenFundsTransitionAction { + fn into_high_level_batch_drive_operations<'b>( + self, + _epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .state_transitions + .convert_to_high_level_operations + .token_destroy_frozen_funds_transition + { + 0 => { + let data_contract_id = self.base().data_contract_id(); + + let identity_contract_nonce = self.base().identity_contract_nonce(); + + let mut ops = vec![IdentityOperation( + IdentityOperationType::UpdateIdentityContractNonce { + identity_id: owner_id.into_buffer(), + contract_id: data_contract_id.into_buffer(), + nonce: identity_contract_nonce, + }, + )]; + + if let Some(GroupStateTransitionResolvedInfo { + group_contract_position, + action_id, + action_is_proposer, + signer_power, + .. + }) = self.base().store_in_group() + { + let event = + TokenEvent::DestroyFrozenFunds(self.frozen_identity_id(), self.amount(), self.public_note().cloned()); + + let initialize_with_insert_action_info = if *action_is_proposer { + Some(GroupAction::V0(GroupActionV0 { + event: GroupActionEvent::TokenEvent(event), + })) + } else { + None + }; + + ops.push(GroupOperation(GroupOperationType::AddGroupAction { + contract_id: data_contract_id, + group_contract_position: *group_contract_position, + initialize_with_insert_action_info, + action_id: *action_id, + signer_identity_id: owner_id, + signer_power: *signer_power, + })); + } + + if self.base().perform_action() { + ops.push(TokenOperation(TokenOperationType::TokenBurn { + token_id: self.token_id(), + identity_balance_holder_id: self.frozen_identity_id(), + burn_amount: self.amount(), + })); + + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::DestroyFrozenFunds( + self.frozen_identity_id(), + self.amount(), + self.public_note_owned(), + ), + })); + } + } + + Ok(ops) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "TokenDestroyFrozenFundsTransitionAction::into_high_level_document_drive_operations" + .to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_emergency_action_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_emergency_action_transition.rs new file mode 100644 index 00000000000..75b5afa455e --- /dev/null +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_emergency_action_transition.rs @@ -0,0 +1,105 @@ +use dpp::block::epoch::Epoch; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::group::action_event::GroupActionEvent; +use dpp::group::group_action::GroupAction; +use dpp::group::group_action::v0::GroupActionV0; +use dpp::group::GroupStateTransitionResolvedInfo; +use dpp::identifier::Identifier; +use dpp::tokens::token_event::TokenEvent; +use platform_version::version::PlatformVersion; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::state_transition_action::action_convert_to_operations::batch::DriveHighLevelBatchOperationConverter; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::{TokenEmergencyActionTransitionAction, TokenEmergencyActionTransitionActionAccessorsV0}; +use crate::util::batch::{DriveOperation, IdentityOperationType}; +use crate::util::batch::drive_op_batch::{GroupOperationType, TokenOperationType}; +use crate::util::batch::DriveOperation::{GroupOperation, IdentityOperation, TokenOperation}; + +impl DriveHighLevelBatchOperationConverter for TokenEmergencyActionTransitionAction { + fn into_high_level_batch_drive_operations<'b>( + self, + _epoch: &Epoch, + owner_id: Identifier, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version + .drive + .methods + .state_transitions + .convert_to_high_level_operations + .token_emergency_action_transition + { + 0 => { + let data_contract_id = self.base().data_contract_id(); + + let identity_contract_nonce = self.base().identity_contract_nonce(); + + let mut ops = vec![IdentityOperation( + IdentityOperationType::UpdateIdentityContractNonce { + identity_id: owner_id.into_buffer(), + contract_id: data_contract_id.into_buffer(), + nonce: identity_contract_nonce, + }, + )]; + + if let Some(GroupStateTransitionResolvedInfo { + group_contract_position, + action_id, + action_is_proposer, + signer_power, + .. + }) = self.base().store_in_group() + { + let event = + TokenEvent::EmergencyAction(self.emergency_action(), self.public_note().cloned()); + + let initialize_with_insert_action_info = if *action_is_proposer { + Some(GroupAction::V0(GroupActionV0 { + event: GroupActionEvent::TokenEvent(event), + })) + } else { + None + }; + + ops.push(GroupOperation(GroupOperationType::AddGroupAction { + contract_id: data_contract_id, + group_contract_position: *group_contract_position, + initialize_with_insert_action_info, + action_id: *action_id, + signer_identity_id: owner_id, + signer_power: *signer_power, + })); + } + + if self.base().perform_action() { + ops.push(TokenOperation(TokenOperationType::TokenEmergencyAction { + token_id: self.token_id(), + emergency_action: self.emergency_action(), + })); + + let token_configuration = self.base().token_configuration()?; + if token_configuration.keeps_history() { + ops.push(TokenOperation(TokenOperationType::TokenHistory { + token_id: self.token_id(), + owner_id, + nonce: identity_contract_nonce, + event: TokenEvent::EmergencyAction( + self.emergency_action(), + self.public_note_owned(), + ), + })); + } + } + + Ok(ops) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "TokenEmergencyActionTransitionAction::into_high_level_document_drive_operations" + .to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_freeze_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_freeze_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_freeze_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_mint_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_mint_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_mint_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_transfer_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transfer_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_transfer_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_unfreeze_transition.rs similarity index 100% rename from packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token_unfreeze_transition.rs rename to packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_unfreeze_transition.rs diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/mod.rs index 15460920d97..b3074af9481 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/mod.rs @@ -1,4 +1,5 @@ use derive_more::From; +use dpp::balances::credits::TokenAmount; use dpp::identifier::Identifier; /// transformer module for token destroy_frozen_funds transition action @@ -43,6 +44,18 @@ impl TokenDestroyFrozenFundsTransitionActionAccessorsV0 } } + fn amount(&self) -> TokenAmount { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.amount, + } + } + + fn set_amount(&mut self, amount: TokenAmount) { + match self { + TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.amount = amount, + } + } + fn public_note(&self) -> Option<&String> { match self { TokenDestroyFrozenFundsTransitionAction::V0(v0) => v0.public_note.as_ref(), diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/mod.rs index c86d550ac63..9cbe01544e9 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/mod.rs @@ -1,6 +1,7 @@ mod transformer; use std::sync::Arc; +use dpp::balances::credits::TokenAmount; use dpp::identifier::Identifier; use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; @@ -12,6 +13,8 @@ pub struct TokenDestroyFrozenFundsTransitionActionV0 { pub base: TokenBaseTransitionAction, /// The identity to credit the token to pub frozen_identity_id: Identifier, + /// The amount that will be burned + pub amount: TokenAmount, /// A public note pub public_note: Option, } @@ -30,6 +33,12 @@ pub trait TokenDestroyFrozenFundsTransitionActionAccessorsV0 { /// Sets the identity balance holder ID fn set_frozen_identity_id(&mut self, frozen_identity_id: Identifier); + /// Returns the amount of tokens that the identity had and will be burned + fn amount(&self) -> TokenAmount; + + /// Sets the amount of tokens that the identity had and will be burned + fn set_amount(&mut self, amount: TokenAmount); + /// Returns the token position in the contract fn token_position(&self) -> u16 { self.base().token_position() @@ -84,6 +93,14 @@ impl TokenDestroyFrozenFundsTransitionActionAccessorsV0 self.frozen_identity_id = frozen_identity_id; } + fn amount(&self) -> TokenAmount { + self.amount + } + + fn set_amount(&mut self, amount: TokenAmount) { + self.amount = amount; + } + fn public_note(&self) -> Option<&String> { self.public_note.as_ref() } diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/transformer.rs index 311ae6d2a2d..0b0ee7adbec 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_destroy_frozen_funds_transition_action/v0/transformer.rs @@ -1,6 +1,8 @@ use std::sync::Arc; use grovedb::TransactionArg; use dpp::block::block_info::BlockInfo; +use dpp::consensus::state::state_error::StateError; +use dpp::consensus::state::token::IdentityDoesNotHaveEnoughTokenBalanceError; use dpp::identifier::Identifier; use dpp::state_transition::batch_transition::token_destroy_frozen_funds_transition::v0::TokenDestroyFrozenFundsTransitionV0; use dpp::ProtocolError; @@ -9,6 +11,7 @@ use crate::state_transition_action::batch::batched_transition::token_transition: use crate::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::v0::TokenDestroyFrozenFundsTransitionActionV0; use dpp::fee::fee_result::FeeResult; use dpp::prelude::{ConsensusValidationResult, UserFeeIncrease}; +use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; use platform_version::version::PlatformVersion; use crate::drive::Drive; use crate::error::Error; @@ -77,6 +80,15 @@ impl TokenDestroyFrozenFundsTransitionActionV0 { platform_version, )?; + let maybe_token_amount = drive.fetch_identity_token_balance_operations( + base.token_id().to_buffer(), + owner_id.to_buffer(), + !approximate_without_state_for_costs, + transaction, + &mut drive_operations, + platform_version, + )?; + let fee_result = Drive::calculate_fee( None, Some(drive_operations), @@ -86,6 +98,34 @@ impl TokenDestroyFrozenFundsTransitionActionV0 { None, )?; + let Some(token_amount) = maybe_token_amount else { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition( + &base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + vec![StateError::IdentityDoesNotHaveEnoughTokenBalanceError( + IdentityDoesNotHaveEnoughTokenBalanceError::new( + base.token_id(), + frozen_identity_id, + 1, + 0, + "destroy_frozen_funds".to_string(), + ), + ) + .into()], + ), + fee_result, + )); + }; + let base_action = match base_action_validation_result.is_valid() { true => base_action_validation_result.into_data()?, false => { @@ -112,6 +152,7 @@ impl TokenDestroyFrozenFundsTransitionActionV0 { TokenDestroyFrozenFundsTransitionActionV0 { base: base_action, frozen_identity_id, + amount: token_amount, public_note, } .into(), @@ -185,6 +226,15 @@ impl TokenDestroyFrozenFundsTransitionActionV0 { platform_version, )?; + let maybe_token_amount = drive.fetch_identity_token_balance_operations( + base.token_id().to_buffer(), + owner_id.to_buffer(), + !approximate_without_state_for_costs, + transaction, + &mut drive_operations, + platform_version, + )?; + let fee_result = Drive::calculate_fee( None, Some(drive_operations), @@ -194,6 +244,34 @@ impl TokenDestroyFrozenFundsTransitionActionV0 { None, )?; + let Some(token_amount) = maybe_token_amount else { + let bump_action = + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition( + &base, + owner_id, + user_fee_increase, + ); + let batched_action = + BatchedTransitionAction::BumpIdentityDataContractNonce(bump_action); + + return Ok(( + ConsensusValidationResult::new_with_data_and_errors( + batched_action.into(), + vec![StateError::IdentityDoesNotHaveEnoughTokenBalanceError( + IdentityDoesNotHaveEnoughTokenBalanceError::new( + base.token_id(), + *frozen_identity_id, + 1, + 0, + "destroy_frozen_funds".to_string(), + ), + ) + .into()], + ), + fee_result, + )); + }; + let base_action = match base_action_validation_result.is_valid() { true => base_action_validation_result.into_data()?, false => { @@ -221,6 +299,7 @@ impl TokenDestroyFrozenFundsTransitionActionV0 { TokenDestroyFrozenFundsTransitionActionV0 { base: base_action, frozen_identity_id: *frozen_identity_id, + amount: token_amount, public_note: public_note.clone(), } .into(), diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index b0357018ad2..a3c126a1107 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -6,6 +6,7 @@ use dpp::balances::credits::TokenAmount; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; +use dpp::tokens::emergency_action::TokenEmergencyAction; use dpp::tokens::token_event::TokenEvent; use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; @@ -60,6 +61,13 @@ pub enum TokenOperationType { /// The frozen identity id frozen_identity_id: Identifier, }, + /// Perform an emergency action on the token. + TokenEmergencyAction { + /// The token id + token_id: Identifier, + /// The emergency action + emergency_action: TokenEmergencyAction, + }, /// Adds a historical document explaining a token action. TokenHistory { /// The token id @@ -186,6 +194,19 @@ impl DriveLowLevelOperationConverter for TokenOperationType { )?; Ok(batch_operations) } + TokenOperationType::TokenEmergencyAction { + token_id, + emergency_action, + } => { + let batch_operations = drive.token_set_emergency_action_operations( + token_id, + emergency_action, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; + Ok(batch_operations) + } } } } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs index ed9e6a59c27..58fa89dddd7 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/mod.rs @@ -35,6 +35,8 @@ pub struct DriveStateTransitionActionConvertToHighLevelOperationsMethodVersions pub partially_use_asset_lock: FeatureVersion, pub token_freeze_transition: FeatureVersion, pub token_unfreeze_transition: FeatureVersion, + pub token_emergency_action_transition: FeatureVersion, + pub token_destroy_frozen_funds_transition: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs index e89684d70c0..772b8807116 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_state_transition_method_versions/v1.rs @@ -37,5 +37,7 @@ pub const DRIVE_STATE_TRANSITION_METHOD_VERSIONS_V1: DriveStateTransitionMethodV partially_use_asset_lock: 0, token_freeze_transition: 0, token_unfreeze_transition: 0, + token_emergency_action_transition: 0, + token_destroy_frozen_funds_transition: 0, }, }; diff --git a/packages/token-history-contract/schema/v1/token-history-contract-documents.json b/packages/token-history-contract/schema/v1/token-history-contract-documents.json index d4880f2f718..5b4dcf32c8a 100644 --- a/packages/token-history-contract/schema/v1/token-history-contract-documents.json +++ b/packages/token-history-contract/schema/v1/token-history-contract-documents.json @@ -425,5 +425,146 @@ "$createdAtBlockHeight" ], "additionalProperties": false + }, + "destroyFrozenFunds": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byOwnerId", + "properties": [ + { + "tokenId": "asc" + }, + { + "$ownerId": "asc" + }, + { + "$createdAt": "asc" + } + ] + }, + { + "name": "byAmount", + "properties": [ + { + "tokenId": "asc" + }, + { + "amount": "asc" + } + ] + }, + { + "name": "byFrozenIdentityId", + "properties": [ + { + "tokenId": "asc" + }, + { + "frozenIdentityId": "asc" + }, + { + "$createdAt": "asc" + } + ] + } + ], + "properties": { + "tokenId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The token ID", + "position": 0 + }, + "frozenIdentityId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The identity Id of the frozen token account", + "position": 1 + }, + "amount": { + "type": "integer", + "minimum": 0, + "description": "The amount that was frost burned", + "position": 2 + } + }, + "required": [ + "tokenId", + "frozenIdentityId", + "amount", + "$createdAt", + "$createdAtBlockHeight" + ], + "additionalProperties": false + }, + "emergencyAction": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byOwnerId", + "properties": [ + { + "tokenId": "asc" + }, + { + "$ownerId": "asc" + }, + { + "action": "asc" + }, + { + "$createdAt": "asc" + } + ] + }, + { + "name": "byAction", + "properties": [ + { + "tokenId": "asc" + }, + { + "action": "asc" + }, + { + "$createdAt": "asc" + } + ] + } + ], + "properties": { + "tokenId": { + "type": "array", + "byteArray": true, + "minItems": 32, + "maxItems": 32, + "description": "The token ID", + "position": 0 + }, + "action": { + "type": "integer", + "minimum": 0, + "description": "The action we are performing", + "position": 1 + } + }, + "required": [ + "tokenId", + "action", + "$createdAt", + "$createdAtBlockHeight" + ], + "additionalProperties": false } } From 6aaadb6ba30ab87487dd92fdf55068581fdb794c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Jan 2025 09:10:39 +0700 Subject: [PATCH 49/61] more work --- .../token_configuration/accessors/mod.rs | 24 ++++ .../token_configuration/accessors/v0/mod.rs | 8 ++ .../v0/mod.rs | 42 +++++++ .../token_configuration/v0/accessors.rs | 20 ++++ .../token_configuration/v0/mod.rs | 22 +++- packages/rs-dpp/src/errors/consensus/codes.rs | 1 + .../src/errors/consensus/state/state_error.rs | 5 +- ...identity_token_account_not_frozen_error.rs | 51 ++++++++ .../src/errors/consensus/state/token/mod.rs | 2 + .../batch/action_validation/mod.rs | 1 + .../token_base_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 2 +- .../structure_v0/mod.rs | 2 +- .../token_burn_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 2 +- .../structure_v0/mod.rs | 2 +- .../mod.rs | 86 ++++++++++++++ .../state_v0/mod.rs | 109 ++++++++++++++++++ .../structure_v0/mod.rs | 27 +++++ .../token_freeze_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 2 +- .../structure_v0/mod.rs | 2 +- .../token_mint_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 2 +- .../token_transfer_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../token_unfreeze_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 32 ++++- .../structure_v0/mod.rs | 2 +- .../batch/advanced_structure/v0/mod.rs | 8 +- .../batch/transformer/v0/mod.rs | 10 +- .../token_transition/mod.rs | 2 +- 34 files changed, 455 insertions(+), 35 deletions(-) create mode 100644 packages/rs-dpp/src/errors/consensus/state/token/identity_token_account_not_frozen_error.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/structure_v0/mod.rs diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs index 4d528fc16d2..12d1f42da9e 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs @@ -109,6 +109,18 @@ impl TokenConfigurationV0Getters for TokenConfiguration { } } + fn destroy_frozen_funds_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.destroy_frozen_funds_rules(), + } + } + + fn emergency_action_rules(&self) -> &ChangeControlRules { + match self { + TokenConfiguration::V0(v0) => v0.emergency_action_rules(), + } + } + /// Returns the main control group. fn main_control_group(&self) -> Option { match self { @@ -196,6 +208,18 @@ impl TokenConfigurationV0Setters for TokenConfiguration { } } + fn set_destroy_frozen_funds_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_destroy_frozen_funds_rules(rules), + } + } + + fn set_emergency_action_rules(&mut self, rules: ChangeControlRules) { + match self { + TokenConfiguration::V0(v0) => v0.set_emergency_action_rules(rules), + } + } + /// Sets the main control group. fn set_main_control_group(&mut self, group: Option) { match self { diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs index dfd34414d67..0d47db8e620 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -44,6 +44,10 @@ pub trait TokenConfigurationV0Getters { /// Returns the unfreeze rules. fn unfreeze_rules(&self) -> &ChangeControlRules; + /// Returns the destroy frozen funds rules. + fn destroy_frozen_funds_rules(&self) -> &ChangeControlRules; + /// Returns the emergency action rules. + fn emergency_action_rules(&self) -> &ChangeControlRules; /// Returns the main control group. fn main_control_group(&self) -> Option; @@ -83,6 +87,10 @@ pub trait TokenConfigurationV0Setters { /// Sets the unfreeze rules. fn set_unfreeze_rules(&mut self, rules: ChangeControlRules); + /// Sets the `destroy frozen funds` rules. + fn set_destroy_frozen_funds_rules(&mut self, rules: ChangeControlRules); + /// Sets the emergency action rules. + fn set_emergency_action_rules(&mut self, rules: ChangeControlRules); /// Sets the main control group. fn set_main_control_group(&mut self, group: Option); diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs index 68eb8c54a9c..a11f775a572 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/methods/validate_token_configuration_update/v0/mod.rs @@ -203,6 +203,48 @@ impl TokenConfiguration { } } + // Check changes to destroy_frozen_funds_rules + if old.destroy_frozen_funds_rules != new.destroy_frozen_funds_rules { + if !old.destroy_frozen_funds_rules.can_change_to( + &new.destroy_frozen_funds_rules, + contract_owner_id, + main_group, + groups, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "destroyFrozenFundsRules".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + + // Check changes to emergency_action_rules + if old.emergency_action_rules != new.emergency_action_rules { + if !old.emergency_action_rules.can_change_to( + &new.emergency_action_rules, + contract_owner_id, + main_group, + groups, + action_taker, + ) { + return SimpleConsensusValidationResult::new_with_error( + DataContractTokenConfigurationUpdateError::new( + "update".to_string(), + "emergencyActionRules".to_string(), + self.clone(), + new_config.clone(), + ) + .into(), + ); + } + } + // Check changes to main_control_group if old.main_control_group != new.main_control_group { if !old diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs index 55eda9646e4..11e0b9ef943 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs @@ -81,6 +81,16 @@ impl TokenConfigurationV0Getters for TokenConfigurationV0 { &self.unfreeze_rules } + /// Returns the `destroy frozen funds` rules. + fn destroy_frozen_funds_rules(&self) -> &ChangeControlRules { + &self.destroy_frozen_funds_rules + } + + /// Returns the emergency action rules. + fn emergency_action_rules(&self) -> &ChangeControlRules { + &self.emergency_action_rules + } + /// Returns the main control group. fn main_control_group(&self) -> Option { self.main_control_group @@ -144,6 +154,16 @@ impl TokenConfigurationV0Setters for TokenConfigurationV0 { self.unfreeze_rules = rules; } + /// Sets the destroy frozen funds rules. + fn set_destroy_frozen_funds_rules(&mut self, rules: ChangeControlRules) { + self.destroy_frozen_funds_rules = rules; + } + + /// Sets the emergency action rules. + fn set_emergency_action_rules(&mut self, rules: ChangeControlRules) { + self.emergency_action_rules = rules; + } + /// Sets the main control group. fn set_main_control_group(&mut self, group: Option) { self.main_control_group = group; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 773f42291c0..8e1851018de 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -64,6 +64,10 @@ pub struct TokenConfigurationV0 { pub freeze_rules: ChangeControlRules, #[serde(default = "default_change_control_rules")] pub unfreeze_rules: ChangeControlRules, + #[serde(default = "default_change_control_rules")] + pub destroy_frozen_funds_rules: ChangeControlRules, + #[serde(default = "default_change_control_rules")] + pub emergency_action_rules: ChangeControlRules, #[serde(default)] pub main_control_group: Option, #[serde(default)] @@ -102,7 +106,7 @@ impl fmt::Display for TokenConfigurationV0 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "TokenConfigurationV0 {{\n conventions: {:?},\n base_supply: {},\n max_supply: {:?},\n max_supply_change_rules: {:?},\n new_tokens_destination_identity: {:?},\n new_tokens_destination_identity_rules: {:?},\n minting_allow_choosing_destination: {},\n minting_allow_choosing_destination_rules: {:?},\n manual_minting_rules: {:?},\n manual_burning_rules: {:?},\n freeze_rules: {:?},\n unfreeze_rules: {:?},\n main_control_group: {:?},\n main_control_group_can_be_modified: {:?}\n}}", + "TokenConfigurationV0 {{\n conventions: {:?},\n base_supply: {},\n max_supply: {:?},\n max_supply_change_rules: {:?},\n new_tokens_destination_identity: {:?},\n new_tokens_destination_identity_rules: {:?},\n minting_allow_choosing_destination: {},\n minting_allow_choosing_destination_rules: {:?},\n manual_minting_rules: {:?},\n manual_burning_rules: {:?},\n freeze_rules: {:?},\n unfreeze_rules: {:?},\n destroy_frozen_funds_rules: {:?},\n emergency_action_rules: {:?},\n main_control_group: {:?},\n main_control_group_can_be_modified: {:?}\n}}", self.conventions, self.base_supply, self.max_supply, @@ -115,6 +119,8 @@ impl fmt::Display for TokenConfigurationV0 { self.manual_burning_rules, self.freeze_rules, self.unfreeze_rules, + self.destroy_frozen_funds_rules, + self.emergency_action_rules, self.main_control_group, self.main_control_group_can_be_modified ) @@ -182,6 +188,20 @@ impl TokenConfigurationV0 { changing_authorized_action_takers_to_contract_owner_allowed: false, } .into(), + destroy_frozen_funds_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + } + .into(), + emergency_action_rules: ChangeControlRulesV0 { + authorized_to_make_change: AuthorizedActionTakers::NoOne, + authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, + changing_authorized_action_takers_to_no_one_allowed: false, + changing_authorized_action_takers_to_contract_owner_allowed: false, + } + .into(), main_control_group: None, main_control_group_can_be_modified: AuthorizedActionTakers::NoOne, } diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index cf7571cfbf5..56f38cfaa2b 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -237,6 +237,7 @@ impl ErrorWithCode for StateError { Self::IdentityDoesNotHaveEnoughTokenBalanceError(_) => 40150, Self::UnauthorizedTokenActionError(_) => 40151, Self::IdentityTokenAccountFrozenError(_) => 40152, + Self::IdentityTokenAccountNotFrozenError(_) => 40153, // Identity Errors: 40200-40299 Self::IdentityAlreadyExistsError(_) => 40200, diff --git a/packages/rs-dpp/src/errors/consensus/state/state_error.rs b/packages/rs-dpp/src/errors/consensus/state/state_error.rs index 9ab79f5e844..9dc0a2938b1 100644 --- a/packages/rs-dpp/src/errors/consensus/state/state_error.rs +++ b/packages/rs-dpp/src/errors/consensus/state/state_error.rs @@ -41,7 +41,7 @@ use crate::consensus::state::identity::missing_transfer_key_error::MissingTransf use crate::consensus::state::identity::no_transfer_key_for_core_withdrawal_available_error::NoTransferKeyForCoreWithdrawalAvailableError; use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_insufficient_error::PrefundedSpecializedBalanceInsufficientError; use crate::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_not_found_error::PrefundedSpecializedBalanceNotFoundError; -use crate::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountFrozenError, UnauthorizedTokenActionError}; +use crate::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountFrozenError, IdentityTokenAccountNotFrozenError, UnauthorizedTokenActionError}; use crate::consensus::state::voting::masternode_incorrect_voter_identity_id_error::MasternodeIncorrectVoterIdentityIdError; use crate::consensus::state::voting::masternode_incorrect_voting_address_error::MasternodeIncorrectVotingAddressError; use crate::consensus::state::voting::masternode_not_found_error::MasternodeNotFoundError; @@ -212,6 +212,9 @@ pub enum StateError { #[error(transparent)] IdentityTokenAccountFrozenError(IdentityTokenAccountFrozenError), + #[error(transparent)] + IdentityTokenAccountNotFrozenError(IdentityTokenAccountNotFrozenError), + #[error(transparent)] IdentityNotMemberOfGroupError(IdentityNotMemberOfGroupError), diff --git a/packages/rs-dpp/src/errors/consensus/state/token/identity_token_account_not_frozen_error.rs b/packages/rs-dpp/src/errors/consensus/state/token/identity_token_account_not_frozen_error.rs new file mode 100644 index 00000000000..479fcc1a500 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/token/identity_token_account_not_frozen_error.rs @@ -0,0 +1,51 @@ +use crate::consensus::state::state_error::StateError; +use crate::consensus::ConsensusError; +use crate::ProtocolError; +use bincode::{Decode, Encode}; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_value::Identifier; +use thiserror::Error; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error( + "Identity {} account is not frozen for token {}. Action attempted: {}", + identity_id, + token_id, + action +)] +#[platform_serialize(unversioned)] +pub struct IdentityTokenAccountNotFrozenError { + token_id: Identifier, + identity_id: Identifier, + action: String, +} + +impl IdentityTokenAccountNotFrozenError { + pub fn new(token_id: Identifier, identity_id: Identifier, action: String) -> Self { + Self { + token_id, + identity_id, + action, + } + } + + pub fn token_id(&self) -> &Identifier { + &self.token_id + } + + pub fn identity_id(&self) -> &Identifier { + &self.identity_id + } + + pub fn action(&self) -> &str { + &self.action + } +} + +impl From for ConsensusError { + fn from(err: IdentityTokenAccountNotFrozenError) -> Self { + Self::StateError(StateError::IdentityTokenAccountNotFrozenError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/state/token/mod.rs b/packages/rs-dpp/src/errors/consensus/state/token/mod.rs index 9d084d981b1..6838bc261c7 100644 --- a/packages/rs-dpp/src/errors/consensus/state/token/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/state/token/mod.rs @@ -1,7 +1,9 @@ mod identity_does_not_have_enough_token_balance_error; mod identity_token_account_frozen_error; +mod identity_token_account_not_frozen_error; mod unauthorized_token_action_error; pub use identity_does_not_have_enough_token_balance_error::*; pub use identity_token_account_frozen_error::*; +pub use identity_token_account_not_frozen_error::*; pub use unauthorized_token_action_error::*; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs index 034c8d387b3..e0ff14413ee 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs @@ -6,6 +6,7 @@ pub(crate) mod document_transfer_transition_action; pub(crate) mod document_update_price_transition_action; pub(crate) mod token_base_transition_action; pub(crate) mod token_burn_transition_action; +pub(crate) mod token_destroy_frozen_funds_transition_action; pub(crate) mod token_freeze_transition_action; pub(crate) mod token_mint_transition_action; pub(crate) mod token_transfer_transition_action; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs index fb68b51540b..ed77bb370d2 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_base_transition_action::TokenBaseTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs index ace0696ec56..d072a906d3d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/state_v0/mod.rs @@ -4,7 +4,7 @@ use dpp::consensus::state::group::GroupActionAlreadySignedByIdentityError; use dpp::consensus::state::state_error::StateError; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs index adcfec8364b..034d208c513 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_base_transition_action/structure_v0/mod.rs @@ -4,7 +4,7 @@ use dpp::consensus::basic::token::InvalidTokenPositionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs index d5ed6209814..0ed8bdfb4d0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_burn_transition_action::TokenBurnTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::TokenBurnTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs index d8b8f00e3e7..85ad0983ef6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/state_v0/mod.rs @@ -8,7 +8,7 @@ use dpp::data_contract::associated_token::token_configuration::accessors::v0::To use dpp::multi_identity_events::ActionTaker; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs index 04a1953093a..3529a60558c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_burn_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/mod.rs new file mode 100644 index 00000000000..9b8428f51db --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/mod.rs @@ -0,0 +1,86 @@ +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::TokenDestroyFrozenFundsTransitionAction; +use dpp::version::PlatformVersion; +use drive::grovedb::TransactionArg; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::token_destroy_frozen_funds_transition_action::state_v0::TokenDestroyFrozenFundsTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_destroy_frozen_funds_transition_action::structure_v0::TokenDestroyFrozenFundsTransitionActionStructureValidationV0; +use crate::platform_types::platform::PlatformStateRef; + +mod state_v0; +mod structure_v0; + +pub trait TokenDestroyFrozenFundsTransitionActionValidation { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result; + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} + +impl TokenDestroyFrozenFundsTransitionActionValidation for TokenDestroyFrozenFundsTransitionAction { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_destroy_frozen_funds_transition_structure_validation + { + 0 => self.validate_structure_v0(platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenDestroyFrozenFundsTransitionAction::validate_structure".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_destroy_frozen_funds_transition_state_validation + { + 0 => self.validate_state_v0( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenDestroyFrozenFundsTransitionAction::validate_state".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..99bf2b350c5 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/state_v0/mod.rs @@ -0,0 +1,109 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::state_error::StateError; +use dpp::consensus::state::token::{IdentityTokenAccountNotFrozenError, UnauthorizedTokenActionError}; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::multi_identity_events::ActionTaker; +use dpp::prelude::Identifier; +use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::{TokenDestroyFrozenFundsTransitionAction, TokenDestroyFrozenFundsTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use drive::query::TransactionArg; +use crate::error::Error; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenDestroyFrozenFundsTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenDestroyFrozenFundsTransitionActionStateValidationV0 + for TokenDestroyFrozenFundsTransitionAction +{ + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let validation_result = self.base().validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + + // We need to validate that we are frozen + + let (info, fee_result) = platform.drive.fetch_identity_token_info_with_costs( + self.token_id().to_buffer(), + self.frozen_identity_id().to_buffer(), + block_info, + true, + transaction, + platform_version, + )?; + execution_context.add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + if info.is_none() || !info.unwrap().frozen() { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::IdentityTokenAccountNotFrozenError( + IdentityTokenAccountNotFrozenError::new( + self.token_id(), + self.frozen_identity_id(), + "destroy_frozen_funds".to_string(), + ), + )), + )); + } + + // Let's first check to see if we are authorized to perform this action + let contract = &self.data_contract_fetch_info_ref().contract; + let token_configuration = contract.expected_token_configuration(self.token_position())?; + let rules = token_configuration.destroy_frozen_funds_rules(); + let main_control_group = token_configuration + .main_control_group() + .map(|position| contract.expected_group(position)) + .transpose()?; + + if !rules.can_make_change( + &contract.owner_id(), + main_control_group, + contract.groups(), + &ActionTaker::SingleIdentity(owner_id), + ) { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + self.token_id(), + owner_id, + "destroy_frozen_funds".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )); + } + + Ok(SimpleConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/structure_v0/mod.rs new file mode 100644 index 00000000000..2f0c22d4179 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_destroy_frozen_funds_transition_action/structure_v0/mod.rs @@ -0,0 +1,27 @@ +use dpp::validation::{SimpleConsensusValidationResult}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::{TokenDestroyFrozenFundsTransitionAction, TokenDestroyFrozenFundsTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use crate::error::Error; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; + +pub(super) trait TokenDestroyFrozenFundsTransitionActionStructureValidationV0 { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenDestroyFrozenFundsTransitionActionStructureValidationV0 + for TokenDestroyFrozenFundsTransitionAction +{ + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result { + let validation_result = self.base().validate_structure(platform_version)?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + + Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs index ca1f1cde835..47777b8d732 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::TokenFreezeTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::TokenFreezeTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs index 49a004f9297..507f02c281f 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/state_v0/mod.rs @@ -8,7 +8,7 @@ use dpp::data_contract::associated_token::token_configuration::accessors::v0::To use dpp::multi_identity_events::ActionTaker; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs index 774dbe37f8d..8b754e60e70 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_freeze_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs index 8a3a5b14ffb..f8cd83b7a6c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::TokenMintTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::TokenMintTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs index 263d0c588a5..7653477deb7 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/state_v0/mod.rs @@ -10,10 +10,10 @@ use dpp::data_contract::change_control_rules::authorized_action_takers::Authoriz use dpp::multi_identity_events::ActionTaker; use dpp::prelude::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::{RetrieveIdentityInfo, ValidationOperation}; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs index 618dfe80328..33648a7e26e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_mint_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::{TokenMintTransitionAction, TokenMintTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs index aabaff973dd..2d9754412f6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs index 41058ffa369..04336501c97 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/state_v0/mod.rs @@ -5,10 +5,10 @@ use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, I use dpp::prelude::Identifier; use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::{TokenTransferTransitionAction}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::{TokenTransferTransitionAction}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index eb4e9ef98ac..b575605cfee 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -1,8 +1,8 @@ use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs index 76145d247f6..0cb5f563fc5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs index c2f40fbd650..e8ba23d7f4a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/state_v0/mod.rs @@ -1,18 +1,20 @@ use dpp::block::block_info::BlockInfo; use dpp::consensus::ConsensusError; use dpp::consensus::state::state_error::StateError; -use dpp::consensus::state::token::UnauthorizedTokenActionError; +use dpp::consensus::state::token::{IdentityTokenAccountNotFrozenError, UnauthorizedTokenActionError}; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::multi_identity_events::ActionTaker; use dpp::prelude::Identifier; +use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; -use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::types::execution_operation::ValidationOperation; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; use crate::platform_types::platform::PlatformStateRef; @@ -49,6 +51,30 @@ impl TokenUnfreezeTransitionActionStateValidationV0 for TokenUnfreezeTransitionA return Ok(validation_result); } + // We need to validate that we are frozen + + let (info, fee_result) = platform.drive.fetch_identity_token_info_with_costs( + self.token_id().to_buffer(), + self.frozen_identity_id().to_buffer(), + block_info, + true, + transaction, + platform_version, + )?; + execution_context.add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + if info.is_none() || !info.unwrap().frozen() { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::IdentityTokenAccountNotFrozenError( + IdentityTokenAccountNotFrozenError::new( + self.token_id(), + self.frozen_identity_id(), + "destroy_frozen_funds".to_string(), + ), + )), + )); + } + // Let's first check to see if we are authorized to perform this action let contract = &self.data_contract_fetch_info_ref().contract; let token_configuration = contract.expected_token_configuration(self.token_position())?; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs index 66289fc23bc..ba729c1f5e6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_unfreeze_transition_action/structure_v0/mod.rs @@ -1,5 +1,5 @@ use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs index 267fb12d381..b8d77035b36 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs @@ -28,10 +28,10 @@ use drive::state_transition_action::document::batch::batched_transition::documen use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionActionAccessorsV0; use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::TokenFreezeTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::TokenFreezeTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionActionAccessorsV0; use drive::state_transition_action::StateTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::execution::ExecutionError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index a2594a1150c..9c98dd44c3b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -53,11 +53,11 @@ use drive::drive::Drive; use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_burn_transition_action::TokenBurnTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_freeze_transition_action::TokenFreezeTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_mint_transition_action::TokenMintTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_transfer_transition_action::TokenTransferTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::TokenBurnTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::TokenFreezeTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::TokenMintTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs index 79defafe132..4a457e10437 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs @@ -19,7 +19,7 @@ pub mod token_destroy_frozen_funds_transition_action; pub mod token_emergency_action_transition_action; use derive_more::From; -use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; From 779114dd749b28bbb54e8c747e18bd966934feb4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 7 Jan 2025 10:55:41 +0700 Subject: [PATCH 50/61] more token work --- .../token_configuration/accessors/mod.rs | 7 ++ .../token_configuration/accessors/v0/mod.rs | 1 + .../token_configuration/v0/accessors.rs | 5 + .../token_configuration/v0/mod.rs | 13 ++- .../rs-dpp/src/tokens/emergency_action.rs | 15 +++ packages/rs-dpp/src/tokens/mod.rs | 1 + packages/rs-dpp/src/tokens/status/methods.rs | 16 +++ packages/rs-dpp/src/tokens/status/mod.rs | 44 ++++++++ packages/rs-dpp/src/tokens/status/v0/mod.rs | 26 +++++ .../document_create_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../state_v1/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../document_delete_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 6 +- .../structure_v0/mod.rs | 6 +- .../mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../document_replace_transition_action/mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../mod.rs | 2 +- .../state_v0/mod.rs | 4 +- .../structure_v0/mod.rs | 4 +- .../batch/action_validation/mod.rs | 1 + .../mod.rs | 86 +++++++++++++++ .../state_v0/mod.rs | 83 +++++++++++++++ .../structure_v0/mod.rs | 27 +++++ .../structure_v0/mod.rs | 2 +- .../batch/advanced_structure/v0/mod.rs | 50 +++++++-- .../bindings/data_trigger_binding/mod.rs | 2 +- .../bindings/data_trigger_binding/v0/mod.rs | 2 +- .../data_triggers/bindings/list/v0/mod.rs | 2 +- .../batch/data_triggers/executor.rs | 4 +- .../batch/data_triggers/mod.rs | 2 +- .../data_triggers/triggers/dashpay/mod.rs | 2 +- .../data_triggers/triggers/dashpay/v0/mod.rs | 10 +- .../batch/data_triggers/triggers/dpns/mod.rs | 2 +- .../data_triggers/triggers/dpns/v0/mod.rs | 10 +- .../triggers/feature_flags/mod.rs | 2 +- .../triggers/feature_flags/v0/mod.rs | 6 +- .../data_triggers/triggers/reject/mod.rs | 2 +- .../data_triggers/triggers/reject/v0/mod.rs | 4 +- .../data_triggers/triggers/withdrawals/mod.rs | 2 +- .../triggers/withdrawals/v0/mod.rs | 12 +-- .../batch/state/v0/data_triggers.rs | 2 +- .../state_transitions/batch/state/v0/mod.rs | 28 ++++- .../batch/transformer/v0/mod.rs | 43 ++++++-- .../verify_state_transitions.rs | 14 +-- .../contract/update/update_contract/v1/mod.rs | 4 +- .../src/drive/tokens/apply_status/mod.rs | 93 ++++++++++++++++ .../src/drive/tokens/apply_status/v0/mod.rs | 100 ++++++++++++++++++ packages/rs-drive/src/drive/tokens/mod.rs | 2 + .../tokens/system/create_token_trees/mod.rs | 6 ++ .../system/create_token_trees/v0/mod.rs | 46 +++++++- .../token_emergency_action_transition.rs | 4 +- .../src/util/batch/drive_op_batch/token.rs | 21 ++-- .../dpp_versions/dpp_token_versions/mod.rs | 1 + .../dpp_versions/dpp_token_versions/v1.rs | 1 + .../drive_abci_validation_versions/mod.rs | 4 + .../drive_abci_validation_versions/v1.rs | 4 + .../drive_abci_validation_versions/v2.rs | 4 + .../drive_abci_validation_versions/v3.rs | 4 + .../drive_abci_validation_versions/v4.rs | 4 + .../drive_abci_validation_versions/v5.rs | 4 + .../drive_token_method_versions/mod.rs | 1 + .../drive_token_method_versions/v1.rs | 1 + 71 files changed, 788 insertions(+), 112 deletions(-) create mode 100644 packages/rs-dpp/src/tokens/status/methods.rs create mode 100644 packages/rs-dpp/src/tokens/status/mod.rs create mode 100644 packages/rs-dpp/src/tokens/status/v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/state_v0/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/structure_v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/apply_status/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs index 12d1f42da9e..46c82e7995f 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/mod.rs @@ -40,6 +40,13 @@ impl TokenConfigurationV0Getters for TokenConfiguration { } } + /// Returns if we start as paused. + fn start_as_paused(&self) -> bool { + match self { + TokenConfiguration::V0(v0) => v0.start_as_paused(), + } + } + /// Returns the maximum supply. fn max_supply(&self) -> Option { match self { diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs index 0d47db8e620..83fde97a8e3 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/accessors/v0/mod.rs @@ -16,6 +16,7 @@ pub trait TokenConfigurationV0Getters { fn base_supply(&self) -> u64; /// Returns the base supply. fn keeps_history(&self) -> bool; + fn start_as_paused(&self) -> bool; /// Returns the maximum supply. fn max_supply(&self) -> Option; diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs index 11e0b9ef943..d0115ead551 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/accessors.rs @@ -31,6 +31,11 @@ impl TokenConfigurationV0Getters for TokenConfigurationV0 { self.keeps_history } + /// Returns if we start off as paused + fn start_as_paused(&self) -> bool { + self.start_as_paused + } + /// Returns the maximum supply. fn max_supply(&self) -> Option { self.max_supply diff --git a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs index 8e1851018de..4aed4bdc11f 100644 --- a/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/associated_token/token_configuration/v0/mod.rs @@ -44,6 +44,9 @@ pub struct TokenConfigurationV0 { /// Do we keep history, default is true. #[serde(default = "default_keeps_history")] pub keeps_history: bool, + /// Do we start off as paused, meaning that we can not transfer till we unpause. + #[serde(default = "default_starts_as_paused")] + pub start_as_paused: bool, /// Who can change the max supply /// Even if set no one can ever change this under the base supply #[serde(default = "default_change_control_rules")] @@ -84,6 +87,11 @@ fn default_keeps_history() -> bool { true // Default to `true` for keeps_history } +// Default function for `starts_as_paused` +fn default_starts_as_paused() -> bool { + false +} + fn default_change_control_rules() -> ChangeControlRules { ChangeControlRules::V0(ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, @@ -106,10 +114,12 @@ impl fmt::Display for TokenConfigurationV0 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, - "TokenConfigurationV0 {{\n conventions: {:?},\n base_supply: {},\n max_supply: {:?},\n max_supply_change_rules: {:?},\n new_tokens_destination_identity: {:?},\n new_tokens_destination_identity_rules: {:?},\n minting_allow_choosing_destination: {},\n minting_allow_choosing_destination_rules: {:?},\n manual_minting_rules: {:?},\n manual_burning_rules: {:?},\n freeze_rules: {:?},\n unfreeze_rules: {:?},\n destroy_frozen_funds_rules: {:?},\n emergency_action_rules: {:?},\n main_control_group: {:?},\n main_control_group_can_be_modified: {:?}\n}}", + "TokenConfigurationV0 {{\n conventions: {:?},\n base_supply: {},\n max_supply: {:?},\n keeps_history: {},\n start_as_paused: {},\n max_supply_change_rules: {:?},\n new_tokens_destination_identity: {:?},\n new_tokens_destination_identity_rules: {:?},\n minting_allow_choosing_destination: {},\n minting_allow_choosing_destination_rules: {:?},\n manual_minting_rules: {:?},\n manual_burning_rules: {:?},\n freeze_rules: {:?},\n unfreeze_rules: {:?},\n destroy_frozen_funds_rules: {:?},\n emergency_action_rules: {:?},\n main_control_group: {:?},\n main_control_group_can_be_modified: {:?}\n}}", self.conventions, self.base_supply, self.max_supply, + self.keeps_history, + self.start_as_paused, self.max_supply_change_rules, self.new_tokens_destination_identity, self.new_tokens_destination_identity_rules, @@ -137,6 +147,7 @@ impl TokenConfigurationV0 { base_supply: 100000, max_supply: None, keeps_history: true, + start_as_paused: false, max_supply_change_rules: ChangeControlRulesV0 { authorized_to_make_change: AuthorizedActionTakers::NoOne, authorized_to_change_authorized_action_takers: AuthorizedActionTakers::NoOne, diff --git a/packages/rs-dpp/src/tokens/emergency_action.rs b/packages/rs-dpp/src/tokens/emergency_action.rs index 0b96033f8b2..7e18e6f4268 100644 --- a/packages/rs-dpp/src/tokens/emergency_action.rs +++ b/packages/rs-dpp/src/tokens/emergency_action.rs @@ -1,4 +1,7 @@ +use crate::tokens::status::TokenStatus; +use crate::ProtocolError; use bincode::{Decode, Encode}; +use platform_version::version::PlatformVersion; #[cfg(feature = "state-transition-serde-conversion")] use serde::{Deserialize, Serialize}; @@ -13,3 +16,15 @@ pub enum TokenEmergencyAction { Pause = 0, Resume = 1, } + +impl TokenEmergencyAction { + pub fn resulting_status( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match self { + TokenEmergencyAction::Pause => TokenStatus::new(true, platform_version), + TokenEmergencyAction::Resume => TokenStatus::new(false, platform_version), + } + } +} diff --git a/packages/rs-dpp/src/tokens/mod.rs b/packages/rs-dpp/src/tokens/mod.rs index 2f40a411a1f..aa8703acbf3 100644 --- a/packages/rs-dpp/src/tokens/mod.rs +++ b/packages/rs-dpp/src/tokens/mod.rs @@ -5,6 +5,7 @@ pub mod allowed_currency; pub mod emergency_action; pub mod errors; pub mod info; +pub mod status; pub mod token_event; pub fn calculate_token_id(contract_id: &[u8; 32], token_pos: TokenContractPosition) -> [u8; 32] { diff --git a/packages/rs-dpp/src/tokens/status/methods.rs b/packages/rs-dpp/src/tokens/status/methods.rs new file mode 100644 index 00000000000..e912ea562e1 --- /dev/null +++ b/packages/rs-dpp/src/tokens/status/methods.rs @@ -0,0 +1,16 @@ +use crate::tokens::status::v0::TokenStatusV0Accessors; +use crate::tokens::status::TokenStatus; + +impl TokenStatusV0Accessors for TokenStatus { + fn paused(&self) -> bool { + match self { + TokenStatus::V0(status) => status.paused, + } + } + + fn set_paused(&mut self, frozen: bool) { + match self { + TokenStatus::V0(status) => status.set_paused(frozen), + } + } +} diff --git a/packages/rs-dpp/src/tokens/status/mod.rs b/packages/rs-dpp/src/tokens/status/mod.rs new file mode 100644 index 00000000000..f39cc6be09f --- /dev/null +++ b/packages/rs-dpp/src/tokens/status/mod.rs @@ -0,0 +1,44 @@ +use crate::tokens::status::v0::TokenStatusV0; +use crate::ProtocolError; +use bincode::Encode; +use derive_more::From; +use platform_serialization::de::Decode; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use platform_version::version::PlatformVersion; +use platform_versioning::PlatformVersioned; + +mod methods; +pub mod v0; + +#[derive( + Debug, + Clone, + Encode, + Decode, + PlatformDeserialize, + PlatformSerialize, + PlatformVersioned, + From, + PartialEq, +)] +#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version +pub enum TokenStatus { + V0(TokenStatusV0), +} + +impl TokenStatus { + pub fn new(paused: bool, platform_version: &PlatformVersion) -> Result { + match platform_version + .dpp + .token_versions + .identity_token_status_default_structure_version + { + 0 => Ok(TokenStatus::V0(TokenStatusV0 { paused })), + version => Err(ProtocolError::UnknownVersionMismatch { + method: "IdentityTokenStatus::new".to_string(), + known_versions: vec![0], + received: version, + }), + } + } +} diff --git a/packages/rs-dpp/src/tokens/status/v0/mod.rs b/packages/rs-dpp/src/tokens/status/v0/mod.rs new file mode 100644 index 00000000000..a8dd3a0f83a --- /dev/null +++ b/packages/rs-dpp/src/tokens/status/v0/mod.rs @@ -0,0 +1,26 @@ +use bincode::{Decode, Encode}; +use derive_more::From; + +#[derive(Debug, Clone, Encode, Decode, From, PartialEq)] +/// Token status +pub struct TokenStatusV0 { + pub paused: bool, +} + +pub trait TokenStatusV0Accessors { + /// Gets the paused state of the token. + fn paused(&self) -> bool; + + /// Sets the paused state of the token. + fn set_paused(&mut self, paused: bool); +} + +impl TokenStatusV0Accessors for TokenStatusV0 { + fn paused(&self) -> bool { + self.paused + } + + fn set_paused(&mut self, paused: bool) { + self.paused = paused; + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs index 1b08592370c..56c8458ced8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/mod.rs @@ -2,7 +2,7 @@ use dashcore_rpc::dashcore::Network; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs index d5322dfbe47..aa752dc2fd0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v0/mod.rs @@ -10,8 +10,8 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; use drive::error::drive::DriveError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs index 9e5f9d97aa3..14cb413f30e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/state_v1/mod.rs @@ -12,8 +12,8 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::prelude::{ConsensusValidationResult, Identifier}; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use dpp::voting::vote_info_storage::contested_document_vote_poll_stored_info::{ContestedDocumentVotePollStatus, ContestedDocumentVotePollStoredInfoV0Getters}; use drive::error::drive::DriveError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs index a8f67dc96ff..49b71dc0214 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_create_transition_action/structure_v0/mod.rs @@ -9,8 +9,8 @@ use dpp::data_contract::document_type::restricted_creation::CreationRestrictionM use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; use dpp::identifier::Identifier; use dpp::validation::{SimpleConsensusValidationResult}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionAction, DocumentCreateTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs index 3f84e860283..a3b71962042 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/mod.rs @@ -1,7 +1,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs index 17115659cd6..6ccb56aa5b5 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/state_v0/mod.rs @@ -9,11 +9,11 @@ use dpp::document::{Document, DocumentV0Getters}; use dpp::identifier::Identifier; use dpp::prelude::ConsensusValidationResult; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs index e547eb2e946..347e495894b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_delete_transition_action/structure_v0/mod.rs @@ -2,9 +2,9 @@ use dpp::consensus::basic::document::{InvalidDocumentTransitionActionError, Inva use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs index 7e92cfc0254..8396ba05772 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/mod.rs @@ -2,7 +2,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs index 5ce257aa516..c5060437b73 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/state_v0/mod.rs @@ -4,10 +4,10 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs index 2294f56c9e1..5a77bd645bb 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_purchase_transition_action/structure_v0/mod.rs @@ -4,8 +4,8 @@ use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::document::DocumentV0Getters; use dpp::nft::TradeMode; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::{DocumentPurchaseTransitionAction, DocumentPurchaseTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs index 1c1cc64fd3a..6392eb68705 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/mod.rs @@ -2,7 +2,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs index e354b1a4a1b..01359fb61e6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/state_v0/mod.rs @@ -4,10 +4,10 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs index b73ea074862..acb84883460 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_replace_transition_action/structure_v0/mod.rs @@ -3,8 +3,8 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::data_contract::validate_document::DataContractDocumentValidationMethodsV0; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::{DocumentReplaceTransitionAction, DocumentReplaceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs index cf6d24f605e..6a517d71401 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/mod.rs @@ -2,7 +2,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs index 358330e82b7..3a779e13023 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/state_v0/mod.rs @@ -4,10 +4,10 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs index 36d52a193f2..a8beba7bae1 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_transfer_transition_action/structure_v0/mod.rs @@ -2,8 +2,8 @@ use dpp::consensus::basic::document::{InvalidDocumentTransitionActionError, Inva use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::{DocumentTransferTransitionAction, DocumentTransferTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs index ad44b1823b8..b541eb15e1c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/mod.rs @@ -4,7 +4,7 @@ use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; use crate::error::Error; use crate::error::execution::ExecutionError; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs index ba000144254..9dc2abd730c 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/state_v0/mod.rs @@ -4,10 +4,10 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::identifier::Identifier; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs index 5c162c084ea..8635df40dd0 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/document_update_price_transition_action/structure_v0/mod.rs @@ -2,8 +2,8 @@ use dpp::consensus::basic::document::{InvalidDocumentTransitionActionError, Inva use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; use dpp::validation::SimpleConsensusValidationResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::{DocumentUpdatePriceTransitionAction, DocumentUpdatePriceTransitionActionAccessorsV0}; use dpp::version::PlatformVersion; use crate::error::Error; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs index e0ff14413ee..f9872eec435 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/mod.rs @@ -7,6 +7,7 @@ pub(crate) mod document_update_price_transition_action; pub(crate) mod token_base_transition_action; pub(crate) mod token_burn_transition_action; pub(crate) mod token_destroy_frozen_funds_transition_action; +pub(crate) mod token_emergency_action_transition_action; pub(crate) mod token_freeze_transition_action; pub(crate) mod token_mint_transition_action; pub(crate) mod token_transfer_transition_action; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/mod.rs new file mode 100644 index 00000000000..a78f9e9537b --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/mod.rs @@ -0,0 +1,86 @@ +use dpp::block::block_info::BlockInfo; +use dpp::identifier::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::TokenEmergencyActionTransitionAction; +use dpp::version::PlatformVersion; +use drive::grovedb::TransactionArg; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; +use crate::execution::validation::state_transition::batch::action_validation::token_emergency_action_transition_action::state_v0::TokenEmergencyActionTransitionActionStateValidationV0; +use crate::execution::validation::state_transition::batch::action_validation::token_emergency_action_transition_action::structure_v0::TokenEmergencyActionTransitionActionStructureValidationV0; +use crate::platform_types::platform::PlatformStateRef; + +mod state_v0; +mod structure_v0; + +pub trait TokenEmergencyActionTransitionActionValidation { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result; + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} + +impl TokenEmergencyActionTransitionActionValidation for TokenEmergencyActionTransitionAction { + fn validate_structure( + &self, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_emergency_action_transition_structure_validation + { + 0 => self.validate_structure_v0(platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenEmergencyActionTransitionAction::validate_structure".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + fn validate_state( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .batch_state_transition + .token_emergency_action_transition_state_validation + { + 0 => self.validate_state_v0( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + ), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "TokenEmergencyActionTransitionAction::validate_state".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/state_v0/mod.rs new file mode 100644 index 00000000000..050a451afb4 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/state_v0/mod.rs @@ -0,0 +1,83 @@ +use dpp::block::block_info::BlockInfo; +use dpp::consensus::ConsensusError; +use dpp::consensus::state::state_error::StateError; +use dpp::consensus::state::token::UnauthorizedTokenActionError; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::multi_identity_events::ActionTaker; +use dpp::prelude::Identifier; +use dpp::validation::SimpleConsensusValidationResult; +use drive::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::{TokenEmergencyActionTransitionAction, TokenEmergencyActionTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use drive::query::TransactionArg; +use crate::error::Error; +use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; +use crate::platform_types::platform::PlatformStateRef; + +pub(super) trait TokenEmergencyActionTransitionActionStateValidationV0 { + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenEmergencyActionTransitionActionStateValidationV0 + for TokenEmergencyActionTransitionAction +{ + fn validate_state_v0( + &self, + platform: &PlatformStateRef, + owner_id: Identifier, + block_info: &BlockInfo, + execution_context: &mut StateTransitionExecutionContext, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let validation_result = self.base().validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + + // Let's first check to see if we are authorized to perform this action + let contract = &self.data_contract_fetch_info_ref().contract; + let token_configuration = contract.expected_token_configuration(self.token_position())?; + let rules = token_configuration.emergency_action_rules(); + let main_control_group = token_configuration + .main_control_group() + .map(|position| contract.expected_group(position)) + .transpose()?; + + if !rules.can_make_change( + &contract.owner_id(), + main_control_group, + contract.groups(), + &ActionTaker::SingleIdentity(owner_id), + ) { + return Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::StateError(StateError::UnauthorizedTokenActionError( + UnauthorizedTokenActionError::new( + self.token_id(), + owner_id, + "emergency_action".to_string(), + rules.authorized_to_make_change_action_takers().clone(), + ), + )), + )); + } + + Ok(SimpleConsensusValidationResult::new()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/structure_v0/mod.rs new file mode 100644 index 00000000000..cc4f6b8d257 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/structure_v0/mod.rs @@ -0,0 +1,27 @@ +use dpp::validation::{SimpleConsensusValidationResult}; +use drive::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::{TokenEmergencyActionTransitionAction, TokenEmergencyActionTransitionActionAccessorsV0}; +use dpp::version::PlatformVersion; +use crate::error::Error; +use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; + +pub(super) trait TokenEmergencyActionTransitionActionStructureValidationV0 { + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result; +} +impl TokenEmergencyActionTransitionActionStructureValidationV0 + for TokenEmergencyActionTransitionAction +{ + fn validate_structure_v0( + &self, + platform_version: &PlatformVersion, + ) -> Result { + let validation_result = self.base().validate_structure(platform_version)?; + if !validation_result.is_valid() { + return Ok(validation_result); + } + + Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs index b575605cfee..92747e6d4f9 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_transfer_transition_action/structure_v0/mod.rs @@ -16,7 +16,7 @@ pub(super) trait TokenTransferTransitionActionStructureValidationV0 { impl TokenTransferTransitionActionStructureValidationV0 for TokenTransferTransitionAction { fn validate_structure_v0( &self, - owner_id: Identifier, + _owner_id: Identifier, platform_version: &PlatformVersion, ) -> Result { let validation_result = self.base().validate_structure(platform_version)?; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs index b8d77035b36..d4da544dc94 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/advanced_structure/v0/mod.rs @@ -17,21 +17,25 @@ use dpp::validation::ConsensusValidationResult; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::batch::batched_transition::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::batch::BatchTransitionAction; +use drive::state_transition_action::batch::BatchTransitionAction; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_replace_transition_action::DocumentReplaceTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; use dpp::state_transition::batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::TokenDestroyFrozenFundsTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::TokenEmergencyActionTransitionActionAccessorsV0; use drive::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::TokenFreezeTransitionActionAccessorsV0; use drive::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::v0::TokenTransferTransitionActionAccessorsV0; use drive::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; use drive::state_transition_action::StateTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::execution::ExecutionError; @@ -41,6 +45,8 @@ use crate::execution::validation::state_transition::batch::action_validation::do use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_burn_transition_action::TokenBurnTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_destroy_frozen_funds_transition_action::TokenDestroyFrozenFundsTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_emergency_action_transition_action::TokenEmergencyActionTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_freeze_transition_action::TokenFreezeTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_mint_transition_action::TokenMintTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_transfer_transition_action::TokenTransferTransitionActionValidation; @@ -284,6 +290,36 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for BatchTransition { BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(unfreeze_action.base(), self.owner_id(), self.user_fee_increase()), ); + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + TokenTransitionAction::EmergencyActionAction(emergency_action_action) => { + let result = + emergency_action_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(emergency_action_action.base(), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); + } + } + TokenTransitionAction::DestroyFrozenFundsAction( + destroy_frozen_funds_action, + ) => { + let result = + destroy_frozen_funds_action.validate_structure(platform_version)?; + if !result.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_token_base_transition_action(destroy_frozen_funds_action.base(), self.owner_id(), self.user_fee_increase()), + ); + return Ok(ConsensusValidationResult::new_with_data_and_errors( bump_action, result.errors, diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs index 8f6dc84768c..9c06e6b4294 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/mod.rs @@ -4,7 +4,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ use derive_more::From; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::batch::batched_transition::document_transition::{ +use drive::state_transition_action::batch::batched_transition::document_transition::{ DocumentTransitionAction, DocumentTransitionActionType, }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs index fd27aff4a18..39e3c871c66 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/data_trigger_binding/v0/mod.rs @@ -4,7 +4,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ }; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::batch::batched_transition::document_transition::{ +use drive::state_transition_action::batch::batched_transition::document_transition::{ DocumentTransitionAction, DocumentTransitionActionType, }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs index f6d9362d1fe..fe3c94b3e45 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/bindings/list/v0/mod.rs @@ -7,7 +7,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::bindin 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::document::batch::batched_transition::document_transition::DocumentTransitionActionType; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionActionType; /// Retrieves a list of data triggers binding with matching params. /// diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs index e7f024b2470..a85f1b6febb 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/executor.rs @@ -1,10 +1,10 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::state_transition::batch_transition::batched_transition::document_transition_action_type::DocumentTransitionActionTypeGetter; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use dpp::version::PlatformVersion; use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBinding; use crate::execution::validation::state_transition::batch::data_triggers::bindings::data_trigger_binding::DataTriggerBindingV0Getters; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs index 442f94318ab..21bdb917740 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/mod.rs @@ -2,7 +2,7 @@ use dpp::validation::SimpleValidationResult; /// Data triggers implement custom validation logic for state transitions /// that modifies documents in a specific data contract. /// Data triggers can be assigned based on the data contract ID, document type, and action. -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use crate::error::Error; use dpp::consensus::state::data_trigger::DataTriggerError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs index e9f99ad8e36..61c486c13ad 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/mod.rs @@ -5,7 +5,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs index 1c7eea3e64a..d3cdf285133 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dashpay/v0/mod.rs @@ -6,9 +6,9 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::ProtocolError; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; use dpp::system_data_contracts::dashpay_contract::v1::document_types::contact_request::properties ::{TO_USER_ID}; use dpp::version::PlatformVersion; @@ -105,8 +105,8 @@ mod test { use dpp::document::{DocumentV0Getters, DocumentV0Setters}; use dpp::platform_value; use dpp::platform_value::{Bytes32}; - use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; - use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionActionType; + use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; + use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionActionType; use crate::execution::validation::state_transition::batch::data_triggers::triggers::dashpay::create_contact_request_data_trigger; use crate::platform_types::platform::PlatformStateRef; use crate::test::helpers::setup::TestPlatformBuilder; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs index 0900bdab3cd..42159810ddf 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/mod.rs @@ -5,7 +5,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs index 62ffea9ac57..55ffa746720 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/dpns/v0/mod.rs @@ -15,9 +15,9 @@ use dpp::document::DocumentV0Getters; use dpp::platform_value::btreemap_extensions::{BTreeValueMapHelper, BTreeValueMapPathHelper}; use dpp::platform_value::Value; use dpp::ProtocolError; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::system_data_contracts::dpns_contract; use dpp::system_data_contracts::dpns_contract::v1::document_types::domain::properties::{ALLOW_SUBDOMAINS, DASH_ALIAS_IDENTITY_ID, DASH_UNIQUE_IDENTITY_ID, LABEL, NORMALIZED_LABEL, NORMALIZED_PARENT_DOMAIN_NAME, PREORDER_SALT, RECORDS}; @@ -369,8 +369,8 @@ mod test { use std::sync::Arc; use dpp::block::block_info::BlockInfo; use dpp::platform_value::Bytes32; - use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; - use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionActionType; + use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; + use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionActionType; use dpp::tests::fixtures::{get_batched_transitions_fixture, get_dpns_data_contract_fixture, get_dpns_parent_document_fixture, ParentDocumentOptions}; use dpp::tests::utils::generate_random_identifier_struct; use dpp::version::{DefaultForPlatformVersion}; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs index a2394175058..31f4b43ccbb 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/mod.rs @@ -1,4 +1,4 @@ -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::version::PlatformVersion; use crate::error::Error; use crate::error::execution::ExecutionError; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs index 3f30194fe97..d1cca4bf1ad 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/feature_flags/v0/mod.rs @@ -6,9 +6,9 @@ use dpp::consensus::state::data_trigger::data_trigger_condition_error::DataTrigg use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::system_data_contracts::feature_flags_contract; use dpp::system_data_contracts::feature_flags_contract::v1::document_types::update_consensus_params::properties ::PROPERTY_ENABLE_AT_HEIGHT; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs index cc5e4fc47b6..7c540836cad 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/mod.rs @@ -5,7 +5,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; mod v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs index 851f536a133..1fe229182f6 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/reject/v0/mod.rs @@ -1,9 +1,9 @@ use dpp::consensus::state::data_trigger::data_trigger_condition_error::DataTriggerConditionError; use dpp::data_contract::accessors::v0::DataContractV0Getters; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use crate::error::Error; use crate::execution::validation::state_transition::batch::data_triggers::DataTriggerExecutionResult; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; /// Creates a data trigger for handling document rejections. /// diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs index 8b8688c2230..967adaba8c8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/mod.rs @@ -3,7 +3,7 @@ use crate::error::Error; use crate::execution::validation::state_transition::batch::data_triggers::{ DataTriggerExecutionContext, DataTriggerExecutionResult, }; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::version::PlatformVersion; use crate::execution::validation::state_transition::batch::data_triggers::triggers::withdrawals::v0::delete_withdrawal_data_trigger_v0; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs index 72c479e872b..e39046a6709 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/data_triggers/triggers/withdrawals/v0/mod.rs @@ -4,7 +4,7 @@ use crate::error::Error; use dpp::platform_value::btreemap_extensions::BTreeValueMapHelper; use dpp::platform_value::Value; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use dpp::system_data_contracts::withdrawals_contract; use dpp::version::PlatformVersion; use drive::query::{DriveDocumentQuery, InternalClauses, WhereClause, WhereOperator}; @@ -13,8 +13,8 @@ use dpp::consensus::state::data_trigger::data_trigger_condition_error::DataTrigg use dpp::{document, ProtocolError}; use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::document::DocumentV0Getters; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionAccessorsV0; use dpp::system_data_contracts::withdrawals_contract::v1::document_types::withdrawal; use drive::drive::document::query::QueryDocumentsOutcomeV0Methods; use crate::execution::validation::state_transition::batch::data_triggers::{DataTriggerExecutionContext, DataTriggerExecutionResult}; @@ -131,9 +131,9 @@ mod tests { use dpp::document::serialization_traits::DocumentPlatformConversionMethodsV0; use dpp::document::{Document, DocumentV0Getters}; use dpp::platform_value::platform_value; - use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; - use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; - use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionV0; + use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::{DocumentBaseTransitionAction, DocumentBaseTransitionActionV0}; + use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; + use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::v0::DocumentDeleteTransitionActionV0; use dpp::system_data_contracts::{load_system_data_contract, SystemDataContract}; use dpp::tests::fixtures::{get_data_contract_fixture, get_withdrawal_document_fixture}; use dpp::version::PlatformVersion; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs index f5ff3235ddd..554fac68077 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/data_triggers.rs @@ -5,7 +5,7 @@ use crate::execution::validation::state_transition::batch::data_triggers::{ }; use dpp::version::PlatformVersion; -use drive::state_transition_action::document::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; #[allow(dead_code)] #[deprecated(note = "This function is marked as unused.")] diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs index a6675e5b402..5b225e70a7d 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/state/v0/mod.rs @@ -7,8 +7,10 @@ use dpp::state_transition::StateTransitionLike; use drive::state_transition_action::StateTransitionAction; use dpp::version::{DefaultForPlatformVersion, PlatformVersion}; use drive::grovedb::TransactionArg; -use drive::state_transition_action::document::batch::batched_transition::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::batch::BatchTransitionAction; +use drive::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; +use drive::state_transition_action::batch::BatchTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::Error; use crate::error::execution::ExecutionError; @@ -20,6 +22,8 @@ use crate::execution::validation::state_transition::batch::action_validation::do use crate::execution::validation::state_transition::batch::action_validation::document_transfer_transition_action::DocumentTransferTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::document_update_price_transition_action::DocumentUpdatePriceTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_burn_transition_action::TokenBurnTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_destroy_frozen_funds_transition_action::TokenDestroyFrozenFundsTransitionActionValidation; +use crate::execution::validation::state_transition::batch::action_validation::token_emergency_action_transition_action::TokenEmergencyActionTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_freeze_transition_action::TokenFreezeTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_mint_transition_action::TokenMintTransitionActionValidation; use crate::execution::validation::state_transition::batch::action_validation::token_transfer_transition_action::TokenTransferTransitionActionValidation; @@ -184,6 +188,26 @@ impl DocumentsBatchStateTransitionStateValidationV0 for BatchTransition { transaction, platform_version, )?, + TokenTransitionAction::EmergencyActionAction(emergency_action_action) => { + emergency_action_action.validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )? + } + TokenTransitionAction::DestroyFrozenFundsAction( + destroy_frozen_funds_action, + ) => destroy_frozen_funds_action.validate_state( + platform, + owner_id, + block_info, + execution_context, + transaction, + platform_version, + )?, }, BatchedTransitionAction::BumpIdentityDataContractNonce(_) => { return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index 9c98dd44c3b..72b5099a94b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -30,12 +30,12 @@ use dpp::state_transition::batch_transition::BatchTransition; use dpp::state_transition::batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; use dpp::state_transition::batch_transition::batched_transition::document_purchase_transition::v0::v0_methods::DocumentPurchaseTransitionV0Methods; use dpp::state_transition::StateTransitionLike; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::{BatchedTransitionAction, DocumentTransitionAction, TokenTransitionAction}; -use drive::state_transition_action::document::batch::BatchTransitionAction; -use drive::state_transition_action::document::batch::v0::BatchTransitionActionV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::DocumentCreateTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_delete_transition_action::DocumentDeleteTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::DocumentReplaceTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; +use drive::state_transition_action::batch::BatchTransitionAction; +use drive::state_transition_action::batch::v0::BatchTransitionActionV0; use crate::execution::validation::state_transition::batch::state::v0::fetch_documents::fetch_documents_for_transitions_knowing_contract_and_document_type; use dpp::version::PlatformVersion; @@ -48,16 +48,21 @@ use dpp::state_transition::batch_transition::batched_transition::document_update use dpp::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; use dpp::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; +use dpp::tokens::emergency_action::TokenEmergencyAction; use drive::drive::contract::DataContractFetchInfo; use drive::drive::Drive; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; +use drive::state_transition_action::batch::batched_transition::BatchedTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionAction; use drive::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::TokenBurnTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::TokenDestroyFrozenFundsTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::TokenEmergencyActionTransitionAction; use drive::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::TokenFreezeTransitionAction; use drive::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::TokenMintTransitionAction; use drive::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; use drive::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionAction; +use drive::state_transition_action::batch::batched_transition::token_transition::TokenTransitionAction; use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::execution::types::execution_operation::ValidationOperation; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; @@ -549,6 +554,26 @@ impl BatchTransitionInternalTransformerV0 for BatchTransition { Ok(data_contract_fetch_info.clone()) }, platform_version)?; + execution_context + .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + Ok(batched_action) + } + TokenTransition::DestroyFrozenFunds(destroy_frozen_funds) => { + let (batched_action, fee_result) = TokenDestroyFrozenFundsTransitionAction::try_from_borrowed_token_destroy_frozen_funds_transition_with_contract_lookup(drive, owner_id, destroy_frozen_funds, approximate_for_costs, transaction, block_info, user_fee_increase, |_identifier| { + Ok(data_contract_fetch_info.clone()) + }, platform_version)?; + + execution_context + .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); + + Ok(batched_action) + } + TokenTransition::EmergencyAction(emergency_action) => { + let (batched_action, fee_result) = TokenEmergencyActionTransitionAction::try_from_borrowed_token_emergency_action_transition_with_contract_lookup(drive, owner_id, emergency_action, approximate_for_costs, transaction, block_info, user_fee_increase, |_identifier| { + Ok(data_contract_fetch_info.clone()) + }, platform_version)?; + execution_context .add_operation(ValidationOperation::PrecalculatedOperation(fee_result)); 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 5d177b6f382..007b1b5e930 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 @@ -15,7 +15,7 @@ use dpp::version::PlatformVersion; use drive::drive::identity::key::fetch::IdentityKeysRequest; use drive::drive::Drive; use drive::query::{SingleDocumentDriveQuery, SingleDocumentDriveQueryContestedStatus}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::{ +use drive::state_transition_action::batch::batched_transition::document_transition::{ BatchedTransitionAction, DocumentTransitionAction, }; use drive::state_transition_action::StateTransitionAction; @@ -29,12 +29,12 @@ use dpp::voting::votes::Vote; use drive::drive::votes::resolved::vote_polls::ResolvedVotePoll; use drive::drive::votes::resolved::votes::resolved_resource_vote::accessors::v0::ResolvedResourceVoteGettersV0; use drive::drive::votes::resolved::votes::ResolvedVote; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionActionAccessorsV0, DocumentFromCreateTransitionAction}; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_replace_transition_action::DocumentFromReplaceTransitionAction; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; -use drive::state_transition_action::document::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionActionAccessorsV0, DocumentFromCreateTransitionAction}; +use drive::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::DocumentFromReplaceTransitionAction; +use drive::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; use drive_abci::abci::app::FullAbciApplication; use drive_abci::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use drive_abci::execution::validation::state_transition::ValidationMode; diff --git a/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs index 75d236e331b..ccd0cde5f1a 100644 --- a/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/update/update_contract/v1/mod.rs @@ -13,6 +13,7 @@ use dpp::serialization::PlatformSerializableWithPlatformVersion; use crate::error::contract::DataContractError; use dpp::data_contract::accessors::v1::DataContractV1Getters; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; @@ -218,7 +219,7 @@ impl Drive { platform_version, )?; - for token_pos in contract.tokens().keys() { + for (token_pos, configuration) in contract.tokens() { let token_id = contract.token_id(*token_pos).ok_or(Error::DataContract( DataContractError::CorruptedDataContract(format!( "data contract has a token at position {}, but can not find it", @@ -228,6 +229,7 @@ impl Drive { batch_operations.extend(self.create_token_trees_operations( token_id.to_buffer(), + configuration.start_as_paused(), true, &mut None, estimated_costs_only_with_layer_info, diff --git a/packages/rs-drive/src/drive/tokens/apply_status/mod.rs b/packages/rs-drive/src/drive/tokens/apply_status/mod.rs new file mode 100644 index 00000000000..f6c88f0b68b --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/apply_status/mod.rs @@ -0,0 +1,93 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::tokens::status::TokenStatus; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + /// Sets a token status + pub fn token_apply_status( + &self, + token_id: [u8; 32], + status: TokenStatus, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + match platform_version.drive.methods.token.update.apply_status { + 0 => self.token_apply_status_v0( + token_id, + status, + block_info, + apply, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_apply_status".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Adds the operations to apply_status tokens without calculating fees and optionally applying. + pub fn token_apply_status_add_to_operations( + &self, + token_id: [u8; 32], + status: TokenStatus, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version.drive.methods.token.update.apply_status { + 0 => self.token_apply_status_add_to_operations_v0( + token_id, + status, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_apply_status_add_to_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Gathers the operations needed to apply_status tokens. + pub fn token_apply_status_operations( + &self, + token_id: [u8; 32], + status: TokenStatus, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.update.apply_status { + 0 => self.token_apply_status_operations_v0( + token_id, + status, + estimated_costs_only_with_layer_info, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "token_apply_status_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs b/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs new file mode 100644 index 00000000000..6b2e229d3ea --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs @@ -0,0 +1,100 @@ +use crate::drive::tokens::{token_path, TOKEN_IDENTITY_INFO_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::object_size_info::PathKeyElementInfo; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::serialization::PlatformSerializable; +use dpp::tokens::status::TokenStatus; +use dpp::version::PlatformVersion; +use grovedb::{batch::KeyInfoPath, Element, EstimatedLayerInformation, TransactionArg}; +use std::collections::HashMap; + +impl Drive { + pub(super) fn token_apply_status_v0( + &self, + token_id: [u8; 32], + status: TokenStatus, + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result { + let mut drive_operations = vec![]; + + self.token_apply_status_add_to_operations_v0( + token_id, + status, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok(fees) + } + + pub(super) fn token_apply_status_add_to_operations_v0( + &self, + token_id: [u8; 32], + status: TokenStatus, + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + let mut estimated_costs_only_with_layer_info = + if apply { None } else { Some(HashMap::new()) }; + + let batch_operations = self.token_apply_status_operations_v0( + token_id, + status, + &mut estimated_costs_only_with_layer_info, + platform_version, + )?; + + self.apply_batch_low_level_drive_operations( + estimated_costs_only_with_layer_info, + transaction, + batch_operations, + drive_operations, + &platform_version.drive, + ) + } + + pub(super) fn token_apply_status_operations_v0( + &self, + token_id: [u8; 32], + status: TokenStatus, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let mut drive_operations = vec![]; + + let token_status_bytes = status.serialize_consume_to_bytes()?; + + self.batch_insert( + PathKeyElementInfo::PathFixedSizeKeyRefElement::<2>(( + token_path(&token_id), + &[TOKEN_IDENTITY_INFO_KEY], + Element::Item(token_status_bytes, None), + )), + &mut drive_operations, + &platform_version.drive, + )?; + + Ok(drive_operations) + } +} diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index 3b8c5541694..be8a53dee1b 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -1,6 +1,7 @@ use crate::drive::RootTree; mod add_transaction_history_operations; +pub mod apply_status; pub mod balance; pub mod burn; pub mod estimated_costs; @@ -11,6 +12,7 @@ pub mod system; pub mod transfer; pub mod unfreeze; +pub const TOKEN_STATUS_INFO_KEY: u8 = 96; pub const TOKEN_IDENTITY_INFO_KEY: u8 = 64; pub const TOKEN_BALANCES_KEY: u8 = 128; diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs index 4f2f6b1575e..ce7ebc2c376 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs @@ -17,6 +17,7 @@ impl Drive { pub fn create_token_trees( &self, token_id: [u8; 32], + start_as_paused: bool, allow_already_exists: bool, block_info: &BlockInfo, apply: bool, @@ -32,6 +33,7 @@ impl Drive { { 0 => self.create_token_trees_v0( token_id, + start_as_paused, allow_already_exists, block_info, apply, @@ -50,6 +52,7 @@ impl Drive { pub fn create_token_trees_add_to_operations( &self, token_id: [u8; 32], + start_as_paused: bool, allow_already_exists: bool, apply: bool, previous_batch_operations: &mut Option<&mut Vec>, @@ -66,6 +69,7 @@ impl Drive { { 0 => self.create_token_trees_add_to_operations_v0( token_id, + start_as_paused, allow_already_exists, apply, previous_batch_operations, @@ -85,6 +89,7 @@ impl Drive { pub fn create_token_trees_operations( &self, token_id: [u8; 32], + start_as_paused: bool, allow_already_exists: bool, previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< @@ -102,6 +107,7 @@ impl Drive { { 0 => self.create_token_trees_operations_v0( token_id, + start_as_paused, allow_already_exists, previous_batch_operations, estimated_costs_only_with_layer_info, diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs index c97bf6e3319..c1ff9cc4d57 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs @@ -1,17 +1,21 @@ use crate::drive::balances::total_tokens_root_supply_path; use crate::drive::tokens::{ token_path, tokens_root_path, TOKEN_BALANCES_KEY, TOKEN_IDENTITY_INFO_KEY, + TOKEN_STATUS_INFO_KEY, }; use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; -use crate::util::grove_operations::BatchInsertTreeApplyType; +use crate::util::grove_operations::{BatchInsertApplyType, BatchInsertTreeApplyType, QueryTarget}; +use crate::util::object_size_info::PathKeyElementInfo; use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKey; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; +use dpp::serialization::PlatformSerializable; +use dpp::tokens::status::TokenStatus; use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::HashMap; @@ -21,6 +25,7 @@ impl Drive { pub(super) fn create_token_trees_v0( &self, token_id: [u8; 32], + start_as_paused: bool, allow_already_exists: bool, block_info: &BlockInfo, apply: bool, @@ -32,6 +37,7 @@ impl Drive { // Add operations to create the token root tree self.create_token_trees_add_to_operations_v0( token_id, + start_as_paused, allow_already_exists, apply, &mut None, @@ -58,6 +64,7 @@ impl Drive { pub(super) fn create_token_trees_add_to_operations_v0( &self, token_id: [u8; 32], + start_as_paused: bool, allow_already_exists: bool, apply: bool, previous_batch_operations: &mut Option<&mut Vec>, @@ -74,6 +81,7 @@ impl Drive { // Get the operations required to create the token tree let batch_operations = self.create_token_trees_operations_v0( token_id, + start_as_paused, allow_already_exists, previous_batch_operations, &mut estimated_costs_only_with_layer_info, @@ -96,6 +104,7 @@ impl Drive { pub(super) fn create_token_trees_operations_v0( &self, token_id: [u8; 32], + start_as_paused: bool, allow_already_exists: bool, previous_batch_operations: &mut Option<&mut Vec>, estimated_costs_only_with_layer_info: &mut Option< @@ -117,6 +126,15 @@ impl Drive { } }; + let item_apply_type = if estimated_costs_only_with_layer_info.is_none() { + BatchInsertApplyType::StatefulBatchInsert + } else { + BatchInsertApplyType::StatelessBatchInsert { + in_tree_using_sums: false, + target: QueryTarget::QueryTargetValue(8), + } + }; + let token_balance_tree_apply_type = if estimated_costs_only_with_layer_info.is_none() { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { @@ -164,8 +182,30 @@ impl Drive { ))); } + let starting_status = TokenStatus::new(start_as_paused, platform_version)?; + let token_status_bytes = starting_status.serialize_consume_to_bytes()?; + + let inserted = self.batch_insert_if_not_exists( + PathKeyElementInfo::PathFixedSizeKeyRefElement::<2>(( + token_path(&token_id), + &[TOKEN_IDENTITY_INFO_KEY], + Element::Item(token_status_bytes, None), + )), + item_apply_type, + transaction, + &mut batch_operations, + &platform_version.drive, + )?; + + if !inserted && !allow_already_exists { + // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. + return Err(Error::Drive(DriveError::CorruptedDriveState( + "token info tree already exists".to_string(), + ))); + } + let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey((token_path(&token_id), vec![TOKEN_IDENTITY_INFO_KEY])), + PathFixedSizeKey((token_path(&token_id), vec![TOKEN_STATUS_INFO_KEY])), false, None, non_sum_tree_apply_type, diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_emergency_action_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_emergency_action_transition.rs index 75b5afa455e..93a0899818e 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_emergency_action_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_emergency_action_transition.rs @@ -73,9 +73,9 @@ impl DriveHighLevelBatchOperationConverter for TokenEmergencyActionTransitionAct } if self.base().perform_action() { - ops.push(TokenOperation(TokenOperationType::TokenEmergencyAction { + ops.push(TokenOperation(TokenOperationType::TokenSetStatus { token_id: self.token_id(), - emergency_action: self.emergency_action(), + status: self.emergency_action().resulting_status(platform_version)?, })); let token_configuration = self.base().token_configuration()?; diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index a3c126a1107..77fda94d41d 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -7,6 +7,7 @@ use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; use dpp::tokens::emergency_action::TokenEmergencyAction; +use dpp::tokens::status::TokenStatus; use dpp::tokens::token_event::TokenEvent; use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; @@ -61,12 +62,12 @@ pub enum TokenOperationType { /// The frozen identity id frozen_identity_id: Identifier, }, - /// Perform an emergency action on the token. - TokenEmergencyAction { + /// Sets the status of the token. + TokenSetStatus { /// The token id token_id: Identifier, - /// The emergency action - emergency_action: TokenEmergencyAction, + /// The status + status: TokenStatus, }, /// Adds a historical document explaining a token action. TokenHistory { @@ -194,15 +195,11 @@ impl DriveLowLevelOperationConverter for TokenOperationType { )?; Ok(batch_operations) } - TokenOperationType::TokenEmergencyAction { - token_id, - emergency_action, - } => { - let batch_operations = drive.token_set_emergency_action_operations( - token_id, - emergency_action, + TokenOperationType::TokenSetStatus { token_id, status } => { + let batch_operations = drive.token_apply_status_operations( + token_id.to_buffer(), + status, estimated_costs_only_with_layer_info, - transaction, platform_version, )?; Ok(batch_operations) diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/mod.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/mod.rs index a964e80e059..2fa2f4f9050 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/mod.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/mod.rs @@ -5,4 +5,5 @@ use versioned_feature_core::FeatureVersion; #[derive(Clone, Debug, Default)] pub struct DPPTokenVersions { pub identity_token_info_default_structure_version: FeatureVersion, + pub identity_token_status_default_structure_version: FeatureVersion, } diff --git a/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/v1.rs b/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/v1.rs index ff0cef29c3e..d36fdbf9a20 100644 --- a/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/v1.rs +++ b/packages/rs-platform-version/src/version/dpp_versions/dpp_token_versions/v1.rs @@ -2,4 +2,5 @@ use crate::version::dpp_versions::dpp_token_versions::DPPTokenVersions; pub const TOKEN_VERSIONS_V1: DPPTokenVersions = DPPTokenVersions { identity_token_info_default_structure_version: 0, + identity_token_status_default_structure_version: 0, }; diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs index 32f2b7268cc..0fe429b5921 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/mod.rs @@ -109,6 +109,10 @@ pub struct DriveAbciDocumentsStateTransitionValidationVersions { pub token_unfreeze_transition_structure_validation: FeatureVersion, pub token_freeze_transition_state_validation: FeatureVersion, pub token_unfreeze_transition_state_validation: FeatureVersion, + pub token_destroy_frozen_funds_transition_structure_validation: FeatureVersion, + pub token_destroy_frozen_funds_transition_state_validation: FeatureVersion, + pub token_emergency_action_transition_structure_validation: FeatureVersion, + pub token_emergency_action_transition_state_validation: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs index 93f10ebed12..11dc69053f8 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v1.rs @@ -140,6 +140,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V1: DriveAbciValidationVersions = token_unfreeze_transition_structure_validation: 0, token_freeze_transition_state_validation: 0, token_unfreeze_transition_state_validation: 0, + token_destroy_frozen_funds_transition_structure_validation: 0, + token_destroy_frozen_funds_transition_state_validation: 0, + token_emergency_action_transition_structure_validation: 0, + token_emergency_action_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs index 63a3e254a49..2a08f59b38a 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v2.rs @@ -140,6 +140,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V2: DriveAbciValidationVersions = token_unfreeze_transition_structure_validation: 0, token_freeze_transition_state_validation: 0, token_unfreeze_transition_state_validation: 0, + token_destroy_frozen_funds_transition_structure_validation: 0, + token_destroy_frozen_funds_transition_state_validation: 0, + token_emergency_action_transition_structure_validation: 0, + token_emergency_action_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs index ba2c6d601f6..d706f0d8389 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v3.rs @@ -140,6 +140,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V3: DriveAbciValidationVersions = token_unfreeze_transition_structure_validation: 0, token_freeze_transition_state_validation: 0, token_unfreeze_transition_state_validation: 0, + token_destroy_frozen_funds_transition_structure_validation: 0, + token_destroy_frozen_funds_transition_state_validation: 0, + token_emergency_action_transition_structure_validation: 0, + token_emergency_action_transition_state_validation: 0, }, }, has_nonce_validation: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs index 4e999d846b4..0faa2b63f69 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v4.rs @@ -143,6 +143,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V4: DriveAbciValidationVersions = token_unfreeze_transition_structure_validation: 0, token_freeze_transition_state_validation: 0, token_unfreeze_transition_state_validation: 0, + token_destroy_frozen_funds_transition_structure_validation: 0, + token_destroy_frozen_funds_transition_state_validation: 0, + token_emergency_action_transition_structure_validation: 0, + token_emergency_action_transition_state_validation: 0, }, }, has_nonce_validation: 1, // <---- changed this diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rs index 896e442aa7f..b5d4d8c3aae 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_validation_versions/v5.rs @@ -144,6 +144,10 @@ pub const DRIVE_ABCI_VALIDATION_VERSIONS_V5: DriveAbciValidationVersions = token_unfreeze_transition_structure_validation: 0, token_freeze_transition_state_validation: 0, token_unfreeze_transition_state_validation: 0, + token_destroy_frozen_funds_transition_structure_validation: 0, + token_destroy_frozen_funds_transition_state_validation: 0, + token_emergency_action_transition_structure_validation: 0, + token_emergency_action_transition_state_validation: 0, }, }, has_nonce_validation: 1, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 7fd86fe126f..6b88759c6ab 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -42,4 +42,5 @@ pub struct DriveTokenUpdateMethodVersions { pub add_transaction_history_operations: FeatureVersion, pub freeze: FeatureVersion, pub unfreeze: FeatureVersion, + pub apply_status: FeatureVersion, } diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index 2e12260ad6f..faabf9f280a 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -32,5 +32,6 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM add_transaction_history_operations: 0, freeze: 0, unfreeze: 0, + apply_status: 0, }, }; From ad720bf4e1b64e7e6f8a5837a9705bd3333dc375 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 10 Jan 2025 07:55:07 +0700 Subject: [PATCH 51/61] support for new grovedb --- Cargo.lock | 27 +++----- .../v0/mod.rs | 1 + .../document/batch_transition/methods/mod.rs | 2 + .../batch_transition/v1/v0_methods.rs | 2 + .../v0/mod.rs | 4 +- .../tests/strategy_tests/strategy.rs | 2 +- .../tests/strategy_tests/token_tests.rs | 4 +- .../verify_state_transitions.rs | 5 +- packages/rs-drive/Cargo.toml | 12 ++-- .../v0/mod.rs | 6 +- .../fetch_asset_lock_outpoint_info/v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 8 +-- .../insert/add_contract_to_storage/v0/mod.rs | 6 +- .../contract/update/update_contract/v0/mod.rs | 6 +- .../credit_pools/epochs/operations_factory.rs | 8 ++- .../v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 8 +-- .../v0/mod.rs | 4 +- .../v0/mod.rs | 8 +-- .../mod.rs | 6 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 4 +- .../add_document_to_primary_storage/v0/mod.rs | 8 +-- .../v0/mod.rs | 10 +-- .../v0/mod.rs | 10 +-- .../v0/mod.rs | 10 +-- .../v0/mod.rs | 4 +- .../v0/mod.rs | 10 +-- .../v0/mod.rs | 6 +- .../v0/mod.rs | 10 +-- .../v0/mod.rs | 10 +-- .../v0/mod.rs | 6 +- .../for_add_group_action/v0/mod.rs | 16 ++--- .../fetch_action_id_has_signer/v0/mod.rs | 4 +- .../fetch/fetch_action_id_info/v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../fetch_action_id_signers_power/v0/mod.rs | 4 +- .../group/insert/add_group_action/v0/mod.rs | 8 +-- .../group/insert/add_new_groups/v0/mod.rs | 6 +- .../fetch_identity_contract_nonce/v0/mod.rs | 4 +- .../merge_identity_contract_nonce/v0/mod.rs | 6 +- .../v0/mod.rs | 10 +-- .../v0/mod.rs | 4 +- .../estimation_costs/for_balances/v0/mod.rs | 6 +- .../for_identity_contract_info/v0/mod.rs | 10 +-- .../v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../for_keys_for_identity_id/v0/mod.rs | 10 +-- .../for_negative_credit/v0/mod.rs | 6 +- .../v0/mod.rs | 4 +- .../for_root_key_reference_tree/v0/mod.rs | 4 +- .../for_update_nonce/v0/mod.rs | 8 +-- .../for_update_revision/v0/mod.rs | 8 +-- .../balance/fetch_identity_balance/v0/mod.rs | 4 +- .../fetch_identity_negative_balance/v0/mod.rs | 4 +- .../nonce/fetch_identity_nonce/v0/mod.rs | 4 +- .../fetch_identity_revision/v0/mod.rs | 4 +- .../insert/add_new_identity/v0/mod.rs | 6 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 8 +-- .../fetch/single_balance/v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 16 ++--- .../v0/mod.rs | 12 ++-- .../v0/mod.rs | 6 +- .../v0/mod.rs | 6 +- .../for_total_system_credits_update/v0/mod.rs | 6 +- .../fetch_identity_token_balance/v0/mod.rs | 4 +- .../for_token_balances/v0/mod.rs | 14 ++-- .../for_token_total_supply/v0/mod.rs | 8 +-- .../src/drive/tokens/freeze/v0/mod.rs | 4 +- .../info/fetch_identity_token_info/v0/mod.rs | 4 +- .../system/create_token_trees/v0/mod.rs | 12 ++-- .../src/drive/tokens/unfreeze/v0/mod.rs | 4 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 4 +- .../v1/mod.rs | 8 +-- .../v0/mod.rs | 6 +- .../v1/mod.rs | 6 +- .../v0/mod.rs | 4 +- .../v1/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 12 ++-- .../src/util/batch/drive_op_batch/token.rs | 1 - .../util/batch/drive_op_batch/withdrawals.rs | 8 +-- .../src/util/batch/grovedb_op_batch/mod.rs | 8 +-- .../grove_operations/batch_delete/v0/mod.rs | 2 +- .../v0/mod.rs | 6 +- .../v0/mod.rs | 8 +-- .../batch_insert_if_changed_value/v0/mod.rs | 3 +- .../batch_insert_if_not_exists/v0/mod.rs | 3 +- .../v0/mod.rs | 3 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 4 +- .../batch_move_items_in_path_query/v0/mod.rs | 12 ++-- .../batch_remove_raw/v0/mod.rs | 6 +- .../util/grove_operations/grove_get/v0/mod.rs | 6 +- .../v0/mod.rs | 6 +- .../grove_operations/grove_get_raw/v0/mod.rs | 6 +- .../grove_get_raw_item/v0/mod.rs | 6 +- .../grove_get_raw_optional/v0/mod.rs | 6 +- .../grove_get_raw_optional_item/v0/mod.rs | 6 +- .../grove_get_sum_tree_total_value/v0/mod.rs | 6 +- .../grove_operations/grove_has_raw/v0/mod.rs | 6 +- .../rs-drive/src/util/grove_operations/mod.rs | 67 +++++++++---------- packages/rs-drive/tests/query_tests.rs | 16 ++--- .../rs-drive/tests/query_tests_history.rs | 2 +- packages/rs-platform-version/Cargo.toml | 2 +- .../src/errors/consensus/consensus_error.rs | 5 +- 121 files changed, 408 insertions(+), 407 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e3ec8a698e1..c5f11ebd4ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2141,8 +2141,7 @@ dependencies = [ [[package]] name = "grovedb" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d91e8f87926c834c7338d0c69a48816c043e0cddf0062a8a567483db2fb1e24" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" dependencies = [ "axum", "bincode", @@ -2176,8 +2175,7 @@ dependencies = [ [[package]] name = "grovedb-costs" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360f7c8d3b20beafcbf3cde8754bbcfd201ae2a30ec7594a4b9678fd2fa3c7a8" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" dependencies = [ "integer-encoding", "intmap", @@ -2187,8 +2185,7 @@ dependencies = [ [[package]] name = "grovedb-epoch-based-storage-flags" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acec1b6962d99d7b079c0fd1532cd3a2c83a3d659ffd9fcf02edda4599334bb4" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" dependencies = [ "grovedb-costs", "hex", @@ -2200,8 +2197,7 @@ dependencies = [ [[package]] name = "grovedb-merk" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72057865f239fdd24f92eaa8668acc0d618da168f330546577a62eda1701210e" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" dependencies = [ "bincode", "blake3", @@ -2226,14 +2222,12 @@ dependencies = [ [[package]] name = "grovedb-path" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d96cc6106e5ca88e548d66f130b877b664da78be226dfdba555fc210f8508f4" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" [[package]] name = "grovedb-storage" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1c9b59bc9fa7123b8485f87f88a886dd109e7aff5f34a29a3812cb64eb897ff" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" dependencies = [ "blake3", "grovedb-costs", @@ -2252,8 +2246,7 @@ dependencies = [ [[package]] name = "grovedb-version" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4be0c1a1ef97068fe93212e7b6f349e0b44a9fc90063c8c28e110cfb8c2fcb2" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" dependencies = [ "thiserror", "versioned-feature-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2262,8 +2255,7 @@ dependencies = [ [[package]] name = "grovedb-visualize" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5865f4335eb99644512a7d80d6b1698ba1099a8268fdfd3ffb1a3a32dcb4af28" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" dependencies = [ "hex", "itertools 0.12.1", @@ -2272,8 +2264,7 @@ dependencies = [ [[package]] name = "grovedbg-types" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921b9a29facf9d3f0de667cd1da083a34695ede9e7bfacd74bb5bd29f8f7c178" +source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" dependencies = [ "serde", "serde_with 3.9.0", diff --git a/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v0/mod.rs index 1050a4c2285..69b497eeeae 100644 --- a/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/class_methods/create_document_types_from_document_schemas/v0/mod.rs @@ -88,6 +88,7 @@ mod tests { false, false, false, + false, &mut vec![], PlatformVersion::latest(), ); diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs index 8decb15b361..f690b7edc2e 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/methods/mod.rs @@ -738,6 +738,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } } + #[cfg(feature = "state-transition-signing")] fn new_token_destroy_frozen_funds_transition( token_id: Identifier, owner_id: Identifier, @@ -798,6 +799,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransition { } } + #[cfg(feature = "state-transition-signing")] fn new_token_emergency_action_transition( token_id: Identifier, owner_id: Identifier, diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index d9d266fe10d..b1e12f82f6f 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -749,6 +749,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { Ok(state_transition) } + #[cfg(feature = "state-transition-signing")] fn new_token_destroy_frozen_funds_transition( token_id: Identifier, owner_id: Identifier, @@ -820,6 +821,7 @@ impl DocumentsBatchTransitionMethodsV1 for BatchTransitionV1 { Ok(state_transition) } + #[cfg(feature = "state-transition-signing")] fn new_token_emergency_action_transition( token_id: Identifier, owner_id: Identifier, diff --git a/packages/rs-drive-abci/src/execution/platform_events/withdrawals/cleanup_expired_locks_of_withdrawal_amounts/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/withdrawals/cleanup_expired_locks_of_withdrawal_amounts/v0/mod.rs index 74315a1d6c7..0c4ab33a051 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/withdrawals/cleanup_expired_locks_of_withdrawal_amounts/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/withdrawals/cleanup_expired_locks_of_withdrawal_amounts/v0/mod.rs @@ -6,7 +6,7 @@ use dpp::block::block_info::BlockInfo; use dpp::version::PlatformVersion; use drive::drive::identity::withdrawals::paths::get_withdrawal_transactions_sum_tree_path_vec; -use drive::grovedb::{PathQuery, QueryItem, Transaction}; +use drive::grovedb::{MaybeTree, PathQuery, QueryItem, Transaction}; use drive::util::grove_operations::BatchDeleteApplyType; impl Platform @@ -49,7 +49,7 @@ where true, // we know that we are not deleting a subtree BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, Some(transaction), &mut batch_operations, diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index 9dbbd3a1ed8..9a4dc5ae8c4 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -1427,7 +1427,7 @@ impl NetworkStrategy { contract, token_id, token_pos, - action: TokenEvent::Mint(amount, note), + action: TokenEvent::Mint(amount, recipient, note), }) if current_identities.len() > 1 => { let random_index = rng.gen_range(0..current_identities.len()); let random_identity_id = current_identities[random_index].id(); diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs index d253aef1462..4c5aae85f02 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -79,7 +79,7 @@ mod tests { contract: contract.clone(), token_id, token_pos: 0, - action: TokenEvent::Mint(1000, None), + action: TokenEvent::Mint(1000, identity2.id(), None), }; let strategy = NetworkStrategy { @@ -206,7 +206,7 @@ mod tests { contract: contract.clone(), token_id, token_pos: 0, - action: TokenEvent::Mint(1000, None), + action: TokenEvent::Mint(1000, identity2.id(), None), }; let strategy = NetworkStrategy { 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 007b1b5e930..49ee1e5c22f 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 @@ -15,9 +15,7 @@ use dpp::version::PlatformVersion; use drive::drive::identity::key::fetch::IdentityKeysRequest; use drive::drive::Drive; use drive::query::{SingleDocumentDriveQuery, SingleDocumentDriveQueryContestedStatus}; -use drive::state_transition_action::batch::batched_transition::document_transition::{ - BatchedTransitionAction, DocumentTransitionAction, -}; +use drive::state_transition_action::batch::batched_transition::document_transition::DocumentTransitionAction; use drive::state_transition_action::StateTransitionAction; use drive_abci::execution::validation::state_transition::transformer::StateTransitionActionTransformerV0; use drive_abci::platform_types::platform::PlatformRef; @@ -29,6 +27,7 @@ use dpp::voting::votes::Vote; use drive::drive::votes::resolved::vote_polls::ResolvedVotePoll; use drive::drive::votes::resolved::votes::resolved_resource_vote::accessors::v0::ResolvedResourceVoteGettersV0; use drive::drive::votes::resolved::votes::ResolvedVote; +use drive::state_transition_action::batch::batched_transition::BatchedTransitionAction; use drive::state_transition_action::batch::batched_transition::document_transition::document_base_transition_action::DocumentBaseTransitionActionAccessorsV0; use drive::state_transition_action::batch::batched_transition::document_transition::document_create_transition_action::{DocumentCreateTransitionActionAccessorsV0, DocumentFromCreateTransitionAction}; use drive::state_transition_action::batch::batched_transition::document_transition::document_purchase_transition_action::DocumentPurchaseTransitionActionAccessorsV0; diff --git a/packages/rs-drive/Cargo.toml b/packages/rs-drive/Cargo.toml index 50a337f27ae..cd76d01dce3 100644 --- a/packages/rs-drive/Cargo.toml +++ b/packages/rs-drive/Cargo.toml @@ -52,12 +52,12 @@ enum-map = { version = "2.0.3", optional = true } intmap = { version = "2.0.0", features = ["serde"], optional = true } chrono = { version = "0.4.35", optional = true } itertools = { version = "0.13", optional = true } -grovedb = { version = "2.1.0", optional = true, default-features = false } -grovedb-costs = { version = "2.1.0", optional = true } -grovedb-path = { version = "2.1.0" } -grovedb-storage = { version = "2.1.0", optional = true } -grovedb-version = { version = "2.1.0" } -grovedb-epoch-based-storage-flags = { version = "2.1.0" } +grovedb = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20", optional = true, default-features = false } +grovedb-costs = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20", optional = true } +grovedb-path = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20" } +grovedb-storage = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20", optional = true } +grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20" } +grovedb-epoch-based-storage-flags = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20" } [dev-dependencies] criterion = "0.5" diff --git a/packages/rs-drive/src/drive/asset_lock/estimation_costs/add_estimation_costs_for_adding_asset_lock/v0/mod.rs b/packages/rs-drive/src/drive/asset_lock/estimation_costs/add_estimation_costs_for_adding_asset_lock/v0/mod.rs index 1110b448445..3973d252e8d 100644 --- a/packages/rs-drive/src/drive/asset_lock/estimation_costs/add_estimation_costs_for_adding_asset_lock/v0/mod.rs +++ b/packages/rs-drive/src/drive/asset_lock/estimation_costs/add_estimation_costs_for_adding_asset_lock/v0/mod.rs @@ -4,8 +4,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::asset_lock::asset_lock_storage_path; use grovedb::EstimatedSumTrees::SomeSumTrees; @@ -61,7 +61,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(3, false), estimated_layer_sizes: AllSubtrees( 12, // 32 + 1 + 1 / 3 @@ -77,7 +77,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(asset_lock_storage_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems( 36, //The size of an outpoint diff --git a/packages/rs-drive/src/drive/asset_lock/fetch_asset_lock_outpoint_info/v0/mod.rs b/packages/rs-drive/src/drive/asset_lock/fetch_asset_lock_outpoint_info/v0/mod.rs index eb929eda17f..c85e0dc84d3 100644 --- a/packages/rs-drive/src/drive/asset_lock/fetch_asset_lock_outpoint_info/v0/mod.rs +++ b/packages/rs-drive/src/drive/asset_lock/fetch_asset_lock_outpoint_info/v0/mod.rs @@ -13,7 +13,7 @@ use dpp::asset_lock::reduced_asset_lock_value::AssetLockValue; use dpp::asset_lock::StoredAssetLockInfo; use dpp::platform_value::Bytes36; use dpp::serialization::PlatformDeserializable; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Checks if a given `outpoint` is present as an asset lock in the transaction. @@ -68,7 +68,7 @@ impl Drive { StatefulDirectQuery } else { StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(36), } }; diff --git a/packages/rs-drive/src/drive/contract/apply/apply_contract_with_serialization/v0/mod.rs b/packages/rs-drive/src/drive/contract/apply/apply_contract_with_serialization/v0/mod.rs index a7b41957bfc..8a7289995e2 100644 --- a/packages/rs-drive/src/drive/contract/apply/apply_contract_with_serialization/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/apply/apply_contract_with_serialization/v0/mod.rs @@ -18,7 +18,7 @@ use dpp::serialization::PlatformDeserializableWithPotentialValidationFromVersion use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::borrow::Cow; use std::collections::HashMap; @@ -99,7 +99,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, // we can ignore flags as this is just an approximation // and it's doubtful that contracts will always be inserted at max size query_target: QueryTargetValue( diff --git a/packages/rs-drive/src/drive/contract/estimation_costs/add_estimation_costs_for_contract_insertion/v0/mod.rs b/packages/rs-drive/src/drive/contract/estimation_costs/add_estimation_costs_for_contract_insertion/v0/mod.rs index ba04d65bc61..c1acab18020 100644 --- a/packages/rs-drive/src/drive/contract/estimation_costs/add_estimation_costs_for_contract_insertion/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/estimation_costs/add_estimation_costs_for_contract_insertion/v0/mod.rs @@ -16,9 +16,9 @@ use crate::util::type_constants::{DEFAULT_FLOAT_SIZE, DEFAULT_FLOAT_SIZE_U8}; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllSubtrees, Mix}; use grovedb::EstimatedSumTrees::NoSumTrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use std::collections::HashMap; impl Drive { @@ -61,7 +61,7 @@ impl Drive { ), ), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(2), estimated_layer_sizes: AllSubtrees( ESTIMATED_AVERAGE_INDEX_NAME_SIZE, @@ -80,7 +80,7 @@ impl Drive { document_type_name.as_str(), )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(0, true), estimated_layer_sizes: AllSubtrees( ESTIMATED_AVERAGE_INDEX_NAME_SIZE, @@ -103,7 +103,7 @@ impl Drive { contract.id_ref().as_bytes(), )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(AVERAGE_NUMBER_OF_UPDATES as u32), estimated_layer_sizes: Mix { subtrees_size: None, diff --git a/packages/rs-drive/src/drive/contract/insert/add_contract_to_storage/v0/mod.rs b/packages/rs-drive/src/drive/contract/insert/add_contract_to_storage/v0/mod.rs index 8844fe39bcc..837d1fcbcc9 100644 --- a/packages/rs-drive/src/drive/contract/insert/add_contract_to_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/add_contract_to_storage/v0/mod.rs @@ -19,7 +19,7 @@ use dpp::version::drive_versions::DriveVersion; use grovedb::batch::key_info::KeyInfo; use grovedb::batch::KeyInfoPath; use grovedb::reference_path::ReferencePathType::SiblingReference; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -64,8 +64,8 @@ impl Drive { } else { let apply_type = if estimated_costs_only_with_layer_info.is_some() { BatchInsertTreeApplyType::StatelessBatchInsertTree { - is_sum_tree: false, - in_tree_using_sums: false, + tree_type: TreeType::NormalTree, + in_tree_type: TreeType::NormalTree, flags_len: storage_flags .as_ref() .map(|flags| flags.to_element_flags().len()) diff --git a/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs b/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs index ddec35b2bae..22ce029f82c 100644 --- a/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs @@ -19,7 +19,7 @@ use dpp::serialization::PlatformSerializableWithPlatformVersion; use dpp::fee::default_costs::CachedEpochIndexFeeVersions; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::{HashMap, HashSet}; impl Drive { @@ -300,8 +300,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: element_flags .as_ref() .map(|e| e.len() as u32) diff --git a/packages/rs-drive/src/drive/credit_pools/epochs/operations_factory.rs b/packages/rs-drive/src/drive/credit_pools/epochs/operations_factory.rs index 81248a8e5a6..ebc0d9ed5ae 100644 --- a/packages/rs-drive/src/drive/credit_pools/epochs/operations_factory.rs +++ b/packages/rs-drive/src/drive/credit_pools/epochs/operations_factory.rs @@ -20,7 +20,7 @@ use dpp::fee::Credits; use dpp::util::deserializer::ProtocolVersion; use dpp::version::PlatformVersion; use grovedb::batch::QualifiedGroveDbOp; -use grovedb::{Element, TransactionArg}; +use grovedb::{Element, TransactionArg, TreeType}; /// Operations on Epochs pub trait EpochOperations { @@ -288,7 +288,11 @@ impl EpochOperations for Epoch { /// Returns a groveDB op which deletes the epoch proposers tree. fn delete_proposers_tree_operation(&self) -> QualifiedGroveDbOp { - QualifiedGroveDbOp::delete_tree_op(self.get_path_vec(), KEY_PROPOSERS.to_vec(), false) + QualifiedGroveDbOp::delete_tree_op( + self.get_path_vec(), + KEY_PROPOSERS.to_vec(), + TreeType::NormalTree, + ) } /// Adds a groveDB op to the batch which deletes the given epoch proposers from the proposers tree. diff --git a/packages/rs-drive/src/drive/document/delete/delete_document_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/delete/delete_document_for_contract_operations/v0/mod.rs index cec20f624ae..3f13cfcc6bb 100644 --- a/packages/rs-drive/src/drive/document/delete/delete_document_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/delete_document_for_contract_operations/v0/mod.rs @@ -1,6 +1,6 @@ use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use dpp::data_contract::document_type::DocumentTypeRef; @@ -83,7 +83,7 @@ impl Drive { &platform_version.drive, )?; DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue( document_type.estimated_size(platform_version)? as u32 ), diff --git a/packages/rs-drive/src/drive/document/delete/internal/add_estimation_costs_for_remove_document_to_primary_storage/v0/mod.rs b/packages/rs-drive/src/drive/document/delete/internal/add_estimation_costs_for_remove_document_to_primary_storage/v0/mod.rs index 2f2863cd4ac..ce3ca4d6e5b 100644 --- a/packages/rs-drive/src/drive/document/delete/internal/add_estimation_costs_for_remove_document_to_primary_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/internal/add_estimation_costs_for_remove_document_to_primary_storage/v0/mod.rs @@ -1,8 +1,8 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::PotentiallyAtMaxElements; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllItems; +use grovedb::{EstimatedLayerInformation, TreeType}; use dpp::data_contract::document_type::DocumentTypeRef; @@ -67,7 +67,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(primary_key_path), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems( DEFAULT_HASH_SIZE_U8, diff --git a/packages/rs-drive/src/drive/document/delete/remove_document_from_primary_storage/v0/mod.rs b/packages/rs-drive/src/drive/document/delete/remove_document_from_primary_storage/v0/mod.rs index b3ea51c398a..07d0b4f5642 100644 --- a/packages/rs-drive/src/drive/document/delete/remove_document_from_primary_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/remove_document_from_primary_storage/v0/mod.rs @@ -1,6 +1,6 @@ use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, MaybeTree, TransactionArg, TreeType}; use dpp::data_contract::document_type::DocumentTypeRef; @@ -38,14 +38,14 @@ impl Drive { ) -> Result<(), Error> { let apply_type = if estimated_costs_only_with_layer_info.is_some() { StatelessBatchDelete { - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, estimated_key_size: DEFAULT_HASH_SIZE_U32, estimated_value_size: document_type.estimated_size(platform_version)? as u32, } } else { // we know we are not deleting a subtree StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), } }; self.batch_delete( diff --git a/packages/rs-drive/src/drive/document/delete/remove_indices_for_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/delete/remove_indices_for_index_level_for_contract_operations/v0/mod.rs index 6ad033a0f41..a7e531ebb1c 100644 --- a/packages/rs-drive/src/drive/document/delete/remove_indices_for_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/remove_indices_for_index_level_for_contract_operations/v0/mod.rs @@ -2,7 +2,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::AllSubtrees; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; use dpp::data_contract::document_type::IndexLevel; @@ -51,7 +51,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(sub_level_index_count + 1), estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, @@ -116,7 +116,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( sub_level_index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( document_top_field_estimated_size as u8, diff --git a/packages/rs-drive/src/drive/document/delete/remove_indices_for_top_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/delete/remove_indices_for_top_index_level_for_contract_operations/v0/mod.rs index 332e9214519..65f48016dd9 100644 --- a/packages/rs-drive/src/drive/document/delete/remove_indices_for_top_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/remove_indices_for_top_index_level_for_contract_operations/v0/mod.rs @@ -2,7 +2,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::AllSubtrees; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; use grovedb::EstimatedSumTrees::NoSumTrees; use std::collections::HashMap; @@ -69,7 +69,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(contract_document_type_path.clone()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(sub_level_index_count + 1), estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, @@ -119,7 +119,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(index_path.clone()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( document_top_field_estimated_size as u8, diff --git a/packages/rs-drive/src/drive/document/delete/remove_reference_for_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/delete/remove_reference_for_index_level_for_contract_operations/v0/mod.rs index 0ee9619ac03..171af548196 100644 --- a/packages/rs-drive/src/drive/document/delete/remove_reference_for_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/remove_reference_for_index_level_for_contract_operations/v0/mod.rs @@ -3,7 +3,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::PotentiallyAtMaxElements; use grovedb::EstimatedLayerSizes::{AllReference, AllSubtrees}; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, MaybeTree, TransactionArg, TreeType}; use dpp::data_contract::document_type::IndexLevelTypeInfo; use dpp::data_contract::document_type::IndexType::{ContestedResourceIndex, NonUniqueIndex}; @@ -64,7 +64,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( key_info_path.clone(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, @@ -83,7 +83,7 @@ impl Drive { ), &key_info_path, // we know we are not deleting a tree - Some((false, false)), + Some(MaybeTree::NotTree), estimated_costs_only_with_layer_info, platform_version, )?; @@ -112,7 +112,7 @@ impl Drive { ), &key_info_path, // we know we are not deleting a tree - Some((false, false)), + Some(MaybeTree::NotTree), estimated_costs_only_with_layer_info, platform_version, )?; diff --git a/packages/rs-drive/src/drive/document/estimation_costs/add_estimation_costs_for_add_contested_document_to_primary_storage/v0/mod.rs b/packages/rs-drive/src/drive/document/estimation_costs/add_estimation_costs_for_add_contested_document_to_primary_storage/v0/mod.rs index 3de9414bc08..2bcaf9ccbc4 100644 --- a/packages/rs-drive/src/drive/document/estimation_costs/add_estimation_costs_for_add_contested_document_to_primary_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/estimation_costs/add_estimation_costs_for_add_contested_document_to_primary_storage/v0/mod.rs @@ -11,8 +11,8 @@ use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::PotentiallyAtMaxElements; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllItems; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; use std::collections::HashMap; @@ -77,7 +77,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(primary_key_path), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems( DEFAULT_HASH_SIZE_U8, diff --git a/packages/rs-drive/src/drive/document/estimation_costs/add_estimation_costs_for_add_document_to_primary_storage/v0/mod.rs b/packages/rs-drive/src/drive/document/estimation_costs/add_estimation_costs_for_add_document_to_primary_storage/v0/mod.rs index a43d53d1bfc..9b5bb29ebde 100644 --- a/packages/rs-drive/src/drive/document/estimation_costs/add_estimation_costs_for_add_document_to_primary_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/estimation_costs/add_estimation_costs_for_add_document_to_primary_storage/v0/mod.rs @@ -15,9 +15,9 @@ use dpp::document::DocumentV0Getters; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees, Mix}; use grovedb::EstimatedSumTrees::NoSumTrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::util::type_constants::{ DEFAULT_FLOAT_SIZE, DEFAULT_FLOAT_SIZE_U8, DEFAULT_HASH_SIZE_U8, @@ -84,7 +84,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(primary_key_path), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, @@ -108,7 +108,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(document_id_in_primary_path), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(AVERAGE_NUMBER_OF_UPDATES as u32), estimated_layer_sizes: Mix { subtrees_size: None, @@ -137,7 +137,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(primary_key_path), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems( DEFAULT_HASH_SIZE_U8, diff --git a/packages/rs-drive/src/drive/document/estimation_costs/stateless_delete_of_non_tree_for_costs/mod.rs b/packages/rs-drive/src/drive/document/estimation_costs/stateless_delete_of_non_tree_for_costs/mod.rs index 4d8a852d845..d31bad5cf55 100644 --- a/packages/rs-drive/src/drive/document/estimation_costs/stateless_delete_of_non_tree_for_costs/mod.rs +++ b/packages/rs-drive/src/drive/document/estimation_costs/stateless_delete_of_non_tree_for_costs/mod.rs @@ -1,6 +1,6 @@ mod v0; -use crate::util::grove_operations::{BatchDeleteUpTreeApplyType, IsSubTree, IsSumSubTree}; +use crate::util::grove_operations::BatchDeleteUpTreeApplyType; use crate::drive::Drive; @@ -10,7 +10,7 @@ use crate::error::drive::DriveError; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, EstimatedLayerSizes}; +use grovedb::{EstimatedLayerInformation, EstimatedLayerSizes, MaybeTree}; use std::collections::HashMap; @@ -39,7 +39,7 @@ impl Drive { pub(crate) fn stateless_delete_of_non_tree_for_costs( element_estimated_sizes: EstimatedLayerSizes, key_info_path: &KeyInfoPath, - is_known_to_be_subtree_with_sum: Option<(IsSubTree, IsSumSubTree)>, + is_known_to_be_subtree_with_sum: Option, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, diff --git a/packages/rs-drive/src/drive/document/estimation_costs/stateless_delete_of_non_tree_for_costs/v0/mod.rs b/packages/rs-drive/src/drive/document/estimation_costs/stateless_delete_of_non_tree_for_costs/v0/mod.rs index 7d70f79819e..504daac2d10 100644 --- a/packages/rs-drive/src/drive/document/estimation_costs/stateless_delete_of_non_tree_for_costs/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/estimation_costs/stateless_delete_of_non_tree_for_costs/v0/mod.rs @@ -1,6 +1,6 @@ use crate::drive::constants::CONTRACT_DOCUMENTS_PATH_HEIGHT; -use crate::util::grove_operations::{BatchDeleteUpTreeApplyType, IsSubTree, IsSumSubTree}; +use crate::util::grove_operations::BatchDeleteUpTreeApplyType; use crate::drive::Drive; use crate::error::fee::FeeError; @@ -8,7 +8,7 @@ use crate::error::Error; use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, EstimatedLayerSizes}; +use grovedb::{EstimatedLayerInformation, EstimatedLayerSizes, MaybeTree}; use intmap::IntMap; use itertools::Itertools; use std::collections::HashMap; @@ -41,7 +41,7 @@ impl Drive { pub(super) fn stateless_delete_of_non_tree_for_costs_v0( element_estimated_sizes: EstimatedLayerSizes, key_info_path: &KeyInfoPath, - is_known_to_be_subtree_with_sum: Option<(IsSubTree, IsSumSubTree)>, + is_known_to_be_subtree_with_sum: Option, estimated_costs_only_with_layer_info: &mut Option< HashMap, >, diff --git a/packages/rs-drive/src/drive/document/insert/add_document_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_document_for_contract_operations/v0/mod.rs index 1faf95a1dc2..f072477da87 100644 --- a/packages/rs-drive/src/drive/document/insert/add_document_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_document_for_contract_operations/v0/mod.rs @@ -12,7 +12,7 @@ use dpp::data_contract::document_type::methods::DocumentTypeV0Methods; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -41,7 +41,7 @@ impl Drive { StatefulDirectQuery } else { StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue( document_and_contract_info .document_type diff --git a/packages/rs-drive/src/drive/document/insert/add_document_to_primary_storage/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_document_to_primary_storage/v0/mod.rs index f0ecde6e3ee..c26d1b944cc 100644 --- a/packages/rs-drive/src/drive/document/insert/add_document_to_primary_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_document_to_primary_storage/v0/mod.rs @@ -5,7 +5,7 @@ use grovedb::batch::key_info::KeyInfo::KnownKey; use grovedb::batch::KeyInfoPath; use grovedb::reference_path::ReferencePathType::SiblingReference; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; use std::option::Option::None; @@ -125,8 +125,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: storage_flags .map(|s| s.serialized_size()) .unwrap_or_default(), @@ -425,7 +425,7 @@ impl Drive { BatchInsertApplyType::StatefulBatchInsert } else { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, target: QueryTargetValue(document_type.estimated_size(platform_version)? as u32), } }; diff --git a/packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v0/mod.rs index 2725cc80b1c..6b4932e1865 100644 --- a/packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v0/mod.rs @@ -14,7 +14,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::AllSubtrees; use grovedb::EstimatedSumTrees::NoSumTrees; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -62,7 +62,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(sub_level_index_count + 1), estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, @@ -77,8 +77,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: storage_flags .map(|s| s.serialized_size()) .unwrap_or_default(), @@ -136,7 +136,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( sub_level_index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( document_top_field_estimated_size as u8, diff --git a/packages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v0/mod.rs index c21146a1832..320a4625af5 100644 --- a/packages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v0/mod.rs @@ -20,7 +20,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::AllSubtrees; use grovedb::EstimatedSumTrees::NoSumTrees; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -70,7 +70,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(contract_document_type_path.clone()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(sub_level_index_count + 1), estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, @@ -85,8 +85,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: storage_flags .map(|s| s.serialized_size()) .unwrap_or_default(), @@ -146,7 +146,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(index_path.clone()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( document_top_field_estimated_size as u8, diff --git a/packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs index 00d3f872cd4..c84ab415615 100644 --- a/packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs @@ -23,7 +23,7 @@ use grovedb::batch::key_info::KeyInfo; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::PotentiallyAtMaxElements; use grovedb::EstimatedLayerSizes::AllReference; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -61,8 +61,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: storage_flags .map(|s| s.serialized_size()) .unwrap_or_default(), @@ -94,7 +94,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllReference( DEFAULT_HASH_SIZE_U8, @@ -194,7 +194,7 @@ impl Drive { BatchInsertApplyType::StatefulBatchInsert } else { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, target: QueryTargetValue( document_reference_size(document_and_contract_info.document_type) + storage_flags diff --git a/packages/rs-drive/src/drive/document/insert_contested/add_contested_document_to_primary_storage/v0/mod.rs b/packages/rs-drive/src/drive/document/insert_contested/add_contested_document_to_primary_storage/v0/mod.rs index 5df447b5ef5..5a18464be37 100644 --- a/packages/rs-drive/src/drive/document/insert_contested/add_contested_document_to_primary_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert_contested/add_contested_document_to_primary_storage/v0/mod.rs @@ -1,7 +1,7 @@ use grovedb::batch::key_info::KeyInfo; use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; @@ -203,7 +203,7 @@ impl Drive { BatchInsertApplyType::StatefulBatchInsert } else { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, target: QueryTargetValue(document_type.estimated_size(platform_version)? as u32), } }; diff --git a/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_contract_operations/v0/mod.rs index 1881419fdd2..43433cb6e70 100644 --- a/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_contract_operations/v0/mod.rs @@ -23,7 +23,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::AllSubtrees; use grovedb::EstimatedSumTrees::NoSumTrees; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -74,8 +74,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: storage_flags .map(|s| s.serialized_size()) .unwrap_or_default(), @@ -123,7 +123,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( document_top_field_estimated_size as u8, @@ -187,7 +187,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(16), // very seldom would more than 16 people want the resource estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, diff --git a/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_index_level_for_contract_operations/v0/mod.rs index a989dd3997b..a1ecffebb30 100644 --- a/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_index_level_for_contract_operations/v0/mod.rs @@ -60,7 +60,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(sub_level_index_count + 1), estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, @@ -76,7 +76,7 @@ impl Drive { } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { in_tree_using_sums: false, - is_sum_tree: false, + tree_type: TreeType::NormalTree, flags_len: storage_flags .map(|s| s.serialized_size()) .unwrap_or_default(), @@ -134,7 +134,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( sub_level_index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( document_top_field_estimated_size as u8, diff --git a/packages/rs-drive/src/drive/document/insert_contested/add_contested_reference_and_vote_subtree_to_document_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert_contested/add_contested_reference_and_vote_subtree_to_document_operations/v0/mod.rs index 3bc068d4f11..4370b1811d3 100644 --- a/packages/rs-drive/src/drive/document/insert_contested/add_contested_reference_and_vote_subtree_to_document_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert_contested/add_contested_reference_and_vote_subtree_to_document_operations/v0/mod.rs @@ -21,7 +21,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::{AllItems, Mix}; use grovedb::EstimatedSumTrees::AllSumTrees; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -53,7 +53,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(2), estimated_layer_sizes: Mix { // The votes don't have storage flags @@ -144,7 +144,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( votes_path_key_info.clone().convert_to_key_info_path()?, EstimatedLayerInformation { - is_sum_tree: true, + tree_type: TreeType::SumTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, U8_SIZE_U32, None), }, @@ -155,8 +155,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: true, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::SumTree, flags_len: storage_flags .map(|s| s.serialized_size()) .unwrap_or_default(), diff --git a/packages/rs-drive/src/drive/document/insert_contested/add_contested_vote_subtrees_for_non_identities_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert_contested/add_contested_vote_subtrees_for_non_identities_operations/v0/mod.rs index bb036014bd5..a23851323de 100644 --- a/packages/rs-drive/src/drive/document/insert_contested/add_contested_vote_subtrees_for_non_identities_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert_contested/add_contested_vote_subtrees_for_non_identities_operations/v0/mod.rs @@ -12,7 +12,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::{AllItems, Mix}; use grovedb::EstimatedSumTrees::AllSumTrees; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -43,7 +43,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( index_path_info.clone().convert_to_key_info_path(), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(1), estimated_layer_sizes: Mix { // The votes don't have storage flags @@ -71,7 +71,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( votes_path_key_info.clone().convert_to_key_info_path()?, EstimatedLayerInformation { - is_sum_tree: true, + tree_type: TreeType::SumTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, U8_SIZE_U32, None), }, @@ -82,8 +82,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: true, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::SumTree, flags_len: storage_flags .map(|s| s.serialized_size()) .unwrap_or_default(), diff --git a/packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs index 0c92a15651f..eb982b4f3c3 100644 --- a/packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs @@ -34,7 +34,7 @@ use dpp::version::PlatformVersion; use grovedb::batch::key_info::KeyInfo; use grovedb::batch::key_info::KeyInfo::KnownKey; use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, MaybeTree, TransactionArg}; use std::borrow::Cow; use std::collections::{HashMap, HashSet}; @@ -380,7 +380,7 @@ impl Drive { document.id().as_slice(), Some(CONTRACT_DOCUMENTS_PATH_HEIGHT), BatchDeleteUpTreeApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, previous_batch_operations, @@ -394,7 +394,7 @@ impl Drive { &[0], Some(CONTRACT_DOCUMENTS_PATH_HEIGHT), BatchDeleteUpTreeApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, previous_batch_operations, diff --git a/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs index c1faf370de5..1133447945b 100644 --- a/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs @@ -8,9 +8,9 @@ use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; use dpp::data_contract::GroupContractPosition; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::EstimatedLevel; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees, Mix}; use grovedb::EstimatedSumTrees::{AllSumTrees, NoSumTrees, SomeSumTrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use std::collections::HashMap; impl Drive { @@ -79,7 +79,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(3, false), estimated_layer_sizes: AllSubtrees( 1, @@ -96,7 +96,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(group_root_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(10, false), // We estimate that on average we need to update 10 nodes estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -105,7 +105,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(group_contract_path(contract_id.as_slice())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees(2, NoSumTrees, None), }, @@ -117,7 +117,7 @@ impl Drive { &group_contract_position.to_be_bytes(), )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, @@ -129,7 +129,7 @@ impl Drive { &group_contract_position.to_be_bytes(), )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(10, false), estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -143,7 +143,7 @@ impl Drive { action_id.as_slice(), )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: Mix { subtrees_size: Some((1, AllSumTrees, None, 1)), @@ -160,7 +160,7 @@ impl Drive { action_id.as_slice(), )), EstimatedLayerInformation { - is_sum_tree: true, + tree_type: TreeType::SumTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllItems(8, 1, None), }, diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs index ef6963b4d3b..c4503fe3286 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_has_signer/v0/mod.rs @@ -9,7 +9,7 @@ use dpp::data_contract::GroupContractPosition; use dpp::fee::fee_result::FeeResult; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// v0 implementation of fetching the signers' power for a given action ID within a group contract. @@ -144,7 +144,7 @@ impl Drive { // no estimated_costs_only_with_layer_info, means we want to apply to state let direct_query_type = if estimate_costs_only { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: true, + in_tree_type: TreeType::SumTree, query_target: QueryTargetValue(8), } } else { diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/v0/mod.rs index f17a4674e99..d01751e4749 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info/v0/mod.rs @@ -12,7 +12,7 @@ use dpp::identifier::Identifier; use dpp::serialization::PlatformDeserializable; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; impl Drive { pub(super) fn fetch_action_id_info_v0( @@ -70,7 +70,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/v0/mod.rs index 95483153889..46f88becaa0 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_info_keep_serialized/v0/mod.rs @@ -10,7 +10,7 @@ use dpp::data_contract::GroupContractPosition; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; impl Drive { /// v0 implementation of fetching the signers' power for a given action ID within a group contract. @@ -113,7 +113,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs index af88918a8fa..d61af2bc7da 100644 --- a/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/fetch_action_id_signers_power/v0/mod.rs @@ -8,7 +8,7 @@ use dpp::data_contract::group::GroupSumPower; use dpp::data_contract::GroupContractPosition; use dpp::identifier::Identifier; use dpp::version::PlatformVersion; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// v0 implementation of fetching the signers' power for a given action ID within a group contract. @@ -109,7 +109,7 @@ impl Drive { // no estimated_costs_only_with_layer_info, means we want to apply to state let direct_query_type = if estimate_costs_only { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(8), } } else { diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs index 8273acfa7f2..a0d8ce1dd97 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -18,7 +18,7 @@ use dpp::serialization::PlatformSerializable; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; use grovedb::element::SumValue; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use grovedb_epoch_based_storage_flags::StorageFlags; use std::collections::HashMap; @@ -141,8 +141,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: 0, } }; @@ -208,7 +208,7 @@ impl Drive { BatchInsertApplyType::StatefulBatchInsert } else { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums: true, + in_tree_type: TreeType::SumTree, target: QueryTarget::QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs index 9e489c31c2a..bde785e07c0 100644 --- a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs @@ -15,7 +15,7 @@ use dpp::identifier::Identifier; use dpp::serialization::PlatformSerializable; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::{BTreeMap, HashMap}; impl Drive { @@ -101,8 +101,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: 0, } }; diff --git a/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/fetch_identity_contract_nonce/v0/mod.rs b/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/fetch_identity_contract_nonce/v0/mod.rs index 14a8e3e05ee..bfbf1c2f4f9 100644 --- a/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/fetch_identity_contract_nonce/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/fetch_identity_contract_nonce/v0/mod.rs @@ -12,7 +12,7 @@ use dpp::prelude::IdentityNonce; use crate::drive::identity::contract_info::ContractInfoStructure::IdentityContractNonceKey; use dpp::version::PlatformVersion; use grovedb::Element::Item; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Fetches the Identity's contract revision from the backing store @@ -51,7 +51,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(1), } }; diff --git a/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs b/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs index aaa805ca542..be3b7075665 100644 --- a/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs @@ -11,7 +11,7 @@ use crate::util::object_size_info::{PathKeyElementInfo, PathKeyInfo}; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; @@ -98,8 +98,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: 0, } }; diff --git a/packages/rs-drive/src/drive/identity/contract_info/keys/add_potential_contract_info_for_contract_bounded_key/v0/mod.rs b/packages/rs-drive/src/drive/identity/contract_info/keys/add_potential_contract_info_for_contract_bounded_key/v0/mod.rs index 745bd2daffa..a2177bd0697 100644 --- a/packages/rs-drive/src/drive/identity/contract_info/keys/add_potential_contract_info_for_contract_bounded_key/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/contract_info/keys/add_potential_contract_info_for_contract_bounded_key/v0/mod.rs @@ -24,7 +24,7 @@ use dpp::identity::{IdentityPublicKey, Purpose}; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; use grovedb::reference_path::ReferencePathType::{SiblingReference, UpstreamRootHeightReference}; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use grovedb_costs::OperationCost; use integer_encoding::VarInt; use std::collections::HashMap; @@ -95,8 +95,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: 0, } }; @@ -233,7 +233,7 @@ impl Drive { BatchInsertApplyType::StatefulBatchInsert } else { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, target: QueryTargetValue(reference_type_path.serialized_size() as u32), } }; @@ -419,7 +419,7 @@ impl Drive { BatchInsertApplyType::StatefulBatchInsert } else { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, target: QueryTargetValue(reference.serialized_size() as u32), } }; diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_authentication_keys_security_level_in_key_reference_tree/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_authentication_keys_security_level_in_key_reference_tree/v0/mod.rs index 28d254ead1a..529b56477f6 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_authentication_keys_security_level_in_key_reference_tree/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_authentication_keys_security_level_in_key_reference_tree/v0/mod.rs @@ -2,8 +2,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::ApproximateElements; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllItems; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::identity::identity_query_keys_security_level_tree_path_vec; @@ -45,7 +45,7 @@ impl Drive { )), //todo: revisit EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(4), //we can estimate that each security level will only have 4 keys //We can mark these as all subtrees, because the revision will be under estimated_layer_sizes: AllItems(1, KEY_REFERENCE_SIZE, None), diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_balances/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_balances/v0/mod.rs index fd7be5dcdb2..59696e6aac5 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_balances/v0/mod.rs @@ -4,8 +4,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::balances::balance_path_vec; @@ -56,7 +56,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees( 1, @@ -73,7 +73,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(balance_path_vec()), EstimatedLayerInformation { - is_sum_tree: true, + tree_type: TreeType::SumTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, AVERAGE_BALANCE_SIZE, None), }, diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info/v0/mod.rs index 79a3a2c57b6..77a184dab7d 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info/v0/mod.rs @@ -3,9 +3,9 @@ use crate::drive::{identity_tree_path, Drive}; use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllSubtrees, Mix}; use grovedb::EstimatedSumTrees::NoSumTrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use std::collections::HashMap; impl Drive { @@ -19,7 +19,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, @@ -29,7 +29,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(identity_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -46,7 +46,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(identity_path_vec(identity_id.as_slice())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(2, false), estimated_layer_sizes: Mix { subtrees_size: Some((1, NoSumTrees, None, 2)), // weight of 2 because 1 for keys and 1 for data contract info @@ -59,7 +59,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(identity_contract_info_root_path_vec(identity_id)), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group/v0/mod.rs index 9fc0347ab8a..563dedebf6a 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group/v0/mod.rs @@ -2,9 +2,9 @@ use crate::drive::identity::identity_contract_info_group_path_vec; use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::ApproximateElements; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::Mix; use grovedb::EstimatedSumTrees::NoSumTrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use std::collections::HashMap; impl Drive { @@ -20,7 +20,7 @@ impl Drive { group_id, )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(2), estimated_layer_sizes: Mix { subtrees_size: Some((1, NoSumTrees, None, 1)), diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group_key_purpose/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group_key_purpose/v0/mod.rs index 2a2d2405d79..195a04d3c7c 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group_key_purpose/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group_key_purpose/v0/mod.rs @@ -2,8 +2,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::ApproximateElements; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllReference; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::identity::estimation_costs::KEY_REFERENCE_SIZE; use crate::drive::identity::identity_contract_info_group_path_key_purpose_vec; @@ -25,7 +25,7 @@ impl Drive { key_purpose, )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(5), estimated_layer_sizes: AllReference(1, KEY_REFERENCE_SIZE, None), }, diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group_keys/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group_keys/v0/mod.rs index efa3892a36c..069fc57bcb8 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group_keys/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_identity_contract_info_group_keys/v0/mod.rs @@ -2,9 +2,9 @@ use crate::drive::identity::identity_contract_info_group_keys_path_vec; use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::ApproximateElements; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllSubtrees; use grovedb::EstimatedSumTrees::NoSumTrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use std::collections::HashMap; impl Drive { @@ -20,7 +20,7 @@ impl Drive { group_id, )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(2), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_keys_for_identity_id/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_keys_for_identity_id/v0/mod.rs index 3721c5cad3b..ac776f1ab24 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_keys_for_identity_id/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_keys_for_identity_id/v0/mod.rs @@ -4,8 +4,8 @@ use crate::drive::{identity_tree_path, Drive}; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::identity::{identity_key_tree_path_vec, identity_path_vec}; @@ -58,7 +58,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, @@ -68,7 +68,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(identity_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -78,7 +78,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(identity_path_vec(identity_id.as_slice())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), //We can mark these as all subtrees, because the revision will be under estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), @@ -89,7 +89,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(identity_key_tree_path_vec(identity_id.as_slice())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(50), //we can estimate that an identity will have amount 50 keys //We can mark these as all subtrees, because the revision will be under estimated_layer_sizes: AllItems(1, 42, Some(3)), diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_negative_credit/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_negative_credit/v0/mod.rs index 34a7a6d214a..c4102f56b77 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_negative_credit/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_negative_credit/v0/mod.rs @@ -4,8 +4,8 @@ use crate::drive::{identity_tree_path, Drive}; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllSubtrees, Mix}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::identity::identity_path_vec; @@ -36,7 +36,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(identity_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -53,7 +53,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(identity_path_vec(identity_id.as_slice())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(2, false), //We can mark these as all subtrees, because the revision will be under estimated_layer_sizes: Mix { diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_purpose_in_key_reference_tree/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_purpose_in_key_reference_tree/v0/mod.rs index 68d4852ad3e..6951d86eda7 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_purpose_in_key_reference_tree/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_purpose_in_key_reference_tree/v0/mod.rs @@ -2,8 +2,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::ApproximateElements; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllReference, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::identity::identity_query_keys_purpose_tree_path_vec; @@ -68,7 +68,7 @@ impl Drive { purpose, )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count, // there are //We can mark these as all subtrees, because the revision will be under estimated_layer_sizes, diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_root_key_reference_tree/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_root_key_reference_tree/v0/mod.rs index ca2672fa5a2..7d312f98fd6 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_root_key_reference_tree/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_root_key_reference_tree/v0/mod.rs @@ -2,8 +2,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::ApproximateElements; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllSubtrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::identity::identity_query_keys_tree_path_vec; @@ -34,7 +34,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(identity_query_keys_tree_path_vec(identity_id)), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(4), //we can estimate that an identity will have amount 50 keys //We can mark these as all subtrees, because the revision will be under estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_update_nonce/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_update_nonce/v0/mod.rs index bbd73f99edf..0f129654927 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_update_nonce/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_update_nonce/v0/mod.rs @@ -4,8 +4,8 @@ use crate::drive::{identity_tree_path, Drive}; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllSubtrees, Mix}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::identity::identity_path_vec; @@ -40,7 +40,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(0, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, @@ -50,7 +50,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(identity_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -67,7 +67,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(identity_path_vec(identity_id.as_slice())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), //We can mark these as all subtrees, because the revision will be under estimated_layer_sizes: Mix { diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_update_revision/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_update_revision/v0/mod.rs index f5fe620cc68..659ffc26169 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_update_revision/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_update_revision/v0/mod.rs @@ -4,8 +4,8 @@ use crate::drive::{identity_tree_path, Drive}; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllSubtrees, Mix}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::identity::identity_path_vec; @@ -40,7 +40,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(0, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, @@ -50,7 +50,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(identity_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -67,7 +67,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(identity_path_vec(identity_id.as_slice())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), //We can mark these as all subtrees, because the revision will be under estimated_layer_sizes: Mix { diff --git a/packages/rs-drive/src/drive/identity/fetch/balance/fetch_identity_balance/v0/mod.rs b/packages/rs-drive/src/drive/identity/fetch/balance/fetch_identity_balance/v0/mod.rs index 2c5c98f7dbe..31c0eb6b9cf 100644 --- a/packages/rs-drive/src/drive/identity/fetch/balance/fetch_identity_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/fetch/balance/fetch_identity_balance/v0/mod.rs @@ -12,7 +12,7 @@ use dpp::fee::Credits; use dpp::version::PlatformVersion; use grovedb::Element::SumItem; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Fetches the Identity's balance from the backing store @@ -77,7 +77,7 @@ impl Drive { } else { // 8 is the size of a i64 used in sum trees DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: true, + in_tree_type: TreeType::SumTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/identity/fetch/balance/fetch_identity_negative_balance/v0/mod.rs b/packages/rs-drive/src/drive/identity/fetch/balance/fetch_identity_negative_balance/v0/mod.rs index ba32dca8740..8bc4ccb63ba 100644 --- a/packages/rs-drive/src/drive/identity/fetch/balance/fetch_identity_negative_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/fetch/balance/fetch_identity_negative_balance/v0/mod.rs @@ -9,7 +9,7 @@ use dpp::fee::Credits; use dpp::version::PlatformVersion; use grovedb::Element::Item; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Fetches the Identity's negative balance operations from the backing store. @@ -26,7 +26,7 @@ impl Drive { } else { // 8 is the size of a encoded u64 DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: true, + in_tree_type: TreeType::SumTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/identity/fetch/nonce/fetch_identity_nonce/v0/mod.rs b/packages/rs-drive/src/drive/identity/fetch/nonce/fetch_identity_nonce/v0/mod.rs index 14a7c3f705e..8aa7fbe80d6 100644 --- a/packages/rs-drive/src/drive/identity/fetch/nonce/fetch_identity_nonce/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/fetch/nonce/fetch_identity_nonce/v0/mod.rs @@ -12,7 +12,7 @@ use dpp::prelude::IdentityNonce; use dpp::version::PlatformVersion; use grovedb::Element::Item; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Fetches the Identity's nonce from the backing store @@ -48,7 +48,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(1), } }; diff --git a/packages/rs-drive/src/drive/identity/fetch/revision/fetch_identity_revision/v0/mod.rs b/packages/rs-drive/src/drive/identity/fetch/revision/fetch_identity_revision/v0/mod.rs index bc58f655241..5257b2f4323 100644 --- a/packages/rs-drive/src/drive/identity/fetch/revision/fetch_identity_revision/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/fetch/revision/fetch_identity_revision/v0/mod.rs @@ -12,7 +12,7 @@ use dpp::prelude::Revision; use dpp::version::PlatformVersion; use grovedb::Element::Item; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Fetches the Identity's revision from the backing store @@ -48,7 +48,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(1), } }; diff --git a/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs b/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs index 64f7dd35021..83146f7a86c 100644 --- a/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs @@ -19,7 +19,7 @@ use dpp::identity::identity_public_key::accessors::v0::{ }; use dpp::version::PlatformVersion; use grovedb::batch::KeyInfoPath; -use grovedb::{EstimatedLayerInformation, TransactionArg}; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; use itertools::Itertools; use std::collections::{BTreeSet, HashMap}; @@ -122,8 +122,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: storage_flags.serialized_size(), } }; diff --git a/packages/rs-drive/src/drive/identity/key/insert/insert_key_searchable_references/v0/mod.rs b/packages/rs-drive/src/drive/identity/key/insert/insert_key_searchable_references/v0/mod.rs index 8ae39f8b345..91fd7fbe21a 100644 --- a/packages/rs-drive/src/drive/identity/key/insert/insert_key_searchable_references/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/key/insert/insert_key_searchable_references/v0/mod.rs @@ -16,7 +16,7 @@ use dpp::identity::{IdentityPublicKey, Purpose, SecurityLevel}; use dpp::version::drive_versions::DriveVersion; use grovedb::batch::KeyInfoPath; use grovedb::reference_path::ReferencePathType; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -79,8 +79,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: SINGLE_EPOCH_FLAGS_SIZE, } }; diff --git a/packages/rs-drive/src/drive/identity/key/insert_key_hash_identity_reference/estimation_costs/add_estimation_costs_for_insert_non_unique_public_key_hash_reference/v0/mod.rs b/packages/rs-drive/src/drive/identity/key/insert_key_hash_identity_reference/estimation_costs/add_estimation_costs_for_insert_non_unique_public_key_hash_reference/v0/mod.rs index 355d05f34ba..a24e1eea04a 100644 --- a/packages/rs-drive/src/drive/identity/key/insert_key_hash_identity_reference/estimation_costs/add_estimation_costs_for_insert_non_unique_public_key_hash_reference/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/key/insert_key_hash_identity_reference/estimation_costs/add_estimation_costs_for_insert_non_unique_public_key_hash_reference/v0/mod.rs @@ -7,9 +7,9 @@ use crate::drive::{ use crate::util::type_constants::{DEFAULT_HASH_160_SIZE_U8, DEFAULT_HASH_SIZE_U8}; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; use grovedb::EstimatedSumTrees::NoSumTrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use std::collections::HashMap; impl Drive { @@ -24,7 +24,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(non_unique_key_hashes_path), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_160_SIZE_U8, NoSumTrees, None), }, @@ -36,7 +36,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(non_unique_key_hashes_sub_path), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(ESTIMATED_NON_UNIQUE_KEY_DUPLICATES), estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, 0, None), }, diff --git a/packages/rs-drive/src/drive/identity/key/insert_key_hash_identity_reference/estimation_costs/add_estimation_costs_for_insert_unique_public_key_hash_reference/v0/mod.rs b/packages/rs-drive/src/drive/identity/key/insert_key_hash_identity_reference/estimation_costs/add_estimation_costs_for_insert_unique_public_key_hash_reference/v0/mod.rs index 80a35c46def..db8a337fa48 100644 --- a/packages/rs-drive/src/drive/identity/key/insert_key_hash_identity_reference/estimation_costs/add_estimation_costs_for_insert_unique_public_key_hash_reference/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/key/insert_key_hash_identity_reference/estimation_costs/add_estimation_costs_for_insert_unique_public_key_hash_reference/v0/mod.rs @@ -5,7 +5,7 @@ use grovedb::EstimatedLayerCount::PotentiallyAtMaxElements; use grovedb::EstimatedLayerSizes::AllItems; use crate::util::type_constants::{DEFAULT_HASH_160_SIZE_U8, DEFAULT_HASH_SIZE_U32}; -use grovedb::EstimatedLayerInformation; +use grovedb::{EstimatedLayerInformation, TreeType}; use std::collections::HashMap; impl Drive { @@ -18,7 +18,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(unique_key_hashes_path), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems( DEFAULT_HASH_160_SIZE_U8, diff --git a/packages/rs-drive/src/drive/prefunded_specialized_balances/estimation_costs/for_prefunded_specialized_balance_update/v0/mod.rs b/packages/rs-drive/src/drive/prefunded_specialized_balances/estimation_costs/for_prefunded_specialized_balance_update/v0/mod.rs index 3400c9e6a43..64cdef76917 100644 --- a/packages/rs-drive/src/drive/prefunded_specialized_balances/estimation_costs/for_prefunded_specialized_balance_update/v0/mod.rs +++ b/packages/rs-drive/src/drive/prefunded_specialized_balances/estimation_costs/for_prefunded_specialized_balance_update/v0/mod.rs @@ -2,8 +2,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::constants::AVERAGE_BALANCE_SIZE; use crate::drive::prefunded_specialized_balances::{ @@ -28,7 +28,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, // We are on the 3rd level estimated_layer_count: EstimatedLevel(3, false), estimated_layer_sizes: AllSubtrees( @@ -45,7 +45,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(prefunded_specialized_balances_path()), EstimatedLayerInformation { - is_sum_tree: true, + tree_type: TreeType::SumTree, estimated_layer_count: EstimatedLevel(0, false), estimated_layer_sizes: AllSubtrees(1, AllSumTrees, None), }, @@ -54,7 +54,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(prefunded_specialized_balances_for_voting_path_vec()), EstimatedLayerInformation { - is_sum_tree: true, + tree_type: TreeType::SumTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, AVERAGE_BALANCE_SIZE, None), }, diff --git a/packages/rs-drive/src/drive/prefunded_specialized_balances/fetch/single_balance/v0/mod.rs b/packages/rs-drive/src/drive/prefunded_specialized_balances/fetch/single_balance/v0/mod.rs index 54c2fd9690f..134a05f582f 100644 --- a/packages/rs-drive/src/drive/prefunded_specialized_balances/fetch/single_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/prefunded_specialized_balances/fetch/single_balance/v0/mod.rs @@ -11,7 +11,7 @@ use dpp::fee::Credits; use crate::drive::prefunded_specialized_balances::prefunded_specialized_balances_for_voting_path; use dpp::version::PlatformVersion; use grovedb::Element::SumItem; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Fetches the Prefunded specialized balance from the backing store @@ -76,7 +76,7 @@ impl Drive { } else { // 8 is the size of a i64 used in sum trees DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: true, + in_tree_type: TreeType::SumTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/protocol_upgrade/remove_validators_proposed_app_versions/v0/mod.rs b/packages/rs-drive/src/drive/protocol_upgrade/remove_validators_proposed_app_versions/v0/mod.rs index 6db3de7a093..871e5d7bceb 100644 --- a/packages/rs-drive/src/drive/protocol_upgrade/remove_validators_proposed_app_versions/v0/mod.rs +++ b/packages/rs-drive/src/drive/protocol_upgrade/remove_validators_proposed_app_versions/v0/mod.rs @@ -14,7 +14,7 @@ use crate::util::batch::grovedb_op_batch::GroveDbOpBatchV0Methods; use dpp::util::deserializer::ProtocolVersion; use dpp::version::drive_versions::DriveVersion; -use grovedb::{Element, TransactionArg}; +use grovedb::{Element, MaybeTree, TransactionArg}; use integer_encoding::VarInt; impl Drive { @@ -121,7 +121,7 @@ impl Drive { (&path).into(), validator_pro_tx_hash.as_slice(), StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, drive_operations, diff --git a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract/v0/mod.rs b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract/v0/mod.rs index 2257bfae60b..3b3969df79c 100644 --- a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract/v0/mod.rs +++ b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract/v0/mod.rs @@ -6,8 +6,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllSubtrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::votes::paths::{ vote_contested_resource_active_polls_contract_document_tree_path, @@ -58,7 +58,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(2, false), //voting is on level 2 // We have balances in the middle which is a sum tree estimated_layer_sizes: AllSubtrees( @@ -76,7 +76,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(vote_root_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, // contested resource tree is a key of "c" so it should be on the top layer of the merk estimated_layer_count: EstimatedLevel(0, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), @@ -87,7 +87,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(vote_contested_resource_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, // active poll "p", with "e" and "i" first so it should be on the second layer of the merk estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), @@ -98,7 +98,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(vote_contested_resource_active_polls_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -111,7 +111,7 @@ impl Drive { contract.id_ref().as_bytes(), )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(document_type_count), estimated_layer_sizes: AllSubtrees( ESTIMATED_AVERAGE_DOCUMENT_TYPE_NAME_SIZE, @@ -130,7 +130,7 @@ impl Drive { ), ), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(2), estimated_layer_sizes: AllSubtrees( ESTIMATED_AVERAGE_INDEX_NAME_SIZE, @@ -148,7 +148,7 @@ impl Drive { ), ), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(1024), //Just a guess estimated_layer_sizes: AllSubtrees( ESTIMATED_AVERAGE_INDEX_NAME_SIZE, diff --git a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded/v0/mod.rs b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded/v0/mod.rs index 83f8c8dbc50..0559137ade7 100644 --- a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded/v0/mod.rs +++ b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded/v0/mod.rs @@ -4,8 +4,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllSubtrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::votes::paths::{ vote_contested_resource_active_polls_contract_tree_path, @@ -49,7 +49,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(2, false), //voting is on level 2 // We have balances in the middle which is a sum tree estimated_layer_sizes: AllSubtrees( @@ -67,7 +67,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(vote_root_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, // contested resource tree is a key of "c" so it should be on the top layer of the merk estimated_layer_count: EstimatedLevel(0, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), @@ -78,7 +78,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(vote_contested_resource_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, // active poll "p", with "e" and "i" first so it should be on the second layer of the merk estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), @@ -89,7 +89,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(vote_contested_resource_active_polls_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -102,7 +102,7 @@ impl Drive { contract.id_ref().as_bytes(), )), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(document_type_count), estimated_layer_sizes: AllSubtrees( ESTIMATED_AVERAGE_DOCUMENT_TYPE_NAME_SIZE, diff --git a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_levels_up_to_contract/v0/mod.rs b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_levels_up_to_contract/v0/mod.rs index 8bae767c7b2..0e6e4630378 100644 --- a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_levels_up_to_contract/v0/mod.rs +++ b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_levels_up_to_contract/v0/mod.rs @@ -5,8 +5,8 @@ use crate::util::storage_flags::StorageFlags; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllSubtrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::contract::paths::all_contracts_global_root_path; @@ -43,7 +43,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(0, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, @@ -53,7 +53,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(all_contracts_global_root_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllSubtrees( DEFAULT_HASH_SIZE_U8, diff --git a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_levels_up_to_contract_document_type_excluded/v0/mod.rs b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_levels_up_to_contract_document_type_excluded/v0/mod.rs index e9376cc3850..443349d04ad 100644 --- a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_levels_up_to_contract_document_type_excluded/v0/mod.rs +++ b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_levels_up_to_contract_document_type_excluded/v0/mod.rs @@ -6,8 +6,8 @@ use crate::util::storage_flags::StorageFlags; use dpp::data_contract::DataContract; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::AllSubtrees; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::contract::paths::contract_root_path; use crate::error::Error; @@ -62,7 +62,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(contract_root_path(contract.id_ref().as_bytes())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, storage_flags), }, @@ -71,7 +71,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(contract_documents_path(contract.id_ref().as_bytes())), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(document_type_count), estimated_layer_sizes: AllSubtrees( ESTIMATED_AVERAGE_DOCUMENT_TYPE_NAME_SIZE, diff --git a/packages/rs-drive/src/drive/system/estimation_costs/for_total_system_credits_update/v0/mod.rs b/packages/rs-drive/src/drive/system/estimation_costs/for_total_system_credits_update/v0/mod.rs index 2d8a9d33bcc..98aaed604c0 100644 --- a/packages/rs-drive/src/drive/system/estimation_costs/for_total_system_credits_update/v0/mod.rs +++ b/packages/rs-drive/src/drive/system/estimation_costs/for_total_system_credits_update/v0/mod.rs @@ -2,8 +2,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{ApproximateElements, EstimatedLevel}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::system::misc_path_vec; @@ -33,7 +33,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(3, false), estimated_layer_sizes: AllSubtrees( 12, // about 32 + 1 + 1 / 3 @@ -50,7 +50,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_owned_path(misc_path_vec()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: ApproximateElements(1), estimated_layer_sizes: AllItems(1, 8, None), }, diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balance/v0/mod.rs index 5adbb9f513c..3a77e56f6c7 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identity_token_balance/v0/mod.rs @@ -8,7 +8,7 @@ use crate::util::grove_operations::QueryTarget::QueryTargetValue; use dpp::balances::credits::TokenAmount; use dpp::version::PlatformVersion; use grovedb::Element::SumItem; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { pub(super) fn fetch_identity_token_balance_v0( @@ -42,7 +42,7 @@ impl Drive { } else { // 8 is the size of an i64 used in sum trees DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: true, + in_tree_type: TreeType::SumTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs index 1386c7979cd..2400e5de715 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs @@ -4,8 +4,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::tokens::{ token_balances_path, token_identity_infos_path, token_path, tokens_root_path, @@ -65,7 +65,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(2, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, @@ -75,7 +75,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(tokens_root_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(10, false), // We estimate that on average we need to update 10 nodes estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), }, @@ -85,7 +85,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(token_path(&token_id)), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(1, false), estimated_layer_sizes: AllSubtrees( 1, @@ -101,7 +101,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(token_path(&token_id)), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(0, false), estimated_layer_sizes: AllSubtrees(1, AllSumTrees, None), }, @@ -113,7 +113,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(token_identity_infos_path(&token_id)), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems( DEFAULT_HASH_SIZE_U8, @@ -128,7 +128,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(token_balances_path(&token_id)), EstimatedLayerInformation { - is_sum_tree: true, + tree_type: TreeType::SumTree, estimated_layer_count: PotentiallyAtMaxElements, estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, AVERAGE_BALANCE_SIZE, None), }, diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs index e8f61934d07..dca4ebe18e0 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs @@ -2,8 +2,8 @@ use crate::drive::Drive; use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::EstimatedLevel; -use grovedb::EstimatedLayerInformation; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; use crate::drive::balances::total_tokens_root_supply_path; use crate::drive::system::misc_path; @@ -61,7 +61,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path([]), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(3, false), // 17 because we have 2 layers at 32 and two layers at 2 estimated_layer_sizes: AllSubtrees( @@ -79,7 +79,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(misc_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(2, false), estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), }, @@ -89,7 +89,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(total_tokens_root_supply_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, estimated_layer_count: EstimatedLevel(10, false), estimated_layer_sizes: AllItems(DEFAULT_HASH_SIZE_U8, U64_SIZE_U32, None), }, diff --git a/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs b/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs index 8b1210d7e07..3df4bb38f1d 100644 --- a/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs @@ -11,7 +11,7 @@ use dpp::serialization::{PlatformDeserializable, PlatformSerializable}; use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; use dpp::tokens::info::IdentityTokenInfo; use dpp::version::PlatformVersion; -use grovedb::{batch::KeyInfoPath, Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{batch::KeyInfoPath, Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -101,7 +101,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/v0/mod.rs b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/v0/mod.rs index 102811581f5..31b139e84ac 100644 --- a/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_info/v0/mod.rs @@ -9,7 +9,7 @@ use dpp::serialization::PlatformDeserializable; use dpp::tokens::info::IdentityTokenInfo; use dpp::version::PlatformVersion; use grovedb::Element::Item; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { pub(super) fn fetch_identity_token_info_v0( @@ -42,7 +42,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs index c1ff9cc4d57..e60f48dfbdd 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs @@ -15,7 +15,7 @@ use dpp::fee::fee_result::FeeResult; use dpp::serialization::PlatformSerializable; use dpp::tokens::status::TokenStatus; use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use platform_version::version::PlatformVersion; use std::collections::HashMap; @@ -120,8 +120,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: 0, } }; @@ -130,7 +130,7 @@ impl Drive { BatchInsertApplyType::StatefulBatchInsert } else { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, target: QueryTarget::QueryTargetValue(8), } }; @@ -139,8 +139,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: true, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::SumTree, flags_len: 0, } }; diff --git a/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs b/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs index da0524e1ce1..ab09dd3f73a 100644 --- a/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs @@ -11,7 +11,7 @@ use dpp::serialization::{PlatformDeserializable, PlatformSerializable}; use dpp::tokens::info::v0::IdentityTokenInfoV0Accessors; use dpp::tokens::info::IdentityTokenInfo; use dpp::version::PlatformVersion; -use grovedb::{batch::KeyInfoPath, Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{batch::KeyInfoPath, Element, EstimatedLayerInformation, TransactionArg, TreeType}; use std::collections::HashMap; impl Drive { @@ -101,7 +101,7 @@ impl Drive { DirectQueryType::StatefulDirectQuery } else { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, query_target: QueryTargetValue(8), } }; diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_all_votes_given_by_identities/v0/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_all_votes_given_by_identities/v0/mod.rs index 81b3d0fab7b..2f2346d88b6 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_all_votes_given_by_identities/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_all_votes_given_by_identities/v0/mod.rs @@ -15,7 +15,7 @@ use dpp::dashcore::Network; use dpp::prelude::{BlockHeight, Identifier}; use dpp::version::PlatformVersion; use grovedb::query_result_type::QueryResultType::QueryPathKeyElementTrioResultType; -use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; +use grovedb::{MaybeTree, PathQuery, Query, SizedQuery, TransactionArg}; impl Drive { /// We remove votes for an identity when that identity is somehow disabled. Currently there is @@ -70,7 +70,7 @@ impl Drive { vote_path_ref.as_slice().into(), vote_id.as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, &mut deletion_batch, @@ -106,7 +106,7 @@ impl Drive { absolute_path_ref.as_slice().into(), identifier_bytes.as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, &mut deletion_batch, diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_contenders_operations/v0/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_contenders_operations/v0/mod.rs index 5e9127abf65..3598e7b0617 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_contenders_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_contenders_operations/v0/mod.rs @@ -8,7 +8,7 @@ use crate::util::grove_operations::BatchDeleteApplyType; use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; @@ -33,7 +33,7 @@ impl Drive { path.as_slice().into(), resource_vote_choice.to_key().as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_contenders_operations/v1/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_contenders_operations/v1/mod.rs index 7440aaadce6..4a2542b3906 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_contenders_operations/v1/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_contenders_operations/v1/mod.rs @@ -10,7 +10,7 @@ use crate::util::grove_operations::BatchDeleteApplyType; use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; @@ -35,7 +35,7 @@ impl Drive { path.as_slice().into(), resource_vote_choice.to_key().as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, @@ -47,7 +47,7 @@ impl Drive { path.as_slice().into(), &RESOURCE_ABSTAIN_VOTE_TREE_KEY_U8_32, BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, @@ -58,7 +58,7 @@ impl Drive { path.as_slice().into(), &RESOURCE_LOCK_VOTE_TREE_KEY_U8_32, BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_documents_operations/v0/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_documents_operations/v0/mod.rs index cb25558a382..c417c36cfb4 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_documents_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_documents_operations/v0/mod.rs @@ -9,7 +9,7 @@ use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use grovedb::query_result_type::QueryResultType; -use grovedb::{PathQuery, TransactionArg}; +use grovedb::{MaybeTree, PathQuery, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; use std::ops::RangeFull; @@ -54,7 +54,7 @@ impl Drive { documents_storage_path.as_slice().into(), document_key.as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, @@ -72,7 +72,7 @@ impl Drive { contender_path.as_slice().into(), vec![0].as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_documents_operations/v1/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_documents_operations/v1/mod.rs index f6722670348..b21d9584fab 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_documents_operations/v1/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_documents_operations/v1/mod.rs @@ -11,7 +11,7 @@ use dpp::document::DocumentV0Getters; use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; @@ -70,7 +70,7 @@ impl Drive { documents_storage_path.as_slice().into(), document_key.as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, @@ -89,7 +89,7 @@ impl Drive { contender_path.as_slice().into(), vec![0].as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_end_date_query_operations/v0/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_end_date_query_operations/v0/mod.rs index 1f2a36d353f..4a0e7c0a4be 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_end_date_query_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_end_date_query_operations/v0/mod.rs @@ -8,7 +8,7 @@ use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use grovedb::batch::KeyInfoPath; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; @@ -34,7 +34,7 @@ impl Drive { // VotePoll Info 1 VotePoll Info 2 VotePoll Info 3 let delete_apply_type = BatchDeleteUpTreeApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }; for (vote_poll, end_date, _) in vote_polls { diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_end_date_query_operations/v1/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_end_date_query_operations/v1/mod.rs index b47e5feb605..ef35e8a2db9 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_end_date_query_operations/v1/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_end_date_query_operations/v1/mod.rs @@ -12,7 +12,7 @@ use crate::util::grove_operations::BatchDeleteApplyType; use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; @@ -38,7 +38,7 @@ impl Drive { // VotePoll Info 1 VotePoll Info 2 VotePoll Info 3 let delete_apply_type = BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }; let mut by_end_date: BTreeMap> = BTreeMap::new(); diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_info_operations/v0/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_info_operations/v0/mod.rs index 141fd3c766e..0f30733b0a9 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_info_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_info_operations/v0/mod.rs @@ -7,7 +7,7 @@ use crate::util::grove_operations::BatchDeleteApplyType; use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; @@ -29,7 +29,7 @@ impl Drive { path.as_slice().into(), &RESOURCE_STORED_INFO_KEY_U8_32, BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_top_level_index_operations/v0/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_top_level_index_operations/v0/mod.rs index 13d3832592c..d1a3583bf08 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_top_level_index_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_top_level_index_operations/v0/mod.rs @@ -7,7 +7,7 @@ use crate::util::grove_operations::BatchDeleteApplyType; use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; @@ -30,7 +30,7 @@ impl Drive { path.as_slice().into(), last_index_path.as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_votes_operations/v0/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_votes_operations/v0/mod.rs index 4bd8edcff97..44ee761e560 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_votes_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_contested_resource_vote_poll_votes_operations/v0/mod.rs @@ -7,7 +7,7 @@ use crate::util::grove_operations::BatchDeleteApplyType; use dpp::identifier::Identifier; use dpp::identity::TimestampMillis; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; use std::collections::BTreeMap; @@ -36,7 +36,7 @@ impl Drive { path.as_slice().into(), vote.as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, @@ -51,7 +51,7 @@ impl Drive { path.as_slice().into(), vec![VOTING_STORAGE_TREE_KEY].as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, diff --git a/packages/rs-drive/src/drive/votes/cleanup/remove_specific_votes_given_by_identity/v0/mod.rs b/packages/rs-drive/src/drive/votes/cleanup/remove_specific_votes_given_by_identity/v0/mod.rs index bc8b4679853..1802e9ab242 100644 --- a/packages/rs-drive/src/drive/votes/cleanup/remove_specific_votes_given_by_identity/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/cleanup/remove_specific_votes_given_by_identity/v0/mod.rs @@ -6,7 +6,7 @@ use crate::fees::op::LowLevelDriveOperation; use crate::util::grove_operations::BatchDeleteApplyType; use dpp::prelude::Identifier; use dpp::version::PlatformVersion; -use grovedb::TransactionArg; +use grovedb::{MaybeTree, TransactionArg}; impl Drive { /// We remove votes for an identity when that identity is somehow disabled. Currently there is @@ -29,7 +29,7 @@ impl Drive { vote_path_ref.as_slice().into(), vote_identifier_to_remove.as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, batch_operations, diff --git a/packages/rs-drive/src/drive/votes/insert/contested_resource/individual_vote/register_contested_resource_identity_vote/v0/mod.rs b/packages/rs-drive/src/drive/votes/insert/contested_resource/individual_vote/register_contested_resource_identity_vote/v0/mod.rs index c7b284b845c..fa3782218f6 100644 --- a/packages/rs-drive/src/drive/votes/insert/contested_resource/individual_vote/register_contested_resource_identity_vote/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/insert/contested_resource/individual_vote/register_contested_resource_identity_vote/v0/mod.rs @@ -16,7 +16,7 @@ use dpp::fee::fee_result::FeeResult; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use dpp::{bincode, ProtocolError}; use grovedb::reference_path::ReferencePathType; -use grovedb::{Element, TransactionArg}; +use grovedb::{Element, MaybeTree, TransactionArg}; use platform_version::version::PlatformVersion; impl Drive { @@ -104,7 +104,7 @@ impl Drive { previous_voting_path.as_slice().into(), voter_pro_tx_hash.as_slice(), BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, true)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, &mut drive_operations, diff --git a/packages/rs-drive/src/drive/votes/insert/vote_poll/add_vote_poll_end_date_query_operations/v0/mod.rs b/packages/rs-drive/src/drive/votes/insert/vote_poll/add_vote_poll_end_date_query_operations/v0/mod.rs index 1c5fb593e9c..696b0841882 100644 --- a/packages/rs-drive/src/drive/votes/insert/vote_poll/add_vote_poll_end_date_query_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/insert/vote_poll/add_vote_poll_end_date_query_operations/v0/mod.rs @@ -22,7 +22,7 @@ use grovedb::batch::KeyInfoPath; use grovedb::EstimatedLayerCount::ApproximateElements; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; use grovedb::EstimatedSumTrees::NoSumTrees; -use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, TransactionArg, TreeType}; use platform_version::version::PlatformVersion; use std::collections::HashMap; @@ -51,7 +51,7 @@ impl Drive { estimated_costs_only_with_layer_info.insert( KeyInfoPath::from_known_path(vote_end_date_queries_tree_path()), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, // We can estimate that there is at least a vote concluding every block, and we put blocks at 6 seconds. estimated_layer_count: ApproximateElements(201_600), estimated_layer_sizes: AllSubtrees( @@ -67,7 +67,7 @@ impl Drive { vote_contested_resource_end_date_queries_at_time_tree_path_vec(end_date), ), EstimatedLayerInformation { - is_sum_tree: false, + tree_type: TreeType::NormalTree, // We can estimate that there is 2 votes ending per block. estimated_layer_count: ApproximateElements(2), estimated_layer_sizes: AllItems( @@ -100,8 +100,8 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, + tree_type: TreeType::NormalTree, flags_len: storage_flags .as_ref() .map(|s| s.serialized_size()) @@ -133,7 +133,7 @@ impl Drive { BatchInsertApplyType::StatefulBatchInsert } else { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums: false, + in_tree_type: TreeType::NormalTree, // todo: figure out a default serialized size to make this faster target: QueryTargetValue( item.serialized_size(&platform_version.drive.grove_version)? as u32, diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index 77fda94d41d..ad08114540e 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -6,7 +6,6 @@ use dpp::balances::credits::TokenAmount; use dpp::block::block_info::BlockInfo; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; -use dpp::tokens::emergency_action::TokenEmergencyAction; use dpp::tokens::status::TokenStatus; use dpp::tokens::token_event::TokenEvent; use grovedb::batch::KeyInfoPath; diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/withdrawals.rs b/packages/rs-drive/src/util/batch/drive_op_batch/withdrawals.rs index 26bf6617a78..8146f534d71 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/withdrawals.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/withdrawals.rs @@ -18,7 +18,7 @@ use dpp::fee::{Credits, SignedCredits}; use dpp::prelude::TimestampMillis; use dpp::version::PlatformVersion; use dpp::withdrawal::{WithdrawalTransactionIndex, WithdrawalTransactionIndexAndBytes}; -use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; +use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, MaybeTree, TransactionArg}; use grovedb::{Element, PathQuery, SizedQuery}; /// Operations for Withdrawals @@ -164,7 +164,7 @@ impl DriveLowLevelOperationConverter for WithdrawalOperationType { true, // we know that we are not deleting a subtree BatchMoveApplyType::StatefulBatchMove { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, &mut drive_operations, @@ -205,7 +205,7 @@ impl DriveLowLevelOperationConverter for WithdrawalOperationType { true, // we know that we are not deleting a subtree BatchMoveApplyType::StatefulBatchMove { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, &mut drive_operations, @@ -244,7 +244,7 @@ impl DriveLowLevelOperationConverter for WithdrawalOperationType { true, // we know that we are not deleting a subtree BatchDeleteApplyType::StatefulBatchDelete { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }, transaction, &mut drive_operations, diff --git a/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs b/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs index 68bac3502d1..ecf25027e2f 100644 --- a/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs +++ b/packages/rs-drive/src/util/batch/grovedb_op_batch/mod.rs @@ -13,7 +13,7 @@ use dpp::prelude::Identifier; use grovedb::batch::key_info::KeyInfo; use grovedb::batch::{GroveDbOpConsistencyResults, GroveOp, KeyInfoPath, QualifiedGroveDbOp}; use grovedb::operations::proof::util::hex_to_ascii; -use grovedb::Element; +use grovedb::{Element, TreeType}; use std::borrow::Cow; use std::fmt; @@ -360,7 +360,7 @@ pub trait GroveDbOpBatchV0Methods { fn add_delete(&mut self, path: Vec>, key: Vec); /// Adds a `Delete` tree operation to a list of GroveDB ops. - fn add_delete_tree(&mut self, path: Vec>, key: Vec, is_sum_tree: bool); + fn add_delete_tree(&mut self, path: Vec>, key: Vec, tree_type: TreeType); /// Adds an `Insert` operation with an element to a list of GroveDB ops. fn add_insert(&mut self, path: Vec>, key: Vec, element: Element); @@ -512,9 +512,9 @@ impl GroveDbOpBatchV0Methods for GroveDbOpBatch { } /// Adds a `Delete` tree operation to a list of GroveDB ops. - fn add_delete_tree(&mut self, path: Vec>, key: Vec, is_sum_tree: bool) { + fn add_delete_tree(&mut self, path: Vec>, key: Vec, tree_type: TreeType) { self.operations - .push(QualifiedGroveDbOp::delete_tree_op(path, key, is_sum_tree)) + .push(QualifiedGroveDbOp::delete_tree_op(path, key, tree_type)) } /// Adds an `Insert` operation with an element to a list of GroveDB ops. diff --git a/packages/rs-drive/src/util/grove_operations/batch_delete/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_delete/v0/mod.rs index 25a083ced3c..bc774456306 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_delete/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_delete/v0/mod.rs @@ -32,7 +32,7 @@ impl Drive { }; let delete_operation = match apply_type { BatchDeleteApplyType::StatelessBatchDelete { - is_sum_tree, + in_tree_type: is_sum_tree, estimated_key_size, estimated_value_size, } => GroveDb::average_case_delete_operation_for_delete::( diff --git a/packages/rs-drive/src/util/grove_operations/batch_delete_items_in_path_query/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_delete_items_in_path_query/v0/mod.rs index a530776986d..6e5b6179010 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_delete_items_in_path_query/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_delete_items_in_path_query/v0/mod.rs @@ -87,7 +87,7 @@ impl Drive { }; let delete_operation = match apply_type { BatchDeleteApplyType::StatelessBatchDelete { - is_sum_tree, + in_tree_type: is_sum_tree, estimated_key_size, estimated_value_size, } => GroveDb::average_case_delete_operation_for_delete::( @@ -136,7 +136,7 @@ mod tests { util::grove_operations::BatchDeleteApplyType, }; use assert_matches::assert_matches; - use grovedb::SizedQuery; + use grovedb::{SizedQuery, TreeType}; use grovedb_path::SubtreePath; use platform_version::version::PlatformVersion; @@ -533,7 +533,7 @@ mod tests { // Set up the stateless apply type with estimated sizes let apply_type = BatchDeleteApplyType::StatelessBatchDelete { - is_sum_tree: false, + in_tree_type: TreeType::NormalTree, estimated_key_size: key.len() as u32, estimated_value_size: element .serialized_size(&platform_version.drive.grove_version) diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs index 4f2c30664c7..3aa69889483 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs @@ -58,7 +58,7 @@ impl Drive { } else if let GroveOperation(grove_op) = previous_drive_operation { if grove_op.key == key && grove_op.path == path - && matches!(grove_op.op, GroveOp::DeleteTree) + && matches!(grove_op.op, GroveOp::DeleteTree(_)) { found = true; existing_operations.remove(i); @@ -133,7 +133,7 @@ impl Drive { } else if let GroveOperation(grove_op) = previous_drive_operation { if grove_op.key == key && grove_op.path == path - && matches!(grove_op.op, GroveOp::DeleteTree) + && matches!(grove_op.op, GroveOp::DeleteTree(_)) { found = true; existing_operations.remove(i); @@ -206,7 +206,7 @@ impl Drive { } else if let GroveOperation(grove_op) = previous_drive_operation { if grove_op.key == key && grove_op.path == path - && matches!(grove_op.op, GroveOp::DeleteTree) + && matches!(grove_op.op, GroveOp::DeleteTree(_)) { found = true; existing_operations.remove(i); @@ -279,7 +279,7 @@ impl Drive { } else if let GroveOperation(grove_op) = previous_drive_operation { if grove_op.key == key && grove_op.path == path - && matches!(grove_op.op, GroveOp::DeleteTree) + && matches!(grove_op.op, GroveOp::DeleteTree(_)) { found = true; existing_operations.remove(i); diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_if_changed_value/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_if_changed_value/v0/mod.rs index de5431d8f1f..f464fc3c18d 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_if_changed_value/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_if_changed_value/v0/mod.rs @@ -99,7 +99,8 @@ impl Drive { PathKeyElementSize((key_info_path, key_info, element)) => { match apply_type { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums, .. + in_tree_type: in_tree_using_sums, + .. } => { // we can estimate that the element was the same size drive_operations.push(CalculatedCostOperation( diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_if_not_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_if_not_exists/v0/mod.rs index 8fc5c16c5b4..cdf15dc489f 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_if_not_exists/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_if_not_exists/v0/mod.rs @@ -87,7 +87,8 @@ impl Drive { PathKeyElementSize((key_info_path, key_info, element)) => { match apply_type { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums, .. + in_tree_type: in_tree_using_sums, + .. } => { // we can estimate that the element was the same size drive_operations.push(CalculatedCostOperation( diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_if_not_exists_return_existing_element/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_if_not_exists_return_existing_element/v0/mod.rs index 55f411caebc..ed3e3568800 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_if_not_exists_return_existing_element/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_if_not_exists_return_existing_element/v0/mod.rs @@ -129,7 +129,8 @@ impl Drive { PathKeyElementSize((key_info_path, key_info, element)) => { match apply_type { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums, .. + in_tree_type: in_tree_using_sums, + .. } => { // Estimate if the element with the given size already exists drive_operations.push(CalculatedCostOperation( diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs index f47ff7052cd..6785633e73e 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs @@ -182,7 +182,7 @@ impl Drive { if let Element::SumItem(new_value, _) = element { match apply_type { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums, .. + in_tree_type, .. } => { // Estimate if the sum item with the given size already exists drive_operations.push(CalculatedCostOperation( @@ -190,7 +190,7 @@ impl Drive { &key_info_path, &key_info, element.serialized_size(&drive_version.grove_version)? as u32, - in_tree_using_sums, + in_tree_type, &drive_version.grove_version, )?, )); diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_or_add_to_if_already_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_or_add_to_if_already_exists/v0/mod.rs index 8294a6786b5..c9abd72a501 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_or_add_to_if_already_exists/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_or_add_to_if_already_exists/v0/mod.rs @@ -178,7 +178,7 @@ impl Drive { if let Element::SumItem(new_value, _) = element { match apply_type { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums, .. + in_tree_type, .. } => { // Estimate if the sum item with the given size already exists drive_operations.push(CalculatedCostOperation( @@ -186,7 +186,7 @@ impl Drive { &key_info_path, &key_info, element.serialized_size(&drive_version.grove_version)? as u32, - in_tree_using_sums, + in_tree_type, &drive_version.grove_version, )?, )); diff --git a/packages/rs-drive/src/util/grove_operations/batch_move_items_in_path_query/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_move_items_in_path_query/v0/mod.rs index f8b2b904cc5..25127f1f66b 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_move_items_in_path_query/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_move_items_in_path_query/v0/mod.rs @@ -89,14 +89,14 @@ impl Drive { }; let delete_operation = match apply_type { BatchMoveApplyType::StatelessBatchMove { - is_sum_tree, + in_tree_type, estimated_key_size, estimated_value_size, .. } => GroveDb::average_case_delete_operation_for_delete::( &KeyInfoPath::from_known_owned_path(path.to_vec()), &KeyInfo::KnownKey(key.to_vec()), - is_sum_tree, + in_tree_type, false, true, 0, @@ -142,7 +142,7 @@ mod tests { util::test_helpers::setup::setup_drive, }; use assert_matches::assert_matches; - use grovedb::{Element, PathQuery, Query, SizedQuery}; + use grovedb::{Element, MaybeTree, PathQuery, Query, SizedQuery}; use grovedb_path::SubtreePath; use platform_version::version::PlatformVersion; @@ -218,7 +218,7 @@ mod tests { // Set up the apply type and drive operations vector let apply_type = BatchMoveApplyType::StatefulBatchMove { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }; let mut drive_operations = Vec::new(); @@ -330,7 +330,7 @@ mod tests { // Set up the apply type and drive operations vector let apply_type = BatchMoveApplyType::StatefulBatchMove { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }; let mut drive_operations = Vec::new(); @@ -433,7 +433,7 @@ mod tests { // Set up the apply type and drive operations vector let apply_type = BatchMoveApplyType::StatefulBatchMove { - is_known_to_be_subtree_with_sum: Some((false, false)), + is_known_to_be_subtree_with_sum: Some(MaybeTree::NotTree), }; let mut drive_operations = Vec::new(); diff --git a/packages/rs-drive/src/util/grove_operations/batch_remove_raw/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_remove_raw/v0/mod.rs index d6ef95dad2c..89902830ef6 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_remove_raw/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_remove_raw/v0/mod.rs @@ -45,9 +45,7 @@ impl Drive { "we should not be seeing internal grovedb operations", ))); } - Some(GroveOp::Delete { .. }) - | Some(GroveOp::DeleteTree { .. }) - | Some(GroveOp::DeleteSumTree { .. }) => false, + Some(GroveOp::Delete { .. }) | Some(GroveOp::DeleteTree { .. }) => false, _ => true, }; @@ -70,7 +68,7 @@ impl Drive { if needs_removal_from_state { let delete_operation = match apply_type { BatchDeleteApplyType::StatelessBatchDelete { - is_sum_tree, + in_tree_type: is_sum_tree, estimated_key_size, estimated_value_size, } => GroveDb::average_case_delete_operation_for_delete::( diff --git a/packages/rs-drive/src/util/grove_operations/grove_get/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get/v0/mod.rs index 9171ff9b9a1..3baac60f013 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get/v0/mod.rs @@ -24,19 +24,19 @@ impl Drive { ) -> Result, Error> { match query_type { QueryType::StatelessQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, estimated_reference_sizes, } => { let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); let key_info = KeyInfo::KnownKey(key.to_vec()); let cost = match query_target { - QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + QueryTarget::QueryTargetTree(flags_size, tree_type) => { GroveDb::average_case_for_get_tree( &key_info_path, &key_info, flags_size, - is_sum_tree, + tree_type, in_tree_using_sums, &drive_version.grove_version, ) diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/v0/mod.rs index fb117ea7a37..59fb0563445 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_optional_sum_tree_total_value/v0/mod.rs @@ -25,18 +25,18 @@ impl Drive { ) -> Result, Error> { match query_type { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, } => { let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); let key_info = KeyInfo::KnownKey(key.to_vec()); let cost = match query_target { - QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + QueryTarget::QueryTargetTree(flags_size, tree_type) => { Ok(GroveDb::average_case_for_get_tree( &key_info_path, &key_info, flags_size, - is_sum_tree, + tree_type, in_tree_using_sums, &drive_version.grove_version, )?) diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw/v0/mod.rs index 4a84959eb1c..0d6778540ce 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw/v0/mod.rs @@ -24,18 +24,18 @@ impl Drive { ) -> Result, Error> { match direct_query_type { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, } => { let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); let key_info = KeyInfo::KnownKey(key.to_vec()); let cost = match query_target { - QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + QueryTarget::QueryTargetTree(flags_size, tree_type) => { GroveDb::average_case_for_get_tree( &key_info_path, &key_info, flags_size, - is_sum_tree, + tree_type, in_tree_using_sums, &drive_version.grove_version, ) diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/v0/mod.rs index 59cdb57e5ec..4f7dc34a369 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_item/v0/mod.rs @@ -26,18 +26,18 @@ impl Drive { ) -> Result, Error> { match direct_query_type { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, } => { let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); let key_info = KeyInfo::KnownKey(key.to_vec()); let cost = match query_target { - QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + QueryTarget::QueryTargetTree(flags_size, tree_type) => { GroveDb::average_case_for_get_tree( &key_info_path, &key_info, flags_size, - is_sum_tree, + tree_type, in_tree_using_sums, &drive_version.grove_version, ) diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional/v0/mod.rs index 9c8f567fa9a..90e2b2b0043 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional/v0/mod.rs @@ -24,18 +24,18 @@ impl Drive { ) -> Result, Error> { match direct_query_type { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, } => { let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); let key_info = KeyInfo::KnownKey(key.to_vec()); let cost = match query_target { - QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + QueryTarget::QueryTargetTree(flags_size, tree_type) => { GroveDb::average_case_for_get_tree( &key_info_path, &key_info, flags_size, - is_sum_tree, + tree_type, in_tree_using_sums, &drive_version.grove_version, ) diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/v0/mod.rs index 4e17e9b0931..3ca57601fda 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_raw_optional_item/v0/mod.rs @@ -26,18 +26,18 @@ impl Drive { ) -> Result>, Error> { match direct_query_type { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, } => { let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); let key_info = KeyInfo::KnownKey(key.to_vec()); let cost = match query_target { - QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + QueryTarget::QueryTargetTree(flags_size, tree_type) => { GroveDb::average_case_for_get_tree( &key_info_path, &key_info, flags_size, - is_sum_tree, + tree_type, in_tree_using_sums, &drive_version.grove_version, ) diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_sum_tree_total_value/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_sum_tree_total_value/v0/mod.rs index 65bd03f3e30..f163c9ac51b 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_get_sum_tree_total_value/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_get_sum_tree_total_value/v0/mod.rs @@ -25,18 +25,18 @@ impl Drive { ) -> Result { match query_type { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, } => { let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); let key_info = KeyInfo::KnownKey(key.to_vec()); let cost = match query_target { - QueryTarget::QueryTargetTree(flags_size, is_sum_tree) => { + QueryTarget::QueryTargetTree(flags_size, tree_type) => { Ok(GroveDb::average_case_for_get_tree( &key_info_path, &key_info, flags_size, - is_sum_tree, + tree_type, in_tree_using_sums, &drive_version.grove_version, )?) diff --git a/packages/rs-drive/src/util/grove_operations/grove_has_raw/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_has_raw/v0/mod.rs index 5b15c0a73c1..f6b57a7c6f6 100644 --- a/packages/rs-drive/src/util/grove_operations/grove_has_raw/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/grove_has_raw/v0/mod.rs @@ -25,18 +25,18 @@ impl Drive { ) -> Result { let CostContext { value, cost } = match query_type { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, } => { let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); let key_info = KeyInfo::KnownKey(key.to_vec()); let cost = match query_target { - QueryTarget::QueryTargetTree(flags_len, is_sum_tree) => { + QueryTarget::QueryTargetTree(flags_len, tree_type) => { GroveDb::average_case_for_has_raw_tree( &key_info_path, &key_info, flags_len, - is_sum_tree, + tree_type, in_tree_using_sums, &drive_version.grove_version, )? diff --git a/packages/rs-drive/src/util/grove_operations/mod.rs b/packages/rs-drive/src/util/grove_operations/mod.rs index ee07d5c1ff4..87818cdc13a 100644 --- a/packages/rs-drive/src/util/grove_operations/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/mod.rs @@ -144,7 +144,7 @@ pub mod grove_get_raw_optional_item; use grovedb_costs::CostContext; -use grovedb::EstimatedLayerInformation; +use grovedb::{EstimatedLayerInformation, MaybeTree, TreeType}; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; @@ -192,7 +192,7 @@ pub enum BatchDeleteApplyType { /// Stateless batch delete StatelessBatchDelete { /// Are we deleting in a sum tree - is_sum_tree: bool, + in_tree_type: TreeType, /// What is the estimated key size estimated_key_size: u32, /// What is the estimated value size @@ -201,7 +201,7 @@ pub enum BatchDeleteApplyType { /// Stateful batch delete StatefulBatchDelete { /// Are we known to be in a subtree and does this subtree have sums - is_known_to_be_subtree_with_sum: Option<(IsSubTree, IsSumSubTree)>, + is_known_to_be_subtree_with_sum: Option, }, } @@ -211,9 +211,9 @@ pub enum BatchMoveApplyType { /// Stateless batch move StatelessBatchMove { /// Are we moving from inside a sum tree - in_tree_using_sums: bool, + in_tree_type: TreeType, /// Are we moving a sum tree - is_sum_tree: bool, + tree_type: TreeType, /// What is the estimated key size estimated_key_size: u32, /// What is the estimated value size @@ -224,7 +224,7 @@ pub enum BatchMoveApplyType { /// Stateful batch move StatefulBatchMove { /// Are we known to be in a subtree and does this subtree have sums - is_known_to_be_subtree_with_sum: Option<(IsSubTree, IsSumSubTree)>, + is_known_to_be_subtree_with_sum: Option, }, } @@ -239,7 +239,7 @@ pub enum BatchDeleteUpTreeApplyType { /// Stateful batch delete StatefulBatchDelete { /// Are we known to be in a subtree and does this subtree have sums - is_known_to_be_subtree_with_sum: Option<(IsSubTree, IsSumSubTree)>, + is_known_to_be_subtree_with_sum: Option, }, } @@ -250,9 +250,9 @@ pub enum BatchInsertTreeApplyType { /// Stateless batch insert tree StatelessBatchInsertTree { /// Does this tree use sums? - in_tree_using_sums: bool, + in_tree_type: TreeType, /// Are we inserting in a sum tree - is_sum_tree: bool, + tree_type: TreeType, /// The flags length flags_len: FlagsLen, }, @@ -272,12 +272,12 @@ impl BatchInsertTreeApplyType { pub(crate) fn to_direct_query_type(self) -> DirectQueryType { match self { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums, - is_sum_tree, + in_tree_type, + tree_type, flags_len, } => DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, - query_target: QueryTarget::QueryTargetTree(flags_len, is_sum_tree), + in_tree_type, + query_target: QueryTarget::QueryTargetTree(flags_len, tree_type), }, BatchInsertTreeApplyType::StatefulBatchInsertTree => { DirectQueryType::StatefulDirectQuery @@ -291,7 +291,7 @@ pub enum BatchInsertApplyType { /// Stateless batch insert StatelessBatchInsert { /// Does this tree use sums? - in_tree_using_sums: bool, + in_tree_type: TreeType, /// the type of Target (Tree or Value) target: QueryTarget, }, @@ -310,10 +310,10 @@ impl BatchInsertApplyType { pub(crate) fn to_direct_query_type(&self) -> DirectQueryType { match self { BatchInsertApplyType::StatelessBatchInsert { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, target, } => DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: *in_tree_using_sums, + in_tree_type: *in_tree_using_sums, query_target: *target, }, BatchInsertApplyType::StatefulBatchInsert => DirectQueryType::StatefulDirectQuery, @@ -329,7 +329,7 @@ pub type FlagsLen = u32; /// Query target pub enum QueryTarget { /// tree - QueryTargetTree(FlagsLen, IsSumTree), + QueryTargetTree(FlagsLen, TreeType), /// value QueryTargetValue(u32), } @@ -338,9 +338,8 @@ impl QueryTarget { /// Length pub(crate) fn len(&self) -> u32 { match self { - QueryTarget::QueryTargetTree(flags_len, is_sum_tree) => { - let len = if *is_sum_tree { 11 } else { 3 }; - *flags_len + len + QueryTarget::QueryTargetTree(flags_len, tree_type) => { + *flags_len + tree_type.inner_node_type().cost() + 3 } QueryTarget::QueryTargetValue(len) => *len, } @@ -354,7 +353,7 @@ pub enum DirectQueryType { /// Stateless direct query StatelessDirectQuery { /// Does this tree use sums? - in_tree_using_sums: bool, + in_tree_type: TreeType, /// the type of Target (Tree or Value) query_target: QueryTarget, }, @@ -366,10 +365,10 @@ impl From for QueryType { fn from(value: DirectQueryType) -> Self { match value { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type, query_target, } => QueryType::StatelessQuery { - in_tree_using_sums, + in_tree_type, query_target, estimated_reference_sizes: vec![], }, @@ -410,10 +409,10 @@ impl DirectQueryType { pub(crate) fn add_reference_sizes(self, reference_sizes: Vec) -> QueryType { match self { DirectQueryType::StatelessDirectQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, } => QueryType::StatelessQuery { - in_tree_using_sums, + in_tree_type: in_tree_using_sums, query_target, estimated_reference_sizes: reference_sizes, }, @@ -428,7 +427,7 @@ pub enum QueryType { /// Stateless query StatelessQuery { /// Does this tree use sums? - in_tree_using_sums: bool, + in_tree_type: TreeType, /// the type of Target (Tree or Value) query_target: QueryTarget, /// The estimated sizes of references @@ -442,11 +441,11 @@ impl From for QueryType { fn from(value: BatchDeleteApplyType) -> Self { match value { BatchDeleteApplyType::StatelessBatchDelete { - is_sum_tree, + in_tree_type: is_sum_tree, estimated_value_size, .. } => QueryType::StatelessQuery { - in_tree_using_sums: is_sum_tree, + in_tree_type: is_sum_tree, query_target: QueryTarget::QueryTargetValue(estimated_value_size), estimated_reference_sizes: vec![], }, @@ -459,11 +458,11 @@ impl From<&BatchDeleteApplyType> for QueryType { fn from(value: &BatchDeleteApplyType) -> Self { match value { BatchDeleteApplyType::StatelessBatchDelete { - is_sum_tree, + in_tree_type: is_sum_tree, estimated_value_size, .. } => QueryType::StatelessQuery { - in_tree_using_sums: *is_sum_tree, + in_tree_type: *is_sum_tree, query_target: QueryTarget::QueryTargetValue(*estimated_value_size), estimated_reference_sizes: vec![], }, @@ -476,11 +475,11 @@ impl From for DirectQueryType { fn from(value: BatchDeleteApplyType) -> Self { match value { BatchDeleteApplyType::StatelessBatchDelete { - is_sum_tree, + in_tree_type: is_sum_tree, estimated_value_size, .. } => DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: is_sum_tree, + in_tree_type: is_sum_tree, query_target: QueryTarget::QueryTargetValue(estimated_value_size), }, BatchDeleteApplyType::StatefulBatchDelete { .. } => { @@ -494,11 +493,11 @@ impl From<&BatchDeleteApplyType> for DirectQueryType { fn from(value: &BatchDeleteApplyType) -> Self { match value { BatchDeleteApplyType::StatelessBatchDelete { - is_sum_tree, + in_tree_type: is_sum_tree, estimated_value_size, .. } => DirectQueryType::StatelessDirectQuery { - in_tree_using_sums: *is_sum_tree, + in_tree_type: *is_sum_tree, query_target: QueryTarget::QueryTargetValue(*estimated_value_size), }, BatchDeleteApplyType::StatefulBatchDelete { .. } => { diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 8e4503817d4..1b2eb985936 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -222,7 +222,7 @@ pub fn setup_family_tests( "tests/supporting_files/contract/family/family-contract.json", None, None, - None, + None::, Some(&db_transaction), Some(platform_version), ); @@ -295,7 +295,7 @@ pub fn setup_family_tests_with_nulls(count: u32, seed: u64) -> (Drive, DataContr "tests/supporting_files/contract/family/family-contract-fields-optional.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -367,7 +367,7 @@ pub fn setup_family_tests_only_first_name_index(count: u32, seed: u64) -> (Drive "tests/supporting_files/contract/family/family-contract-only-first-name-index.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -835,7 +835,7 @@ pub fn setup_dpns_tests_with_batches( "tests/supporting_files/contract/dpns/dpns-contract.json", None, None, - None, + None::, Some(&db_transaction), Some(platform_version), ); @@ -885,7 +885,7 @@ pub fn setup_withdrawal_tests( "tests/supporting_files/contract/withdrawals/withdrawals-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -931,7 +931,7 @@ pub fn setup_references_tests(_count: u32, _seed: u64) -> (Drive, DataContract) "tests/supporting_files/contract/references/references_with_contract_history.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -969,7 +969,7 @@ pub fn setup_dpns_tests_label_not_required(count: u32, seed: u64) -> (Drive, Dat "tests/supporting_files/contract/dpns/dpns-contract-label-not-required.json", None, None, - None, + None::, Some(&db_transaction), None, ); @@ -1007,7 +1007,7 @@ pub fn setup_dpns_test_with_data(path: &str) -> (Drive, DataContract) { "tests/supporting_files/contract/dpns/dpns-contract.json", None, None, - None, + None::, Some(&db_transaction), None, ); diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index 6ea120b342e..c2af5d317e1 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -187,7 +187,7 @@ pub fn setup( "tests/supporting_files/contract/family/family-contract-with-history.json", None, None, - None, + None::, Some(&db_transaction), Some(platform_version), ); diff --git a/packages/rs-platform-version/Cargo.toml b/packages/rs-platform-version/Cargo.toml index a05504d9ecb..6103074b3e3 100644 --- a/packages/rs-platform-version/Cargo.toml +++ b/packages/rs-platform-version/Cargo.toml @@ -11,7 +11,7 @@ license = "MIT" thiserror = { version = "1.0.63" } bincode = { version = "2.0.0-rc.3" } versioned-feature-core = { git = "https://github.com/dashpay/versioned-feature-core", version = "1.0.0" } -grovedb-version = { version = "2.1.0" } +grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20" } once_cell = "1.19.0" [features] diff --git a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs index 2301255352b..c3105e31870 100644 --- a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs @@ -83,7 +83,7 @@ use dpp::consensus::state::identity::no_transfer_key_for_core_withdrawal_availab use dpp::consensus::state::identity::RecipientIdentityDoesNotExistError; use dpp::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_insufficient_error::PrefundedSpecializedBalanceInsufficientError; use dpp::consensus::state::prefunded_specialized_balances::prefunded_specialized_balance_not_found_error::PrefundedSpecializedBalanceNotFoundError; -use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountFrozenError, UnauthorizedTokenActionError}; +use dpp::consensus::state::token::{IdentityDoesNotHaveEnoughTokenBalanceError, IdentityTokenAccountNotFrozenError, IdentityTokenAccountFrozenError, UnauthorizedTokenActionError}; use dpp::consensus::state::voting::masternode_incorrect_voter_identity_id_error::MasternodeIncorrectVoterIdentityIdError; use dpp::consensus::state::voting::masternode_incorrect_voting_address_error::MasternodeIncorrectVotingAddressError; use dpp::consensus::state::voting::masternode_not_found_error::MasternodeNotFoundError; @@ -337,6 +337,9 @@ pub fn from_state_error(state_error: &StateError) -> JsValue { StateError::GroupActionAlreadySignedByIdentityError(e) => { generic_consensus_error!(GroupActionAlreadySignedByIdentityError, e).into() } + StateError::IdentityTokenAccountNotFrozenError(e) => { + generic_consensus_error!(IdentityTokenAccountNotFrozenError, e).into() + } } } From 29dadbfe38c22484c2d07e279c1c69d206ca08a4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 11 Jan 2025 05:14:25 +0700 Subject: [PATCH 52/61] a lot of grovedb support --- Cargo.lock | 18 ++-- packages/rs-dpp/src/balances/credits.rs | 3 + packages/rs-dpp/src/balances/mod.rs | 1 + .../src/balances/total_tokens_balance/mod.rs | 53 +++++++++++ .../batch_transition/v1/v0_methods.rs | 1 + packages/rs-drive-abci/src/config.rs | 8 ++ .../src/execution/platform_events/mod.rs | 1 + .../v0/mod.rs | 33 ++++++- .../execution/platform_events/tokens/mod.rs | 1 + .../validate_token_aggregated_balance/mod.rs | 1 + .../validate_token_aggregated_balance/v0.rs | 46 +++++++++ packages/rs-drive/Cargo.toml | 12 +-- .../v0/mod.rs | 3 + .../insert/add_contract_to_storage/v0/mod.rs | 2 +- .../contract/insert/insert_contract/v1/mod.rs | 27 ++---- .../contract/update/update_contract/v0/mod.rs | 2 +- .../add_document_to_primary_storage/v0/mod.rs | 2 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/mod.rs | 8 +- .../v0/mod.rs | 2 +- .../v0/mod.rs | 2 +- .../v0/mod.rs | 10 +- .../for_add_group_action/v0/mod.rs | 3 + .../group/insert/add_group_action/v0/mod.rs | 2 +- .../group/insert/add_new_groups/v0/mod.rs | 4 +- packages/rs-drive/src/drive/group/mod.rs | 24 ++--- .../merge_identity_contract_nonce/v0/mod.rs | 4 +- .../estimation_costs/for_balances/v0/mod.rs | 3 + .../insert/add_new_identity/v0/mod.rs | 2 +- .../src/drive/initialization/v1/mod.rs | 21 ++++ packages/rs-drive/src/drive/mod.rs | 6 +- .../v0/mod.rs | 3 + .../v0/mod.rs | 3 + .../v0/mod.rs | 3 + .../for_total_system_credits_update/v0/mod.rs | 3 + .../src/drive/tokens/apply_status/v0/mod.rs | 14 ++- .../add_to_previous_token_balance/v0/mod.rs | 1 - .../v0/mod.rs | 1 - .../calculate_total_tokens_balance/mod.rs | 42 ++++++++ .../calculate_total_tokens_balance/v0/mod.rs | 47 +++++++++ .../estimated_costs/for_token_balances/mod.rs | 23 +++-- .../for_token_balances/v0/mod.rs | 61 +++--------- .../for_token_identity_infos/mod.rs | 57 +++++++++++ .../for_token_identity_infos/v0/mod.rs | 81 ++++++++++++++++ .../for_token_status_infos/mod.rs | 57 +++++++++++ .../for_token_status_infos/v0/mod.rs | 69 ++++++++++++++ .../for_token_total_supply/v0/mod.rs | 3 + .../src/drive/tokens/estimated_costs/mod.rs | 9 ++ .../src/drive/tokens/freeze/v0/mod.rs | 3 +- packages/rs-drive/src/drive/tokens/mod.rs | 95 +++++++++++++++---- .../add_to_token_total_supply/v0/mod.rs | 23 +++-- .../tokens/system/create_token_trees/mod.rs | 2 +- .../system/create_token_trees/v0/mod.rs | 67 ++++--------- .../remove_from_token_total_supply/v0/mod.rs | 5 +- .../src/drive/tokens/unfreeze/v0/mod.rs | 3 +- .../v0/mod.rs | 4 +- .../v0/mod.rs | 2 +- packages/rs-drive/src/fees/op.rs | 81 +++++++++++++++- .../mod.rs | 6 +- .../v0/mod.rs | 78 +++++---------- .../mod.rs | 2 +- .../v0/mod.rs | 40 ++++---- .../grove_get_big_sum_tree_total_value/mod.rs | 58 +++++++++++ .../v0/mod.rs | 67 +++++++++++++ .../rs-drive/src/util/grove_operations/mod.rs | 3 + packages/rs-platform-version/Cargo.toml | 2 +- .../drive_grove_method_versions/mod.rs | 1 + .../drive_grove_method_versions/v1.rs | 1 + .../drive_identity_method_versions/mod.rs | 1 + .../drive_identity_method_versions/v1.rs | 1 + .../drive_token_method_versions/mod.rs | 1 + .../drive_token_method_versions/v1.rs | 1 + 74 files changed, 1039 insertions(+), 298 deletions(-) create mode 100644 packages/rs-dpp/src/balances/total_tokens_balance/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/platform_events/tokens/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/mod.rs create mode 100644 packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs create mode 100644 packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/for_token_identity_infos/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/for_token_identity_infos/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/v0/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/grove_get_big_sum_tree_total_value/mod.rs create mode 100644 packages/rs-drive/src/util/grove_operations/grove_get_big_sum_tree_total_value/v0/mod.rs diff --git a/Cargo.lock b/Cargo.lock index c5f11ebd4ea..f0603cd424a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2141,7 +2141,7 @@ dependencies = [ [[package]] name = "grovedb" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" dependencies = [ "axum", "bincode", @@ -2175,7 +2175,7 @@ dependencies = [ [[package]] name = "grovedb-costs" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" dependencies = [ "integer-encoding", "intmap", @@ -2185,7 +2185,7 @@ dependencies = [ [[package]] name = "grovedb-epoch-based-storage-flags" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" dependencies = [ "grovedb-costs", "hex", @@ -2197,7 +2197,7 @@ dependencies = [ [[package]] name = "grovedb-merk" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" dependencies = [ "bincode", "blake3", @@ -2222,12 +2222,12 @@ dependencies = [ [[package]] name = "grovedb-path" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" [[package]] name = "grovedb-storage" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" dependencies = [ "blake3", "grovedb-costs", @@ -2246,7 +2246,7 @@ dependencies = [ [[package]] name = "grovedb-version" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" dependencies = [ "thiserror", "versioned-feature-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2255,7 +2255,7 @@ dependencies = [ [[package]] name = "grovedb-visualize" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" dependencies = [ "hex", "itertools 0.12.1", @@ -2264,7 +2264,7 @@ dependencies = [ [[package]] name = "grovedbg-types" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=2417f7a72900cd3dca943ad52c979bc8abfdaa20#2417f7a72900cd3dca943ad52c979bc8abfdaa20" +source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" dependencies = [ "serde", "serde_with 3.9.0", diff --git a/packages/rs-dpp/src/balances/credits.rs b/packages/rs-dpp/src/balances/credits.rs index 678159d24a3..4376686a967 100644 --- a/packages/rs-dpp/src/balances/credits.rs +++ b/packages/rs-dpp/src/balances/credits.rs @@ -22,6 +22,9 @@ pub type Credits = u64; /// Token Amount type pub type TokenAmount = u64; +/// Sum token amount +pub type SumTokenAmount = i128; + /// Signed Credits type is used for internal computations and total credits /// balance verification diff --git a/packages/rs-dpp/src/balances/mod.rs b/packages/rs-dpp/src/balances/mod.rs index a6b48811208..c0f505ac786 100644 --- a/packages/rs-dpp/src/balances/mod.rs +++ b/packages/rs-dpp/src/balances/mod.rs @@ -1,3 +1,4 @@ pub mod total_credits_balance; pub mod credits; +pub mod total_tokens_balance; diff --git a/packages/rs-dpp/src/balances/total_tokens_balance/mod.rs b/packages/rs-dpp/src/balances/total_tokens_balance/mod.rs new file mode 100644 index 00000000000..84aa157643a --- /dev/null +++ b/packages/rs-dpp/src/balances/total_tokens_balance/mod.rs @@ -0,0 +1,53 @@ +use crate::balances::credits::SumTokenAmount; +use crate::ProtocolError; +use std::fmt; + +/// The outcome of verifying token balances +#[derive(Copy, Clone, Debug)] +pub struct TotalTokensBalance { + /// all the tokens in platform + pub total_tokens_in_platform: SumTokenAmount, + /// all the tokens in identity token balances + pub total_identity_token_balances: SumTokenAmount, +} + +impl fmt::Display for TotalTokensBalance { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "TotalTokensBalance {{")?; + writeln!( + f, + " total_tokens_in_platform: {},", + self.total_tokens_in_platform + )?; + writeln!( + f, + " total_identity_token_balances: {}", + self.total_identity_token_balances + )?; + write!(f, "}}") + } +} +impl TotalTokensBalance { + /// Is the outcome okay? basically do the values match up + /// Errors in case of overflow + pub fn ok(&self) -> Result { + let TotalTokensBalance { + total_tokens_in_platform, + total_identity_token_balances, + } = *self; + + if total_tokens_in_platform < 0 { + return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution( + "Tokens in platform are less than 0".to_string(), + )); + } + + if total_identity_token_balances < 0 { + return Err(ProtocolError::CriticalCorruptedCreditsCodeExecution( + "Tokens in identity balances are less than 0".to_string(), + )); + } + + Ok(total_tokens_in_platform == total_identity_token_balances) + } +} diff --git a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs index b1e12f82f6f..91d9120c443 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/document/batch_transition/v1/v0_methods.rs @@ -60,6 +60,7 @@ use crate::state_transition::batch_transition::token_freeze_transition::TokenFre use crate::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; use crate::state_transition::batch_transition::token_transfer_transition::TokenTransferTransitionV0; use crate::state_transition::batch_transition::token_unfreeze_transition::TokenUnfreezeTransitionV0; +#[cfg(feature = "state-transition-signing")] use crate::tokens::emergency_action::TokenEmergencyAction; impl DocumentsBatchTransitionAccessorsV0 for BatchTransitionV1 { diff --git a/packages/rs-drive-abci/src/config.rs b/packages/rs-drive-abci/src/config.rs index 1e8f5f3c264..e004e14df60 100644 --- a/packages/rs-drive-abci/src/config.rs +++ b/packages/rs-drive-abci/src/config.rs @@ -105,6 +105,10 @@ pub struct ExecutionConfig { #[serde(default = "ExecutionConfig::default_verify_sum_trees")] pub verify_sum_trees: bool, + /// Should we verify sum trees? Useful to set as `false` for tests + #[serde(default = "ExecutionConfig::default_verify_token_sum_trees")] + pub verify_token_sum_trees: bool, + /// How long in seconds should an epoch last /// It might last a lot longer if the chain is halted #[serde( @@ -614,6 +618,10 @@ impl ExecutionConfig { true } + fn default_verify_token_sum_trees() -> bool { + true + } + fn default_use_document_triggers() -> bool { true } diff --git a/packages/rs-drive-abci/src/execution/platform_events/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/mod.rs index 41b64d63b18..759deac244c 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/mod.rs @@ -22,6 +22,7 @@ pub(in crate::execution) mod initialization; pub(in crate::execution) mod protocol_upgrade; /// State transition processing pub(in crate::execution) mod state_transition_processing; +mod tokens; /// Voting pub(in crate::execution) mod voting; /// Withdrawal methods diff --git a/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs index b3d9eae7f67..810e091b318 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs @@ -17,6 +17,9 @@ use drive::drive::identity::withdrawals::paths::{ WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY, }; use drive::drive::system::misc_path; +use drive::drive::tokens::{ + tokens_root_path, TOKEN_BALANCES_KEY, TOKEN_IDENTITY_INFO_KEY, TOKEN_STATUS_INFO_KEY, +}; use drive::drive::RootTree; use drive::grovedb::{Element, Transaction}; use drive::grovedb_path::SubtreePath; @@ -113,11 +116,39 @@ impl Platform { &platform_version.drive, )?; + let path = tokens_root_path(); + self.drive.grove_insert_if_not_exists( + (&path).into(), + &[TOKEN_BALANCES_KEY], + Element::empty_big_sum_tree(), + Some(transaction), + None, + &platform_version.drive, + )?; + + self.drive.grove_insert_if_not_exists( + (&path).into(), + &[TOKEN_IDENTITY_INFO_KEY], + Element::empty_tree(), + Some(transaction), + None, + &platform_version.drive, + )?; + + self.drive.grove_insert_if_not_exists( + (&path).into(), + &[TOKEN_STATUS_INFO_KEY], + Element::empty_tree(), + Some(transaction), + None, + &platform_version.drive, + )?; + let path = misc_path(); self.drive.grove_insert_if_not_exists( (&path).into(), TOTAL_TOKEN_SUPPLIES_STORAGE_KEY.as_slice(), - Element::empty_tree(), + Element::empty_big_sum_tree(), Some(transaction), None, &platform_version.drive, diff --git a/packages/rs-drive-abci/src/execution/platform_events/tokens/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/tokens/mod.rs new file mode 100644 index 00000000000..b3c9f415e5e --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/tokens/mod.rs @@ -0,0 +1 @@ +mod validate_token_aggregated_balance; diff --git a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/mod.rs new file mode 100644 index 00000000000..e084dffc38f --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/mod.rs @@ -0,0 +1 @@ +mod v0; diff --git a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs new file mode 100644 index 00000000000..c1defaa1236 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs @@ -0,0 +1,46 @@ +use dpp::block::epoch::Epoch; +use drive::drive::Drive; +use drive::grovedb::Transaction; + +use crate::error::execution::ExecutionError; +use crate::error::Error; +use crate::execution::types::block_execution_context::BlockExecutionContext; +use crate::platform_types::platform::Platform; +use platform_version::version::PlatformVersion; + +impl Platform { + /// Adds operations to GroveDB op batch related to processing + /// and distributing the block fees from the previous block and applies the batch. + /// + /// Returns `ProcessedBlockFeesOutcome`. + #[inline(always)] + pub(super) fn validate_token_aggregated_balance_v0( + &self, + block_execution_context: &BlockExecutionContext, + transaction: &Transaction, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + if self.config.execution.verify_token_sum_trees { + // Verify sum trees + let credits_verified = self + .drive + .calculate_total_token_balance(Some(transaction), &platform_version.drive) + .map_err(Error::Drive)?; + + if !credits_verified.ok()? { + return Err(Error::Execution( + ExecutionError::CorruptedCreditsNotBalanced(format!( + "credits are not balanced after block execution {:?} off by {}", + credits_verified, + credits_verified + .total_in_trees() + .unwrap() + .abs_diff(credits_verified.total_credits_in_platform) + )), + )); + } + } + + Ok(outcome) + } +} diff --git a/packages/rs-drive/Cargo.toml b/packages/rs-drive/Cargo.toml index cd76d01dce3..2441804b839 100644 --- a/packages/rs-drive/Cargo.toml +++ b/packages/rs-drive/Cargo.toml @@ -52,12 +52,12 @@ enum-map = { version = "2.0.3", optional = true } intmap = { version = "2.0.0", features = ["serde"], optional = true } chrono = { version = "0.4.35", optional = true } itertools = { version = "0.13", optional = true } -grovedb = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20", optional = true, default-features = false } -grovedb-costs = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20", optional = true } -grovedb-path = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20" } -grovedb-storage = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20", optional = true } -grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20" } -grovedb-epoch-based-storage-flags = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20" } +grovedb = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50", optional = true, default-features = false } +grovedb-costs = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50", optional = true } +grovedb-path = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50" } +grovedb-storage = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50", optional = true } +grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50" } +grovedb-epoch-based-storage-flags = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50" } [dev-dependencies] criterion = "0.5" diff --git a/packages/rs-drive/src/drive/asset_lock/estimation_costs/add_estimation_costs_for_adding_asset_lock/v0/mod.rs b/packages/rs-drive/src/drive/asset_lock/estimation_costs/add_estimation_costs_for_adding_asset_lock/v0/mod.rs index 3973d252e8d..1d8cb180eea 100644 --- a/packages/rs-drive/src/drive/asset_lock/estimation_costs/add_estimation_costs_for_adding_asset_lock/v0/mod.rs +++ b/packages/rs-drive/src/drive/asset_lock/estimation_costs/add_estimation_costs_for_adding_asset_lock/v0/mod.rs @@ -67,6 +67,9 @@ impl Drive { 12, // 32 + 1 + 1 / 3 SomeSumTrees { sum_trees_weight: 1, + big_sum_trees_weight: 0, + count_trees_weight: 0, + count_sum_trees_weight: 0, non_sum_trees_weight: 2, }, None, diff --git a/packages/rs-drive/src/drive/contract/insert/add_contract_to_storage/v0/mod.rs b/packages/rs-drive/src/drive/contract/insert/add_contract_to_storage/v0/mod.rs index 837d1fcbcc9..07e33e9be1f 100644 --- a/packages/rs-drive/src/drive/contract/insert/add_contract_to_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/add_contract_to_storage/v0/mod.rs @@ -79,7 +79,7 @@ impl Drive { self.batch_insert_empty_tree_if_not_exists( key_info, - false, + TreeType::NormalTree, storage_flags.as_ref().map(|flags| flags.as_ref()), apply_type, transaction, diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs index 9d5c2536108..69f9dfe2ba7 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs @@ -11,8 +11,7 @@ use dpp::fee::fee_result::FeeResult; use crate::drive::balances::total_tokens_root_supply_path_vec; use crate::drive::tokens::{ - token_balances_path_vec, token_path, tokens_root_path, TOKEN_BALANCES_KEY, - TOKEN_IDENTITY_INFO_KEY, + token_balances_path_vec, token_balances_root_path, token_identity_infos_root_path, }; use crate::error::contract::DataContractError; use crate::util::object_size_info::DriveKeyInfo; @@ -23,9 +22,8 @@ use dpp::serialization::PlatformSerializableWithPlatformVersion; use dpp::version::PlatformVersion; use dpp::ProtocolError; use grovedb::batch::KeyInfoPath; -use grovedb::Element::Item; +use grovedb::Element::SumItem; use grovedb::{Element, EstimatedLayerInformation, TransactionArg}; -use integer_encoding::VarInt; use std::collections::HashMap; impl Drive { @@ -186,7 +184,6 @@ impl Drive { { Drive::add_estimation_costs_for_token_balances( token_id_bytes, - false, estimated_costs_only_with_layer_info, &platform_version.drive, )?; @@ -196,25 +193,17 @@ impl Drive { )?; } - self.batch_insert_empty_tree( - tokens_root_path(), - DriveKeyInfo::KeyRef(&token_id_bytes), - None, - &mut batch_operations, - &platform_version.drive, - )?; - self.batch_insert_empty_sum_tree( - token_path(&token_id_bytes), - DriveKeyInfo::Key(vec![TOKEN_BALANCES_KEY]), + token_balances_root_path(), + DriveKeyInfo::KeyRef(token_id_bytes.as_slice()), None, &mut batch_operations, &platform_version.drive, )?; self.batch_insert_empty_tree( - token_path(&token_id_bytes), - DriveKeyInfo::Key(vec![TOKEN_IDENTITY_INFO_KEY]), + token_identity_infos_root_path(), + DriveKeyInfo::KeyRef(token_id_bytes.as_slice()), None, &mut batch_operations, &platform_version.drive, @@ -251,7 +240,7 @@ impl Drive { PathKeyElement(( path_holding_total_token_supply, token_id.to_vec(), - Item(token_config.base_supply().encode_var_vec(), None), + Element::new_sum_item(token_config.base_supply() as i64), )), &mut batch_operations, &platform_version.drive, @@ -261,7 +250,7 @@ impl Drive { PathKeyElement(( path_holding_total_token_supply, token_id.to_vec(), - Item(0u64.encode_var_vec(), None), + SumItem(0, None), )), &mut batch_operations, &platform_version.drive, diff --git a/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs b/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs index 22ce029f82c..141749a2ffb 100644 --- a/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs +++ b/packages/rs-drive/src/drive/contract/update/update_contract/v0/mod.rs @@ -317,7 +317,7 @@ impl Drive { if !index_cache.contains(index_bytes) { self.batch_insert_empty_tree_if_not_exists( PathFixedSizeKeyRef((type_path, index.name.as_bytes())), - false, + TreeType::NormalTree, storage_flags.as_ref().map(|flags| flags.as_ref()), apply_type, transaction, diff --git a/packages/rs-drive/src/drive/document/insert/add_document_to_primary_storage/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_document_to_primary_storage/v0/mod.rs index c26d1b944cc..ea1ae0f2a7c 100644 --- a/packages/rs-drive/src/drive/document/insert/add_document_to_primary_storage/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_document_to_primary_storage/v0/mod.rs @@ -135,7 +135,7 @@ impl Drive { // we first insert an empty tree if the document is new self.batch_insert_empty_tree_if_not_exists( path_key_info, - false, + TreeType::NormalTree, storage_flags, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v0/mod.rs index 6b4932e1865..0bfcf82e67f 100644 --- a/packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_indices_for_index_level_for_contract_operations/v0/mod.rs @@ -109,7 +109,7 @@ impl Drive { // here we are inserting an empty tree that will have a subtree of all other index properties self.batch_insert_empty_tree_if_not_exists( path_key_info.clone(), - false, + TreeType::NormalTree, *storage_flags, apply_type, transaction, @@ -157,7 +157,7 @@ impl Drive { // here we are inserting an empty tree that will have a subtree of all other index properties self.batch_insert_empty_tree_if_not_exists( path_key_info.clone(), - false, + TreeType::NormalTree, *storage_flags, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v0/mod.rs index 320a4625af5..4ca3e7662d8 100644 --- a/packages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_indices_for_top_index_level_for_contract_operations/v0/mod.rs @@ -120,7 +120,7 @@ impl Drive { // here we are inserting an empty tree that will have a subtree of all other index properties self.batch_insert_empty_tree_if_not_exists( path_key_info.clone(), - false, + TreeType::NormalTree, storage_flags, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs index c84ab415615..c3744cbcdcb 100644 --- a/packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert/add_reference_for_index_level_for_contract_operations/v0/mod.rs @@ -75,7 +75,7 @@ impl Drive { // a contested resource index self.batch_insert_empty_tree_if_not_exists( path_key_info, - false, + TreeType::NormalTree, *storage_flags, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_contract_operations/v0/mod.rs index 43433cb6e70..52297150a0f 100644 --- a/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert_contested/add_contested_indices_for_contract_operations/v0/mod.rs @@ -153,7 +153,7 @@ impl Drive { document_top_field .clone() .add_path_info(index_path_info.clone()), - false, + TreeType::NormalTree, storage_flags, apply_type, transaction, @@ -200,7 +200,7 @@ impl Drive { self.batch_insert_empty_tree_if_not_exists( DriveKeyInfo::Key(owner_id.to_vec()).add_path_info(index_path_info.clone()), - false, + TreeType::NormalTree, storage_flags, apply_type, transaction, @@ -212,7 +212,7 @@ impl Drive { let inserted_abstain = self.batch_insert_empty_tree_if_not_exists( DriveKeyInfo::Key(RESOURCE_ABSTAIN_VOTE_TREE_KEY_U8_32.to_vec()) .add_path_info(index_path_info.clone()), - false, + TreeType::NormalTree, storage_flags, apply_type, transaction, @@ -224,7 +224,7 @@ impl Drive { let inserted_lock = self.batch_insert_empty_tree_if_not_exists( DriveKeyInfo::Key(RESOURCE_LOCK_VOTE_TREE_KEY_U8_32.to_vec()) .add_path_info(index_path_info.clone()), - false, + TreeType::NormalTree, storage_flags, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/document/insert_contested/add_contested_reference_and_vote_subtree_to_document_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert_contested/add_contested_reference_and_vote_subtree_to_document_operations/v0/mod.rs index 4370b1811d3..cd4fa6ecd11 100644 --- a/packages/rs-drive/src/drive/document/insert_contested/add_contested_reference_and_vote_subtree_to_document_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert_contested/add_contested_reference_and_vote_subtree_to_document_operations/v0/mod.rs @@ -166,7 +166,7 @@ impl Drive { // here we are the tree that will contain the voting tree let inserted = self.batch_insert_empty_tree_if_not_exists( votes_path_key_info, - true, + TreeType::SumTree, storage_flags, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/document/insert_contested/add_contested_vote_subtrees_for_non_identities_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/insert_contested/add_contested_vote_subtrees_for_non_identities_operations/v0/mod.rs index a23851323de..c6d8faedcbb 100644 --- a/packages/rs-drive/src/drive/document/insert_contested/add_contested_vote_subtrees_for_non_identities_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/insert_contested/add_contested_vote_subtrees_for_non_identities_operations/v0/mod.rs @@ -93,7 +93,7 @@ impl Drive { // here we are the tree that will contain the voting tree let inserted = self.batch_insert_empty_tree_if_not_exists( votes_path_key_info.clone(), - true, + TreeType::SumTree, storage_flags, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs b/packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs index eb982b4f3c3..5a6a14e759e 100644 --- a/packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/document/update/internal/update_document_for_contract_operations/v0/mod.rs @@ -34,7 +34,7 @@ use dpp::version::PlatformVersion; use grovedb::batch::key_info::KeyInfo; use grovedb::batch::key_info::KeyInfo::KnownKey; use grovedb::batch::KeyInfoPath; -use grovedb::{Element, EstimatedLayerInformation, MaybeTree, TransactionArg}; +use grovedb::{Element, EstimatedLayerInformation, MaybeTree, TransactionArg, TreeType}; use std::borrow::Cow; use std::collections::{HashMap, HashSet}; @@ -227,7 +227,7 @@ impl Drive { index_path.clone(), document_top_field.as_slice(), )), - false, + TreeType::NormalTree, storage_flags, BatchInsertTreeApplyType::StatefulBatchInsertTree, transaction, @@ -300,7 +300,7 @@ impl Drive { index_path.clone(), index_property.name.as_bytes(), )), - false, + TreeType::NormalTree, storage_flags, BatchInsertTreeApplyType::StatefulBatchInsertTree, transaction, @@ -332,7 +332,7 @@ impl Drive { index_path.clone(), document_index_field.as_slice(), )), - false, + TreeType::NormalTree, storage_flags, BatchInsertTreeApplyType::StatefulBatchInsertTree, transaction, @@ -409,7 +409,7 @@ impl Drive { // here we are inserting an empty tree that will have a subtree of all other index properties self.batch_insert_empty_tree_if_not_exists( PathKeyInfo::PathKeyRef::<0>((index_path.clone(), &[0])), - false, + TreeType::NormalTree, storage_flags, BatchInsertTreeApplyType::StatefulBatchInsertTree, transaction, diff --git a/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs index 1133447945b..00829a54679 100644 --- a/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/estimated_costs/for_add_group_action/v0/mod.rs @@ -85,6 +85,9 @@ impl Drive { 1, SomeSumTrees { sum_trees_weight: 1, + big_sum_trees_weight: 0, + count_trees_weight: 0, + count_sum_trees_weight: 0, non_sum_trees_weight: 2, }, None, diff --git a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs index a0d8ce1dd97..2bb92154586 100644 --- a/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_group_action/v0/mod.rs @@ -160,7 +160,7 @@ impl Drive { // We insert the contract root into the group tree inserted_root_action = self.batch_insert_empty_tree_if_not_exists( PathFixedSizeKeyRef((group_action_root_path, action_id.as_slice())), - false, + TreeType::NormalTree, None, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs index bde785e07c0..2064aecb6d9 100644 --- a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs @@ -110,7 +110,7 @@ impl Drive { // We insert the contract root into the group tree let inserted = self.batch_insert_empty_tree_if_not_exists( PathFixedSizeKey((group_tree_path, contract_id.to_vec())), - false, + TreeType::NormalTree, None, apply_type, transaction, @@ -158,7 +158,7 @@ impl Drive { let path = group_contract_path(contract_id.as_slice()); let inserted = self.batch_insert_empty_tree_if_not_exists( PathFixedSizeKeyRef((path, group_pos_bytes.as_slice())), - false, + TreeType::NormalTree, None, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/group/mod.rs b/packages/rs-drive/src/drive/group/mod.rs index d283c314a97..b6f530ccd81 100644 --- a/packages/rs-drive/src/drive/group/mod.rs +++ b/packages/rs-drive/src/drive/group/mod.rs @@ -19,31 +19,31 @@ pub const ACTION_SIGNERS_KEY: &[u8; 1] = b"S"; /// Group root path #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_root_path() -> [&'static [u8]; 1] { +pub fn group_root_path() -> [&'static [u8]; 1] { [Into::<&[u8; 1]>::into(RootTree::GroupActions)] } /// Group root path vector #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_root_path_vec() -> Vec> { +pub fn group_root_path_vec() -> Vec> { vec![vec![RootTree::GroupActions as u8]] } /// Group path #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_contract_path(contract_id: &[u8]) -> [&[u8]; 2] { +pub fn group_contract_path(contract_id: &[u8]) -> [&[u8]; 2] { [Into::<&[u8; 1]>::into(RootTree::GroupActions), contract_id] } /// Group path vector #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_contract_path_vec(contract_id: &[u8]) -> Vec> { +pub fn group_contract_path_vec(contract_id: &[u8]) -> Vec> { vec![vec![RootTree::GroupActions as u8], contract_id.to_vec()] } /// Group path #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_path<'a>( +pub fn group_path<'a>( contract_id: &'a [u8], group_contract_position_bytes: &'a [u8], ) -> [&'a [u8]; 3] { @@ -56,7 +56,7 @@ pub(crate) fn group_path<'a>( /// Group path vector #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_path_vec( +pub fn group_path_vec( contract_id: &[u8], group_contract_position: GroupContractPosition, ) -> Vec> { @@ -69,7 +69,7 @@ pub(crate) fn group_path_vec( /// Group action path #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_action_root_path<'a>( +pub fn group_action_root_path<'a>( contract_id: &'a [u8], group_contract_position_bytes: &'a [u8], ) -> [&'a [u8]; 4] { @@ -83,7 +83,7 @@ pub(crate) fn group_action_root_path<'a>( /// Group action path vector #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_action_root_path_vec( +pub fn group_action_root_path_vec( contract_id: &[u8], group_contract_position: GroupContractPosition, ) -> Vec> { @@ -97,7 +97,7 @@ pub(crate) fn group_action_root_path_vec( /// Group path #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_action_path<'a>( +pub fn group_action_path<'a>( contract_id: &'a [u8], group_contract_position_bytes: &'a [u8], action_id: &'a [u8], @@ -113,7 +113,7 @@ pub(crate) fn group_action_path<'a>( /// Group path vector #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_action_path_vec( +pub fn group_action_path_vec( contract_id: &[u8], group_contract_position: GroupContractPosition, action_id: &[u8], @@ -129,7 +129,7 @@ pub(crate) fn group_action_path_vec( /// Group path #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_action_signers_path<'a>( +pub fn group_action_signers_path<'a>( contract_id: &'a [u8], group_contract_position_bytes: &'a [u8], action_id: &'a [u8], @@ -146,7 +146,7 @@ pub(crate) fn group_action_signers_path<'a>( /// Group path vector #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn group_action_signers_path_vec( +pub fn group_action_signers_path_vec( contract_id: &[u8], group_contract_position: GroupContractPosition, action_id: &[u8], diff --git a/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs b/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs index be3b7075665..500e9ba394e 100644 --- a/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs @@ -119,7 +119,7 @@ impl Drive { // we insert the contract root tree if it doesn't exist already self.batch_insert_empty_tree_if_not_exists( PathKeyInfo::<0>::PathKey((identity_path, vec![IdentityContractInfo as u8])), - false, + TreeType::NormalTree, None, apply_type, transaction, @@ -134,7 +134,7 @@ impl Drive { identity_contract_info_root_path_vec(&identity_id), contract_id.to_vec(), )), - false, + TreeType::NormalTree, None, apply_type, transaction, diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_balances/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_balances/v0/mod.rs index 59696e6aac5..db78d1fff31 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_balances/v0/mod.rs @@ -62,6 +62,9 @@ impl Drive { 1, SomeSumTrees { sum_trees_weight: 1, + big_sum_trees_weight: 0, + count_trees_weight: 0, + count_sum_trees_weight: 0, non_sum_trees_weight: 1, }, None, diff --git a/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs b/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs index 83146f7a86c..26055d92799 100644 --- a/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/insert/add_new_identity/v0/mod.rs @@ -131,7 +131,7 @@ impl Drive { // We insert the identity tree let inserted = self.batch_insert_empty_tree_if_not_exists( PathFixedSizeKey((identity_tree_path, id.to_vec())), - false, + TreeType::NormalTree, Some(&storage_flags), apply_type, transaction, diff --git a/packages/rs-drive/src/drive/initialization/v1/mod.rs b/packages/rs-drive/src/drive/initialization/v1/mod.rs index 4fbf480d0bc..ba85cc27746 100644 --- a/packages/rs-drive/src/drive/initialization/v1/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v1/mod.rs @@ -4,6 +4,9 @@ use crate::drive::balances::TOTAL_TOKEN_SUPPLIES_STORAGE_KEY; use crate::util::batch::GroveDbOpBatch; use crate::drive::system::misc_path_vec; +use crate::drive::tokens::{ + tokens_root_path_vec, TOKEN_BALANCES_KEY, TOKEN_IDENTITY_INFO_KEY, TOKEN_STATUS_INFO_KEY, +}; use crate::drive::{Drive, RootTree}; use crate::error::Error; use crate::util::batch::grovedb_op_batch::GroveDbOpBatchV0Methods; @@ -55,6 +58,24 @@ impl Drive { Element::empty_tree(), ); + batch.add_insert( + tokens_root_path_vec(), + vec![TOKEN_BALANCES_KEY], + Element::empty_big_sum_tree(), + ); + + batch.add_insert( + tokens_root_path_vec(), + vec![TOKEN_IDENTITY_INFO_KEY], + Element::empty_tree(), + ); + + batch.add_insert( + tokens_root_path_vec(), + vec![TOKEN_STATUS_INFO_KEY], + Element::empty_tree(), + ); + Ok(()) } } diff --git a/packages/rs-drive/src/drive/mod.rs b/packages/rs-drive/src/drive/mod.rs index 1f8a8f8dc58..4f71c6346f5 100644 --- a/packages/rs-drive/src/drive/mod.rs +++ b/packages/rs-drive/src/drive/mod.rs @@ -49,10 +49,14 @@ pub(crate) mod prefunded_specialized_balances; pub mod votes; /// Group module +#[cfg(any(feature = "server", feature = "verify"))] pub mod group; #[cfg(feature = "server")] mod shared; -mod tokens; + +/// Token module +#[cfg(any(feature = "server", feature = "verify"))] +pub mod tokens; #[cfg(feature = "server")] use crate::cache::DriveCache; diff --git a/packages/rs-drive/src/drive/prefunded_specialized_balances/estimation_costs/for_prefunded_specialized_balance_update/v0/mod.rs b/packages/rs-drive/src/drive/prefunded_specialized_balances/estimation_costs/for_prefunded_specialized_balance_update/v0/mod.rs index 64cdef76917..5e7925cf1d7 100644 --- a/packages/rs-drive/src/drive/prefunded_specialized_balances/estimation_costs/for_prefunded_specialized_balance_update/v0/mod.rs +++ b/packages/rs-drive/src/drive/prefunded_specialized_balances/estimation_costs/for_prefunded_specialized_balance_update/v0/mod.rs @@ -35,6 +35,9 @@ impl Drive { 1, SomeSumTrees { sum_trees_weight: 1, + big_sum_trees_weight: 0, + count_trees_weight: 0, + count_sum_trees_weight: 0, non_sum_trees_weight: 1, }, None, diff --git a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract/v0/mod.rs b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract/v0/mod.rs index 3b3969df79c..32d25eae456 100644 --- a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract/v0/mod.rs +++ b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract/v0/mod.rs @@ -65,6 +65,9 @@ impl Drive { 1, SomeSumTrees { sum_trees_weight: 1, + big_sum_trees_weight: 0, + count_trees_weight: 0, + count_sum_trees_weight: 0, non_sum_trees_weight: 2, }, None, diff --git a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded/v0/mod.rs b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded/v0/mod.rs index 0559137ade7..aff3c4d5fc2 100644 --- a/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded/v0/mod.rs +++ b/packages/rs-drive/src/drive/shared/shared_estimation_costs/add_estimation_costs_for_contested_document_tree_levels_up_to_contract_document_type_excluded/v0/mod.rs @@ -56,6 +56,9 @@ impl Drive { 1, SomeSumTrees { sum_trees_weight: 1, + big_sum_trees_weight: 0, + count_trees_weight: 0, + count_sum_trees_weight: 0, non_sum_trees_weight: 2, }, None, diff --git a/packages/rs-drive/src/drive/system/estimation_costs/for_total_system_credits_update/v0/mod.rs b/packages/rs-drive/src/drive/system/estimation_costs/for_total_system_credits_update/v0/mod.rs index 98aaed604c0..40f013d0104 100644 --- a/packages/rs-drive/src/drive/system/estimation_costs/for_total_system_credits_update/v0/mod.rs +++ b/packages/rs-drive/src/drive/system/estimation_costs/for_total_system_credits_update/v0/mod.rs @@ -39,6 +39,9 @@ impl Drive { 12, // about 32 + 1 + 1 / 3 SomeSumTrees { sum_trees_weight: 1, + big_sum_trees_weight: 0, + count_trees_weight: 0, + count_sum_trees_weight: 0, non_sum_trees_weight: 2, }, None, diff --git a/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs b/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs index 6b2e229d3ea..d7efeb25e47 100644 --- a/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs @@ -1,4 +1,4 @@ -use crate::drive::tokens::{token_path, TOKEN_IDENTITY_INFO_KEY}; +use crate::drive::tokens::token_statuses_root_path; use crate::drive::Drive; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; @@ -85,10 +85,18 @@ impl Drive { let token_status_bytes = status.serialize_consume_to_bytes()?; + if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { + Self::add_estimation_costs_for_token_status_infos( + token_id, + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; + } + self.batch_insert( PathKeyElementInfo::PathFixedSizeKeyRefElement::<2>(( - token_path(&token_id), - &[TOKEN_IDENTITY_INFO_KEY], + token_statuses_root_path(), + token_id.as_slice(), Element::Item(token_status_bytes, None), )), &mut drive_operations, diff --git a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs index 5d3a0ebac7e..4b81e534d46 100644 --- a/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/add_to_previous_token_balance/v0/mod.rs @@ -84,7 +84,6 @@ impl Drive { if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { Self::add_estimation_costs_for_token_balances( token_id, - false, estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs index 4367a872a80..d6428c10b2f 100644 --- a/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/remove_from_identity_token_balance/v0/mod.rs @@ -82,7 +82,6 @@ impl Drive { if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { Self::add_estimation_costs_for_token_balances( token_id, - false, estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/mod.rs b/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/mod.rs new file mode 100644 index 00000000000..8799421a9db --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/mod.rs @@ -0,0 +1,42 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use dpp::balances::total_tokens_balance::TotalTokensBalance; +use dpp::version::drive_versions::DriveVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Calculates the total credits balance. + /// + /// This function verifies that the sum tree identity credits + pool credits + refunds are equal to the total credits in the system. + /// + /// # Arguments + /// + /// * `transaction` - A `TransactionArg` object representing the transaction to be used for calculating the total credits balance. + /// * `drive_version` - A `DriveVersion` object specifying the version of the Drive. + /// + /// # Returns + /// + /// * `Result` - If successful, returns a `TotalTokensBalance` object representing the total tokens balance. + /// If an error occurs during the calculation, returns an `Error`. + /// + /// # Errors + /// + /// This function will return an error if the version of the Drive is unknown. + pub fn calculate_total_tokens_balance( + &self, + transaction: TransactionArg, + drive_version: &DriveVersion, + ) -> Result { + match drive_version.methods.token.calculate_total_tokens_balance { + 0 => self.calculate_total_tokens_balance_v0(transaction, drive_version), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "calculate_total_tokens_balance".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs new file mode 100644 index 00000000000..6f312692557 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs @@ -0,0 +1,47 @@ +use crate::drive::balances::TOTAL_TOKEN_SUPPLIES_STORAGE_KEY; +use crate::drive::system::misc_path; +use crate::drive::tokens::token_balances_root_path; +use crate::drive::{Drive, RootTree}; +use crate::error::Error; +use crate::util::grove_operations::DirectQueryType; +use dpp::balances::total_tokens_balance::TotalTokensBalance; +use dpp::version::drive_versions::DriveVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Verify that the sum tree identity credits + pool credits + refunds are equal to the + /// Total credits in the system + #[inline(always)] + pub(super) fn calculate_total_tokens_balance_v0( + &self, + transaction: TransactionArg, + drive_version: &DriveVersion, + ) -> Result { + let mut drive_operations = vec![]; + let path_holding_total_credits = misc_path(); + let total_tokens_in_platform = self.grove_get_big_sum_tree_total_value( + (&path_holding_total_credits).into(), + TOTAL_TOKEN_SUPPLIES_STORAGE_KEY, + DirectQueryType::StatefulDirectQuery, + transaction, + &mut drive_operations, + drive_version, + )?; + + let tokens_balances_path = token_balances_root_path(); + + let total_identity_token_balances = self.grove_get_big_sum_tree_total_value( + (&tokens_balances_path).into(), + Into::<&[u8; 1]>::into(RootTree::Balances), + DirectQueryType::StatefulDirectQuery, + transaction, + &mut drive_operations, + drive_version, + )?; + + Ok(TotalTokensBalance { + total_tokens_in_platform, + total_identity_token_balances, + }) + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs index d4eb0bff2ed..fcce3e3dff7 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/mod.rs @@ -9,24 +9,28 @@ use grovedb::EstimatedLayerInformation; use std::collections::HashMap; impl Drive { - /// Adds estimation costs for token balance changes. + /// Adds estimation costs for token balance changes based on the provided drive version. /// - /// It operates on the provided HashMap, `estimated_costs_only_with_layer_info`, and adds - /// new entries to it, representing the estimated costs for different layers of the balance tree. + /// This method updates the `estimated_costs_only_with_layer_info` HashMap with entries + /// representing the estimated costs for different layers of the balance tree. The method + /// adjusts its behavior depending on the provided `drive_version`, allowing it to support + /// different versioned implementations for cost estimation. /// /// # Parameters - /// - `estimated_costs_only_with_layer_info`: A mutable reference to a HashMap storing - /// the `KeyInfoPath` and `EstimatedLayerInformation`. + /// - `token_id`: A 32-byte identifier for the token whose balance changes are being estimated. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to a HashMap that holds + /// `KeyInfoPath` and `EstimatedLayerInformation` for each token balance layer. + /// - `drive_version`: The version of the drive to determine which estimation logic to apply. /// /// # Returns - /// - `Ok(())` if successful. - /// - `Err(DriveError::UnknownVersionMismatch)` if the method version doesn't match any known versions. + /// - `Ok(())` if the operation is successful. + /// - `Err(DriveError::UnknownVersionMismatch)` if the provided `drive_version` does not match + /// any known supported versions. /// /// # Errors - /// This function will return an error if the method version doesn't match any known versions. + /// This function will return an error if the provided `drive_version` does not match a known version. pub(crate) fn add_estimation_costs_for_token_balances( token_id: [u8; 32], - with_info_tree: bool, estimated_costs_only_with_layer_info: &mut HashMap, drive_version: &DriveVersion, ) -> Result<(), Error> { @@ -39,7 +43,6 @@ impl Drive { 0 => { Self::add_estimation_costs_for_token_balances_v0( token_id, - with_info_tree, estimated_costs_only_with_layer_info, ); Ok(()) diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs index 2400e5de715..cf9611d800c 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_balances/v0/mod.rs @@ -7,11 +7,9 @@ use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; use grovedb::{EstimatedLayerInformation, TreeType}; -use crate::drive::tokens::{ - token_balances_path, token_identity_infos_path, token_path, tokens_root_path, -}; +use crate::drive::tokens::{token_balances_path, token_balances_root_path, tokens_root_path}; use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; -use grovedb::EstimatedSumTrees::{AllSumTrees, NoSumTrees, SomeSumTrees}; +use grovedb::EstimatedSumTrees::{AllBigSumTrees, AllSumTrees, NoSumTrees}; use std::collections::HashMap; pub const ESTIMATED_TOKEN_INFO_SIZE_BYTES: u32 = 256; @@ -52,7 +50,6 @@ impl Drive { /// ``` pub(super) fn add_estimation_costs_for_token_balances_v0( token_id: [u8; 32], - with_info_tree: bool, estimated_costs_only_with_layer_info: &mut HashMap, ) { // we have constructed the top layer so contract/documents tree are at the top @@ -76,53 +73,19 @@ impl Drive { KeyInfoPath::from_known_path(tokens_root_path()), EstimatedLayerInformation { tree_type: TreeType::NormalTree, - estimated_layer_count: EstimatedLevel(10, false), // We estimate that on average we need to update 10 nodes - estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), + estimated_layer_count: EstimatedLevel(0, false), // this should be at the top + estimated_layer_sizes: AllSubtrees(1, AllBigSumTrees, None), }, ); - if with_info_tree { - estimated_costs_only_with_layer_info.insert( - KeyInfoPath::from_known_path(token_path(&token_id)), - EstimatedLayerInformation { - tree_type: TreeType::NormalTree, - estimated_layer_count: EstimatedLevel(1, false), - estimated_layer_sizes: AllSubtrees( - 1, - SomeSumTrees { - sum_trees_weight: 1, - non_sum_trees_weight: 1, - }, - None, - ), - }, - ); - } else { - estimated_costs_only_with_layer_info.insert( - KeyInfoPath::from_known_path(token_path(&token_id)), - EstimatedLayerInformation { - tree_type: TreeType::NormalTree, - estimated_layer_count: EstimatedLevel(0, false), - estimated_layer_sizes: AllSubtrees(1, AllSumTrees, None), - }, - ); - } - - if with_info_tree { - // there is one tree for the root path - estimated_costs_only_with_layer_info.insert( - KeyInfoPath::from_known_path(token_identity_infos_path(&token_id)), - EstimatedLayerInformation { - tree_type: TreeType::NormalTree, - estimated_layer_count: PotentiallyAtMaxElements, - estimated_layer_sizes: AllItems( - DEFAULT_HASH_SIZE_U8, - ESTIMATED_TOKEN_INFO_SIZE_BYTES, - None, - ), - }, - ); - } + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(token_balances_root_path()), + EstimatedLayerInformation { + tree_type: TreeType::BigSumTree, + estimated_layer_count: EstimatedLevel(10, false), // we can estimate 10 levels deep + estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, AllSumTrees, None), + }, + ); // this is where the balances are estimated_costs_only_with_layer_info.insert( diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_identity_infos/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_identity_infos/mod.rs new file mode 100644 index 00000000000..a5225fa37be --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_identity_infos/mod.rs @@ -0,0 +1,57 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use dpp::version::drive_versions::DriveVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerInformation; +use std::collections::HashMap; + +impl Drive { + /// Adds estimation costs for token identity infos changes based on the provided drive version. + /// + /// This method updates the `estimated_costs_only_with_layer_info` HashMap with entries + /// representing the estimated costs for different layers of the balance tree. The method + /// adjusts its behavior depending on the provided `drive_version`, allowing it to support + /// different versioned implementations for cost estimation. + /// + /// # Parameters + /// - `token_id`: A 32-byte identifier for the token whose balance changes are being estimated. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to a HashMap that holds + /// `KeyInfoPath` and `EstimatedLayerInformation` for each token balance layer. + /// - `drive_version`: The version of the drive to determine which estimation logic to apply. + /// + /// # Returns + /// - `Ok(())` if the operation is successful. + /// - `Err(DriveError::UnknownVersionMismatch)` if the provided `drive_version` does not match + /// any known supported versions. + /// + /// # Errors + /// This function will return an error if the provided `drive_version` does not match a known version. + pub(crate) fn add_estimation_costs_for_token_identity_infos( + token_id: [u8; 32], + estimated_costs_only_with_layer_info: &mut HashMap, + drive_version: &DriveVersion, + ) -> Result<(), Error> { + match drive_version + .methods + .identity + .cost_estimation + .for_token_identity_infos + { + 0 => { + Self::add_estimation_costs_for_token_identity_infos_v0( + token_id, + estimated_costs_only_with_layer_info, + ); + Ok(()) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_estimation_costs_for_token_identity_infos".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_identity_infos/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_identity_infos/v0/mod.rs new file mode 100644 index 00000000000..70b2caae362 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_identity_infos/v0/mod.rs @@ -0,0 +1,81 @@ +use crate::drive::Drive; + +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerCount::{EstimatedLevel, PotentiallyAtMaxElements}; +use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; + +use crate::drive::tokens::{ + token_identity_infos_path, token_identity_infos_root_path, tokens_root_path, +}; +use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; +use grovedb::EstimatedSumTrees::{NoSumTrees, SomeSumTrees}; +use std::collections::HashMap; + +pub const ESTIMATED_TOKEN_INFO_SIZE_BYTES: u32 = 32; + +impl Drive { + pub(super) fn add_estimation_costs_for_token_identity_infos_v0( + token_id: [u8; 32], + estimated_costs_only_with_layer_info: &mut HashMap, + ) { + // we have constructed the top layer so contract/documents tree are at the top + // since balance will be on layer 3 (level 2 on left then left) + // updating will mean we will update: + // 1 normal tree (token balances) + // 1 normal tree (identities) + // 1 normal tree (contract/documents) + // hence we should give an equal weight to both + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path([]), + EstimatedLayerInformation { + tree_type: TreeType::NormalTree, + estimated_layer_count: EstimatedLevel(2, false), + estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), + }, + ); + + // there is one tree for the root path + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(tokens_root_path()), + EstimatedLayerInformation { + tree_type: TreeType::NormalTree, + estimated_layer_count: EstimatedLevel(1, false), // this should be at the top + estimated_layer_sizes: AllSubtrees( + 1, + SomeSumTrees { + sum_trees_weight: 0, + big_sum_trees_weight: 1, + count_trees_weight: 0, + count_sum_trees_weight: 0, + non_sum_trees_weight: 1, + }, + None, + ), + }, + ); + + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(token_identity_infos_root_path()), + EstimatedLayerInformation { + tree_type: TreeType::NormalTree, + estimated_layer_count: EstimatedLevel(10, false), // we can estimate 10 levels deep + estimated_layer_sizes: AllSubtrees(DEFAULT_HASH_SIZE_U8, NoSumTrees, None), + }, + ); + + // this is where the balances are + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(token_identity_infos_path(&token_id)), + EstimatedLayerInformation { + tree_type: TreeType::NormalTree, + estimated_layer_count: PotentiallyAtMaxElements, + estimated_layer_sizes: AllItems( + DEFAULT_HASH_SIZE_U8, + ESTIMATED_TOKEN_INFO_SIZE_BYTES, + None, + ), + }, + ); + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/mod.rs new file mode 100644 index 00000000000..c72eb62ba47 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/mod.rs @@ -0,0 +1,57 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use dpp::version::drive_versions::DriveVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerInformation; +use std::collections::HashMap; + +impl Drive { + /// Adds estimation costs for token status infos changes based on the provided drive version. + /// + /// This method updates the `estimated_costs_only_with_layer_info` HashMap with entries + /// representing the estimated costs for different layers of the balance tree. The method + /// adjusts its behavior depending on the provided `drive_version`, allowing it to support + /// different versioned implementations for cost estimation. + /// + /// # Parameters + /// - `token_id`: A 32-byte identifier for the token whose balance changes are being estimated. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to a HashMap that holds + /// `KeyInfoPath` and `EstimatedLayerInformation` for each token balance layer. + /// - `drive_version`: The version of the drive to determine which estimation logic to apply. + /// + /// # Returns + /// - `Ok(())` if the operation is successful. + /// - `Err(DriveError::UnknownVersionMismatch)` if the provided `drive_version` does not match + /// any known supported versions. + /// + /// # Errors + /// This function will return an error if the provided `drive_version` does not match a known version. + pub(crate) fn add_estimation_costs_for_token_status_infos( + token_id: [u8; 32], + estimated_costs_only_with_layer_info: &mut HashMap, + drive_version: &DriveVersion, + ) -> Result<(), Error> { + match drive_version + .methods + .identity + .cost_estimation + .for_token_identity_infos + { + 0 => { + Self::add_estimation_costs_for_token_status_infos_v0( + token_id, + estimated_costs_only_with_layer_info, + ); + Ok(()) + } + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "add_estimation_costs_for_token_status_infos".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/v0/mod.rs new file mode 100644 index 00000000000..1933c9fd3fe --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/v0/mod.rs @@ -0,0 +1,69 @@ +use crate::drive::Drive; + +use grovedb::batch::KeyInfoPath; +use grovedb::EstimatedLayerCount::EstimatedLevel; +use grovedb::EstimatedLayerSizes::{AllItems, AllSubtrees}; +use grovedb::{EstimatedLayerInformation, TreeType}; + +use crate::drive::tokens::{token_statuses_root_path, tokens_root_path}; +use crate::util::type_constants::DEFAULT_HASH_SIZE_U8; +use grovedb::EstimatedSumTrees::{NoSumTrees, SomeSumTrees}; +use std::collections::HashMap; + +pub const ESTIMATED_TOKEN_STATUS_INFO_SIZE_BYTES: u32 = 32; + +impl Drive { + pub(super) fn add_estimation_costs_for_token_status_infos_v0( + token_id: [u8; 32], + estimated_costs_only_with_layer_info: &mut HashMap, + ) { + // we have constructed the top layer so contract/documents tree are at the top + // since balance will be on layer 3 (level 2 on left then left) + // updating will mean we will update: + // 1 normal tree (token balances) + // 1 normal tree (identities) + // 1 normal tree (contract/documents) + // hence we should give an equal weight to both + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path([]), + EstimatedLayerInformation { + tree_type: TreeType::NormalTree, + estimated_layer_count: EstimatedLevel(2, false), + estimated_layer_sizes: AllSubtrees(1, NoSumTrees, None), + }, + ); + + // there is one tree for the root path + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(tokens_root_path()), + EstimatedLayerInformation { + tree_type: TreeType::NormalTree, + estimated_layer_count: EstimatedLevel(1, false), // this should be at the top + estimated_layer_sizes: AllSubtrees( + 1, + SomeSumTrees { + sum_trees_weight: 0, + big_sum_trees_weight: 1, + count_trees_weight: 0, + count_sum_trees_weight: 0, + non_sum_trees_weight: 1, + }, + None, + ), + }, + ); + + estimated_costs_only_with_layer_info.insert( + KeyInfoPath::from_known_path(token_statuses_root_path()), + EstimatedLayerInformation { + tree_type: TreeType::NormalTree, + estimated_layer_count: EstimatedLevel(10, false), // we can estimate 10 levels deep + estimated_layer_sizes: AllItems( + DEFAULT_HASH_SIZE_U8, + ESTIMATED_TOKEN_STATUS_INFO_SIZE_BYTES, + None, + ), + }, + ); + } +} diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs index dca4ebe18e0..7f022ceec82 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_total_supply/v0/mod.rs @@ -68,6 +68,9 @@ impl Drive { 17, SomeSumTrees { sum_trees_weight: 1, + big_sum_trees_weight: 0, + count_trees_weight: 0, + count_sum_trees_weight: 0, non_sum_trees_weight: 3, }, None, diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs index d9e96b7e250..8028de53755 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/mod.rs @@ -1,2 +1,11 @@ +/// Module for handling operations related to token balances. pub mod for_token_balances; + +/// Module for handling operations related to token total supply. pub mod for_token_total_supply; + +/// Module for handling operations related to token identity information. +pub mod for_token_identity_infos; + +/// Module for handling operations related to token status information. +pub mod for_token_status_infos; diff --git a/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs b/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs index 3df4bb38f1d..343cf6accc4 100644 --- a/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/freeze/v0/mod.rs @@ -88,9 +88,8 @@ impl Drive { ) -> Result, Error> { let mut drive_operations = vec![]; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_token_balances( + Self::add_estimation_costs_for_token_identity_infos( token_id.to_buffer(), - true, estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index be8a53dee1b..e54e92e7974 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -1,81 +1,142 @@ use crate::drive::RootTree; +/// Handles operations related to adding transaction history. mod add_transaction_history_operations; + +/// Defines logic for applying status updates within the system. pub mod apply_status; + +/// Manages operations related to balance handling. pub mod balance; + +/// Implements functionality for burning tokens. pub mod burn; + +/// Computes estimated costs for various operations. pub mod estimated_costs; + +/// Manages freezing operations in the system. pub mod freeze; + +/// Contains informational utility functions. mod info; + +/// Implements minting operations for creating new tokens. pub mod mint; + +/// Manages system-level operations and utilities. pub mod system; + +/// Handles transfer operations, including token movement. pub mod transfer; + +/// Manages unfreezing operations within the system. pub mod unfreeze; +/// Calculates the total token balance across all accounts. +pub mod calculate_total_tokens_balance; + +/// Key for accessing token status information. pub const TOKEN_STATUS_INFO_KEY: u8 = 96; -pub const TOKEN_IDENTITY_INFO_KEY: u8 = 64; + +/// Key for accessing token identity information tree. +pub const TOKEN_IDENTITY_INFO_KEY: u8 = 160; + +/// Key for accessing token balances tree. pub const TOKEN_BALANCES_KEY: u8 = 128; /// The path for the balances tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn tokens_root_path() -> [&'static [u8]; 1] { +pub fn tokens_root_path() -> [&'static [u8]; 1] { [Into::<&[u8; 1]>::into(RootTree::Tokens)] } /// The path for the balances tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn tokens_root_path_vec() -> Vec> { +pub fn tokens_root_path_vec() -> Vec> { vec![Into::<&[u8; 1]>::into(RootTree::Tokens).to_vec()] } -/// The path for the token tree +/// The root path of token balances tree, this refers to a big sum tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_path(token_id: &[u8; 32]) -> [&[u8]; 2] { - [Into::<&[u8; 1]>::into(RootTree::Tokens), token_id] +pub fn token_balances_root_path() -> [&'static [u8]; 2] { + [ + Into::<&[u8; 1]>::into(RootTree::Tokens), + &[TOKEN_BALANCES_KEY], + ] } -/// The path for the token tree +/// The root path of token balances tree, this refers to a big sum tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_path_vec(token_id: [u8; 32]) -> Vec> { - vec![vec![RootTree::Tokens as u8], token_id.to_vec()] +pub fn token_balances_root_path_vec() -> Vec> { + vec![vec![RootTree::Tokens as u8], vec![TOKEN_BALANCES_KEY]] +} +/// Returns the root path for token identity information as a fixed-size array of byte slices. +#[cfg(any(feature = "server", feature = "verify"))] +pub fn token_identity_infos_root_path() -> [&'static [u8]; 2] { + [ + Into::<&[u8; 1]>::into(RootTree::Tokens), + &[TOKEN_IDENTITY_INFO_KEY], + ] +} + +/// Returns the root path for token identity information as a vector of byte vectors. +#[cfg(any(feature = "server", feature = "verify"))] +pub fn token_identity_infos_root_path_vec() -> Vec> { + vec![vec![RootTree::Tokens as u8], vec![TOKEN_IDENTITY_INFO_KEY]] +} + +/// Returns the root path for token statuses as a fixed-size array of byte slices. +#[cfg(any(feature = "server", feature = "verify"))] +pub fn token_statuses_root_path() -> [&'static [u8]; 2] { + [ + Into::<&[u8; 1]>::into(RootTree::Tokens), + &[TOKEN_STATUS_INFO_KEY], + ] +} + +/// Returns the root path for token statuses as a vector of byte vectors. +#[cfg(any(feature = "server", feature = "verify"))] +pub fn token_statuses_root_path_vec() -> Vec> { + vec![vec![RootTree::Tokens as u8], vec![TOKEN_STATUS_INFO_KEY]] } /// The path for the token balances tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_balances_path(token_id: &[u8; 32]) -> [&[u8]; 3] { +pub fn token_balances_path(token_id: &[u8; 32]) -> [&[u8]; 3] { [ Into::<&[u8; 1]>::into(RootTree::Tokens), - token_id, &[TOKEN_BALANCES_KEY], + token_id, ] } /// The path for the token balances tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_balances_path_vec(token_id: [u8; 32]) -> Vec> { +pub fn token_balances_path_vec(token_id: [u8; 32]) -> Vec> { vec![ vec![RootTree::Tokens as u8], - token_id.to_vec(), vec![TOKEN_BALANCES_KEY], + token_id.to_vec(), ] } /// The path for the token info tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_identity_infos_path(token_id: &[u8; 32]) -> [&[u8]; 3] { +pub fn token_identity_infos_path(token_id: &[u8; 32]) -> [&[u8]; 3] { [ Into::<&[u8; 1]>::into(RootTree::Tokens), - token_id, &[TOKEN_IDENTITY_INFO_KEY], + token_id, ] } /// The path for the token info tree #[cfg(any(feature = "server", feature = "verify"))] -pub(crate) fn token_identity_infos_path_vec(token_id: [u8; 32]) -> Vec> { +pub fn token_identity_infos_path_vec(token_id: [u8; 32]) -> Vec> { vec![ vec![RootTree::Tokens as u8], - token_id.to_vec(), vec![TOKEN_IDENTITY_INFO_KEY], + token_id.to_vec(), ] } diff --git a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs index 3aa28799baa..686591211a8 100644 --- a/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/add_to_token_total_supply/v0/mod.rs @@ -9,9 +9,8 @@ use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::version::PlatformVersion; use grovedb::batch::{KeyInfoPath, QualifiedGroveDbOp}; -use grovedb::Element::Item; +use grovedb::Element::SumItem; use grovedb::{EstimatedLayerInformation, TransactionArg}; -use integer_encoding::VarInt; use std::collections::HashMap; impl Drive { @@ -115,23 +114,27 @@ impl Drive { )?; if let Some(total_token_supply_in_platform) = total_token_supply_in_platform { - let new_total = - total_token_supply_in_platform - .checked_add(amount) - .ok_or(Error::Drive(DriveError::CriticalCorruptedState( - "trying to add an amount that would underflow total supply", - )))?; + let new_total = (total_token_supply_in_platform as i64) + .checked_add(amount as i64) + .ok_or(Error::Drive(DriveError::CriticalCorruptedState( + "trying to add an amount that would underflow total supply", + )))?; let replace_op = QualifiedGroveDbOp::replace_op( path_holding_total_token_supply_vec, token_id.to_vec(), - Item(new_total.encode_var_vec(), None), + SumItem(new_total, None), ); drive_operations.push(GroveOperation(replace_op)); } else if allow_first_mint { + if amount > i64::MAX as u64 { + return Err(Error::Drive(DriveError::CriticalCorruptedState( + "amount is over max allowed in Sum Item (i64::Max)", + ))); + } let insert_op = QualifiedGroveDbOp::insert_only_op( path_holding_total_token_supply_vec, token_id.to_vec(), - Item(amount.encode_var_vec(), None), + SumItem(amount as i64, None), ); drive_operations.push(GroveOperation(insert_op)); } else { diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs index ce7ebc2c376..49656bb930c 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/mod.rs @@ -13,7 +13,7 @@ use grovedb::{EstimatedLayerInformation, TransactionArg}; use std::collections::HashMap; impl Drive { - /// Adds a identity by inserting a new identity subtree structure to the `Identities` subtree. + /// Adds an identity by inserting a new identity subtree structure to the `Identities` subtree. pub fn create_token_trees( &self, token_id: [u8; 32], diff --git a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs index e60f48dfbdd..e9b8a688cde 100644 --- a/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/create_token_trees/v0/mod.rs @@ -1,7 +1,6 @@ use crate::drive::balances::total_tokens_root_supply_path; use crate::drive::tokens::{ - token_path, tokens_root_path, TOKEN_BALANCES_KEY, TOKEN_IDENTITY_INFO_KEY, - TOKEN_STATUS_INFO_KEY, + token_balances_root_path, token_identity_infos_root_path, token_statuses_root_path, }; use crate::drive::Drive; use crate::error::drive::DriveError; @@ -9,7 +8,7 @@ use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use crate::util::grove_operations::{BatchInsertApplyType, BatchInsertTreeApplyType, QueryTarget}; use crate::util::object_size_info::PathKeyElementInfo; -use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKey; +use crate::util::object_size_info::PathKeyInfo::PathFixedSizeKeyRef; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::serialization::PlatformSerializable; @@ -115,7 +114,6 @@ impl Drive { ) -> Result, Error> { let mut batch_operations: Vec = vec![]; - // Decide if we're doing a stateful or stateless insert for cost estimation let non_sum_tree_apply_type = if estimated_costs_only_with_layer_info.is_none() { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { @@ -139,7 +137,7 @@ impl Drive { BatchInsertTreeApplyType::StatefulBatchInsertTree } else { BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_type: TreeType::NormalTree, + in_tree_type: TreeType::BigSumTree, tree_type: TreeType::SumTree, flags_len: 0, } @@ -147,10 +145,10 @@ impl Drive { // Insert an empty tree for this token if it doesn't exist let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey((tokens_root_path(), token_id.to_vec())), - false, - None, // No storage flags - non_sum_tree_apply_type, + PathFixedSizeKeyRef::<2>((token_balances_root_path(), token_id.as_slice())), + TreeType::SumTree, + None, + token_balance_tree_apply_type, transaction, previous_batch_operations, &mut batch_operations, @@ -160,15 +158,15 @@ impl Drive { if !inserted && !allow_already_exists { // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. return Err(Error::Drive(DriveError::CorruptedDriveState( - "token root tree already exists".to_string(), + "token balance root tree already exists".to_string(), ))); } let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey((token_path(&token_id), vec![TOKEN_BALANCES_KEY])), - true, + PathFixedSizeKeyRef::<2>((token_identity_infos_root_path(), token_id.as_slice())), + TreeType::NormalTree, None, - token_balance_tree_apply_type, + non_sum_tree_apply_type, transaction, &mut None, &mut batch_operations, @@ -187,8 +185,8 @@ impl Drive { let inserted = self.batch_insert_if_not_exists( PathKeyElementInfo::PathFixedSizeKeyRefElement::<2>(( - token_path(&token_id), - &[TOKEN_IDENTITY_INFO_KEY], + token_statuses_root_path(), + token_id.as_slice(), Element::Item(token_status_bytes, None), )), item_apply_type, @@ -204,42 +202,19 @@ impl Drive { ))); } - let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey((token_path(&token_id), vec![TOKEN_STATUS_INFO_KEY])), - false, - None, - non_sum_tree_apply_type, - transaction, - &mut None, - &mut batch_operations, - &platform_version.drive, - )?; - - if !inserted && !allow_already_exists { - // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. - return Err(Error::Drive(DriveError::CorruptedDriveState( - "token info tree already exists".to_string(), - ))); - } - - let inserted = self.batch_insert_empty_tree_if_not_exists( - PathFixedSizeKey((total_tokens_root_supply_path(), token_id.to_vec())), - false, - None, - non_sum_tree_apply_type, + self.batch_insert_sum_item_if_not_exists( + PathKeyElementInfo::PathFixedSizeKeyRefElement::<2>(( + total_tokens_root_supply_path(), + token_id.as_slice(), + Element::SumItem(0, None), + )), + !allow_already_exists, + item_apply_type, transaction, - &mut None, &mut batch_operations, &platform_version.drive, )?; - if !inserted && !allow_already_exists { - // The token root already exists. Depending on your logic, this might be allowed or should be treated as an error. - return Err(Error::Drive(DriveError::CorruptedDriveState( - "sum tree tree already exists".to_string(), - ))); - } - Ok(batch_operations) } } diff --git a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs index 311c3254c8d..1bdbe38ebb5 100644 --- a/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/system/remove_from_token_total_supply/v0/mod.rs @@ -9,9 +9,8 @@ use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; use dpp::version::PlatformVersion; use grovedb::batch::QualifiedGroveDbOp; -use grovedb::Element::Item; +use grovedb::Element::SumItem; use grovedb::{batch::KeyInfoPath, EstimatedLayerInformation, TransactionArg}; -use integer_encoding::VarInt; use std::collections::HashMap; impl Drive { @@ -120,7 +119,7 @@ impl Drive { let replace_op = QualifiedGroveDbOp::replace_op( path_holding_total_token_supply_vec, token_id.to_vec(), - Item(new_total.encode_var_vec(), None), + SumItem(new_total as i64, None), ); drive_operations.push(GroveOperation(replace_op)); diff --git a/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs b/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs index ab09dd3f73a..7e581b4b82e 100644 --- a/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/unfreeze/v0/mod.rs @@ -88,9 +88,8 @@ impl Drive { ) -> Result, Error> { let mut drive_operations = vec![]; if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { - Self::add_estimation_costs_for_token_balances( + Self::add_estimation_costs_for_token_identity_infos( token_id.to_buffer(), - true, estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/votes/insert/contested_resource/individual_vote/register_contested_resource_identity_vote/v0/mod.rs b/packages/rs-drive/src/drive/votes/insert/contested_resource/individual_vote/register_contested_resource_identity_vote/v0/mod.rs index fa3782218f6..2a1ddacfddf 100644 --- a/packages/rs-drive/src/drive/votes/insert/contested_resource/individual_vote/register_contested_resource_identity_vote/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/insert/contested_resource/individual_vote/register_contested_resource_identity_vote/v0/mod.rs @@ -16,7 +16,7 @@ use dpp::fee::fee_result::FeeResult; use dpp::voting::vote_choices::resource_vote_choice::ResourceVoteChoice; use dpp::{bincode, ProtocolError}; use grovedb::reference_path::ReferencePathType; -use grovedb::{Element, MaybeTree, TransactionArg}; +use grovedb::{Element, MaybeTree, TransactionArg, TreeType}; use platform_version::version::PlatformVersion; impl Drive { @@ -118,7 +118,7 @@ impl Drive { self.batch_insert_empty_tree_if_not_exists( PathKeyInfo::PathKey::<0>((votes_identities_path, voter_pro_tx_hash.to_vec())), - false, + TreeType::NormalTree, None, BatchInsertTreeApplyType::StatefulBatchInsertTree, //todo this shouldn't always be stateful transaction, diff --git a/packages/rs-drive/src/drive/votes/insert/vote_poll/add_vote_poll_end_date_query_operations/v0/mod.rs b/packages/rs-drive/src/drive/votes/insert/vote_poll/add_vote_poll_end_date_query_operations/v0/mod.rs index 696b0841882..e3ac582a483 100644 --- a/packages/rs-drive/src/drive/votes/insert/vote_poll/add_vote_poll_end_date_query_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/votes/insert/vote_poll/add_vote_poll_end_date_query_operations/v0/mod.rs @@ -113,7 +113,7 @@ impl Drive { // end data in the documents batch transition self.batch_insert_empty_tree_if_not_exists( path_key_info.clone(), - false, + TreeType::NormalTree, storage_flags.as_ref(), apply_type, transaction, diff --git a/packages/rs-drive/src/fees/op.rs b/packages/rs-drive/src/fees/op.rs index ecd1c605311..e874a89b1da 100644 --- a/packages/rs-drive/src/fees/op.rs +++ b/packages/rs-drive/src/fees/op.rs @@ -9,7 +9,7 @@ use grovedb::batch::key_info::KeyInfo; use grovedb::batch::KeyInfoPath; use grovedb::element::MaxReferenceHop; use grovedb::reference_path::ReferencePathType; -use grovedb::{batch::QualifiedGroveDbOp, Element, ElementFlags}; +use grovedb::{batch::QualifiedGroveDbOp, Element, ElementFlags, TreeType}; use grovedb_costs::OperationCost; use itertools::Itertools; @@ -382,6 +382,54 @@ impl LowLevelDriveOperation { LowLevelDriveOperation::insert_for_known_path_key_element(path, key, tree) } + /// Sets `GroveOperation` for inserting an empty sum tree at the given path and key + pub fn for_known_path_key_empty_big_sum_tree( + path: Vec>, + key: Vec, + storage_flags: Option<&StorageFlags>, + ) -> Self { + let tree = match storage_flags { + Some(storage_flags) => { + Element::new_big_sum_tree_with_flags(None, storage_flags.to_some_element_flags()) + } + None => Element::empty_big_sum_tree(), + }; + + LowLevelDriveOperation::insert_for_known_path_key_element(path, key, tree) + } + + /// Sets `GroveOperation` for inserting an empty count tree at the given path and key + pub fn for_known_path_key_empty_count_tree( + path: Vec>, + key: Vec, + storage_flags: Option<&StorageFlags>, + ) -> Self { + let tree = match storage_flags { + Some(storage_flags) => { + Element::new_count_tree_with_flags(None, storage_flags.to_some_element_flags()) + } + None => Element::empty_count_tree(), + }; + + LowLevelDriveOperation::insert_for_known_path_key_element(path, key, tree) + } + + /// Sets `GroveOperation` for inserting an empty count tree at the given path and key + pub fn for_known_path_key_empty_count_sum_tree( + path: Vec>, + key: Vec, + storage_flags: Option<&StorageFlags>, + ) -> Self { + let tree = match storage_flags { + Some(storage_flags) => { + Element::new_count_sum_tree_with_flags(None, storage_flags.to_some_element_flags()) + } + None => Element::new_count_sum_tree(None), + }; + + LowLevelDriveOperation::insert_for_known_path_key_element(path, key, tree) + } + /// Sets `GroveOperation` for inserting an empty tree at the given path and key pub fn for_estimated_path_key_empty_tree( path: KeyInfoPath, @@ -486,6 +534,37 @@ impl LowLevelDriveOperation { } } +pub trait LowLevelDriveOperationTreeTypeConverter { + /// Sets `GroveOperation` for inserting an empty tree at the given path and key + fn empty_tree_operation_for_known_path_key( + &self, + path: Vec>, + key: Vec, + storage_flags: Option<&StorageFlags>, + ) -> LowLevelDriveOperation; +} + +impl LowLevelDriveOperationTreeTypeConverter for TreeType { + /// Sets `GroveOperation` for inserting an empty tree at the given path and key + fn empty_tree_operation_for_known_path_key( + &self, + path: Vec>, + key: Vec, + storage_flags: Option<&StorageFlags>, + ) -> LowLevelDriveOperation { + let element_flags = storage_flags.map(|storage_flags| storage_flags.to_element_flags()); + let element = match self { + TreeType::NormalTree => Element::empty_tree_with_flags(element_flags), + TreeType::SumTree => Element::empty_sum_tree_with_flags(element_flags), + TreeType::BigSumTree => Element::empty_big_sum_tree_with_flags(element_flags), + TreeType::CountTree => Element::empty_count_tree_with_flags(element_flags), + TreeType::CountSumTree => Element::empty_count_sum_tree_with_flags(element_flags), + }; + + LowLevelDriveOperation::insert_for_known_path_key_element(path, key, element) + } +} + /// Drive cost trait pub trait DriveCost { /// Ephemeral cost diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/mod.rs index a4f630e691e..5425de9741b 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/mod.rs @@ -10,7 +10,7 @@ use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use dpp::version::drive_versions::DriveVersion; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Pushes an "insert empty tree where path key does not yet exist" operation to `drive_operations`. @@ -19,7 +19,7 @@ impl Drive { pub fn batch_insert_empty_tree_if_not_exists( &self, path_key_info: PathKeyInfo, - use_sum_tree: bool, + tree_type: TreeType, storage_flags: Option<&StorageFlags>, apply_type: BatchInsertTreeApplyType, transaction: TransactionArg, @@ -34,7 +34,7 @@ impl Drive { { 0 => self.batch_insert_empty_tree_if_not_exists_v0( path_key_info, - use_sum_tree, + tree_type, storage_flags, apply_type, transaction, diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs index 3aa69889483..e1b0dc30b38 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_empty_tree_if_not_exists/v0/mod.rs @@ -1,8 +1,8 @@ use crate::drive::Drive; use crate::error::drive::DriveError; use crate::error::Error; -use crate::fees::op::LowLevelDriveOperation; use crate::fees::op::LowLevelDriveOperation::GroveOperation; +use crate::fees::op::{LowLevelDriveOperation, LowLevelDriveOperationTreeTypeConverter}; use crate::util::grove_operations::BatchInsertTreeApplyType; use crate::util::object_size_info::PathKeyInfo; use crate::util::object_size_info::PathKeyInfo::{ @@ -11,7 +11,7 @@ use crate::util::object_size_info::PathKeyInfo::{ use crate::util::storage_flags::StorageFlags; use dpp::version::drive_versions::DriveVersion; use grovedb::batch::GroveOp; -use grovedb::TransactionArg; +use grovedb::{TransactionArg, TreeType}; impl Drive { /// Pushes an "insert empty tree where path key does not yet exist" operation to `drive_operations`. @@ -19,7 +19,7 @@ impl Drive { pub(crate) fn batch_insert_empty_tree_if_not_exists_v0( &self, path_key_info: PathKeyInfo, - use_sum_tree: bool, + tree_type: TreeType, storage_flags: Option<&StorageFlags>, apply_type: BatchInsertTreeApplyType, transaction: TransactionArg, @@ -30,19 +30,11 @@ impl Drive { //todo: clean up the duplication match path_key_info { PathKeyRef((path, key)) => { - let drive_operation = if use_sum_tree { - LowLevelDriveOperation::for_known_path_key_empty_sum_tree( - path.clone(), - key.to_vec(), - storage_flags, - ) - } else { - LowLevelDriveOperation::for_known_path_key_empty_tree( - path.clone(), - key.to_vec(), - storage_flags, - ) - }; + let drive_operation = tree_type.empty_tree_operation_for_known_path_key( + path.clone(), + key.to_vec(), + storage_flags, + ); // we only add the operation if it doesn't already exist in the current batch if let Some(existing_operations) = check_existing_operations { let mut i = 0; @@ -105,19 +97,11 @@ impl Drive { DriveError::NotSupportedPrivate("document sizes in batch operations not supported"), )), PathKey((path, key)) => { - let drive_operation = if use_sum_tree { - LowLevelDriveOperation::for_known_path_key_empty_sum_tree( - path.clone(), - key.to_vec(), - storage_flags, - ) - } else { - LowLevelDriveOperation::for_known_path_key_empty_tree( - path.clone(), - key.to_vec(), - storage_flags, - ) - }; + let drive_operation = tree_type.empty_tree_operation_for_known_path_key( + path.clone(), + key.to_vec(), + storage_flags, + ); // we only add the operation if it doesn't already exist in the current batch if let Some(existing_operations) = check_existing_operations { let mut i = 0; @@ -178,19 +162,11 @@ impl Drive { } PathFixedSizeKey((path, key)) => { let path_items: Vec> = path.into_iter().map(Vec::from).collect(); - let drive_operation = if use_sum_tree { - LowLevelDriveOperation::for_known_path_key_empty_sum_tree( - path_items, - key.to_vec(), - storage_flags, - ) - } else { - LowLevelDriveOperation::for_known_path_key_empty_tree( - path_items, - key.to_vec(), - storage_flags, - ) - }; + let drive_operation = tree_type.empty_tree_operation_for_known_path_key( + path_items, + key.to_vec(), + storage_flags, + ); // we only add the operation if it doesn't already exist in the current batch if let Some(existing_operations) = check_existing_operations { let mut i = 0; @@ -251,19 +227,11 @@ impl Drive { } PathFixedSizeKeyRef((path, key)) => { let path_items: Vec> = path.into_iter().map(Vec::from).collect(); - let drive_operation = if use_sum_tree { - LowLevelDriveOperation::for_known_path_key_empty_sum_tree( - path_items, - key.to_vec(), - storage_flags, - ) - } else { - LowLevelDriveOperation::for_known_path_key_empty_tree( - path_items, - key.to_vec(), - storage_flags, - ) - }; + let drive_operation = tree_type.empty_tree_operation_for_known_path_key( + path_items, + key.to_vec(), + storage_flags, + ); // we only add the operation if it doesn't already exist in the current batch if let Some(existing_operations) = check_existing_operations { let mut i = 0; diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/mod.rs index 943dac0b8e0..9200949046b 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/mod.rs @@ -47,7 +47,7 @@ impl Drive { transaction: TransactionArg, drive_operations: &mut Vec, drive_version: &DriveVersion, - ) -> Result<(), Error> { + ) -> Result { match drive_version .grove_methods .batch diff --git a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs index 6785633e73e..902f806e797 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_insert_sum_item_if_not_exists/v0/mod.rs @@ -55,7 +55,7 @@ impl Drive { transaction: TransactionArg, drive_operations: &mut Vec, drive_version: &DriveVersion, - ) -> Result<(), Error> { + ) -> Result { match path_key_element_info { PathKeyRefElement((path, key, element)) => { if let Element::SumItem(new_value, _) = element { @@ -70,11 +70,13 @@ impl Drive { )?; if let Some(Element::SumItem(..)) = existing_element { - if error_if_exists { - return Err(Error::Drive(DriveError::CorruptedDriveState( + return if error_if_exists { + Err(Error::Drive(DriveError::CorruptedDriveState( "expected no sum item".to_string(), - ))); - } + ))) + } else { + Ok(false) + }; // Else do nothing } else if existing_element.is_some() { return Err(Error::Drive(DriveError::CorruptedElementType( @@ -95,7 +97,7 @@ impl Drive { "expected sum item element type", ))); } - Ok(()) + Ok(true) } PathKeyElement((path, key, element)) => { if let Element::SumItem(new_value, _) = element { @@ -110,11 +112,13 @@ impl Drive { )?; if let Some(Element::SumItem(..)) = existing_element { - if error_if_exists { - return Err(Error::Drive(DriveError::CorruptedDriveState( + return if error_if_exists { + Err(Error::Drive(DriveError::CorruptedDriveState( "expected no sum item".to_string(), - ))); - } + ))) + } else { + Ok(false) + }; // Else do nothing } else if existing_element.is_some() { return Err(Error::Drive(DriveError::CorruptedElementType( @@ -135,7 +139,7 @@ impl Drive { "expected sum item element type", ))); } - Ok(()) + Ok(true) } PathFixedSizeKeyRefElement((path, key, element)) => { if let Element::SumItem(new_value, _) = element { @@ -150,11 +154,13 @@ impl Drive { )?; if let Some(Element::SumItem(..)) = existing_element { - if error_if_exists { - return Err(Error::Drive(DriveError::CorruptedDriveState( + return if error_if_exists { + Err(Error::Drive(DriveError::CorruptedDriveState( "expected no sum item".to_string(), - ))); - } + ))) + } else { + Ok(false) + }; // Else do nothing } else if existing_element.is_some() { return Err(Error::Drive(DriveError::CorruptedElementType( @@ -176,7 +182,7 @@ impl Drive { "expected sum item element type", ))); } - Ok(()) + Ok(true) } PathKeyElementSize((key_info_path, key_info, element)) => { if let Element::SumItem(new_value, _) = element { @@ -202,7 +208,7 @@ impl Drive { Element::new_sum_item(new_value), ), ); - Ok(()) + Ok(true) } BatchInsertApplyType::StatefulBatchInsert => { Err(Error::Drive(DriveError::NotSupportedPrivate( diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_big_sum_tree_total_value/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_big_sum_tree_total_value/mod.rs new file mode 100644 index 00000000000..571cd7461b5 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/grove_get_big_sum_tree_total_value/mod.rs @@ -0,0 +1,58 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use dpp::version::drive_versions::DriveVersion; +use grovedb::TransactionArg; +use grovedb_path::SubtreePath; + +impl Drive { + /// Retrieves the total value from a sum tree within groveDB at the specified path and key. + /// The cost of the operation is then appended to `drive_operations` for later processing. + /// + /// # Parameters + /// * `path`: The groveDB hierarchical authenticated structure path where the sum tree is located. + /// * `key`: The key where the sum tree resides within the subtree. + /// * `query_type`: The type of query to perform, either `StatelessDirectQuery` or `StatefulDirectQuery`. + /// * `transaction`: The groveDB transaction associated with this operation. + /// * `drive_operations`: A vector to collect the costs of operations for later computation. + /// * `platform_version`: The platform version to select the correct function version to run. + /// + /// # Returns + /// * `Ok(i64)` if the operation was successful, returning the total value of the sum tree. + /// * `Err(DriveError::UnknownVersionMismatch)` if the platform version does not match known versions. + /// * `Err(DriveError::CorruptedBalancePath)` if the balance path does not refer to a sum tree. + /// * `Err(DriveError::CorruptedCodeExecution)` if trying to query a non-tree element. + pub fn grove_get_big_sum_tree_total_value>( + &self, + path: SubtreePath<'_, B>, + key: &[u8], + query_type: DirectQueryType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result { + match drive_version + .grove_methods + .basic + .grove_get_big_sum_tree_total_value + { + 0 => self.grove_get_big_sum_tree_total_value_v0( + path, + key, + query_type, + transaction, + drive_operations, + drive_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "grove_get_big_sum_tree_total_value".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/grove_get_big_sum_tree_total_value/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/grove_get_big_sum_tree_total_value/v0/mod.rs new file mode 100644 index 00000000000..71ab45ea201 --- /dev/null +++ b/packages/rs-drive/src/util/grove_operations/grove_get_big_sum_tree_total_value/v0/mod.rs @@ -0,0 +1,67 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::fees::op::LowLevelDriveOperation::CalculatedCostOperation; +use crate::util::grove_operations::{DirectQueryType, QueryTarget}; +use grovedb::batch::key_info::KeyInfo; +use grovedb::batch::KeyInfoPath; +use grovedb::{Element, GroveDb, TransactionArg}; +use grovedb_costs::CostContext; +use grovedb_path::SubtreePath; +use platform_version::version::drive_versions::DriveVersion; + +impl Drive { + /// Gets the element at the given path from groveDB. + /// Pushes the `OperationCost` of getting the element to `drive_operations`. + pub(super) fn grove_get_big_sum_tree_total_value_v0>( + &self, + path: SubtreePath<'_, B>, + key: &[u8], + query_type: DirectQueryType, + transaction: TransactionArg, + drive_operations: &mut Vec, + drive_version: &DriveVersion, + ) -> Result { + match query_type { + DirectQueryType::StatelessDirectQuery { + in_tree_type, + query_target, + } => { + let key_info_path = KeyInfoPath::from_known_owned_path(path.to_vec()); + let key_info = KeyInfo::KnownKey(key.to_vec()); + let cost = match query_target { + QueryTarget::QueryTargetTree(flags_size, tree_type) => { + Ok(GroveDb::average_case_for_get_tree( + &key_info_path, + &key_info, + flags_size, + tree_type, + in_tree_type, + &drive_version.grove_version, + )?) + } + _ => Err(Error::Drive(DriveError::CorruptedCodeExecution( + "can not query a non tree", + ))), + }?; + + drive_operations.push(CalculatedCostOperation(cost)); + Ok(0) + } + DirectQueryType::StatefulDirectQuery => { + let CostContext { value, cost } = + self.grove + .get_raw(path, key, transaction, &drive_version.grove_version); + drive_operations.push(CalculatedCostOperation(cost)); + let element = value.map_err(Error::GroveDB)?; + match element { + Element::BigSumTree(_, value, _) => Ok(value), + _ => Err(Error::Drive(DriveError::CorruptedBalancePath( + "balance path does not refer to a big sum tree", + ))), + } + } + } + } +} diff --git a/packages/rs-drive/src/util/grove_operations/mod.rs b/packages/rs-drive/src/util/grove_operations/mod.rs index 87818cdc13a..82694d57be2 100644 --- a/packages/rs-drive/src/util/grove_operations/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/mod.rs @@ -137,6 +137,8 @@ pub mod batch_insert_sum_item_if_not_exists; /// Moved items that are found in a path query to a new path. pub mod batch_move_items_in_path_query; +/// Get the total value from a big sum tree +pub mod grove_get_big_sum_tree_total_value; /// Get total value from sum tree in grove if it exists pub mod grove_get_optional_sum_tree_total_value; /// Fetch raw grove data if it exists, None otherwise @@ -287,6 +289,7 @@ impl BatchInsertTreeApplyType { } /// Batch insert apply type +#[derive(Clone, Copy)] pub enum BatchInsertApplyType { /// Stateless batch insert StatelessBatchInsert { diff --git a/packages/rs-platform-version/Cargo.toml b/packages/rs-platform-version/Cargo.toml index 6103074b3e3..5bce71ac114 100644 --- a/packages/rs-platform-version/Cargo.toml +++ b/packages/rs-platform-version/Cargo.toml @@ -11,7 +11,7 @@ license = "MIT" thiserror = { version = "1.0.63" } bincode = { version = "2.0.0-rc.3" } versioned-feature-core = { git = "https://github.com/dashpay/versioned-feature-core", version = "1.0.0" } -grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "2417f7a72900cd3dca943ad52c979bc8abfdaa20" } +grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50" } once_cell = "1.19.0" [features] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs index 7b281cd6cc6..71d7fc8b00c 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/mod.rs @@ -36,6 +36,7 @@ pub struct DriveGroveBasicMethodVersions { pub grove_get_raw_item: FeatureVersion, pub grove_get_optional_sum_tree_total_value: FeatureVersion, pub grove_get_raw_optional_item: FeatureVersion, + pub grove_get_big_sum_tree_total_value: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs index 31b39cfad3e..0fa2d7d09c9 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_grove_method_versions/v1.rs @@ -29,6 +29,7 @@ pub const DRIVE_GROVE_METHOD_VERSIONS_V1: DriveGroveMethodVersions = DriveGroveM grove_get_raw_item: 0, grove_get_optional_sum_tree_total_value: 0, grove_get_raw_optional_item: 0, + grove_get_big_sum_tree_total_value: 0, }, batch: DriveGroveBatchMethodVersions { batch_insert_empty_tree: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs index 031cd38dfa5..958724c7a8b 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/mod.rs @@ -69,6 +69,7 @@ pub struct DriveIdentityCostEstimationMethodVersions { pub for_purpose_in_key_reference_tree: FeatureVersion, pub for_root_key_reference_tree: FeatureVersion, pub for_update_revision: FeatureVersion, + pub for_token_identity_infos: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs index d0b23ccc1a0..385078e380f 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_identity_method_versions/v1.rs @@ -130,6 +130,7 @@ pub const DRIVE_IDENTITY_METHOD_VERSIONS_V1: DriveIdentityMethodVersions = for_purpose_in_key_reference_tree: 0, for_root_key_reference_tree: 0, for_update_revision: 0, + for_token_identity_infos: 0, }, withdrawals: DriveIdentityWithdrawalMethodVersions { document: DriveIdentityWithdrawalDocumentMethodVersions { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 6b88759c6ab..53b97598cf4 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -7,6 +7,7 @@ pub struct DriveTokenMethodVersions { pub fetch: DriveTokenFetchMethodVersions, pub prove: DriveTokenProveMethodVersions, pub update: DriveTokenUpdateMethodVersions, + pub calculate_total_tokens_balance: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index faabf9f280a..2cc010c109a 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -34,4 +34,5 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM unfreeze: 0, apply_status: 0, }, + calculate_total_tokens_balance: 0, }; From bfbce84a8153d5c03d8c8708d0920803d1301245 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Sat, 11 Jan 2025 16:23:01 +0700 Subject: [PATCH 53/61] added search contract --- packages/rs-drive-abci/src/config.rs | 1 + .../validate_token_aggregated_balance/v0.rs | 21 +- .../add_new_unique_keys_to_identity/v0/mod.rs | 1 + .../src/drive/initialization/v0/mod.rs | 4 - packages/search-contract/.eslintrc | 18 ++ packages/search-contract/.mocharc.yml | 2 + packages/search-contract/Cargo.toml | 13 ++ packages/search-contract/LICENSE | 20 ++ packages/search-contract/README.md | 26 +++ packages/search-contract/lib/systemIds.js | 4 + packages/search-contract/package.json | 29 +++ .../schema/v1/search-contract-documents.json | 62 ++++++ packages/search-contract/src/error.rs | 17 ++ packages/search-contract/src/lib.rs | 37 ++++ packages/search-contract/src/v1/mod.rs | 27 +++ packages/search-contract/test/.eslintrc | 12 ++ packages/search-contract/test/bootstrap.js | 30 +++ .../test/unit/searchContract.spec.js | 187 ++++++++++++++++++ 18 files changed, 495 insertions(+), 16 deletions(-) create mode 100644 packages/search-contract/.eslintrc create mode 100644 packages/search-contract/.mocharc.yml create mode 100644 packages/search-contract/Cargo.toml create mode 100644 packages/search-contract/LICENSE create mode 100644 packages/search-contract/README.md create mode 100644 packages/search-contract/lib/systemIds.js create mode 100644 packages/search-contract/package.json create mode 100644 packages/search-contract/schema/v1/search-contract-documents.json create mode 100644 packages/search-contract/src/error.rs create mode 100644 packages/search-contract/src/lib.rs create mode 100644 packages/search-contract/src/v1/mod.rs create mode 100644 packages/search-contract/test/.eslintrc create mode 100644 packages/search-contract/test/bootstrap.js create mode 100644 packages/search-contract/test/unit/searchContract.spec.js diff --git a/packages/rs-drive-abci/src/config.rs b/packages/rs-drive-abci/src/config.rs index e004e14df60..afa20e34f5d 100644 --- a/packages/rs-drive-abci/src/config.rs +++ b/packages/rs-drive-abci/src/config.rs @@ -677,6 +677,7 @@ impl Default for ExecutionConfig { Self { use_document_triggers: ExecutionConfig::default_use_document_triggers(), verify_sum_trees: ExecutionConfig::default_verify_sum_trees(), + verify_token_sum_trees: ExecutionConfig::default_verify_token_sum_trees(), epoch_time_length_s: ExecutionConfig::default_epoch_time_length_s(), } } diff --git a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs index c1defaa1236..34362477603 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs @@ -1,12 +1,10 @@ -use dpp::block::epoch::Epoch; -use drive::drive::Drive; use drive::grovedb::Transaction; use crate::error::execution::ExecutionError; use crate::error::Error; use crate::execution::types::block_execution_context::BlockExecutionContext; use crate::platform_types::platform::Platform; -use platform_version::version::PlatformVersion; +use dpp::version::PlatformVersion; impl Platform { /// Adds operations to GroveDB op batch related to processing @@ -22,25 +20,24 @@ impl Platform { ) -> Result<(), Error> { if self.config.execution.verify_token_sum_trees { // Verify sum trees - let credits_verified = self + let token_balance = self .drive - .calculate_total_token_balance(Some(transaction), &platform_version.drive) + .calculate_total_tokens_balance(Some(transaction), &platform_version.drive) .map_err(Error::Drive)?; - if !credits_verified.ok()? { + if !token_balance.ok()? { return Err(Error::Execution( ExecutionError::CorruptedCreditsNotBalanced(format!( "credits are not balanced after block execution {:?} off by {}", - credits_verified, - credits_verified - .total_in_trees() - .unwrap() - .abs_diff(credits_verified.total_credits_in_platform) + token_balance, + token_balance + .total_identity_token_balances + .abs_diff(token_balance.total_tokens_in_platform) )), )); } } - Ok(outcome) + Ok(()) } } diff --git a/packages/rs-drive/src/drive/identity/update/methods/add_new_unique_keys_to_identity/v0/mod.rs b/packages/rs-drive/src/drive/identity/update/methods/add_new_unique_keys_to_identity/v0/mod.rs index 70de562e499..7ca4f44d18a 100644 --- a/packages/rs-drive/src/drive/identity/update/methods/add_new_unique_keys_to_identity/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/update/methods/add_new_unique_keys_to_identity/v0/mod.rs @@ -45,6 +45,7 @@ impl Drive { &mut drive_operations, &platform_version.drive, )?; + println!("{:?}", drive_operations); let fees = Drive::calculate_fee( None, Some(drive_operations), diff --git a/packages/rs-drive/src/drive/initialization/v0/mod.rs b/packages/rs-drive/src/drive/initialization/v0/mod.rs index 1d5b0d17831..71a52818d8f 100644 --- a/packages/rs-drive/src/drive/initialization/v0/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v0/mod.rs @@ -284,8 +284,6 @@ mod tests { let platform_version = PlatformVersion::first(); let drive = setup_drive_with_initial_state_structure(Some(platform_version)); - let _db_transaction = drive.grove.start_transaction(); - let platform_version = PlatformVersion::first(); let drive_version = &platform_version.drive; @@ -574,8 +572,6 @@ mod tests { fn test_initial_state_structure_proper_heights_in_latest_protocol_version() { let drive = setup_drive_with_initial_state_structure(None); - let _db_transaction = drive.grove.start_transaction(); - let platform_version = PlatformVersion::latest(); let drive_version = &platform_version.drive; diff --git a/packages/search-contract/.eslintrc b/packages/search-contract/.eslintrc new file mode 100644 index 00000000000..cb6c7636b60 --- /dev/null +++ b/packages/search-contract/.eslintrc @@ -0,0 +1,18 @@ +{ + "extends": "airbnb-base", + "rules": { + "no-plusplus": 0, + "eol-last": [ + "error", + "always" + ], + "class-methods-use-this": "off", + "curly": [ + "error", + "all" + ] + }, + "globals": { + "BigInt": true + } +} diff --git a/packages/search-contract/.mocharc.yml b/packages/search-contract/.mocharc.yml new file mode 100644 index 00000000000..164b941c1b6 --- /dev/null +++ b/packages/search-contract/.mocharc.yml @@ -0,0 +1,2 @@ +require: test/bootstrap.js +recursive: true diff --git a/packages/search-contract/Cargo.toml b/packages/search-contract/Cargo.toml new file mode 100644 index 00000000000..3625f97a47e --- /dev/null +++ b/packages/search-contract/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "token-history-contract" +description = "Token history data contract schema and tools" +version = "1.6.2" +edition = "2021" +rust-version.workspace = true +license = "MIT" + +[dependencies] +thiserror = "1.0.64" +platform-version = { path = "../rs-platform-version" } +serde_json = { version = "1.0" } +platform-value = { path = "../rs-platform-value" } diff --git a/packages/search-contract/LICENSE b/packages/search-contract/LICENSE new file mode 100644 index 00000000000..3be95833750 --- /dev/null +++ b/packages/search-contract/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2019 Dash Core Group, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/search-contract/README.md b/packages/search-contract/README.md new file mode 100644 index 00000000000..6f6caf4d9d6 --- /dev/null +++ b/packages/search-contract/README.md @@ -0,0 +1,26 @@ +# Search Contract + +[![Build Status](https://github.com/dashpay/platform/actions/workflows/release.yml/badge.svg)](https://github.com/dashpay/platform/actions/workflows/release.yml) +[![NPM version](https://img.shields.io/npm/v/@dashevo/wallet-contract.svg?style=flat-square)](https://npmjs.org/package/@dashevo/wallet-contract) + +JSON Contracts for Searching Data Contracts + +## Table of Contents + +- [Install](#install) +- [Contributing](#contributing) +- [License](#license) + +## Install + +```sh +npm install @dashevo/search-contract +``` + +## Contributing + +Feel free to dive in! [Open an issue](https://github.com/dashpay/platform/issues/new/choose) or submit PRs. + +## License + +[MIT](LICENSE) © Dash Core Group, Inc. diff --git a/packages/search-contract/lib/systemIds.js b/packages/search-contract/lib/systemIds.js new file mode 100644 index 00000000000..7335d3d1635 --- /dev/null +++ b/packages/search-contract/lib/systemIds.js @@ -0,0 +1,4 @@ +module.exports = { + ownerId: '11111111111111111111111111111111', + contractId: '8v8CoKCDdBcQu1Y7GDNJjR7a5vkMmgpXycJURkaUhfU9', +}; diff --git a/packages/search-contract/package.json b/packages/search-contract/package.json new file mode 100644 index 00000000000..82782f0d627 --- /dev/null +++ b/packages/search-contract/package.json @@ -0,0 +1,29 @@ +{ + "name": "@dashevo/search-contract", + "version": "1.6.2", + "description": "A contract that allows searching for contracts", + "scripts": { + "lint": "eslint .", + "test": "yarn run test:unit", + "test:unit": "mocha 'test/unit/**/*.spec.js'" + }, + "contributors": [ + { + "name": "Samuel Westrich", + "email": "sam@dash.org", + "url": "https://github.com/quantumexplorer" + } + ], + "license": "MIT", + "devDependencies": { + "@dashevo/wasm-dpp": "workspace:*", + "chai": "^4.3.10", + "dirty-chai": "^2.0.1", + "eslint": "^8.53.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.29.0", + "mocha": "^10.2.0", + "sinon": "^17.0.1", + "sinon-chai": "^3.7.0" + } +} diff --git a/packages/search-contract/schema/v1/search-contract-documents.json b/packages/search-contract/schema/v1/search-contract-documents.json new file mode 100644 index 00000000000..f146ecb3e6c --- /dev/null +++ b/packages/search-contract/schema/v1/search-contract-documents.json @@ -0,0 +1,62 @@ +{ + "contract": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "referenceType": "contract", + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byKeyword", + "properties": [ + { + "keyword": "asc" + } + ] + } + ], + "properties": { + "keyword": { + "type": "string", + "minLength": 3, + "maxLength": 50, + "position": 0 + } + }, + "required": [ + "$contractId", + "keyword" + ], + "additionalProperties": false + }, + "token": { + "type": "object", + "documentsMutable": false, + "canBeDeleted": false, + "referenceType": "token", + "creationRestrictionMode": 2, + "indices": [ + { + "name": "byKeyword", + "properties": [ + { + "keyword": "asc" + } + ] + } + ], + "properties": { + "keyword": { + "type": "string", + "minLength": 3, + "maxLength": 50, + "position": 0 + } + }, + "required": [ + "$tokenId", + "keyword" + ], + "additionalProperties": false + } +} diff --git a/packages/search-contract/src/error.rs b/packages/search-contract/src/error.rs new file mode 100644 index 00000000000..d01bbcc91cf --- /dev/null +++ b/packages/search-contract/src/error.rs @@ -0,0 +1,17 @@ +use platform_version::version::FeatureVersion; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + /// Platform expected some specific versions + #[error("platform unknown version on {method}, received: {received}")] + UnknownVersionMismatch { + /// method + method: String, + /// the allowed versions for this method + known_versions: Vec, + /// requested core height + received: FeatureVersion, + }, + #[error("schema deserialize error: {0}")] + InvalidSchemaJson(#[from] serde_json::Error), +} diff --git a/packages/search-contract/src/lib.rs b/packages/search-contract/src/lib.rs new file mode 100644 index 00000000000..f7767ea6c26 --- /dev/null +++ b/packages/search-contract/src/lib.rs @@ -0,0 +1,37 @@ +mod error; +pub mod v1; + +pub use crate::error::Error; +use platform_value::{Identifier, IdentifierBytes32}; +use platform_version::version::PlatformVersion; +use serde_json::Value; + +pub const ID_BYTES: [u8; 32] = [ + 92, 20, 14, 101, 92, 2, 101, 187, 194, 168, 8, 113, 109, 225, 132, 121, 133, 19, 89, 24, 173, + 81, 205, 253, 11, 118, 102, 75, 169, 91, 163, 124, +]; + +pub const OWNER_ID_BYTES: [u8; 32] = [0; 32]; + +pub const ID: Identifier = Identifier(IdentifierBytes32(ID_BYTES)); +pub const OWNER_ID: Identifier = Identifier(IdentifierBytes32(OWNER_ID_BYTES)); +pub fn load_definitions(platform_version: &PlatformVersion) -> Result, Error> { + match platform_version.system_data_contracts.withdrawals { + 1 => Ok(None), + version => Err(Error::UnknownVersionMismatch { + method: "search_contract::load_definitions".to_string(), + known_versions: vec![1], + received: version, + }), + } +} +pub fn load_documents_schemas(platform_version: &PlatformVersion) -> Result { + match platform_version.system_data_contracts.withdrawals { + 1 => v1::load_documents_schemas(), + version => Err(Error::UnknownVersionMismatch { + method: "search_contract::load_documents_schemas".to_string(), + known_versions: vec![1], + received: version, + }), + } +} diff --git a/packages/search-contract/src/v1/mod.rs b/packages/search-contract/src/v1/mod.rs new file mode 100644 index 00000000000..e5d6a067712 --- /dev/null +++ b/packages/search-contract/src/v1/mod.rs @@ -0,0 +1,27 @@ +use crate::Error; +use serde_json::Value; + +pub mod document_types { + pub mod contract { + pub const NAME: &str = "contract"; + + pub mod properties { + pub const KEY_INDEX: &str = "byKeyword"; + } + } + + pub mod token { + pub const NAME: &str = "token"; + + pub mod properties { + pub const KEY_INDEX: &str = "byKeyword"; + } + } +} + +pub fn load_documents_schemas() -> Result { + serde_json::from_str(include_str!( + "../../schema/v1/search-contract-documents.json" + )) + .map_err(Error::InvalidSchemaJson) +} diff --git a/packages/search-contract/test/.eslintrc b/packages/search-contract/test/.eslintrc new file mode 100644 index 00000000000..720ced73852 --- /dev/null +++ b/packages/search-contract/test/.eslintrc @@ -0,0 +1,12 @@ +{ + "env": { + "node": true, + "mocha": true + }, + "rules": { + "import/no-extraneous-dependencies": "off" + }, + "globals": { + "expect": true + } +} diff --git a/packages/search-contract/test/bootstrap.js b/packages/search-contract/test/bootstrap.js new file mode 100644 index 00000000000..7af04f464d7 --- /dev/null +++ b/packages/search-contract/test/bootstrap.js @@ -0,0 +1,30 @@ +const sinon = require('sinon'); +const sinonChai = require('sinon-chai'); + +const { expect, use } = require('chai'); +const dirtyChai = require('dirty-chai'); + +const { + default: loadWasmDpp, +} = require('@dashevo/wasm-dpp'); + +use(dirtyChai); +use(sinonChai); + +exports.mochaHooks = { + beforeAll: loadWasmDpp, + + beforeEach() { + if (!this.sinon) { + this.sinon = sinon.createSandbox(); + } else { + this.sinon.restore(); + } + }, + + afterEach() { + this.sinon.restore(); + }, +}; + +global.expect = expect; diff --git a/packages/search-contract/test/unit/searchContract.spec.js b/packages/search-contract/test/unit/searchContract.spec.js new file mode 100644 index 00000000000..2fd94a879b7 --- /dev/null +++ b/packages/search-contract/test/unit/searchContract.spec.js @@ -0,0 +1,187 @@ +const crypto = require('crypto'); + +const { + DashPlatformProtocol, + JsonSchemaError, +} = require('@dashevo/wasm-dpp'); +const generateRandomIdentifier = require('@dashevo/wasm-dpp/lib/test/utils/generateRandomIdentifierAsync'); + +const { expect } = require('chai'); +const walletContractDocumentsSchema = require('../../schema/v1/search-contract-documents.json'); + +const expectJsonSchemaError = (validationResult, errorCount = 1) => { + const errors = validationResult.getErrors(); + expect(errors) + .to + .have + .length(errorCount); + + const error = validationResult.getErrors()[0]; + expect(error) + .to + .be + .instanceof(JsonSchemaError); + + return error; +}; + +describe('Search Contract', () => { + let dpp; + let dataContract; + let identityId; + + beforeEach(async () => { + dpp = new DashPlatformProtocol( + { generate: () => crypto.randomBytes(32) }, + ); + + identityId = await generateRandomIdentifier(); + + dataContract = dpp.dataContract.create(identityId, BigInt(1), walletContractDocumentsSchema); + }); + + it('should have a valid contract definition', async () => { + expect(() => dpp.dataContract.create(identityId, BigInt(1), walletContractDocumentsSchema)) + .to + .not + .throw(); + }); + + describe('documents', () => { + describe('txMetadata', () => { + let rawTxMetadataDocument; + + beforeEach(() => { + rawTxMetadataDocument = { + keyIndex: 0, + encryptionKeyIndex: 100, + encryptedMetadata: crypto.randomBytes(64), + }; + }); + + describe('keyIndex', () => { + it('should be defined', async () => { + delete rawTxMetadataDocument.keyIndex; + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('required'); + expect(error.params.missingProperty) + .to + .equal('keyIndex'); + }); + + it('should be a non-negative integer', async () => { + rawTxMetadataDocument.keyIndex = -1; + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + describe('encryptionKeyIndex', () => { + it('should be defined', async () => { + delete rawTxMetadataDocument.encryptionKeyIndex; + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('required'); + expect(error.params.missingProperty) + .to + .equal('encryptionKeyIndex'); + }); + + it('should be a non-negative integer', async () => { + rawTxMetadataDocument.encryptionKeyIndex = -1; + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + describe('encryptedMetadata', () => { + it('should be defined', async () => { + delete rawTxMetadataDocument.encryptedMetadata; + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('required'); + expect(error.params.missingProperty) + .to + .equal('encryptedMetadata'); + }); + + it('should be not shorter than 32 bytes', async () => { + rawTxMetadataDocument.encryptedMetadata = crypto.randomBytes(31); + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('minItems'); + expect(error.instancePath) + .to + .equal('/encryptedMetadata'); + }); + + it('should be not longer than 4096 bytes', async () => { + rawTxMetadataDocument.encryptedMetadata = crypto.randomBytes(4097); + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('maxItems'); + expect(error.instancePath) + .to + .equal('/encryptedMetadata'); + }); + }); + + it('should not have additional properties', async () => { + rawTxMetadataDocument.someOtherProperty = 42; + + const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + + expect(error.keyword) + .to + .equal('additionalProperties'); + expect(error.params.additionalProperties) + .to + .deep + .equal(['someOtherProperty']); + }); + + it('should be valid', async () => { + const txMetadata = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); + + const result = await txMetadata.validate(dpp.protocolVersion); + + expect(result.isValid()) + .to + .be + .true(); + }); + }); + }); +}); From e800861f787b88d327243fe6bbd47d6a86de5bbe Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 13 Jan 2025 04:09:29 +0700 Subject: [PATCH 54/61] more token support --- .../engine/run_block_proposal/v0/mod.rs | 2 +- .../mod.rs | 0 .../v0/mod.rs | 0 .../mod.rs | 2 +- .../mod.rs | 17 +++-- .../v0/mod.rs | 4 +- .../v1/mod.rs | 68 +++++++++++++++++++ .../tests.rs | 0 .../src/execution/platform_events/mod.rs | 2 +- .../validate_token_aggregated_balance/mod.rs | 53 +++++++++++++++ .../{v0.rs => v0/mod.rs} | 7 +- .../state_transitions/identity_create/mod.rs | 12 ++-- .../state_transition/state_transitions/mod.rs | 2 +- packages/rs-drive-abci/src/main.rs | 4 +- .../src/platform_types/platform/mod.rs | 16 +++-- .../tests/strategy_tests/main.rs | 2 +- .../tests/strategy_tests/token_tests.rs | 3 - .../contract/insert/insert_contract/v1/mod.rs | 5 ++ .../credit_pools/epochs/operations_factory.rs | 12 ++-- .../v0/mod.rs | 2 +- .../get_unpaid_epoch_index/v0/mod.rs | 2 +- .../rs-drive/src/drive/document/delete/mod.rs | 5 +- .../rs-drive/src/drive/document/update/mod.rs | 8 +-- .../merge_identity_contract_nonce/v0/mod.rs | 2 +- .../fetch/fetch_by_public_key_hashes/mod.rs | 2 +- .../identity/insert/add_new_identity/mod.rs | 6 +- .../src/drive/identity/key/fetch/mod.rs | 8 +-- .../add_new_unique_keys_to_identity/v0/mod.rs | 1 - .../rs-drive/src/drive/identity/update/mod.rs | 29 +++++--- .../merge_identity_nonce_operations/v0/mod.rs | 2 +- .../src/drive/initialization/v0/mod.rs | 2 +- .../src/drive/system/genesis_time/mod.rs | 6 +- packages/rs-drive/src/open/mod.rs | 18 +++-- packages/rs-drive/src/query/mod.rs | 10 +-- .../v0/mod.rs | 10 +-- .../batch_move_items_in_path_query/v0/mod.rs | 6 +- .../rs-drive/src/util/test_helpers/setup.rs | 19 ++++-- .../rs-drive/tests/deterministic_root_hash.rs | 4 +- packages/rs-drive/tests/query_tests.rs | 16 ++--- .../rs-drive/tests/query_tests_history.rs | 2 +- .../drive_abci_method_versions/mod.rs | 8 ++- .../drive_abci_method_versions/v1.rs | 8 ++- .../drive_abci_method_versions/v2.rs | 8 ++- .../drive_abci_method_versions/v3.rs | 8 ++- .../drive_abci_method_versions/v4.rs | 8 ++- .../drive_abci_method_versions/v5.rs | 8 ++- .../src/version/drive_versions/v3.rs | 4 +- .../src/version/mocks/v3_test.rs | 8 ++- 48 files changed, 308 insertions(+), 123 deletions(-) rename packages/rs-drive-abci/src/execution/platform_events/{block_fee_processing => block_processing_end_events}/add_process_epoch_change_operations/mod.rs (100%) rename packages/rs-drive-abci/src/execution/platform_events/{block_fee_processing => block_processing_end_events}/add_process_epoch_change_operations/v0/mod.rs (100%) rename packages/rs-drive-abci/src/execution/platform_events/{block_fee_processing => block_processing_end_events}/mod.rs (56%) rename packages/rs-drive-abci/src/execution/platform_events/{block_fee_processing/process_block_fees => block_processing_end_events/process_block_fees_and_validate_sum_trees}/mod.rs (79%) rename packages/rs-drive-abci/src/execution/platform_events/{block_fee_processing/process_block_fees => block_processing_end_events/process_block_fees_and_validate_sum_trees}/v0/mod.rs (99%) create mode 100644 packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs rename packages/rs-drive-abci/src/execution/platform_events/{block_fee_processing => block_processing_end_events}/tests.rs (100%) rename packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/{v0.rs => v0/mod.rs} (80%) diff --git a/packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs b/packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs index 4cef4a48bca..d6097a5d8ad 100644 --- a/packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs @@ -364,7 +364,7 @@ where let block_fees_v0: BlockFeesV0 = state_transitions_result.aggregated_fees().clone().into(); // Process fees - let processed_block_fees = self.process_block_fees( + let processed_block_fees = self.process_block_fees_and_validate_sum_trees( &block_execution_context, block_fees_v0.into(), transaction, diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/add_process_epoch_change_operations/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/add_process_epoch_change_operations/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/add_process_epoch_change_operations/mod.rs rename to packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/add_process_epoch_change_operations/mod.rs diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/add_process_epoch_change_operations/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/add_process_epoch_change_operations/v0/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/add_process_epoch_change_operations/v0/mod.rs rename to packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/add_process_epoch_change_operations/v0/mod.rs diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/mod.rs similarity index 56% rename from packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/mod.rs rename to packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/mod.rs index 232c76143e8..03c783e1dd9 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/mod.rs @@ -1,5 +1,5 @@ mod add_process_epoch_change_operations; -pub mod process_block_fees; +pub mod process_block_fees_and_validate_sum_trees; #[cfg(test)] mod tests; diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/process_block_fees/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/mod.rs similarity index 79% rename from packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/process_block_fees/mod.rs rename to packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/mod.rs index 7ab4cbe08d8..012bc0528b9 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/process_block_fees/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/mod.rs @@ -1,4 +1,5 @@ mod v0; +mod v1; use dpp::version::PlatformVersion; @@ -34,7 +35,7 @@ impl Platform { /// * `Result` - /// If the operation is successful, it returns `Ok(ProcessedBlockFeesOutcome)`. If there is an error, it returns `Error`. /// - pub fn process_block_fees( + pub fn process_block_fees_and_validate_sum_trees( &self, block_execution_context: &BlockExecutionContext, block_fees: BlockFees, @@ -45,17 +46,23 @@ impl Platform { .drive_abci .methods .block_fee_processing - .process_block_fees + .process_block_fees_and_validate_sum_trees { - 0 => self.process_block_fees_v0( + 0 => self.process_block_fees_and_validate_sum_trees_v0( + block_execution_context, + block_fees, + transaction, + platform_version, + ), + 1 => self.process_block_fees_and_validate_sum_trees_v1( block_execution_context, block_fees, transaction, platform_version, ), version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { - method: "process_block_fees".to_string(), - known_versions: vec![0], + method: "process_block_fees_and_validate_sum_trees".to_string(), + known_versions: vec![0, 1], received: version, })), } diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/process_block_fees/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v0/mod.rs similarity index 99% rename from packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/process_block_fees/v0/mod.rs rename to packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v0/mod.rs index 4bb341a678e..a3fa6719562 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/process_block_fees/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v0/mod.rs @@ -47,7 +47,7 @@ impl Platform { /// /// Returns `ProcessedBlockFeesOutcome`. #[inline(always)] - pub(super) fn process_block_fees_v0( + pub(super) fn process_block_fees_and_validate_sum_trees_v0( &self, block_execution_context: &BlockExecutionContext, block_fees: BlockFees, @@ -274,7 +274,7 @@ mod tests { }; let storage_fee_distribution_outcome = platform - .process_block_fees_v0( + .process_block_fees_and_validate_sum_trees_v0( &block_execution_context.into(), block_fees.clone(), transaction, diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs new file mode 100644 index 00000000000..5fbaadd8f7c --- /dev/null +++ b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs @@ -0,0 +1,68 @@ +//! Block Fees Processing. +//! +//! This module defines functions related to processing block fees upon block and +//! epoch changes. +//! + +use std::option::Option::None; + +use dpp::block::epoch::Epoch; +use dpp::version::PlatformVersion; +use drive::drive::Drive; +use drive::grovedb::Transaction; +use drive::util::batch::DriveOperation; + +use crate::error::execution::ExecutionError; +use crate::error::Error; +use crate::execution::types::block_execution_context::v0::BlockExecutionContextV0Getters; +use crate::execution::types::block_execution_context::BlockExecutionContext; +use crate::execution::types::block_fees::v0::BlockFeesV0Getters; +use crate::execution::types::block_fees::BlockFees; +use crate::execution::types::block_state_info::v0::{ + BlockStateInfoV0Getters, BlockStateInfoV0Methods, +}; +use crate::execution::types::processed_block_fees_outcome; +use crate::platform_types::epoch_info::v0::EpochInfoV0Getters; +use crate::platform_types::platform::Platform; + +use crate::platform_types::platform_state::v0::PlatformStateV0Methods; +use drive::drive::credit_pools::epochs::operations_factory::EpochOperations; + +/// From the Dash Improvement Proposal: + +/// For the purpose of this explanation we can trivialize that the execution of a block comprises +/// the sum of the execution of all state transitions contained within the block. In order to +/// avoid altering participating masternode identity balances every block and distribute fees +/// evenly, the concept of pools is introduced. We will also introduce the concepts of an Epoch +/// and the Epoch Era that are both covered later in this document. As the block executes state +/// transitions, processing and storage fees are accumulated, as well as a list of refunded fees +/// from various Epochs and fee multipliers. When there are no more state transitions to execute +/// we can say the block has ended its state transition execution phase. The system will then add +/// the accumulated fees to their corresponding pools, and in the case of deletion of data, remove +/// storage fees from future Epoch storage pools. + +impl Platform { + /// Adds operations to GroveDB op batch related to processing + /// and distributing the block fees from the previous block and applies the batch. + /// + /// Returns `ProcessedBlockFeesOutcome`. + #[inline(always)] + pub(super) fn process_block_fees_and_validate_sum_trees_v1( + &self, + block_execution_context: &BlockExecutionContext, + block_fees: BlockFees, + transaction: &Transaction, + platform_version: &PlatformVersion, + ) -> Result { + let outcome = self.process_block_fees_and_validate_sum_trees_v0( + block_execution_context, + block_fees, + transaction, + platform_version, + )?; + + self.validate_token_aggregated_balance(transaction, platform_version)?; + + Ok(outcome) + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/platform_events/block_fee_processing/tests.rs rename to packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs diff --git a/packages/rs-drive-abci/src/execution/platform_events/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/mod.rs index 759deac244c..1ac0715b9d2 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/mod.rs @@ -1,7 +1,7 @@ /// Methods occurring at the finalization of a block pub(in crate::execution) mod block_end; /// Block fee processing -pub(in crate::execution) mod block_fee_processing; +pub(in crate::execution) mod block_processing_end_events; /// Events happening what starting to process a block pub(in crate::execution) mod block_start; /// Update from core such as a masternode list update or quorums being updated diff --git a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/mod.rs index e084dffc38f..68718a29b63 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/mod.rs @@ -1 +1,54 @@ mod v0; + +use dpp::version::PlatformVersion; + +use drive::grovedb::Transaction; + +use crate::error::execution::ExecutionError; +use crate::error::Error; + +use crate::platform_types::platform::Platform; + +impl Platform { + /// Validates the aggregated token balance for the platform. + /// + /// This function verifies that the total token balances in the platform are consistent + /// and correctly aggregated. It delegates the validation to a version-specific implementation + /// based on the `PlatformVersion` provided. + /// + /// # Arguments + /// + /// * `transaction` - A reference to the current transaction. + /// * `platform_version` - The platform version specifying the implementation to use. + /// + /// # Returns + /// + /// * `Ok(())` if the token balances are validated successfully. + /// * `Err(Error)` if the validation fails due to inconsistencies or an unknown version. + /// + /// # Errors + /// + /// Returns an `ExecutionError::CorruptedCreditsNotBalanced` if the token sum trees + /// are not balanced. + /// + /// Returns an `ExecutionError::UnknownVersionMismatch` if the platform version is not recognized. + pub fn validate_token_aggregated_balance( + &self, + transaction: &Transaction, + platform_version: &PlatformVersion, + ) -> Result<(), Error> { + match platform_version + .drive_abci + .methods + .tokens_processing + .validate_token_aggregated_balance + { + 0 => self.validate_token_aggregated_balance_v0(transaction, platform_version), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "validate_token_aggregated_balance".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0/mod.rs similarity index 80% rename from packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs rename to packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0/mod.rs index 34362477603..59e60de94c7 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0/mod.rs @@ -6,15 +6,10 @@ use crate::execution::types::block_execution_context::BlockExecutionContext; use crate::platform_types::platform::Platform; use dpp::version::PlatformVersion; -impl Platform { - /// Adds operations to GroveDB op batch related to processing - /// and distributing the block fees from the previous block and applies the batch. - /// - /// Returns `ProcessedBlockFeesOutcome`. +impl Platform { #[inline(always)] pub(super) fn validate_token_aggregated_balance_v0( &self, - block_execution_context: &BlockExecutionContext, transaction: &Transaction, platform_version: &PlatformVersion, ) -> Result<(), Error> { 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 12b36b9479a..2e2cab9ece8 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 @@ -423,7 +423,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 1913060); + assert_eq!(processing_result.aggregated_fees().processing_fee, 1913100); platform .drive @@ -438,7 +438,7 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 99913873940); + assert_eq!(identity_balance, 99913873900); } #[test] @@ -868,7 +868,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 2188720); + assert_eq!(processing_result.aggregated_fees().processing_fee, 2188760); platform .drive @@ -883,7 +883,7 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 99909268580); // The identity balance is smaller than if there hadn't been any issue + assert_eq!(identity_balance, 99909268540); // The identity balance is smaller than if there hadn't been any issue } #[test] @@ -1820,7 +1820,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 2188720); + assert_eq!(processing_result.aggregated_fees().processing_fee, 2188760); platform .drive @@ -1835,6 +1835,6 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 99909268580); // The identity balance is smaller than if there hadn't been any issue + assert_eq!(identity_balance, 99909268540); // The identity balance is smaller than if there hadn't been any issue } } 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 bea871af407..0c7b345be77 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 @@ -482,7 +482,7 @@ pub(in crate::execution) mod tests { // Process fees let processed_block_fees = platform - .process_block_fees( + .process_block_fees_and_validate_sum_trees( &block_execution_context, block_fees_v0.into(), &transaction, diff --git a/packages/rs-drive-abci/src/main.rs b/packages/rs-drive-abci/src/main.rs index a8ae1adccdc..67a68a40914 100644 --- a/packages/rs-drive-abci/src/main.rs +++ b/packages/rs-drive-abci/src/main.rs @@ -468,10 +468,10 @@ mod test { let path = tempdir.join("db"); fs::create_dir(&path).expect("create db dir"); - let (drive, _) = Drive::open(&path, None).expect("open drive"); - let platform_version = PlatformVersion::latest(); + let (drive, _) = Drive::open(&path, None, Some(platform_version)).expect("open drive"); + drive .create_initial_state_structure(None, platform_version) .expect("should create root tree successfully"); diff --git a/packages/rs-drive-abci/src/platform_types/platform/mod.rs b/packages/rs-drive-abci/src/platform_types/platform/mod.rs index d5d99f71b37..379c3a4b571 100644 --- a/packages/rs-drive-abci/src/platform_types/platform/mod.rs +++ b/packages/rs-drive-abci/src/platform_types/platform/mod.rs @@ -180,12 +180,18 @@ impl Platform { { let config = config.unwrap_or(PlatformConfig::default_testnet()); - let (drive, current_protocol_version) = - Drive::open(path, Some(config.drive.clone())).map_err(Error::Drive)?; - - if let Some(protocol_version) = current_protocol_version { - let platform_version = PlatformVersion::get(protocol_version)?; + let default_initial_platform_version = initial_protocol_version + .map(|protocol_version| PlatformVersion::get(protocol_version)) + .transpose()?; + + let (drive, current_platform_version) = Drive::open( + path, + Some(config.drive.clone()), + default_initial_platform_version, + ) + .map_err(Error::Drive)?; + if let Some(platform_version) = current_platform_version { let Some(execution_state) = Platform::::fetch_platform_state(&drive, None, platform_version)? else { diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index eeb7e1874e9..428868c8ece 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -604,7 +604,7 @@ mod tests { .expect("expected to fetch balances") .expect("expected to have an identity to get balance from"); - assert_eq!(balance, 99864009980) + assert_eq!(balance, 99864009940) } #[test] diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs index 4c5aae85f02..f51d24c7349 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -3,12 +3,9 @@ mod tests { use crate::execution::run_chain_for_strategy; use crate::strategy::NetworkStrategy; use dpp::dash_to_duffs; - use dpp::data_contract::accessors::v0::DataContractV0Setters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::Identity; - use dpp::platform_value::string_encoding::Encoding; - use dpp::prelude::Identifier; use dpp::state_transition::StateTransition; use dpp::tests::json_document::json_document_to_created_contract; use dpp::tokens::token_event::TokenEvent; diff --git a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs index 69f9dfe2ba7..5f4bdb6dbba 100644 --- a/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs +++ b/packages/rs-drive/src/drive/contract/insert/insert_contract/v1/mod.rs @@ -187,6 +187,11 @@ impl Drive { estimated_costs_only_with_layer_info, &platform_version.drive, )?; + Drive::add_estimation_costs_for_token_identity_infos( + token_id_bytes, + estimated_costs_only_with_layer_info, + &platform_version.drive, + )?; Drive::add_estimation_costs_for_token_total_supply( estimated_costs_only_with_layer_info, &platform_version.drive, diff --git a/packages/rs-drive/src/drive/credit_pools/epochs/operations_factory.rs b/packages/rs-drive/src/drive/credit_pools/epochs/operations_factory.rs index ebc0d9ed5ae..b6ea2661eae 100644 --- a/packages/rs-drive/src/drive/credit_pools/epochs/operations_factory.rs +++ b/packages/rs-drive/src/drive/credit_pools/epochs/operations_factory.rs @@ -425,7 +425,7 @@ mod tests { #[test] fn test_error_if_fee_pools_not_initialized() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); let platform_version = PlatformVersion::first(); @@ -449,10 +449,9 @@ mod tests { #[test] fn test_values_are_set() { - let drive = setup_drive_with_initial_state_structure(None); - let transaction = drive.grove.start_transaction(); - let platform_version = PlatformVersion::first(); + let drive = setup_drive_with_initial_state_structure(Some(platform_version)); + let transaction = drive.grove.start_transaction(); let epoch = Epoch::new(1042).unwrap(); @@ -484,10 +483,9 @@ mod tests { #[test] fn test_values_are_set() { - let drive = setup_drive_with_initial_state_structure(None); - let transaction = drive.grove.start_transaction(); - let platform_version = PlatformVersion::first(); + let drive = setup_drive_with_initial_state_structure(Some(platform_version)); + let transaction = drive.grove.start_transaction(); let epoch = Epoch::new(1042).unwrap(); diff --git a/packages/rs-drive/src/drive/credit_pools/storage_fee_distribution_pool/get_storage_fees_from_distribution_pool/v0/mod.rs b/packages/rs-drive/src/drive/credit_pools/storage_fee_distribution_pool/get_storage_fees_from_distribution_pool/v0/mod.rs index ee90eec06c4..bf740821f00 100644 --- a/packages/rs-drive/src/drive/credit_pools/storage_fee_distribution_pool/get_storage_fees_from_distribution_pool/v0/mod.rs +++ b/packages/rs-drive/src/drive/credit_pools/storage_fee_distribution_pool/get_storage_fees_from_distribution_pool/v0/mod.rs @@ -52,7 +52,7 @@ mod tests { #[test] fn test_error_if_epoch_is_not_initiated() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); let platform_version = PlatformVersion::first(); diff --git a/packages/rs-drive/src/drive/credit_pools/unpaid_epoch/get_unpaid_epoch_index/v0/mod.rs b/packages/rs-drive/src/drive/credit_pools/unpaid_epoch/get_unpaid_epoch_index/v0/mod.rs index bcfdaf59b1b..def6c7f229d 100644 --- a/packages/rs-drive/src/drive/credit_pools/unpaid_epoch/get_unpaid_epoch_index/v0/mod.rs +++ b/packages/rs-drive/src/drive/credit_pools/unpaid_epoch/get_unpaid_epoch_index/v0/mod.rs @@ -57,7 +57,7 @@ mod tests { #[test] fn test_error_if_fee_pools_tree_is_not_initiated() { let platform_version = PlatformVersion::latest(); - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); let result = drive.get_unpaid_epoch_index_v0(Some(&transaction), platform_version); diff --git a/packages/rs-drive/src/drive/document/delete/mod.rs b/packages/rs-drive/src/drive/document/delete/mod.rs index 7edbfa42a27..5a1d2ebbb2d 100644 --- a/packages/rs-drive/src/drive/document/delete/mod.rs +++ b/packages/rs-drive/src/drive/document/delete/mod.rs @@ -87,10 +87,11 @@ mod tests { fn test_add_and_remove_family_one_document_no_transaction() { let tmp_dir = TempDir::new().unwrap(); - let (drive, _) = Drive::open(tmp_dir, None).expect("expected to open Drive successfully"); - let platform_version = PlatformVersion::latest(); + let (drive, _) = Drive::open(tmp_dir, None, Some(platform_version)) + .expect("expected to open Drive successfully"); + drive .create_initial_state_structure(None, platform_version) .expect("expected to create root tree successfully"); diff --git a/packages/rs-drive/src/drive/document/update/mod.rs b/packages/rs-drive/src/drive/document/update/mod.rs index cd5ef18a076..478921f994e 100644 --- a/packages/rs-drive/src/drive/document/update/mod.rs +++ b/packages/rs-drive/src/drive/document/update/mod.rs @@ -852,7 +852,7 @@ mod tests { let platform_version = PlatformVersion::latest(); - let drive: Drive = setup_drive(Some(config)); + let drive: Drive = setup_drive(Some(config), None); let transaction = if using_transaction { Some(drive.grove.start_transaction()) @@ -1155,7 +1155,7 @@ mod tests { let platform_version = PlatformVersion::latest(); - let drive: Drive = setup_drive(Some(config)); + let drive: Drive = setup_drive(Some(config), None); let transaction = if using_transaction { Some(drive.grove.start_transaction()) @@ -1362,7 +1362,7 @@ mod tests { let platform_version = PlatformVersion::latest(); - let drive: Drive = setup_drive(Some(config)); + let drive: Drive = setup_drive(Some(config), None); let transaction = if using_transaction { Some(drive.grove.start_transaction()) @@ -1705,7 +1705,7 @@ mod tests { let platform_version = PlatformVersion::latest(); - let drive: Drive = setup_drive(Some(config)); + let drive: Drive = setup_drive(Some(config), None); let transaction = if using_transaction { Some(drive.grove.start_transaction()) diff --git a/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs b/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs index 500e9ba394e..9585f029fe6 100644 --- a/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/contract_info/identity_contract_nonce/merge_identity_contract_nonce/v0/mod.rs @@ -302,7 +302,7 @@ mod tests { use platform_version::version::PlatformVersion; fn setup_base_test(contract_id: [u8; 32]) -> (Drive, Identity) { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); let platform_version = PlatformVersion::first(); diff --git a/packages/rs-drive/src/drive/identity/fetch/fetch_by_public_key_hashes/mod.rs b/packages/rs-drive/src/drive/identity/fetch/fetch_by_public_key_hashes/mod.rs index 9a928d7b272..859982396ab 100644 --- a/packages/rs-drive/src/drive/identity/fetch/fetch_by_public_key_hashes/mod.rs +++ b/packages/rs-drive/src/drive/identity/fetch/fetch_by_public_key_hashes/mod.rs @@ -21,7 +21,7 @@ mod tests { #[test] fn test_fetch_all_keys_on_identity() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let drive_version = &platform_version.drive; diff --git a/packages/rs-drive/src/drive/identity/insert/add_new_identity/mod.rs b/packages/rs-drive/src/drive/identity/insert/add_new_identity/mod.rs index 3494ceb37ca..16f9767ef34 100644 --- a/packages/rs-drive/src/drive/identity/insert/add_new_identity/mod.rs +++ b/packages/rs-drive/src/drive/identity/insert/add_new_identity/mod.rs @@ -150,7 +150,9 @@ mod tests { let platform_version = PlatformVersion::latest(); let expected_fee_result = FeeResult { storage_fee: 128871000, - processing_fee: 2330320, + // 2 extra loaded bytes because the token tree is no longer empty + // these 2 loaded bytes cost 20 credits each + processing_fee: 2330360, ..Default::default() }; @@ -186,7 +188,7 @@ mod tests { platform_version: &PlatformVersion, expected_fee_result: FeeResult, ) { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); diff --git a/packages/rs-drive/src/drive/identity/key/fetch/mod.rs b/packages/rs-drive/src/drive/identity/key/fetch/mod.rs index 75466736bd2..44d104288a5 100644 --- a/packages/rs-drive/src/drive/identity/key/fetch/mod.rs +++ b/packages/rs-drive/src/drive/identity/key/fetch/mod.rs @@ -1027,7 +1027,7 @@ mod tests { #[test] fn test_fetch_all_keys_on_identity() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); @@ -1063,7 +1063,7 @@ mod tests { #[test] fn test_fetch_single_identity_key() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); @@ -1103,7 +1103,7 @@ mod tests { #[test] fn test_fetch_multiple_identity_key() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); @@ -1143,7 +1143,7 @@ mod tests { #[test] fn test_fetch_unknown_identity_key_returns_not_found() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); diff --git a/packages/rs-drive/src/drive/identity/update/methods/add_new_unique_keys_to_identity/v0/mod.rs b/packages/rs-drive/src/drive/identity/update/methods/add_new_unique_keys_to_identity/v0/mod.rs index 7ca4f44d18a..70de562e499 100644 --- a/packages/rs-drive/src/drive/identity/update/methods/add_new_unique_keys_to_identity/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/update/methods/add_new_unique_keys_to_identity/v0/mod.rs @@ -45,7 +45,6 @@ impl Drive { &mut drive_operations, &platform_version.drive, )?; - println!("{:?}", drive_operations); let fees = Drive::calculate_fee( None, Some(drive_operations), diff --git a/packages/rs-drive/src/drive/identity/update/mod.rs b/packages/rs-drive/src/drive/identity/update/mod.rs index bae24132457..bffc73961ee 100644 --- a/packages/rs-drive/src/drive/identity/update/mod.rs +++ b/packages/rs-drive/src/drive/identity/update/mod.rs @@ -57,7 +57,9 @@ mod tests { let platform_version = PlatformVersion::latest(); let expected_fee_result = FeeResult { storage_fee: 14202000, - processing_fee: 1098260, + // 2 extra loaded bytes because the token tree is no longer empty + // these 2 loaded bytes cost 20 credits each + processing_fee: 1098300, ..Default::default() }; @@ -81,7 +83,7 @@ mod tests { platform_version: &PlatformVersion, expected_fee_result: FeeResult, ) { - let drive = setup_drive_with_initial_state_structure(None); + let drive = setup_drive_with_initial_state_structure(Some(&platform_version)); let identity = Identity::random_identity(5, Some(12345), platform_version) .expect("expected a random identity"); @@ -143,6 +145,9 @@ mod tests { // ------------------------------------------------- // check_reference_below_tokens_cost (4 tests) + // This test exists to make sure the update cost that goes through the tokens tree + // (as key hash references are below the token tree) + // stay the same cost. // ------------------------------------------------- #[test] fn check_reference_below_tokens_cost_first_version_apply() { @@ -171,7 +176,9 @@ mod tests { let platform_version = PlatformVersion::latest(); let expected_fee_result = FeeResult { storage_fee: 9423000, - processing_fee: 406100, + // 2 extra loaded bytes because the token tree is no longer empty + // these 2 loaded bytes cost 20 credits each + processing_fee: 406140, ..Default::default() }; do_check_reference_below_tokens_cost(true, platform_version, expected_fee_result); @@ -182,7 +189,9 @@ mod tests { let platform_version = PlatformVersion::latest(); let expected_fee_result = FeeResult { storage_fee: 9423000, - processing_fee: 314560, + // 2 extra loaded bytes because the token tree is no longer empty + // these 2 loaded bytes cost 20 credits each + processing_fee: 314600, ..Default::default() }; do_check_reference_below_tokens_cost(false, platform_version, expected_fee_result); @@ -193,7 +202,7 @@ mod tests { platform_version: &PlatformVersion, expected_fee_result: FeeResult, ) { - let drive = setup_drive_with_initial_state_structure(None); + let drive = setup_drive_with_initial_state_structure(Some(platform_version)); let identity = Identity::random_identity(5, Some(12345), platform_version) .expect("expected a random identity"); @@ -302,7 +311,7 @@ mod tests { let platform_version = PlatformVersion::latest(); let expected_fee_result = FeeResult { storage_fee: 347382000, - processing_fee: 6819220, + processing_fee: 6819260, ..Default::default() }; @@ -334,7 +343,7 @@ mod tests { platform_version: &PlatformVersion, expected_fee_result: FeeResult, ) { - let drive = setup_drive_with_initial_state_structure(None); + let drive = setup_drive_with_initial_state_structure(Some(&platform_version)); let identity = Identity::random_identity(5, Some(12345), platform_version) .expect("expected a random identity"); @@ -449,7 +458,7 @@ mod tests { platform_version: &PlatformVersion, expected_fee_result: FeeResult, ) { - let drive = setup_drive_with_initial_state_structure(None); + let drive = setup_drive_with_initial_state_structure(Some(&platform_version)); let identity = Identity::random_identity(5, Some(12345), platform_version) .expect("expected a random identity"); @@ -563,7 +572,7 @@ mod tests { expected_estimated_fee_result: FeeResult, expected_fee_result: FeeResult, ) { - let drive = setup_drive_with_initial_state_structure(None); + let drive = setup_drive_with_initial_state_structure(Some(&platform_version)); let identity = Identity::random_identity(5, Some(12345), platform_version) .expect("expected a random identity"); @@ -682,7 +691,7 @@ mod tests { platform_version: &PlatformVersion, expected_fee_result: FeeResult, ) { - let drive = setup_drive_with_initial_state_structure(None); + let drive = setup_drive_with_initial_state_structure(Some(&platform_version)); let identity = Identity::random_identity(5, Some(12345), platform_version) .expect("expected a random identity"); diff --git a/packages/rs-drive/src/drive/identity/update/operations/merge_identity_nonce_operations/v0/mod.rs b/packages/rs-drive/src/drive/identity/update/operations/merge_identity_nonce_operations/v0/mod.rs index dcca501abd8..5bc218428df 100644 --- a/packages/rs-drive/src/drive/identity/update/operations/merge_identity_nonce_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/update/operations/merge_identity_nonce_operations/v0/mod.rs @@ -177,7 +177,7 @@ mod tests { use platform_version::version::PlatformVersion; fn setup_base_test() -> (Drive, Identity) { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let transaction = drive.grove.start_transaction(); let platform_version = PlatformVersion::first(); diff --git a/packages/rs-drive/src/drive/initialization/v0/mod.rs b/packages/rs-drive/src/drive/initialization/v0/mod.rs index 71a52818d8f..681a9f45d1c 100644 --- a/packages/rs-drive/src/drive/initialization/v0/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v0/mod.rs @@ -660,7 +660,7 @@ mod tests { drive_version, ) .expect("expected to get root elements"); - assert_eq!(proof.len(), 248); //it + left + right + parent + sibling + parent sibling + grandparent + assert_eq!(proof.len(), 250); //it + left + right + parent + sibling + parent sibling + grandparent let mut query = Query::new(); query.insert_key(vec![RootTree::Pools as u8]); diff --git a/packages/rs-drive/src/drive/system/genesis_time/mod.rs b/packages/rs-drive/src/drive/system/genesis_time/mod.rs index 9eee51529b7..93addd701d3 100644 --- a/packages/rs-drive/src/drive/system/genesis_time/mod.rs +++ b/packages/rs-drive/src/drive/system/genesis_time/mod.rs @@ -64,7 +64,7 @@ mod tests { #[test] fn should_return_none_if_cache_is_empty_and_start_time_is_not_persisted() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let result = drive .get_genesis_time(None) @@ -75,7 +75,7 @@ mod tests { #[test] fn should_return_some_if_cache_is_set() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let mut genesis_time_ms_cache = drive.cache.genesis_time_ms.write(); @@ -141,7 +141,7 @@ mod tests { #[test] fn should_set_genesis_time_to_cache() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let genesis_time_ms: u64 = 100; diff --git a/packages/rs-drive/src/open/mod.rs b/packages/rs-drive/src/open/mod.rs index 8e2c599264c..47adf7620d7 100644 --- a/packages/rs-drive/src/open/mod.rs +++ b/packages/rs-drive/src/open/mod.rs @@ -29,7 +29,8 @@ impl Drive { pub fn open>( path: P, config: Option, - ) -> Result<(Self, Option), Error> { + default_platform_version: Option<&PlatformVersion>, + ) -> Result<(Self, Option<&'static PlatformVersion>), Error> { let config = config.unwrap_or_default(); let grove = Arc::new(GroveDb::open(path)?); @@ -42,13 +43,18 @@ impl Drive { let data_contracts_global_cache_size = config.data_contracts_global_cache_size; let data_contracts_block_cache_size = config.data_contracts_block_cache_size; - let protocol_version = Drive::fetch_current_protocol_version_with_grovedb(&grove, None)?; + let maybe_protocol_version = + Drive::fetch_current_protocol_version_with_grovedb(&grove, None)?; + let maybe_platform_version = maybe_protocol_version + .map(|protocol_version| { + PlatformVersion::get(protocol_version).map_err(ProtocolError::PlatformVersionError) + }) + .transpose()?; // At this point we don't know the version what we need to process next block or initialize the chain // so version related data should be updated on init chain or on block execution - let platform_version = - PlatformVersion::get(protocol_version.unwrap_or(INITIAL_PROTOCOL_VERSION)) - .map_err(ProtocolError::PlatformVersionError)?; + let platform_version = maybe_platform_version + .unwrap_or_else(|| default_platform_version.unwrap_or(PlatformVersion::latest())); let drive = Drive { grove, @@ -66,6 +72,6 @@ impl Drive { }, }; - Ok((drive, protocol_version)) + Ok((drive, maybe_platform_version)) } } diff --git a/packages/rs-drive/src/query/mod.rs b/packages/rs-drive/src/query/mod.rs index 03a568103f0..5cdc6dcca6a 100644 --- a/packages/rs-drive/src/query/mod.rs +++ b/packages/rs-drive/src/query/mod.rs @@ -2308,10 +2308,11 @@ mod tests { fn setup_family_contract() -> (Drive, DataContract) { let tmp_dir = TempDir::new().unwrap(); - let (drive, _) = Drive::open(tmp_dir, None).expect("expected to open Drive successfully"); - let platform_version = PlatformVersion::latest(); + let (drive, _) = Drive::open(tmp_dir, None, Some(platform_version)) + .expect("expected to open Drive successfully"); + drive .create_initial_state_structure(None, platform_version) .expect("expected to create root tree successfully"); @@ -2340,10 +2341,11 @@ mod tests { fn setup_withdrawal_contract() -> (Drive, DataContract) { let tmp_dir = TempDir::new().unwrap(); - let (drive, _) = Drive::open(tmp_dir, None).expect("expected to open Drive successfully"); - let platform_version = PlatformVersion::latest(); + let (drive, _) = Drive::open(tmp_dir, None, Some(platform_version)) + .expect("expected to open Drive successfully"); + drive .create_initial_state_structure(None, platform_version) .expect("expected to create root tree successfully"); diff --git a/packages/rs-drive/src/util/grove_operations/batch_delete_items_in_path_query/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_delete_items_in_path_query/v0/mod.rs index 6e5b6179010..3ae43af7c82 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_delete_items_in_path_query/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_delete_items_in_path_query/v0/mod.rs @@ -143,7 +143,7 @@ mod tests { #[test] fn test_batch_delete_items_in_path_query_success() { // Set up a test drive instance and transaction - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); @@ -234,7 +234,7 @@ mod tests { #[test] fn test_batch_delete_items_in_path_query_range_query() { // Set up a test drive instance and transaction - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); @@ -379,7 +379,7 @@ mod tests { #[test] fn test_batch_delete_items_in_path_query_no_elements() { // Set up a test drive instance and transaction - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); @@ -455,7 +455,7 @@ mod tests { #[test] fn test_batch_delete_items_in_path_query_intermediate_path_missing() { // Set up a test drive instance and transaction - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); @@ -491,7 +491,7 @@ mod tests { #[test] fn test_batch_delete_items_in_path_query_stateless_delete() { // Set up a test drive instance and transaction - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); diff --git a/packages/rs-drive/src/util/grove_operations/batch_move_items_in_path_query/v0/mod.rs b/packages/rs-drive/src/util/grove_operations/batch_move_items_in_path_query/v0/mod.rs index 25127f1f66b..15ee4c5bda6 100644 --- a/packages/rs-drive/src/util/grove_operations/batch_move_items_in_path_query/v0/mod.rs +++ b/packages/rs-drive/src/util/grove_operations/batch_move_items_in_path_query/v0/mod.rs @@ -149,7 +149,7 @@ mod tests { #[test] fn test_batch_move_items_in_path_query_success() { // Set up a test drive instance and transaction - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); @@ -305,7 +305,7 @@ mod tests { #[test] fn test_batch_move_items_in_path_query_no_elements() { // Set up a test drive instance and transaction - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); @@ -351,7 +351,7 @@ mod tests { #[test] fn test_batch_move_items_in_path_query_range_query() { // Set up a test drive instance and transaction - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); let transaction = drive.grove.start_transaction(); diff --git a/packages/rs-drive/src/util/test_helpers/setup.rs b/packages/rs-drive/src/util/test_helpers/setup.rs index d80f600def9..bbb935219cc 100644 --- a/packages/rs-drive/src/util/test_helpers/setup.rs +++ b/packages/rs-drive/src/util/test_helpers/setup.rs @@ -36,10 +36,14 @@ impl Default for SetupFeePoolsOptions { #[cfg(feature = "full")] /// Sets up Drive using a temporary directory and the optionally given Drive configuration settings. -pub fn setup_drive(drive_config: Option) -> Drive { +pub fn setup_drive( + drive_config: Option, + specific_platform_version: Option<&PlatformVersion>, +) -> Drive { let tmp_dir = TempDir::new().unwrap(); - let (drive, _) = Drive::open(tmp_dir, drive_config).expect("should open Drive successfully"); + let (drive, _) = Drive::open(tmp_dir, drive_config, specific_platform_version) + .expect("should open Drive successfully"); drive } @@ -49,10 +53,13 @@ pub fn setup_drive(drive_config: Option) -> Drive { pub fn setup_drive_with_initial_state_structure( specific_platform_version: Option<&PlatformVersion>, ) -> Drive { - let drive = setup_drive(Some(DriveConfig { - batching_consistency_verification: true, - ..Default::default() - })); + let drive = setup_drive( + Some(DriveConfig { + batching_consistency_verification: true, + ..Default::default() + }), + specific_platform_version, + ); let platform_version = specific_platform_version.unwrap_or(PlatformVersion::latest()); drive diff --git a/packages/rs-drive/tests/deterministic_root_hash.rs b/packages/rs-drive/tests/deterministic_root_hash.rs index e6f900f401f..690fce96091 100644 --- a/packages/rs-drive/tests/deterministic_root_hash.rs +++ b/packages/rs-drive/tests/deterministic_root_hash.rs @@ -311,7 +311,7 @@ mod tests { /// Runs `test_root_hash_with_batches` 10 times. #[test] fn test_deterministic_root_hash_with_batches_first_platform_version() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::first(); @@ -330,7 +330,7 @@ mod tests { /// Runs `test_root_hash_with_batches` 10 times. #[test] fn test_deterministic_root_hash_with_batches_latest_platform_version() { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let platform_version = PlatformVersion::latest(); diff --git a/packages/rs-drive/tests/query_tests.rs b/packages/rs-drive/tests/query_tests.rs index 1b2eb985936..8451908d687 100644 --- a/packages/rs-drive/tests/query_tests.rs +++ b/packages/rs-drive/tests/query_tests.rs @@ -203,7 +203,7 @@ pub fn setup_family_tests( ) -> (Drive, DataContract) { let drive_config = DriveConfig::default(); - let drive = setup_drive(Some(drive_config)); + let drive = setup_drive(Some(drive_config), None); let db_transaction = drive.grove.start_transaction(); @@ -274,7 +274,7 @@ pub fn setup_family_tests( pub fn setup_family_tests_with_nulls(count: u32, seed: u64) -> (Drive, DataContract) { let drive_config = DriveConfig::default(); - let drive = setup_drive(Some(drive_config)); + let drive = setup_drive(Some(drive_config), None); let db_transaction = drive.grove.start_transaction(); @@ -346,7 +346,7 @@ pub fn setup_family_tests_with_nulls(count: u32, seed: u64) -> (Drive, DataContr pub fn setup_family_tests_only_first_name_index(count: u32, seed: u64) -> (Drive, DataContract) { let drive_config = DriveConfig::default(); - let drive = setup_drive(Some(drive_config)); + let drive = setup_drive(Some(drive_config), None); let db_transaction = drive.grove.start_transaction(); @@ -816,7 +816,7 @@ pub fn setup_dpns_tests_with_batches( seed: u64, platform_version: &PlatformVersion, ) -> (Drive, DataContract) { - let drive = setup_drive(Some(DriveConfig::default())); + let drive = setup_drive(Some(DriveConfig::default()), None); let db_transaction = drive.grove.start_transaction(); @@ -864,7 +864,7 @@ pub fn setup_withdrawal_tests( total_owners: Option, seed: u64, ) -> (Drive, DataContract) { - let drive = setup_drive(Some(DriveConfig::default())); + let drive = setup_drive(Some(DriveConfig::default()), None); let db_transaction = drive.grove.start_transaction(); @@ -910,7 +910,7 @@ pub fn setup_withdrawal_tests( #[cfg(feature = "server")] /// Sets up the References contract to test queries on. pub fn setup_references_tests(_count: u32, _seed: u64) -> (Drive, DataContract) { - let drive = setup_drive(Some(DriveConfig::default())); + let drive = setup_drive(Some(DriveConfig::default()), None); let db_transaction = drive.grove.start_transaction(); @@ -948,7 +948,7 @@ pub fn setup_references_tests(_count: u32, _seed: u64) -> (Drive, DataContract) #[cfg(feature = "server")] /// Sets up and inserts random domain name data to the DPNS contract to test queries on. pub fn setup_dpns_tests_label_not_required(count: u32, seed: u64) -> (Drive, DataContract) { - let drive = setup_drive(Some(DriveConfig::default())); + let drive = setup_drive(Some(DriveConfig::default()), None); let db_transaction = drive.grove.start_transaction(); @@ -987,7 +987,7 @@ pub fn setup_dpns_tests_label_not_required(count: u32, seed: u64) -> (Drive, Dat #[cfg(feature = "server")] /// Sets up the DPNS contract and inserts data from the given path to test queries on. pub fn setup_dpns_test_with_data(path: &str) -> (Drive, DataContract) { - let drive = setup_drive(None); + let drive = setup_drive(None, None); let db_transaction = drive.grove.start_transaction(); diff --git a/packages/rs-drive/tests/query_tests_history.rs b/packages/rs-drive/tests/query_tests_history.rs index c2af5d317e1..1aa1b98fe48 100644 --- a/packages/rs-drive/tests/query_tests_history.rs +++ b/packages/rs-drive/tests/query_tests_history.rs @@ -168,7 +168,7 @@ pub fn setup( let epoch_change_fee_version_test: Lazy = Lazy::new(|| BTreeMap::from([(0, FeeVersion::first())])); - let drive = setup_drive(Some(drive_config)); + let drive = setup_drive(Some(drive_config), None); let db_transaction = drive.grove.start_transaction(); diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs index 8d671176f41..d599036abbb 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/mod.rs @@ -13,6 +13,7 @@ pub struct DriveAbciMethodVersions { pub core_based_updates: DriveAbciCoreBasedUpdatesMethodVersions, pub protocol_upgrade: DriveAbciProtocolUpgradeMethodVersions, pub block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions, + pub tokens_processing: DriveAbciTokensProcessingMethodVersions, pub core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants, pub core_instant_send_lock: DriveAbciCoreInstantSendLockMethodVersions, pub fee_pool_inwards_distribution: DriveAbciFeePoolInwardsDistributionMethodVersions, @@ -76,7 +77,12 @@ pub struct DriveAbciInitializationMethodVersions { #[derive(Clone, Debug, Default)] pub struct DriveAbciBlockFeeProcessingMethodVersions { pub add_process_epoch_change_operations: FeatureVersion, - pub process_block_fees: FeatureVersion, + pub process_block_fees_and_validate_sum_trees: FeatureVersion, +} + +#[derive(Clone, Debug, Default)] +pub struct DriveAbciTokensProcessingMethodVersions { + pub validate_token_aggregated_balance: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs index e6e1c63a401..922358607b9 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v1.rs @@ -8,7 +8,8 @@ use crate::version::drive_abci_versions::drive_abci_method_versions::{ DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, DriveAbciPlatformStateStorageMethodVersions, DriveAbciProtocolUpgradeMethodVersions, - DriveAbciStateTransitionProcessingMethodVersions, DriveAbciVotingMethodVersions, + DriveAbciStateTransitionProcessingMethodVersions, DriveAbciTokensProcessingMethodVersions, + DriveAbciVotingMethodVersions, }; pub const DRIVE_ABCI_METHOD_VERSIONS_V1: DriveAbciMethodVersions = DriveAbciMethodVersions { @@ -52,7 +53,10 @@ pub const DRIVE_ABCI_METHOD_VERSIONS_V1: DriveAbciMethodVersions = DriveAbciMeth }, block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions { add_process_epoch_change_operations: 0, - process_block_fees: 0, + process_block_fees_and_validate_sum_trees: 0, + }, + tokens_processing: DriveAbciTokensProcessingMethodVersions { + validate_token_aggregated_balance: 0, }, core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { choose_quorum: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs index 1e355fa6a2e..fa1db356869 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v2.rs @@ -8,7 +8,8 @@ use crate::version::drive_abci_versions::drive_abci_method_versions::{ DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, DriveAbciPlatformStateStorageMethodVersions, DriveAbciProtocolUpgradeMethodVersions, - DriveAbciStateTransitionProcessingMethodVersions, DriveAbciVotingMethodVersions, + DriveAbciStateTransitionProcessingMethodVersions, DriveAbciTokensProcessingMethodVersions, + DriveAbciVotingMethodVersions, }; pub const DRIVE_ABCI_METHOD_VERSIONS_V2: DriveAbciMethodVersions = DriveAbciMethodVersions { @@ -53,7 +54,10 @@ pub const DRIVE_ABCI_METHOD_VERSIONS_V2: DriveAbciMethodVersions = DriveAbciMeth }, block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions { add_process_epoch_change_operations: 0, - process_block_fees: 0, + process_block_fees_and_validate_sum_trees: 0, + }, + tokens_processing: DriveAbciTokensProcessingMethodVersions { + validate_token_aggregated_balance: 0, }, core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { choose_quorum: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v3.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v3.rs index 2b48e7a0340..c6439e23fdb 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v3.rs @@ -8,7 +8,8 @@ use crate::version::drive_abci_versions::drive_abci_method_versions::{ DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, DriveAbciPlatformStateStorageMethodVersions, DriveAbciProtocolUpgradeMethodVersions, - DriveAbciStateTransitionProcessingMethodVersions, DriveAbciVotingMethodVersions, + DriveAbciStateTransitionProcessingMethodVersions, DriveAbciTokensProcessingMethodVersions, + DriveAbciVotingMethodVersions, }; pub const DRIVE_ABCI_METHOD_VERSIONS_V3: DriveAbciMethodVersions = DriveAbciMethodVersions { @@ -52,7 +53,10 @@ pub const DRIVE_ABCI_METHOD_VERSIONS_V3: DriveAbciMethodVersions = DriveAbciMeth }, block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions { add_process_epoch_change_operations: 0, - process_block_fees: 0, + process_block_fees_and_validate_sum_trees: 0, + }, + tokens_processing: DriveAbciTokensProcessingMethodVersions { + validate_token_aggregated_balance: 0, }, core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { choose_quorum: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs index bedfb591c30..b3d961563cd 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v4.rs @@ -8,7 +8,8 @@ use crate::version::drive_abci_versions::drive_abci_method_versions::{ DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, DriveAbciPlatformStateStorageMethodVersions, DriveAbciProtocolUpgradeMethodVersions, - DriveAbciStateTransitionProcessingMethodVersions, DriveAbciVotingMethodVersions, + DriveAbciStateTransitionProcessingMethodVersions, DriveAbciTokensProcessingMethodVersions, + DriveAbciVotingMethodVersions, }; pub const DRIVE_ABCI_METHOD_VERSIONS_V4: DriveAbciMethodVersions = DriveAbciMethodVersions { @@ -52,7 +53,10 @@ pub const DRIVE_ABCI_METHOD_VERSIONS_V4: DriveAbciMethodVersions = DriveAbciMeth }, block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions { add_process_epoch_change_operations: 0, - process_block_fees: 0, + process_block_fees_and_validate_sum_trees: 0, + }, + tokens_processing: DriveAbciTokensProcessingMethodVersions { + validate_token_aggregated_balance: 0, }, core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { choose_quorum: 0, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs index f02d1679d38..15a86993bf1 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs @@ -8,7 +8,8 @@ use crate::version::drive_abci_versions::drive_abci_method_versions::{ DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, DriveAbciPlatformStateStorageMethodVersions, DriveAbciProtocolUpgradeMethodVersions, - DriveAbciStateTransitionProcessingMethodVersions, DriveAbciVotingMethodVersions, + DriveAbciStateTransitionProcessingMethodVersions, DriveAbciTokensProcessingMethodVersions, + DriveAbciVotingMethodVersions, }; // Introduced in Protocol version 8 for tokens @@ -53,7 +54,10 @@ pub const DRIVE_ABCI_METHOD_VERSIONS_V5: DriveAbciMethodVersions = DriveAbciMeth }, block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions { add_process_epoch_change_operations: 0, - process_block_fees: 0, + process_block_fees_and_validate_sum_trees: 1, + }, + tokens_processing: DriveAbciTokensProcessingMethodVersions { + validate_token_aggregated_balance: 0, }, core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { choose_quorum: 0, diff --git a/packages/rs-platform-version/src/version/drive_versions/v3.rs b/packages/rs-platform-version/src/version/drive_versions/v3.rs index f7e8b1b1e78..6212e6ed912 100644 --- a/packages/rs-platform-version/src/version/drive_versions/v3.rs +++ b/packages/rs-platform-version/src/version/drive_versions/v3.rs @@ -17,7 +17,7 @@ use crate::version::drive_versions::{ DrivePrefundedSpecializedMethodVersions, DriveProtocolUpgradeVersions, DriveProveMethodVersions, DriveSystemEstimationCostsMethodVersions, DriveVersion, }; -use grovedb_version::version::v1::GROVE_V1; +use grovedb_version::version::v2::GROVE_V2; pub const DRIVE_VERSION_V3: DriveVersion = DriveVersion { structure: DRIVE_STRUCTURE_V1, @@ -100,5 +100,5 @@ pub const DRIVE_VERSION_V3: DriveVersion = DriveVersion { group: DRIVE_GROUP_METHOD_VERSIONS_V1, }, grove_methods: DRIVE_GROVE_METHOD_VERSIONS_V1, - grove_version: GROVE_V1, + grove_version: GROVE_V2, }; 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 caae43ccea9..3a8964266da 100644 --- a/packages/rs-platform-version/src/version/mocks/v3_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v3_test.rs @@ -24,7 +24,8 @@ use crate::version::drive_abci_versions::drive_abci_method_versions::{ DriveAbciIdentityCreditWithdrawalMethodVersions, DriveAbciInitializationMethodVersions, DriveAbciMasternodeIdentitiesUpdatesMethodVersions, DriveAbciMethodVersions, DriveAbciPlatformStateStorageMethodVersions, DriveAbciProtocolUpgradeMethodVersions, - DriveAbciStateTransitionProcessingMethodVersions, DriveAbciVotingMethodVersions, + DriveAbciStateTransitionProcessingMethodVersions, DriveAbciTokensProcessingMethodVersions, + DriveAbciVotingMethodVersions, }; use crate::version::drive_abci_versions::drive_abci_query_versions::v1::DRIVE_ABCI_QUERY_VERSIONS_V1; use crate::version::drive_abci_versions::drive_abci_structure_versions::v1::DRIVE_ABCI_STRUCTURE_VERSIONS_V1; @@ -86,7 +87,10 @@ pub const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { }, block_fee_processing: DriveAbciBlockFeeProcessingMethodVersions { add_process_epoch_change_operations: 0, - process_block_fees: 0, + process_block_fees_and_validate_sum_trees: 0, + }, + tokens_processing: DriveAbciTokensProcessingMethodVersions { + validate_token_aggregated_balance: 0, }, core_chain_lock: DriveAbciCoreChainLockMethodVersionsAndConstants { choose_quorum: 0, From 44dce25afb982817d80c5a5ac688b8d2ba445079 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 13 Jan 2025 08:44:28 +0700 Subject: [PATCH 55/61] work on token proofs --- Cargo.lock | 21 ++-- ...set_lock_transaction_is_not_found_error.rs | 12 -- .../v1/mod.rs | 2 + .../block_processing_end_events/tests.rs | 3 - .../tests/strategy_tests/main.rs | 24 ++-- .../tests/strategy_tests/strategy.rs | 19 +-- .../tests/strategy_tests/token_tests.rs | 58 +++++----- .../verify_state_transitions.rs | 97 +++++++++++++++- .../tests/strategy_tests/voting_tests.rs | 109 +++++++----------- packages/rs-drive/Cargo.toml | 12 +- .../src/drive/initialization/v1/mod.rs | 2 +- .../calculate_total_tokens_balance/v0/mod.rs | 8 +- .../token_transition/mod.rs | 33 +++++- packages/rs-platform-version/Cargo.toml | 2 +- .../drive_abci_method_versions/v5.rs | 2 +- packages/strategy-tests/src/operations.rs | 6 + packages/strategy-tests/src/transitions.rs | 13 ++- 17 files changed, 255 insertions(+), 168 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f0603cd424a..aeabf93c66a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2141,7 +2141,7 @@ dependencies = [ [[package]] name = "grovedb" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" dependencies = [ "axum", "bincode", @@ -2175,7 +2175,7 @@ dependencies = [ [[package]] name = "grovedb-costs" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" dependencies = [ "integer-encoding", "intmap", @@ -2185,7 +2185,7 @@ dependencies = [ [[package]] name = "grovedb-epoch-based-storage-flags" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" dependencies = [ "grovedb-costs", "hex", @@ -2197,7 +2197,7 @@ dependencies = [ [[package]] name = "grovedb-merk" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" dependencies = [ "bincode", "blake3", @@ -2222,12 +2222,15 @@ dependencies = [ [[package]] name = "grovedb-path" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" +dependencies = [ + "hex", +] [[package]] name = "grovedb-storage" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" dependencies = [ "blake3", "grovedb-costs", @@ -2246,7 +2249,7 @@ dependencies = [ [[package]] name = "grovedb-version" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" dependencies = [ "thiserror", "versioned-feature-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2255,7 +2258,7 @@ dependencies = [ [[package]] name = "grovedb-visualize" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" dependencies = [ "hex", "itertools 0.12.1", @@ -2264,7 +2267,7 @@ dependencies = [ [[package]] name = "grovedbg-types" version = "2.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=263dcd5164c7db597bf7de7b6de133ad7cd77d50#263dcd5164c7db597bf7de7b6de133ad7cd77d50" +source = "git+https://github.com/dashpay/grovedb?rev=a25cc077d2e425cab7dcba41e4611444857f62d7#a25cc077d2e425cab7dcba41e4611444857f62d7" dependencies = [ "serde", "serde_with 3.9.0", diff --git a/packages/rs-dpp/src/errors/consensus/basic/identity/identity_asset_lock_transaction_is_not_found_error.rs b/packages/rs-dpp/src/errors/consensus/basic/identity/identity_asset_lock_transaction_is_not_found_error.rs index 61aaa959d29..b4d39d261c3 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/identity/identity_asset_lock_transaction_is_not_found_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/identity/identity_asset_lock_transaction_is_not_found_error.rs @@ -44,15 +44,3 @@ impl From for ConsensusError { Self::BasicError(BasicError::IdentityAssetLockTransactionIsNotFoundError(err)) } } - -#[cfg(test)] -mod test { - use crate::consensus::basic::identity::IdentityAssetLockTransactionIsNotFoundError; - - #[test] - pub fn test_message() { - let error = IdentityAssetLockTransactionIsNotFoundError::new([1; 32]); - - println!("{}", error); - } -} diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs index 5fbaadd8f7c..4c380c2269f 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs @@ -46,6 +46,8 @@ impl Platform { /// and distributing the block fees from the previous block and applies the batch. /// /// Returns `ProcessedBlockFeesOutcome`. + /// + /// V1 adds the validation of the token aggregated balance #[inline(always)] pub(super) fn process_block_fees_and_validate_sum_trees_v1( &self, diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs index 617502349bb..2c0fe0a0275 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/tests.rs @@ -842,9 +842,6 @@ mod refund_tests { .calculate_refunds_amount_for_identity(identity.id()) .expect("expected refunds for identity"); - // println!("{}", insertion_fee_result.storage_fee); - // println!("{}", refund_amount); - // we should be refunding around 21% after 25 years. let refunded_percentage = refund_amount * 100 / insertion_fee_result.storage_fee; assert_eq!(refunded_percentage, 98); diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 428868c8ece..9622e724596 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -2653,28 +2653,22 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys1) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys1) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys1); - let (identity2, keys2) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity2, keys2) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys2); let start_identities = create_state_transitions_for_identities( - vec![identity1, identity2], + vec![&mut identity1, &mut identity2], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index 9a4dc5ae8c4..f029a4a22a3 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -1427,13 +1427,18 @@ impl NetworkStrategy { contract, token_id, token_pos, + use_identity_with_id, action: TokenEvent::Mint(amount, recipient, note), }) if current_identities.len() > 1 => { - let random_index = rng.gen_range(0..current_identities.len()); - let random_identity_id = current_identities[random_index].id(); + let operation_owner_id = if let Some(identity_id) = use_identity_with_id { + *identity_id + } else { + let random_index = rng.gen_range(0..current_identities.len()); + current_identities[random_index].id() + }; let request = IdentityKeysRequest { - identity_id: random_identity_id.to_buffer(), + identity_id: operation_owner_id.to_buffer(), request_type: KeyRequestType::SpecificKeys(vec![1]), limit: Some(1), offset: None, @@ -1442,9 +1447,9 @@ impl NetworkStrategy { .drive .fetch_identity_balance_with_keys(request, None, platform_version) .expect("expected to be able to get identity") - .expect("expected to get an identity"); + .expect("expected to get an identity for token mint operation"); let identity_contract_nonce = contract_nonce_counter - .entry((random_identity_id, contract.id())) + .entry((operation_owner_id, contract.id())) .or_default(); *identity_contract_nonce += 1; let token_mint_transition: TokenMintTransition = TokenMintTransitionV0 { @@ -1456,7 +1461,7 @@ impl NetworkStrategy { using_group_info: None, } .into(), - issued_to_identity_id: Some(random_identity_id), + issued_to_identity_id: Some(*recipient), amount: *amount, public_note: note.clone(), } @@ -1642,7 +1647,7 @@ impl NetworkStrategy { ) } else { create_state_transitions_for_identities( - identities, + &mut identities, balance_range, signer, rng, diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs index f51d24c7349..4e4eb56a760 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -3,12 +3,15 @@ mod tests { use crate::execution::run_chain_for_strategy; use crate::strategy::NetworkStrategy; use dpp::dash_to_duffs; + use dpp::data_contract::accessors::v0::DataContractV0Setters; use dpp::data_contract::accessors::v1::DataContractV1Getters; + use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Setters; use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::Identity; use dpp::state_transition::StateTransition; use dpp::tests::json_document::json_document_to_created_contract; use dpp::tokens::token_event::TokenEvent; + use drive::query::PathQuery; use drive_abci::config::{ ChainLockConfig, ExecutionConfig, InstantLockConfig, PlatformConfig, PlatformTestConfig, ValidatorSetConfig, @@ -38,28 +41,22 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys1) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys1) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); - let (identity2, keys2) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity2, keys2) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys1); simple_signer.add_keys(keys2); let start_identities: Vec<(Identity, Option)> = create_state_transitions_for_identities( - vec![identity1.clone(), identity2.clone()], + vec![&mut identity1, &mut identity2], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, @@ -70,12 +67,18 @@ mod tests { .collect(); let contract = created_contract.data_contract_mut(); + let mut token_configuration = contract + .token_configuration_mut(0) + .expect("expected to get token configuration"); + token_configuration.set_minting_allow_choosing_destination(true); let token_id = contract.token_id(0).expect("expected to get token_id"); + contract.set_owner_id(identity1.id()); let token_op = TokenOp { contract: contract.clone(), token_id, token_pos: 0, + use_identity_with_id: Some(identity1.id()), action: TokenEvent::Mint(1000, identity2.id(), None), }; @@ -164,28 +167,22 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys1) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys1) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); - let (identity2, keys2) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity2, keys2) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys1); simple_signer.add_keys(keys2); let start_identities: Vec<(Identity, Option)> = create_state_transitions_for_identities( - vec![identity1.clone(), identity2.clone()], + vec![&mut identity1, &mut identity2], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, @@ -203,6 +200,7 @@ mod tests { contract: contract.clone(), token_id, token_pos: 0, + use_identity_with_id: None, action: TokenEvent::Mint(1000, identity2.id(), None), }; 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 49ee1e5c22f..2d803233429 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 @@ -21,8 +21,8 @@ use drive_abci::execution::validation::state_transition::transformer::StateTrans use drive_abci::platform_types::platform::PlatformRef; use drive_abci::rpc::core::MockCoreRPCLike; use tenderdash_abci::proto::abci::ExecTxResult; - -use dpp::state_transition::batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; +use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; +use dpp::data_contracts::SystemDataContract; use dpp::voting::votes::Vote; use drive::drive::votes::resolved::vote_polls::ResolvedVotePoll; use drive::drive::votes::resolved::votes::resolved_resource_vote::accessors::v0::ResolvedResourceVoteGettersV0; @@ -34,6 +34,7 @@ use drive::state_transition_action::batch::batched_transition::document_transiti use drive::state_transition_action::batch::batched_transition::document_transition::document_replace_transition_action::DocumentFromReplaceTransitionAction; use drive::state_transition_action::batch::batched_transition::document_transition::document_transfer_transition_action::DocumentTransferTransitionActionAccessorsV0; use drive::state_transition_action::batch::batched_transition::document_transition::document_update_price_transition_action::DocumentUpdatePriceTransitionActionAccessorsV0; +use drive::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionActionAccessorsV0; use drive_abci::abci::app::FullAbciApplication; use drive_abci::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use drive_abci::execution::validation::state_transition::ValidationMode; @@ -259,7 +260,37 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( }, ); } - BatchedTransitionAction::TokenAction(_) => {} + BatchedTransitionAction::TokenAction(token_transition_action) => { + if token_transition_action + .base() + .token_configuration() + .expect("expected token configuration") + .keeps_history() + { + // if we keep history we just need to check the historical document + proofs_request.documents.push( + get_proofs_request_v0::DocumentRequest { + contract_id: SystemDataContract::TokenHistory + .id() + .to_vec(), + document_type: token_transition_action + .historical_document_type_name() + .to_string(), + document_type_keeps_history: false, + document_id: token_transition_action + .historical_document_id( + batch_transition.owner_id(), + token_transition_action + .base() + .identity_contract_nonce(), + ) + .to_vec(), + document_contested_status: 0, + }, + ); + } else { + } + } BatchedTransitionAction::BumpIdentityDataContractNonce(_) => {} }); let versioned_request = GetProofsRequest { @@ -468,8 +499,64 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( } } } - BatchedTransitionAction::TokenAction(_) => { - todo!(); + BatchedTransitionAction::TokenAction(token_transition_action) => { + if token_transition_action + .base() + .token_configuration() + .expect("expected token configuration") + .keeps_history() + { + let document_type_name = token_transition_action + .historical_document_type_name() + .to_string(); + + let token_history = platform + .drive + .cache + .system_data_contracts + .load_token_history(); + + let document_type = token_history + .document_type_for_name(document_type_name.as_str()) + .expect("get document type"); + + let query = SingleDocumentDriveQuery { + contract_id: SystemDataContract::TokenHistory + .id() + .to_buffer(), + document_type_name, + document_type_keeps_history: false, + document_id: token_transition_action + .historical_document_id( + batch_transition.owner_id(), + token_transition_action + .base() + .identity_contract_nonce(), + ) + .to_buffer(), + block_time_ms: None, //None because we want latest + contested_status: + SingleDocumentDriveQueryContestedStatus::NotContested, + }; + + let (root_hash, document) = query + .verify_proof( + false, + &response_proof.grovedb_proof, + document_type, + platform_version, + ) + .expect("expected to verify a document"); + + assert_eq!( + &root_hash, + expected_root_hash, + "state last block info {:?}", + platform.state.last_committed_block_info() + ); + } else { + todo!(); + } } BatchedTransitionAction::BumpIdentityDataContractNonce(_) => { panic!("we should not have a bump identity data contract nonce"); diff --git a/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs index c26bc7a51f7..4d269486f25 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/voting_tests.rs @@ -69,19 +69,16 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys1) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys1) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys1); let start_identities: Vec<(Identity, Option)> = create_state_transitions_for_identities( - vec![identity1], + vec![&mut identity1], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, @@ -347,29 +344,23 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys1) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys1) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys1); - let (identity2, keys2) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity2, keys2) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys2); let start_identities: Vec<(Identity, Option)> = create_state_transitions_for_identities( - vec![identity1, identity2], + vec![&mut identity1, &mut identity2], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, @@ -623,29 +614,23 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys1) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys1) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys1); - let (identity2, keys2) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity2, keys2) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys2); let start_identities: Vec<(Identity, Option)> = create_state_transitions_for_identities( - vec![identity1, identity2], + vec![&mut identity1, &mut identity2], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, @@ -980,29 +965,23 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys1) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys1) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys1); - let (identity2, keys2) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity2, keys2) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys2); let start_identities: Vec<(Identity, Option)> = create_state_transitions_for_identities( - vec![identity1, identity2], + vec![&mut identity1, &mut identity2], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, @@ -1349,29 +1328,23 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys1) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys1) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys1); - let (identity2, keys2) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity2, keys2) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys2); let start_identities: Vec<(Identity, Option)> = create_state_transitions_for_identities( - vec![identity1, identity2], + vec![&mut identity1, &mut identity2], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &simple_signer, &mut rng, diff --git a/packages/rs-drive/Cargo.toml b/packages/rs-drive/Cargo.toml index 2441804b839..66f78c909b4 100644 --- a/packages/rs-drive/Cargo.toml +++ b/packages/rs-drive/Cargo.toml @@ -52,12 +52,12 @@ enum-map = { version = "2.0.3", optional = true } intmap = { version = "2.0.0", features = ["serde"], optional = true } chrono = { version = "0.4.35", optional = true } itertools = { version = "0.13", optional = true } -grovedb = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50", optional = true, default-features = false } -grovedb-costs = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50", optional = true } -grovedb-path = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50" } -grovedb-storage = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50", optional = true } -grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50" } -grovedb-epoch-based-storage-flags = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50" } +grovedb = { git = "https://github.com/dashpay/grovedb", rev= "a25cc077d2e425cab7dcba41e4611444857f62d7", optional = true, default-features = false } +grovedb-costs = { git = "https://github.com/dashpay/grovedb", rev= "a25cc077d2e425cab7dcba41e4611444857f62d7", optional = true } +grovedb-path = { git = "https://github.com/dashpay/grovedb", rev= "a25cc077d2e425cab7dcba41e4611444857f62d7" } +grovedb-storage = { git = "https://github.com/dashpay/grovedb", rev= "a25cc077d2e425cab7dcba41e4611444857f62d7", optional = true } +grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "a25cc077d2e425cab7dcba41e4611444857f62d7" } +grovedb-epoch-based-storage-flags = { git = "https://github.com/dashpay/grovedb", rev= "a25cc077d2e425cab7dcba41e4611444857f62d7" } [dev-dependencies] criterion = "0.5" diff --git a/packages/rs-drive/src/drive/initialization/v1/mod.rs b/packages/rs-drive/src/drive/initialization/v1/mod.rs index ba85cc27746..d1e338ed27f 100644 --- a/packages/rs-drive/src/drive/initialization/v1/mod.rs +++ b/packages/rs-drive/src/drive/initialization/v1/mod.rs @@ -55,7 +55,7 @@ impl Drive { batch.add_insert( misc_path_vec(), TOTAL_TOKEN_SUPPLIES_STORAGE_KEY.to_vec(), - Element::empty_tree(), + Element::empty_big_sum_tree(), ); batch.add_insert( diff --git a/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs index 6f312692557..1d0bdd63176 100644 --- a/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs @@ -1,6 +1,6 @@ use crate::drive::balances::TOTAL_TOKEN_SUPPLIES_STORAGE_KEY; use crate::drive::system::misc_path; -use crate::drive::tokens::token_balances_root_path; +use crate::drive::tokens::{token_balances_root_path, tokens_root_path, TOKEN_BALANCES_KEY}; use crate::drive::{Drive, RootTree}; use crate::error::Error; use crate::util::grove_operations::DirectQueryType; @@ -28,11 +28,11 @@ impl Drive { drive_version, )?; - let tokens_balances_path = token_balances_root_path(); + let tokens_root_path = tokens_root_path(); let total_identity_token_balances = self.grove_get_big_sum_tree_total_value( - (&tokens_balances_path).into(), - Into::<&[u8; 1]>::into(RootTree::Balances), + (&tokens_root_path).into(), + &[TOKEN_BALANCES_KEY], DirectQueryType::StatefulDirectQuery, transaction, &mut drive_operations, diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs index 4a457e10437..fa6021cfd57 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs @@ -19,7 +19,10 @@ pub mod token_destroy_frozen_funds_transition_action; pub mod token_emergency_action_transition_action; use derive_more::From; -use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; +use dpp::document::Document; +use dpp::identifier::Identifier; +use dpp::prelude::IdentityNonce; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; @@ -76,4 +79,32 @@ impl TokenTransitionAction { TokenTransitionAction::DestroyFrozenFundsAction(action) => action.base_owned(), } } + + /// Historical document type name for the token history contract + pub fn historical_document_type_name(&self) -> &str { + match self { + TokenTransitionAction::BurnAction(_) => "burn", + TokenTransitionAction::MintAction(_) => "mint", + TokenTransitionAction::TransferAction(_) => "transfer", + TokenTransitionAction::FreezeAction(_) => "freeze", + TokenTransitionAction::UnfreezeAction(_) => "unfreeze", + TokenTransitionAction::EmergencyActionAction(_) => "emergencyAction", + TokenTransitionAction::DestroyFrozenFundsAction(_) => "destroyFrozenFunds", + } + } + + /// Historical document id + pub fn historical_document_id( + &self, + owner_id: Identifier, + owner_nonce: IdentityNonce, + ) -> Identifier { + let name = self.historical_document_type_name(); + Document::generate_document_id_v0( + &self.base().data_contract_id(), + &owner_id, + name, + owner_nonce.to_be_bytes().as_slice(), + ) + } } diff --git a/packages/rs-platform-version/Cargo.toml b/packages/rs-platform-version/Cargo.toml index 5bce71ac114..d31d504b360 100644 --- a/packages/rs-platform-version/Cargo.toml +++ b/packages/rs-platform-version/Cargo.toml @@ -11,7 +11,7 @@ license = "MIT" thiserror = { version = "1.0.63" } bincode = { version = "2.0.0-rc.3" } versioned-feature-core = { git = "https://github.com/dashpay/versioned-feature-core", version = "1.0.0" } -grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "263dcd5164c7db597bf7de7b6de133ad7cd77d50" } +grovedb-version = { git = "https://github.com/dashpay/grovedb", rev= "a25cc077d2e425cab7dcba41e4611444857f62d7" } once_cell = "1.19.0" [features] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs index 15a86993bf1..ef351a0de20 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_method_versions/v5.rs @@ -86,7 +86,7 @@ pub const DRIVE_ABCI_METHOD_VERSIONS_V5: DriveAbciMethodVersions = DriveAbciMeth fetch_transactions_block_inclusion_status: 0, pool_withdrawals_into_transactions_queue: 0, update_broadcasted_withdrawal_statuses: 0, - rebroadcast_expired_withdrawal_documents: 0, + rebroadcast_expired_withdrawal_documents: 1, append_signatures_and_broadcast_withdrawal_transactions: 0, cleanup_expired_locks_of_withdrawal_amounts: 0, }, diff --git a/packages/strategy-tests/src/operations.rs b/packages/strategy-tests/src/operations.rs index 7f9728bb1b1..4dcebb9f62a 100644 --- a/packages/strategy-tests/src/operations.rs +++ b/packages/strategy-tests/src/operations.rs @@ -35,6 +35,7 @@ pub struct TokenOp { pub contract: Contract, pub token_id: Identifier, pub token_pos: TokenContractPosition, + pub use_identity_with_id: Option, pub action: TokenEvent, } @@ -43,6 +44,7 @@ pub struct TokenOpInSerializationFormat { pub contract: DataContractInSerializationFormat, pub token_id: Identifier, pub token_pos: TokenContractPosition, + pub use_identity_with_id: Option, pub action: TokenEvent, } @@ -65,6 +67,7 @@ impl PlatformSerializableWithPlatformVersion for TokenOp { contract, token_id, token_pos, + use_identity_with_id, action, } = self; let data_contract_serialization_format: DataContractInSerializationFormat = @@ -74,6 +77,7 @@ impl PlatformSerializableWithPlatformVersion for TokenOp { contract: data_contract_serialization_format, token_id, token_pos, + use_identity_with_id, action, }; let config = bincode::config::standard() @@ -107,6 +111,7 @@ impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for Tok contract, token_id, token_pos, + use_identity_with_id, action, } = token_op_in_serialization_format; let data_contract = DataContract::try_from_platform_versioned( @@ -119,6 +124,7 @@ impl PlatformDeserializableWithPotentialValidationFromVersionedStructure for Tok contract: data_contract, token_id, token_pos, + use_identity_with_id, action, }) } diff --git a/packages/strategy-tests/src/transitions.rs b/packages/strategy-tests/src/transitions.rs index c77b51e2903..d3607d179ab 100644 --- a/packages/strategy-tests/src/transitions.rs +++ b/packages/strategy-tests/src/transitions.rs @@ -1018,16 +1018,19 @@ pub fn create_identities_state_transitions( /// - When unable to generate random cryptographic keys. /// - When failing to transform an identity into its corresponding state transition. /// - Conversion and encoding errors related to the cryptographic data. -pub fn create_state_transitions_for_identities( - identities: Vec, +pub fn create_state_transitions_for_identities<'a, I>( + identities: I, amount_range: &AmountRange, signer: &SimpleSigner, rng: &mut StdRng, platform_version: &PlatformVersion, -) -> Vec<(Identity, StateTransition)> { +) -> Vec<(Identity, StateTransition)> +where + I: IntoIterator, +{ identities .into_iter() - .map(|mut identity| { + .map(|identity| { let (_, pk) = ECDSA_SECP256K1 .random_public_and_private_key_data(rng, platform_version) .unwrap(); @@ -1051,7 +1054,7 @@ pub fn create_state_transitions_for_identities( .expect("expected to transform identity into identity create transition"); identity.set_id(identity_create_transition.owner_id()); - (identity, identity_create_transition) + (identity.clone(), identity_create_transition) }) .collect() } From 999a432908cec73e80a774e90d4978f1da77f7c0 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 13 Jan 2025 10:54:35 +0700 Subject: [PATCH 56/61] more work --- .../class_methods/try_from_schema/v0/mod.rs | 46 +- .../src/data_contract/document_type/mod.rs | 2 + packages/rs-dpp/src/tokens/token_event.rs | 167 +++++++- .../verify_state_transitions.rs | 27 ++ .../v0/mod.rs | 396 ++---------------- .../batch/token/token_transition.rs | 57 +++ .../token_transition/mod.rs | 27 +- .../token_transfer_transition_action/mod.rs | 16 + .../v0/mod.rs | 31 ++ .../v1/token-history-contract-documents.json | 30 +- 10 files changed, 416 insertions(+), 383 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs index 57b3bffb37f..f9bf1cd923f 100644 --- a/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs @@ -744,7 +744,51 @@ fn insert_values_nested( let is_transient = known_transient.contains(&property_key); let field_type = match type_value { - "integer" => DocumentPropertyType::I64, + "integer" => { + let minimum = inner_properties.get_optional_integer::(property_names::MINIMUM)?; + let maximum = inner_properties.get_optional_integer::(property_names::MAXIMUM)?; + + match (minimum, maximum) { + (Some(min), Some(max)) => { + if min >= 0 { + if max <= u8::MAX as i64 { + DocumentPropertyType::U8 + } else if max <= u16::MAX as i64 { + DocumentPropertyType::U16 + } else if max <= u32::MAX as i64 { + DocumentPropertyType::U32 + } else { + DocumentPropertyType::U64 + } + } else { + if min >= i8::MIN as i64 && max <= i8::MAX as i64 { + DocumentPropertyType::I8 + } else if min >= i16::MIN as i64 && max <= i16::MAX as i64 { + DocumentPropertyType::I16 + } else if min >= i32::MIN as i64 && max <= i32::MAX as i64 { + DocumentPropertyType::I32 + } else { + DocumentPropertyType::I64 + } + } + } + (Some(min), None) => { + if min >= 0 { + DocumentPropertyType::U64 + } else { + DocumentPropertyType::I64 + } + } + (None, Some(max)) => { + if max >= 0 { + DocumentPropertyType::U64 + } else { + DocumentPropertyType::I64 + } + } + (None, None) => DocumentPropertyType::I64, + } + } "number" => DocumentPropertyType::F64, "string" => DocumentPropertyType::String(StringPropertySizes { min_length: inner_properties.get_optional_integer(property_names::MIN_LENGTH)?, diff --git a/packages/rs-dpp/src/data_contract/document_type/mod.rs b/packages/rs-dpp/src/data_contract/document_type/mod.rs index a87ceb3c9cc..23382dab535 100644 --- a/packages/rs-dpp/src/data_contract/document_type/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/mod.rs @@ -53,6 +53,8 @@ mod property_names { pub const CREATED_AT: &str = "$createdAt"; pub const UPDATED_AT: &str = "$updatedAt"; pub const TRANSFERRED_AT: &str = "$transferredAt"; + pub const MINIMUM: &str = "minimum"; + pub const MAXIMUM: &str = "maximum"; pub const MIN_ITEMS: &str = "minItems"; pub const MAX_ITEMS: &str = "maxItems"; pub const MIN_LENGTH: &str = "minLength"; diff --git a/packages/rs-dpp/src/tokens/token_event.rs b/packages/rs-dpp/src/tokens/token_event.rs index 632437aa3d0..df805788b1f 100644 --- a/packages/rs-dpp/src/tokens/token_event.rs +++ b/packages/rs-dpp/src/tokens/token_event.rs @@ -1,10 +1,16 @@ use crate::balances::credits::TokenAmount; +use crate::block::block_info::BlockInfo; +use crate::data_contract::accessors::v0::DataContractV0Getters; +use crate::data_contract::document_type::DocumentTypeRef; +use crate::document::{Document, DocumentV0}; use crate::prelude::{ - DerivationEncryptionKeyIndex, RecipientKeyIndex, RootEncryptionKeyIndex, SenderKeyIndex, + DataContract, DerivationEncryptionKeyIndex, IdentityNonce, RecipientKeyIndex, + RootEncryptionKeyIndex, SenderKeyIndex, }; use bincode::{Decode, Encode}; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; use platform_value::Identifier; +use std::collections::BTreeMap; pub type TokenEventPublicNote = Option; pub type TokenEventSharedEncryptedNote = Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>; @@ -38,3 +44,162 @@ pub enum TokenEvent { ), EmergencyAction(TokenEmergencyAction, TokenEventPublicNote), } + +impl TokenEvent { + pub fn associated_document_type_name(&self) -> &str { + match self { + TokenEvent::Mint(_, _, _) => "mint", + TokenEvent::Burn(_, _) => "burn", + TokenEvent::Freeze(_, _) => "freeze", + TokenEvent::Unfreeze(_, _) => "unfreeze", + TokenEvent::DestroyFrozenFunds(_, _, _) => "destroyFrozenFunds", + TokenEvent::Transfer(_, _, _, _, _) => "transfer", + TokenEvent::EmergencyAction(_, _) => "emergencyAction", + } + } + + pub fn associated_document_type<'a>( + &self, + token_history_contract: &'a DataContract, + ) -> Result, ProtocolError> { + Ok(token_history_contract.document_type_for_name(self.associated_document_type_name())?) + } + + pub fn build_historical_document_owned( + self, + token_history_contract: &DataContract, + token_id: Identifier, + owner_id: Identifier, + owner_nonce: IdentityNonce, + block_info: &BlockInfo, + ) -> Result { + let document_id = Document::generate_document_id_v0( + &token_history_contract.id(), + &owner_id, + self.associated_document_type_name(), + owner_nonce.to_be_bytes().as_slice(), + ); + + let properties = match self { + TokenEvent::Mint(mint_amount, recipient_id, public_note) => { + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("recipientId".to_string(), recipient_id.into()), + ("amount".to_string(), mint_amount.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + properties + } + TokenEvent::Burn(burn_amount, public_note) => { + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("amount".to_string(), burn_amount.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + properties + } + TokenEvent::Transfer( + to, + public_note, + token_event_shared_encrypted_note, + token_event_personal_encrypted_note, + amount, + ) => { + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("amount".to_string(), amount.into()), + ("toIdentityId".to_string(), to.into()), + ]); + if let Some(note) = public_note { + properties.insert("publicNote".to_string(), note.into()); + } + if let Some((sender_key_index, recipient_key_index, note)) = + token_event_shared_encrypted_note + { + properties.insert("encryptedSharedNote".to_string(), note.into()); + properties.insert("senderKeyIndex".to_string(), sender_key_index.into()); + properties.insert("recipientKeyIndex".to_string(), recipient_key_index.into()); + } + + if let Some((root_encryption_key_index, derivation_encryption_key_index, note)) = + token_event_personal_encrypted_note + { + properties.insert("encryptedPersonalNote".to_string(), note.into()); + properties.insert( + "rootEncryptionKeyIndex".to_string(), + root_encryption_key_index.into(), + ); + properties.insert( + "derivationEncryptionKeyIndex".to_string(), + derivation_encryption_key_index.into(), + ); + } + properties + } + TokenEvent::Freeze(frozen_identity_id, public_note) => { + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("frozenIdentityId".to_string(), frozen_identity_id.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + properties + } + TokenEvent::Unfreeze(frozen_identity_id, public_note) => { + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("frozenIdentityId".to_string(), frozen_identity_id.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + properties + } + TokenEvent::DestroyFrozenFunds(frozen_identity_id, amount, public_note) => { + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("frozenIdentityId".to_string(), frozen_identity_id.into()), + ("amount".to_string(), amount.into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + properties + } + TokenEvent::EmergencyAction(action, public_note) => { + let mut properties = BTreeMap::from([ + ("tokenId".to_string(), token_id.into()), + ("action".to_string(), (action as u8).into()), + ]); + if let Some(note) = public_note { + properties.insert("note".to_string(), note.into()); + } + properties + } + }; + + let document: Document = DocumentV0 { + id: document_id, + owner_id, + properties, + revision: None, + created_at: Some(block_info.time_ms), + updated_at: None, + transferred_at: None, + created_at_block_height: Some(block_info.height), + updated_at_block_height: None, + transferred_at_block_height: None, + created_at_core_block_height: None, + updated_at_core_block_height: None, + transferred_at_core_block_height: None, + } + .into(); + + Ok(document) + } +} 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 2d803233429..23e0b6922e7 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 @@ -21,8 +21,10 @@ use drive_abci::execution::validation::state_transition::transformer::StateTrans use drive_abci::platform_types::platform::PlatformRef; use drive_abci::rpc::core::MockCoreRPCLike; use tenderdash_abci::proto::abci::ExecTxResult; +use dpp::block::extended_block_info::v0::ExtendedBlockInfoV0Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::data_contracts::SystemDataContract; +use dpp::prelude::Identifier; use dpp::voting::votes::Vote; use drive::drive::votes::resolved::vote_polls::ResolvedVotePoll; use drive::drive::votes::resolved::votes::resolved_resource_vote::accessors::v0::ResolvedResourceVoteGettersV0; @@ -506,6 +508,7 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( .expect("expected token configuration") .keeps_history() { + let token_id = token_transition_action.base().token_id(); let document_type_name = token_transition_action .historical_document_type_name() .to_string(); @@ -554,6 +557,30 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( "state last block info {:?}", platform.state.last_committed_block_info() ); + + assert!( + document.is_some(), + "we expect a token history document" + ); + + let expected_document = token_transition_action + .build_historical_document( + &token_history, + token_id, + batch_transition.owner_id(), + token_transition_action + .base() + .identity_contract_nonce(), + platform + .state + .last_committed_block_info() + .as_ref() + .expect("expected last commited block info") + .basic_info(), + ) + .expect("expected to build historical document"); + + assert_eq!(document.unwrap(), expected_document); } else { todo!(); } diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs index 1f36ac81c7f..7dbcc7064b2 100644 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs @@ -29,378 +29,36 @@ impl Drive { transaction: TransactionArg, platform_version: &PlatformVersion, ) -> Result, Error> { - let operations; - let contract = self.cache.system_data_contracts.load_token_history(); - match event { - TokenEvent::Mint(mint_amount, recipient_id, public_note) => { - let document_type = contract.document_type_for_name("mint")?; - let document_id = Document::generate_document_id_v0( - &contract.id(), - &owner_id, - "mint", - owner_nonce.to_be_bytes().as_slice(), - ); - let mut properties = BTreeMap::from([ - ("tokenId".to_string(), token_id.into()), - ("recipientId".to_string(), recipient_id.into()), - ("amount".to_string(), mint_amount.into()), - ]); - if let Some(note) = public_note { - properties.insert("note".to_string(), note.into()); - } - let document: Document = DocumentV0 { - id: document_id, - owner_id, - properties, - revision: None, - created_at: Some(block_info.time_ms), - updated_at: None, - transferred_at: None, - created_at_block_height: Some(block_info.height), - updated_at_block_height: None, - transferred_at_block_height: None, - created_at_core_block_height: None, - updated_at_core_block_height: None, - transferred_at_core_block_height: None, - } - .into(); - operations = self.add_document_for_contract_operations( - DocumentAndContractInfo { - owned_document_info: OwnedDocumentInfo { - document_info: DocumentOwnedInfo((document, None)), - owner_id: Some(owner_id.to_buffer()), - }, - contract: &contract, - document_type, - }, - true, - block_info, - &mut None, - estimated_costs_only_with_layer_info, - transaction, - platform_version, - )?; - } - TokenEvent::Burn(burn_amount, public_note) => { - let document_type = contract.document_type_for_name("burn")?; - let document_id = Document::generate_document_id_v0( - &contract.id(), - &owner_id, - "burn", - owner_nonce.to_be_bytes().as_slice(), - ); - let mut properties = BTreeMap::from([ - ("tokenId".to_string(), token_id.into()), - ("amount".to_string(), burn_amount.into()), - ]); - if let Some(note) = public_note { - properties.insert("note".to_string(), note.into()); - } - let document: Document = DocumentV0 { - id: document_id, - owner_id, - properties, - revision: None, - created_at: Some(block_info.time_ms), - updated_at: None, - transferred_at: None, - created_at_block_height: Some(block_info.height), - updated_at_block_height: None, - transferred_at_block_height: None, - created_at_core_block_height: None, - updated_at_core_block_height: None, - transferred_at_core_block_height: None, - } - .into(); - operations = self.add_document_for_contract_operations( - DocumentAndContractInfo { - owned_document_info: OwnedDocumentInfo { - document_info: DocumentOwnedInfo((document, None)), - owner_id: Some(owner_id.to_buffer()), - }, - contract: &contract, - document_type, - }, - true, - block_info, - &mut None, - estimated_costs_only_with_layer_info, - transaction, - platform_version, - )?; - } - TokenEvent::Transfer( - to, - public_note, - token_event_shared_encrypted_note, - token_event_personal_encrypted_note, - amount, - ) => { - let document_type = contract.document_type_for_name("transfer")?; - let document_id = Document::generate_document_id_v0( - &contract.id(), - &owner_id, - "transfer", - owner_nonce.to_be_bytes().as_slice(), - ); - let mut properties = BTreeMap::from([ - ("tokenId".to_string(), token_id.into()), - ("amount".to_string(), amount.into()), - ("toIdentityId".to_string(), to.into()), - ]); - if let Some(note) = public_note { - properties.insert("publicNote".to_string(), note.into()); - } - if let Some((sender_key_index, recipient_key_index, note)) = - token_event_shared_encrypted_note - { - properties.insert("encryptedSharedNote".to_string(), note.into()); - properties.insert("senderKeyIndex".to_string(), sender_key_index.into()); - properties.insert("recipientKeyIndex".to_string(), recipient_key_index.into()); - } + let document_type = event.associated_document_type(&contract)?; + + let document = event.build_historical_document_owned( + &contract, + token_id, + owner_id, + owner_nonce, + block_info, + )?; + + println!("document {:?}", document); - if let Some((root_encryption_key_index, derivation_encryption_key_index, note)) = - token_event_personal_encrypted_note - { - properties.insert("encryptedPersonalNote".to_string(), note.into()); - properties.insert( - "rootEncryptionKeyIndex".to_string(), - root_encryption_key_index.into(), - ); - properties.insert( - "derivationEncryptionKeyIndex".to_string(), - derivation_encryption_key_index.into(), - ); - } - let document: Document = DocumentV0 { - id: document_id, - owner_id, - properties, - revision: None, - created_at: Some(block_info.time_ms), - updated_at: None, - transferred_at: None, - created_at_block_height: Some(block_info.height), - updated_at_block_height: None, - transferred_at_block_height: None, - created_at_core_block_height: None, - updated_at_core_block_height: None, - transferred_at_core_block_height: None, - } - .into(); - operations = self.add_document_for_contract_operations( - DocumentAndContractInfo { - owned_document_info: OwnedDocumentInfo { - document_info: DocumentOwnedInfo((document, None)), - owner_id: Some(owner_id.to_buffer()), - }, - contract: &contract, - document_type, - }, - true, - block_info, - &mut None, - estimated_costs_only_with_layer_info, - transaction, - platform_version, - )?; - } - TokenEvent::Freeze(frozen_identity_id, public_note) => { - let document_type = contract.document_type_for_name("frozen")?; - let document_id = Document::generate_document_id_v0( - &contract.id(), - &owner_id, - "frozen", - owner_nonce.to_be_bytes().as_slice(), - ); - let mut properties = BTreeMap::from([ - ("tokenId".to_string(), token_id.into()), - ("frozenIdentityId".to_string(), frozen_identity_id.into()), - ]); - if let Some(note) = public_note { - properties.insert("note".to_string(), note.into()); - } - let document: Document = DocumentV0 { - id: document_id, - owner_id, - properties, - revision: None, - created_at: Some(block_info.time_ms), - updated_at: None, - transferred_at: None, - created_at_block_height: Some(block_info.height), - updated_at_block_height: None, - transferred_at_block_height: None, - created_at_core_block_height: None, - updated_at_core_block_height: None, - transferred_at_core_block_height: None, - } - .into(); - operations = self.add_document_for_contract_operations( - DocumentAndContractInfo { - owned_document_info: OwnedDocumentInfo { - document_info: DocumentOwnedInfo((document, None)), - owner_id: Some(owner_id.to_buffer()), - }, - contract: &contract, - document_type, - }, - true, - block_info, - &mut None, - estimated_costs_only_with_layer_info, - transaction, - platform_version, - )?; - } - TokenEvent::Unfreeze(frozen_identity_id, public_note) => { - let document_type = contract.document_type_for_name("unfrozen")?; - let document_id = Document::generate_document_id_v0( - &contract.id(), - &owner_id, - "unfrozen", - owner_nonce.to_be_bytes().as_slice(), - ); - let mut properties = BTreeMap::from([ - ("tokenId".to_string(), token_id.into()), - ("frozenIdentityId".to_string(), frozen_identity_id.into()), - ]); - if let Some(note) = public_note { - properties.insert("note".to_string(), note.into()); - } - let document: Document = DocumentV0 { - id: document_id, - owner_id, - properties, - revision: None, - created_at: Some(block_info.time_ms), - updated_at: None, - transferred_at: None, - created_at_block_height: Some(block_info.height), - updated_at_block_height: None, - transferred_at_block_height: None, - created_at_core_block_height: None, - updated_at_core_block_height: None, - transferred_at_core_block_height: None, - } - .into(); - operations = self.add_document_for_contract_operations( - DocumentAndContractInfo { - owned_document_info: OwnedDocumentInfo { - document_info: DocumentOwnedInfo((document, None)), - owner_id: Some(owner_id.to_buffer()), - }, - contract: &contract, - document_type, - }, - true, - block_info, - &mut None, - estimated_costs_only_with_layer_info, - transaction, - platform_version, - )?; - } - TokenEvent::DestroyFrozenFunds(frozen_identity_id, amount, public_note) => { - let document_type = contract.document_type_for_name("destroyFrozenFunds")?; - let document_id = Document::generate_document_id_v0( - &contract.id(), - &owner_id, - "destroyFrozenFunds", - owner_nonce.to_be_bytes().as_slice(), - ); - let mut properties = BTreeMap::from([ - ("tokenId".to_string(), token_id.into()), - ("frozenIdentityId".to_string(), frozen_identity_id.into()), - ("amount".to_string(), amount.into()), - ]); - if let Some(note) = public_note { - properties.insert("note".to_string(), note.into()); - } - let document: Document = DocumentV0 { - id: document_id, - owner_id, - properties, - revision: None, - created_at: Some(block_info.time_ms), - updated_at: None, - transferred_at: None, - created_at_block_height: Some(block_info.height), - updated_at_block_height: None, - transferred_at_block_height: None, - created_at_core_block_height: None, - updated_at_core_block_height: None, - transferred_at_core_block_height: None, - } - .into(); - operations = self.add_document_for_contract_operations( - DocumentAndContractInfo { - owned_document_info: OwnedDocumentInfo { - document_info: DocumentOwnedInfo((document, None)), - owner_id: Some(owner_id.to_buffer()), - }, - contract: &contract, - document_type, - }, - true, - block_info, - &mut None, - estimated_costs_only_with_layer_info, - transaction, - platform_version, - )?; - } - TokenEvent::EmergencyAction(action, public_note) => { - let document_type = contract.document_type_for_name("emergencyAction")?; - let document_id = Document::generate_document_id_v0( - &contract.id(), - &owner_id, - "emergencyAction", - owner_nonce.to_be_bytes().as_slice(), - ); - let mut properties = BTreeMap::from([ - ("tokenId".to_string(), token_id.into()), - ("action".to_string(), (action as u8).into()), - ]); - if let Some(note) = public_note { - properties.insert("note".to_string(), note.into()); - } - let document: Document = DocumentV0 { - id: document_id, - owner_id, - properties, - revision: None, - created_at: Some(block_info.time_ms), - updated_at: None, - transferred_at: None, - created_at_block_height: Some(block_info.height), - updated_at_block_height: None, - transferred_at_block_height: None, - created_at_core_block_height: None, - updated_at_core_block_height: None, - transferred_at_core_block_height: None, - } - .into(); - operations = self.add_document_for_contract_operations( - DocumentAndContractInfo { - owned_document_info: OwnedDocumentInfo { - document_info: DocumentOwnedInfo((document, None)), - owner_id: Some(owner_id.to_buffer()), - }, - contract: &contract, - document_type, - }, - true, - block_info, - &mut None, - estimated_costs_only_with_layer_info, - transaction, - platform_version, - )?; - } - } + let operations = self.add_document_for_contract_operations( + DocumentAndContractInfo { + owned_document_info: OwnedDocumentInfo { + document_info: DocumentOwnedInfo((document, None)), + owner_id: Some(owner_id.to_buffer()), + }, + contract: &contract, + document_type, + }, + true, + block_info, + &mut None, + estimated_costs_only_with_layer_info, + transaction, + platform_version, + )?; Ok(operations) } diff --git a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_transition.rs b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_transition.rs index 57b786c3be3..adb128e016c 100644 --- a/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_transition.rs +++ b/packages/rs-drive/src/state_transition_action/action_convert_to_operations/batch/token/token_transition.rs @@ -4,7 +4,15 @@ use crate::state_transition_action::batch::batched_transition::token_transition: use crate::util::batch::DriveOperation; use dpp::block::epoch::Epoch; use dpp::prelude::Identifier; +use dpp::tokens::token_event::TokenEvent; use dpp::version::PlatformVersion; +use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::TokenBurnTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_destroy_frozen_funds_transition_action::TokenDestroyFrozenFundsTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_emergency_action_transition_action::TokenEmergencyActionTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::TokenFreezeTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_mint_transition_action::TokenMintTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionActionAccessorsV0; +use crate::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::TokenUnfreezeTransitionActionAccessorsV0; impl DriveHighLevelBatchOperationConverter for TokenTransitionAction { fn into_high_level_batch_drive_operations<'b>( @@ -46,3 +54,52 @@ impl DriveHighLevelBatchOperationConverter for TokenTransitionAction { } } } + +impl TokenTransitionAction { + /// Gets the associated token event for the transition action + pub fn associated_token_event(&self) -> TokenEvent { + match self { + TokenTransitionAction::BurnAction(burn_action) => TokenEvent::Burn( + burn_action.burn_amount(), + burn_action.public_note().cloned(), + ), + TokenTransitionAction::MintAction(mint_action) => TokenEvent::Mint( + mint_action.mint_amount(), + mint_action.identity_balance_holder_id(), + mint_action.public_note().cloned(), + ), + TokenTransitionAction::TransferAction(transfer_action) => { + let (public_note, shared_encrypted_note, private_encrypted_note) = + transfer_action.notes(); + TokenEvent::Transfer( + transfer_action.recipient_id(), + public_note, + shared_encrypted_note, + private_encrypted_note, + transfer_action.amount(), + ) + } + TokenTransitionAction::FreezeAction(freeze_action) => TokenEvent::Freeze( + freeze_action.frozen_identity_id(), + freeze_action.public_note().cloned(), + ), + TokenTransitionAction::UnfreezeAction(unfreeze_action) => TokenEvent::Unfreeze( + unfreeze_action.frozen_identity_id(), + unfreeze_action.public_note().cloned(), + ), + TokenTransitionAction::EmergencyActionAction(emergency_action) => { + TokenEvent::EmergencyAction( + emergency_action.emergency_action(), + emergency_action.public_note().cloned(), + ) + } + TokenTransitionAction::DestroyFrozenFundsAction(destroy_action) => { + TokenEvent::DestroyFrozenFunds( + destroy_action.frozen_identity_id(), + destroy_action.amount(), + destroy_action.public_note().cloned(), + ) + } + } + } +} diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs index fa6021cfd57..2900b4a008c 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs @@ -19,9 +19,12 @@ pub mod token_destroy_frozen_funds_transition_action; pub mod token_emergency_action_transition_action; use derive_more::From; +use dpp::block::block_info::BlockInfo; +use dpp::data_contracts::SystemDataContract; use dpp::document::Document; use dpp::identifier::Identifier; -use dpp::prelude::IdentityNonce; +use dpp::prelude::{DataContract, IdentityNonce}; +use crate::error::Error; use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; @@ -101,10 +104,30 @@ impl TokenTransitionAction { ) -> Identifier { let name = self.historical_document_type_name(); Document::generate_document_id_v0( - &self.base().data_contract_id(), + &SystemDataContract::TokenHistory.id(), &owner_id, name, owner_nonce.to_be_bytes().as_slice(), ) } + + /// Historical document id + pub fn build_historical_document( + &self, + token_historical_contract: &DataContract, + token_id: Identifier, + owner_id: Identifier, + owner_nonce: IdentityNonce, + block_info: &BlockInfo, + ) -> Result { + self.associated_token_event() + .build_historical_document_owned( + token_historical_contract, + token_id, + owner_id, + owner_nonce, + block_info, + ) + .map_err(Error::Protocol) + } } diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs index 6d4c88b6b3a..9202c66a24e 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/mod.rs @@ -123,6 +123,22 @@ impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionAction } } + fn notes( + &self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { + match self { + TokenTransferTransitionAction::V0(v0) => v0.notes(), + } + } + fn notes_owned( self, ) -> ( diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs index af1007df8b3..518e9d3098b 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs @@ -12,6 +12,7 @@ use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{ TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0, }; +use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; /// Token transfer transition action v0 #[derive(Debug, Clone)] @@ -139,6 +140,18 @@ pub trait TokenTransferTransitionActionAccessorsV0 { Vec, )>, ); + /// All notes + fn notes( + &self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ); } impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionActionV0 { @@ -216,6 +229,24 @@ impl TokenTransferTransitionActionAccessorsV0 for TokenTransferTransitionActionV self.private_encrypted_note = private_encrypted_note; } + fn notes( + &self, + ) -> ( + Option, + Option<(SenderKeyIndex, RecipientKeyIndex, Vec)>, + Option<( + RootEncryptionKeyIndex, + DerivationEncryptionKeyIndex, + Vec, + )>, + ) { + ( + self.public_note.clone(), + self.shared_encrypted_note.clone(), + self.private_encrypted_note.clone(), + ) + } + fn notes_owned( self, ) -> ( diff --git a/packages/token-history-contract/schema/v1/token-history-contract-documents.json b/packages/token-history-contract/schema/v1/token-history-contract-documents.json index 5b4dcf32c8a..576f285eae6 100644 --- a/packages/token-history-contract/schema/v1/token-history-contract-documents.json +++ b/packages/token-history-contract/schema/v1/token-history-contract-documents.json @@ -49,7 +49,8 @@ "minItems": 32, "maxItems": 32, "description": "The token ID", - "position": 0 + "position": 0, + "contentMediaType": "application/x.dash.dpp.identifier" }, "amount": { "type": "integer", @@ -136,7 +137,8 @@ "minItems": 32, "maxItems": 32, "description": "The token ID", - "position": 0 + "position": 0, + "contentMediaType": "application/x.dash.dpp.identifier" }, "recipientId": { "type": "array", @@ -144,7 +146,8 @@ "minItems": 32, "maxItems": 32, "description": "The token ID", - "position": 1 + "position": 1, + "contentMediaType": "application/x.dash.dpp.identifier" }, "amount": { "type": "integer", @@ -232,7 +235,8 @@ "minItems": 32, "maxItems": 32, "description": "The token ID", - "position": 0 + "position": 0, + "contentMediaType": "application/x.dash.dpp.identifier" }, "amount": { "type": "integer", @@ -246,7 +250,8 @@ "minItems": 32, "maxItems": 32, "description": "The identity or the group Id", - "position": 2 + "position": 2, + "contentMediaType": "application/x.dash.dpp.identifier" }, "encryptedPersonalNote": { "type": "array", @@ -346,7 +351,8 @@ "minItems": 32, "maxItems": 32, "description": "The token ID", - "position": 0 + "position": 0, + "contentMediaType": "application/x.dash.dpp.identifier" }, "frozenIdentityId": { "type": "array", @@ -354,7 +360,8 @@ "minItems": 32, "maxItems": 32, "description": "The identity Id of the frozen token account", - "position": 1 + "position": 1, + "contentMediaType": "application/x.dash.dpp.identifier" } }, "required": [ @@ -479,7 +486,8 @@ "minItems": 32, "maxItems": 32, "description": "The token ID", - "position": 0 + "position": 0, + "contentMediaType": "application/x.dash.dpp.identifier" }, "frozenIdentityId": { "type": "array", @@ -487,7 +495,8 @@ "minItems": 32, "maxItems": 32, "description": "The identity Id of the frozen token account", - "position": 1 + "position": 1, + "contentMediaType": "application/x.dash.dpp.identifier" }, "amount": { "type": "integer", @@ -550,7 +559,8 @@ "minItems": 32, "maxItems": 32, "description": "The token ID", - "position": 0 + "position": 0, + "contentMediaType": "application/x.dash.dpp.identifier" }, "action": { "type": "integer", From 184d1e3cd04f325d97dcc1b285436d0950e6a5f4 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Mon, 13 Jan 2025 14:08:57 +0700 Subject: [PATCH 57/61] more work on strategy tests --- .../class_methods/try_from_schema/v0/mod.rs | 88 +++++++++--------- .../state_transitions/batch/mod.rs | 5 +- .../state_transitions/identity_create/mod.rs | 12 +-- .../state_transitions/identity_top_up/mod.rs | 4 +- .../tests/strategy_tests/strategy.rs | 89 ++++++++++++++++++- .../tests/strategy_tests/token_tests.rs | 77 +++++++++++++--- .../verify_state_transitions.rs | 26 ++++-- .../v0/mod.rs | 6 +- .../fetch_identities_token_balances/mod.rs | 7 +- .../fetch_identities_token_balances/v0/mod.rs | 7 +- .../token_transition/mod.rs | 11 +++ .../src/util/batch/drive_op_batch/token.rs | 4 + packages/rs-platform-value/src/inner_value.rs | 2 +- packages/strategy-tests/src/lib.rs | 24 ++--- .../v1/token-history-contract-documents.json | 4 +- 15 files changed, 262 insertions(+), 104 deletions(-) diff --git a/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs index f9bf1cd923f..3394b0f6fc7 100644 --- a/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/class_methods/try_from_schema/v0/mod.rs @@ -745,49 +745,51 @@ fn insert_values_nested( let field_type = match type_value { "integer" => { - let minimum = inner_properties.get_optional_integer::(property_names::MINIMUM)?; - let maximum = inner_properties.get_optional_integer::(property_names::MAXIMUM)?; - - match (minimum, maximum) { - (Some(min), Some(max)) => { - if min >= 0 { - if max <= u8::MAX as i64 { - DocumentPropertyType::U8 - } else if max <= u16::MAX as i64 { - DocumentPropertyType::U16 - } else if max <= u32::MAX as i64 { - DocumentPropertyType::U32 - } else { - DocumentPropertyType::U64 - } - } else { - if min >= i8::MIN as i64 && max <= i8::MAX as i64 { - DocumentPropertyType::I8 - } else if min >= i16::MIN as i64 && max <= i16::MAX as i64 { - DocumentPropertyType::I16 - } else if min >= i32::MIN as i64 && max <= i32::MAX as i64 { - DocumentPropertyType::I32 - } else { - DocumentPropertyType::I64 - } - } - } - (Some(min), None) => { - if min >= 0 { - DocumentPropertyType::U64 - } else { - DocumentPropertyType::I64 - } - } - (None, Some(max)) => { - if max >= 0 { - DocumentPropertyType::U64 - } else { - DocumentPropertyType::I64 - } - } - (None, None) => DocumentPropertyType::I64, - } + DocumentPropertyType::I64 + // todo: we might want to do the following in the future (must be versioned) + // let minimum = inner_properties.get_optional_integer::(property_names::MINIMUM)?; + // let maximum = inner_properties.get_optional_integer::(property_names::MAXIMUM)?; + // + // match (minimum, maximum) { + // (Some(min), Some(max)) => { + // if min >= 0 { + // if max <= u8::MAX as i64 { + // DocumentPropertyType::U8 + // } else if max <= u16::MAX as i64 { + // DocumentPropertyType::U16 + // } else if max <= u32::MAX as i64 { + // DocumentPropertyType::U32 + // } else { + // DocumentPropertyType::U64 + // } + // } else { + // if min >= i8::MIN as i64 && max <= i8::MAX as i64 { + // DocumentPropertyType::I8 + // } else if min >= i16::MIN as i64 && max <= i16::MAX as i64 { + // DocumentPropertyType::I16 + // } else if min >= i32::MIN as i64 && max <= i32::MAX as i64 { + // DocumentPropertyType::I32 + // } else { + // DocumentPropertyType::I64 + // } + // } + // } + // (Some(min), None) => { + // if min >= 0 { + // DocumentPropertyType::U64 + // } else { + // DocumentPropertyType::I64 + // } + // } + // (None, Some(max)) => { + // if max >= 0 { + // DocumentPropertyType::U64 + // } else { + // DocumentPropertyType::I64 + // } + // } + // (None, None) => DocumentPropertyType::I64, + // } } "number" => DocumentPropertyType::F64, "string" => DocumentPropertyType::String(StringPropertySizes { diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs index 94686f58bac..7db789f837b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/mod.rs @@ -10776,7 +10776,7 @@ mod tests { let (identity, signer, key) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); - let (identity_2, signer2, key2) = + let (identity_2, _, _) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); let (contract, token_id) = create_token_contract_with_owner_identity( @@ -11889,7 +11889,7 @@ mod tests { let platform_state = platform.state.load(); - let (identity, signer, key) = + let (identity, _, _) = setup_identity(&mut platform, rng.gen(), dash_to_credits!(0.5)); let (identity_2, signer2, key2) = @@ -12508,7 +12508,6 @@ mod tests { platform_version, ) .expect("expected to fetch token balance"); - let expected_amount = 100000 - 1337; assert_eq!(token_balance, Some(100000)); } 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 2e2cab9ece8..4b9f5523457 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 @@ -423,7 +423,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 1913100); + assert_eq!(processing_result.aggregated_fees().processing_fee, 1919540); platform .drive @@ -438,7 +438,7 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 99913873900); + assert_eq!(identity_balance, 99913867460); } #[test] @@ -868,7 +868,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 2188760); + assert_eq!(processing_result.aggregated_fees().processing_fee, 2195200); platform .drive @@ -883,7 +883,7 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 99909268540); // The identity balance is smaller than if there hadn't been any issue + assert_eq!(identity_balance, 99909262100); // The identity balance is smaller than if there hadn't been any issue } #[test] @@ -1820,7 +1820,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 2188760); + assert_eq!(processing_result.aggregated_fees().processing_fee, 2195200); platform .drive @@ -1835,6 +1835,6 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 99909268540); // The identity balance is smaller than if there hadn't been any issue + assert_eq!(identity_balance, 99909262100); // The identity balance is smaller than if there hadn't been any issue } } 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 eedeea42066..1b35c361310 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 @@ -359,7 +359,7 @@ mod tests { assert_eq!(processing_result.valid_count(), 1); - assert_eq!(processing_result.aggregated_fees().processing_fee, 582400); + assert_eq!(processing_result.aggregated_fees().processing_fee, 588840); platform .drive @@ -378,6 +378,6 @@ mod tests { .expect("expected to get identity balance") .expect("expected there to be an identity balance for this identity"); - assert_eq!(identity_balance, 149993612600); // about 0.5 Dash starting balance + 1 Dash asset lock top up + assert_eq!(identity_balance, 149993606160); // about 0.5 Dash starting balance + 1 Dash asset lock top up } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index f029a4a22a3..b93a8957baf 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -56,8 +56,10 @@ use dpp::state_transition::batch_transition::document_create_transition::{ }; use dpp::state_transition::batch_transition::token_base_transition::v0::TokenBaseTransitionV0; use dpp::state_transition::batch_transition::token_mint_transition::TokenMintTransitionV0; +use dpp::state_transition::batch_transition::token_transfer_transition::TokenTransferTransitionV0; use dpp::state_transition::batch_transition::{ BatchTransition, BatchTransitionV0, BatchTransitionV1, TokenMintTransition, + TokenTransferTransition, }; use dpp::state_transition::data_contract_create_transition::methods::v0::DataContractCreateTransitionMethodsV0; use dpp::state_transition::data_contract_update_transition::methods::DataContractUpdateTransitionMethodsV0; @@ -1455,7 +1457,7 @@ impl NetworkStrategy { let token_mint_transition: TokenMintTransition = TokenMintTransitionV0 { base: TokenBaseTransitionV0 { identity_contract_nonce: *identity_contract_nonce, - token_contract_position: 0, + token_contract_position: *token_pos, data_contract_id: contract.id(), token_id: *token_id, using_group_info: None, @@ -1498,6 +1500,91 @@ impl NetworkStrategy { operations.push(batch_transition); } + OperationType::Token(TokenOp { + contract, + token_id, + token_pos, + use_identity_with_id, + action: + TokenEvent::Transfer( + recipient, + public_note, + shared_encrypted_note, + private_encrypted_note, + amount, + ), + }) if current_identities.len() > 1 => { + let operation_owner_id = if let Some(identity_id) = use_identity_with_id { + *identity_id + } else { + let random_index = rng.gen_range(0..current_identities.len()); + current_identities[random_index].id() + }; + + let request = IdentityKeysRequest { + identity_id: operation_owner_id.to_buffer(), + request_type: KeyRequestType::SpecificKeys(vec![1]), + limit: Some(1), + offset: None, + }; + let identity = platform + .drive + .fetch_identity_balance_with_keys(request, None, platform_version) + .expect("expected to be able to get identity") + .expect("expected to get an identity for token mint operation"); + let identity_contract_nonce = contract_nonce_counter + .entry((operation_owner_id, contract.id())) + .or_default(); + *identity_contract_nonce += 1; + let token_transfer_transition: TokenTransferTransition = + TokenTransferTransitionV0 { + base: TokenBaseTransitionV0 { + identity_contract_nonce: *identity_contract_nonce, + token_contract_position: *token_pos, + data_contract_id: contract.id(), + token_id: *token_id, + using_group_info: None, + } + .into(), + amount: *amount, + recipient_id: *recipient, + public_note: public_note.clone(), + shared_encrypted_note: shared_encrypted_note.clone(), + private_encrypted_note: private_encrypted_note.clone(), + } + .into(); + + let batch_transition: BatchTransition = BatchTransitionV1 { + owner_id: identity.id, + transitions: vec![BatchedTransition::Token( + token_transfer_transition.into(), + )], + user_fee_increase: 0, + signature_public_key_id: 0, + signature: BinaryData::default(), + } + .into(); + + let mut batch_transition: StateTransition = batch_transition.into(); + + let identity_public_key = identity + .loaded_public_keys + .values() + .next() + .expect("expected a key"); + + batch_transition + .sign_external( + identity_public_key, + signer, + Some(|_data_contract_id, _document_type_name| { + Ok(SecurityLevel::HIGH) + }), + ) + .expect("expected to sign"); + + operations.push(batch_transition); + } _ => {} } } diff --git a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs index 4e4eb56a760..484e517ece6 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/token_tests.rs @@ -6,6 +6,7 @@ mod tests { use dpp::data_contract::accessors::v0::DataContractV0Setters; use dpp::data_contract::accessors::v1::DataContractV1Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Setters; + use dpp::data_contract::DataContract; use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::Identity; use dpp::state_transition::StateTransition; @@ -71,8 +72,10 @@ mod tests { .token_configuration_mut(0) .expect("expected to get token configuration"); token_configuration.set_minting_allow_choosing_destination(true); - let token_id = contract.token_id(0).expect("expected to get token_id"); contract.set_owner_id(identity1.id()); + let new_id = DataContract::generate_data_contract_id_v0(identity1.id(), 1); + contract.set_id(new_id); + let token_id = contract.token_id(0).expect("expected to get token_id"); let token_op = TokenOp { contract: contract.clone(), @@ -136,8 +139,6 @@ mod tests { let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15, &mut None); - println!("{:?}", &outcome.state_transition_results_per_block); - let drive = &outcome.abci_app.platform.drive; let identity_ids = vec![identity1.id().to_buffer(), identity2.id().to_buffer()]; let balances = drive @@ -149,13 +150,35 @@ mod tests { ) .expect("expected to get balances"); - println!("{:?}", balances); + for (identity_id, token_balance) in balances { + assert!(token_balance.is_some()) + } + + let identity_1_token_balance = drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity1.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch"); + let identity_2_token_balance = drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch"); + + assert_eq!(identity_1_token_balance, Some(100000)); // The initial amount from creating the contract + assert_eq!(identity_2_token_balance, Some(11000)); // 11 blocks of 1000 } #[test] fn run_chain_insert_one_new_identity_per_block_and_a_token_transfer() { let platform_version = PlatformVersion::latest(); - let created_contract = json_document_to_created_contract( + let mut created_contract = json_document_to_created_contract( "tests/supporting_files/contract/basic-token/basic-token.json", 1, true, @@ -192,16 +215,22 @@ mod tests { .map(|(identity, transition)| (identity, Some(transition))) .collect(); - let contract = created_contract.data_contract(); - + let contract = created_contract.data_contract_mut(); + let mut token_configuration = contract + .token_configuration_mut(0) + .expect("expected to get token configuration"); + token_configuration.set_minting_allow_choosing_destination(true); + contract.set_owner_id(identity1.id()); + let new_id = DataContract::generate_data_contract_id_v0(identity1.id(), 1); + contract.set_id(new_id); let token_id = contract.token_id(0).expect("expected to get token_id"); let token_op = TokenOp { contract: contract.clone(), token_id, token_pos: 0, - use_identity_with_id: None, - action: TokenEvent::Mint(1000, identity2.id(), None), + use_identity_with_id: Some(identity1.id()), + action: TokenEvent::Transfer(identity2.id(), None, None, None, 1000), }; let strategy = NetworkStrategy { @@ -250,7 +279,7 @@ mod tests { testing_configs: PlatformTestConfig::default_minimal_verifications(), ..Default::default() }; - let block_count = 120; + let block_count = 12; let mut platform = TestPlatformBuilder::new() .with_config(config.clone()) .build_with_mock_rpc(); @@ -269,6 +298,32 @@ mod tests { ) .expect("expected to get balances"); - println!("{:?}", balances); + assert_eq!( + balances.get(&identity1.id()).copied(), + Some(Some(100000 - 11000)) + ); + assert_eq!(balances.get(&identity2.id()).copied(), Some(Some(11000))); + + // Let's also try this fetching + + let identity_1_token_balance = drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity1.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch"); + let identity_2_token_balance = drive + .fetch_identity_token_balance( + token_id.to_buffer(), + identity2.id().to_buffer(), + None, + platform_version, + ) + .expect("expected to fetch"); + + assert_eq!(identity_1_token_balance, Some(100000 - 11000)); // The initial amount from creating the contract less 11 times 1000 that we transferred + assert_eq!(identity_2_token_balance, Some(11000)); // 11 blocks of 1000 } } 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 23e0b6922e7..64701edcfa8 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 tenderdash_abci::proto::abci::ExecTxResult; use dpp::block::extended_block_info::v0::ExtendedBlockInfoV0Getters; use dpp::data_contract::associated_token::token_configuration::accessors::v0::TokenConfigurationV0Getters; use dpp::data_contracts::SystemDataContract; +use dpp::document::serialization_traits::DocumentPlatformConversionMethodsV0; use dpp::prelude::Identifier; use dpp::voting::votes::Vote; use drive::drive::votes::resolved::vote_polls::ResolvedVotePoll; @@ -519,10 +520,6 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( .system_data_contracts .load_token_history(); - let document_type = token_history - .document_type_for_name(document_type_name.as_str()) - .expect("get document type"); - let query = SingleDocumentDriveQuery { contract_id: SystemDataContract::TokenHistory .id() @@ -542,11 +539,10 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( SingleDocumentDriveQueryContestedStatus::NotContested, }; - let (root_hash, document) = query - .verify_proof( + let (root_hash, serialized_document) = query + .verify_proof_keep_serialized( false, &response_proof.grovedb_proof, - document_type, platform_version, ) .expect("expected to verify a document"); @@ -559,7 +555,7 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( ); assert!( - document.is_some(), + serialized_document.is_some(), "we expect a token history document" ); @@ -580,7 +576,19 @@ pub(crate) fn verify_state_transitions_were_or_were_not_executed( ) .expect("expected to build historical document"); - assert_eq!(document.unwrap(), expected_document); + let serialized_expected_document = expected_document + .serialize( + token_transition_action + .historical_document_type(&token_history) + .expect("expected document type"), + platform_version, + ) + .expect("expected to serialize"); + + assert_eq!( + serialized_document.unwrap(), + serialized_expected_document + ); } else { todo!(); } diff --git a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs index 7dbcc7064b2..4f7a8e24c67 100644 --- a/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/add_transaction_history_operations/v0/mod.rs @@ -4,15 +4,13 @@ use crate::fees::op::LowLevelDriveOperation; use crate::util::object_size_info::DocumentInfo::DocumentOwnedInfo; use crate::util::object_size_info::{DocumentAndContractInfo, OwnedDocumentInfo}; use dpp::block::block_info::BlockInfo; -use dpp::data_contract::accessors::v0::DataContractV0Getters; -use dpp::document::{Document, DocumentV0}; use dpp::identifier::Identifier; use dpp::prelude::IdentityNonce; use dpp::tokens::token_event::TokenEvent; use grovedb::batch::KeyInfoPath; use grovedb::{EstimatedLayerInformation, TransactionArg}; use platform_version::version::PlatformVersion; -use std::collections::{BTreeMap, HashMap}; +use std::collections::HashMap; impl Drive { /// Adds token transaction history @@ -41,8 +39,6 @@ impl Drive { block_info, )?; - println!("document {:?}", document); - let operations = self.add_document_for_contract_operations( DocumentAndContractInfo { owned_document_info: OwnedDocumentInfo { diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs index 3a41cda8be5..9e45812091c 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/mod.rs @@ -7,6 +7,7 @@ use crate::fees::op::LowLevelDriveOperation; use dpp::balances::credits::TokenAmount; use dpp::block::block_info::BlockInfo; use dpp::fee::fee_result::FeeResult; +use dpp::prelude::Identifier; use dpp::version::PlatformVersion; use grovedb::TransactionArg; use std::collections::BTreeMap; @@ -34,7 +35,7 @@ impl Drive { identity_ids: &[[u8; 32]], transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result>, Error> { + ) -> Result>, Error> { match platform_version .drive .methods @@ -80,7 +81,7 @@ impl Drive { block_info: &BlockInfo, transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result<(BTreeMap<[u8; 32], Option>, FeeResult), Error> { + ) -> Result<(BTreeMap>, FeeResult), Error> { let mut drive_operations: Vec = vec![]; let value = self.fetch_identities_token_balances_operations( token_id, @@ -126,7 +127,7 @@ impl Drive { transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result>, Error> { + ) -> Result>, Error> { match platform_version .drive .methods diff --git a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs index fd884c1eba1..b9dddc6e8cf 100644 --- a/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/balance/fetch_identities_token_balances/v0/mod.rs @@ -3,6 +3,7 @@ use crate::error::drive::DriveError; use crate::error::Error; use crate::fees::op::LowLevelDriveOperation; use dpp::balances::credits::TokenAmount; +use dpp::identifier::Identifier; use dpp::version::PlatformVersion; use grovedb::Element::SumItem; use grovedb::TransactionArg; @@ -15,7 +16,7 @@ impl Drive { identity_ids: &[[u8; 32]], transaction: TransactionArg, platform_version: &PlatformVersion, - ) -> Result>, Error> { + ) -> Result>, Error> { self.fetch_identities_token_balances_operations_v0( token_id, identity_ids, @@ -32,7 +33,7 @@ impl Drive { transaction: TransactionArg, drive_operations: &mut Vec, platform_version: &PlatformVersion, - ) -> Result>, Error> { + ) -> Result>, Error> { let path_query = Self::token_balances_for_identity_ids_query(token_id, identity_ids); self.grove_get_raw_path_query_with_optional( @@ -44,7 +45,7 @@ impl Drive { )? .into_iter() .map(|(_, key, element)| { - let identity_id: [u8; 32] = key.try_into().map_err(|_| { + let identity_id: Identifier = key.try_into().map_err(|_| { Error::Drive(DriveError::CorruptedDriveState( "identity id not 32 bytes".to_string(), )) diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs index 2900b4a008c..06c9087dcf9 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs @@ -20,10 +20,13 @@ pub mod token_emergency_action_transition_action; use derive_more::From; use dpp::block::block_info::BlockInfo; +use dpp::data_contract::accessors::v0::DataContractV0Getters; +use dpp::data_contract::document_type::DocumentTypeRef; use dpp::data_contracts::SystemDataContract; use dpp::document::Document; use dpp::identifier::Identifier; use dpp::prelude::{DataContract, IdentityNonce}; +use dpp::ProtocolError; use crate::error::Error; use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; @@ -96,6 +99,14 @@ impl TokenTransitionAction { } } + /// Historical document type for the token history contract + pub fn historical_document_type<'a>( + &self, + token_history_contract: &'a DataContract, + ) -> Result, ProtocolError> { + Ok(token_history_contract.document_type_for_name(self.historical_document_type_name())?) + } + /// Historical document id pub fn historical_document_id( &self, diff --git a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs index ad08114540e..51b976c4dcc 100644 --- a/packages/rs-drive/src/util/batch/drive_op_batch/token.rs +++ b/packages/rs-drive/src/util/batch/drive_op_batch/token.rs @@ -116,6 +116,10 @@ impl DriveLowLevelOperationConverter for TokenOperationType { mint_amount, allow_first_mint, } => { + println!( + "minting in {} token to id {} ({})", + token_id, identity_balance_holder_id, mint_amount + ); let token_id_bytes: [u8; 32] = token_id.to_buffer(); let identity_id_bytes: [u8; 32] = identity_balance_holder_id.to_buffer(); let batch_operations = drive.token_mint_operations( diff --git a/packages/rs-platform-value/src/inner_value.rs b/packages/rs-platform-value/src/inner_value.rs index c92828e91c0..d8606bd478b 100644 --- a/packages/rs-platform-value/src/inner_value.rs +++ b/packages/rs-platform-value/src/inner_value.rs @@ -361,7 +361,7 @@ impl Value { Self::inner_array_mut_ref(map, key) } - pub fn get_array_slice<'a>(&'a self, key: &'a str) -> Result<&[Value], Error> { + pub fn get_array_slice<'a>(&'a self, key: &'a str) -> Result<&'a [Value], Error> { let map = self.to_map()?; Self::inner_array_slice(map, key) } diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index 6455feaf401..6d5d3e5161f 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -1920,28 +1920,22 @@ mod tests { let mut simple_signer = SimpleSigner::default(); - let (identity1, keys) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity1, keys) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys); - let (identity2, keys) = - Identity::random_identity_with_main_keys_with_private_key::>( - 2, - &mut rng, - platform_version, - ) - .unwrap(); + let (mut identity2, keys) = Identity::random_identity_with_main_keys_with_private_key::< + Vec<_>, + >(2, &mut rng, platform_version) + .unwrap(); simple_signer.add_keys(keys); let start_identities = create_state_transitions_for_identities( - vec![identity1, identity2], + vec![&mut identity1, &mut identity2], &(dash_to_duffs!(1)..=dash_to_duffs!(1)), &mut simple_signer, &mut rng, diff --git a/packages/token-history-contract/schema/v1/token-history-contract-documents.json b/packages/token-history-contract/schema/v1/token-history-contract-documents.json index 576f285eae6..0946d7a29ea 100644 --- a/packages/token-history-contract/schema/v1/token-history-contract-documents.json +++ b/packages/token-history-contract/schema/v1/token-history-contract-documents.json @@ -309,7 +309,7 @@ ], "additionalProperties": false }, - "frozen": { + "freeze": { "type": "object", "documentsMutable": false, "canBeDeleted": false, @@ -372,7 +372,7 @@ ], "additionalProperties": false }, - "unfrozen": { + "unfreeze": { "type": "object", "documentsMutable": false, "canBeDeleted": false, From 346b80319303a6b71bd10aabaaba30686caf8d00 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 14 Jan 2025 03:35:45 +0700 Subject: [PATCH 58/61] token statuses query --- .../protos/platform/v0/platform.proto | 134 ++++++++++++++++++ .../v1/mod.rs | 20 +-- .../v0/mod.rs | 1 - .../state_v0/mod.rs | 2 +- .../batch/transformer/v0/mod.rs | 1 - packages/rs-drive-abci/src/query/service.rs | 32 ++++- .../src/query/token_queries/mod.rs | 1 + .../query/token_queries/token_status/mod.rs | 59 ++++++++ .../token_queries/token_status/v0/mod.rs | 73 ++++++++++ .../calculate_total_tokens_balance/v0/mod.rs | 4 +- .../info/fetch_identity_token_infos/v0/mod.rs | 2 +- packages/rs-drive/src/drive/tokens/mod.rs | 7 +- .../tokens/status/fetch_token_status/mod.rs | 110 ++++++++++++++ .../status/fetch_token_status/v0/mod.rs | 70 +++++++++ .../tokens/status/fetch_token_statuses/mod.rs | 126 ++++++++++++++++ .../status/fetch_token_statuses/v0/mod.rs | 76 ++++++++++ .../rs-drive/src/drive/tokens/status/mod.rs | 7 + .../tokens/status/prove_token_statuses/mod.rs | 124 ++++++++++++++++ .../status/prove_token_statuses/v0/mod.rs | 52 +++++++ packages/rs-drive/src/open/mod.rs | 3 +- .../v0/mod.rs | 1 - .../drive_abci_query_versions/mod.rs | 1 + .../drive_abci_query_versions/v1.rs | 5 + .../drive_token_method_versions/mod.rs | 3 + .../drive_token_method_versions/v1.rs | 3 + .../src/version/mocks/v2_test.rs | 5 + 26 files changed, 890 insertions(+), 32 deletions(-) create mode 100644 packages/rs-drive-abci/src/query/token_queries/token_status/mod.rs create mode 100644 packages/rs-drive-abci/src/query/token_queries/token_status/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/status/fetch_token_status/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/status/fetch_token_status/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/status/fetch_token_statuses/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/status/fetch_token_statuses/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/status/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/status/prove_token_statuses/mod.rs create mode 100644 packages/rs-drive/src/drive/tokens/status/prove_token_statuses/v0/mod.rs diff --git a/packages/dapi-grpc/protos/platform/v0/platform.proto b/packages/dapi-grpc/protos/platform/v0/platform.proto index f31f4658eb1..945bd3c2b18 100644 --- a/packages/dapi-grpc/protos/platform/v0/platform.proto +++ b/packages/dapi-grpc/protos/platform/v0/platform.proto @@ -59,6 +59,8 @@ service Platform { rpc getIdentitiesTokenBalances(GetIdentitiesTokenBalancesRequest) returns (GetIdentitiesTokenBalancesResponse); rpc getIdentityTokenInfos(GetIdentityTokenInfosRequest) returns (GetIdentityTokenInfosResponse); rpc getIdentitiesTokenInfos(GetIdentitiesTokenInfosRequest) returns (GetIdentitiesTokenInfosResponse); + rpc getTokenStatuses(GetTokenStatusesRequest) returns (GetTokenStatusesResponse); + rpc getActiveGroupActions(GetActiveGroupActionsRequest) returns (GetActiveGroupActionsResponse); } // Proof message includes cryptographic proofs for validating responses @@ -1360,4 +1362,136 @@ message GetIdentitiesTokenInfosResponse { oneof version { GetIdentitiesTokenInfosResponseV0 v0 = 1; } +} + +message GetTokenStatusesRequest { + message GetTokenStatusesRequestV0 { + repeated bytes token_ids = 1; + bool prove = 2; + } + oneof version { + GetTokenStatusesRequestV0 v0 = 1; + } +} + +message GetTokenStatusesResponse { + message GetTokenStatusesResponseV0 { + message TokenStatusEntry { + bytes token_id = 1; + optional bool paused = 2; + } + + message TokenStatuses { + repeated TokenStatusEntry token_statuses = 1; + } + + oneof result { + TokenStatuses token_statuses = 1; + Proof proof = 2; + } + ResponseMetadata metadata = 3; + } + oneof version { + GetTokenStatusesResponseV0 v0 = 1; + } +} + +message GetActiveGroupActionsRequest { + message GetActiveGroupActionsRequestV0 { + bytes contract_id = 1; + uint32 group_contract_position = 2; + bool prove = 3; + } + oneof version { + GetActiveGroupActionsRequestV0 v0 = 1; + } +} + +message GetActiveGroupActionsResponse { + message GetActiveGroupActionsResponseV0 { + // Mint event + message MintEvent { + uint64 amount = 1; // Amount to mint + bytes recipient_id = 2; // Recipient identifier + string public_note = 3; // Public note + } + + // Burn event + message BurnEvent { + uint64 amount = 1; // Amount to burn + string public_note = 2; // Public note + } + + // Freeze event + message FreezeEvent { + bytes frozen_id = 1; // Identifier of the frozen entity + string public_note = 2; // Public note + } + + // Unfreeze event + message UnfreezeEvent { + bytes frozen_id = 1; // Identifier of the unfrozen entity + string public_note = 2; // Public note + } + + // Destroy frozen funds event + message DestroyFrozenFundsEvent { + bytes frozen_id = 1; // Identifier of the frozen entity + uint64 amount = 2; // Amount to destroy + string public_note = 3; // Public note + } + + // Transfer event + message TransferEvent { + bytes recipient_id = 1; // Recipient identifier + string public_note = 2; // Public note + bytes shared_encrypted_note = 3; // Shared encrypted note + bytes personal_encrypted_note = 4; // Personal encrypted note + uint64 amount = 5; // Amount transferred + } + + // Emergency action event + message EmergencyActionEvent { + string action_type = 1; // Emergency action type + string public_note = 2; // Public note + } + + // Event associated with this action + message GroupActionEvent { + oneof event_type { + TokenEvent token_event = 1; // Token event details + } + } + + // Details for token events + message TokenEvent { + oneof type { + MintEvent mint = 1; // Mint event details + BurnEvent burn = 2; // Burn event details + FreezeEvent freeze = 3; // Freeze event details + UnfreezeEvent unfreeze = 4; // Unfreeze event details + DestroyFrozenFundsEvent destroy_frozen_funds = 5; // Destroy frozen funds + TransferEvent transfer = 6; // Transfer event details + EmergencyActionEvent emergency_action = 7; // Emergency action details + } + } + + message GroupActionEntry { + bytes action_id = 1; // Unique identifier for the action + GroupActionEvent event = 2; // The event data + } + + message GroupActions { + repeated GroupActionEntry group_actions = 1; + } + + oneof result { + GroupActions group_actions = 1; + Proof proof = 2; + } + ResponseMetadata metadata = 3; + } + oneof version { + GetActiveGroupActionsResponseV0 v0 = 1; + } } \ No newline at end of file diff --git a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs index 4c380c2269f..4e9edf37f22 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/block_processing_end_events/process_block_fees_and_validate_sum_trees/v1/mod.rs @@ -4,29 +4,13 @@ //! epoch changes. //! -use std::option::Option::None; - -use dpp::block::epoch::Epoch; -use dpp::version::PlatformVersion; -use drive::drive::Drive; -use drive::grovedb::Transaction; -use drive::util::batch::DriveOperation; - -use crate::error::execution::ExecutionError; use crate::error::Error; -use crate::execution::types::block_execution_context::v0::BlockExecutionContextV0Getters; use crate::execution::types::block_execution_context::BlockExecutionContext; -use crate::execution::types::block_fees::v0::BlockFeesV0Getters; use crate::execution::types::block_fees::BlockFees; -use crate::execution::types::block_state_info::v0::{ - BlockStateInfoV0Getters, BlockStateInfoV0Methods, -}; use crate::execution::types::processed_block_fees_outcome; -use crate::platform_types::epoch_info::v0::EpochInfoV0Getters; use crate::platform_types::platform::Platform; - -use crate::platform_types::platform_state::v0::PlatformStateV0Methods; -use drive::drive::credit_pools::epochs::operations_factory::EpochOperations; +use dpp::version::PlatformVersion; +use drive::grovedb::Transaction; /// From the Dash Improvement Proposal: diff --git a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0/mod.rs index 59e60de94c7..072d8dfc7e8 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/tokens/validate_token_aggregated_balance/v0/mod.rs @@ -2,7 +2,6 @@ use drive::grovedb::Transaction; use crate::error::execution::ExecutionError; use crate::error::Error; -use crate::execution::types::block_execution_context::BlockExecutionContext; use crate::platform_types::platform::Platform; use dpp::version::PlatformVersion; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/state_v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/state_v0/mod.rs index 050a451afb4..c5ea53f9b03 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/state_v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/action_validation/token_emergency_action_transition_action/state_v0/mod.rs @@ -12,7 +12,7 @@ use drive::state_transition_action::batch::batched_transition::token_transition: use dpp::version::PlatformVersion; use drive::query::TransactionArg; use crate::error::Error; -use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext, StateTransitionExecutionContextMethodsV0}; +use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use crate::execution::validation::state_transition::batch::action_validation::token_base_transition_action::TokenBaseTransitionActionValidation; use crate::platform_types::platform::PlatformStateRef; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs index 72b5099a94b..f9ed1d6d66b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/transformer/v0/mod.rs @@ -48,7 +48,6 @@ use dpp::state_transition::batch_transition::batched_transition::document_update use dpp::state_transition::batch_transition::batched_transition::token_transition::{TokenTransition, TokenTransitionV0Methods}; use dpp::state_transition::batch_transition::document_base_transition::document_base_transition_trait::DocumentBaseTransitionAccessors; use dpp::state_transition::batch_transition::token_base_transition::v0::v0_methods::TokenBaseTransitionV0Methods; -use dpp::tokens::emergency_action::TokenEmergencyAction; use drive::drive::contract::DataContractFetchInfo; use drive::drive::Drive; use drive::state_transition_action::batch::batched_transition::BatchedTransitionAction; diff --git a/packages/rs-drive-abci/src/query/service.rs b/packages/rs-drive-abci/src/query/service.rs index 3847b7d1bb4..224276e82a7 100644 --- a/packages/rs-drive-abci/src/query/service.rs +++ b/packages/rs-drive-abci/src/query/service.rs @@ -10,7 +10,8 @@ use crate::utils::spawn_blocking_task_with_name_if_supported; use async_trait::async_trait; use dapi_grpc::platform::v0::platform_server::Platform as PlatformService; use dapi_grpc::platform::v0::{ - BroadcastStateTransitionRequest, BroadcastStateTransitionResponse, GetConsensusParamsRequest, + BroadcastStateTransitionRequest, BroadcastStateTransitionResponse, + GetActiveGroupActionsRequest, GetActiveGroupActionsResponse, GetConsensusParamsRequest, GetConsensusParamsResponse, GetContestedResourceIdentityVotesRequest, GetContestedResourceIdentityVotesResponse, GetContestedResourceVoteStateRequest, GetContestedResourceVoteStateResponse, GetContestedResourceVotersForIdentityRequest, @@ -35,8 +36,9 @@ use dapi_grpc::platform::v0::{ GetPrefundedSpecializedBalanceResponse, GetProofsRequest, GetProofsResponse, GetProtocolVersionUpgradeStateRequest, GetProtocolVersionUpgradeStateResponse, GetProtocolVersionUpgradeVoteStatusRequest, GetProtocolVersionUpgradeVoteStatusResponse, - GetStatusRequest, GetStatusResponse, GetTotalCreditsInPlatformRequest, - GetTotalCreditsInPlatformResponse, GetVotePollsByEndDateRequest, GetVotePollsByEndDateResponse, + GetStatusRequest, GetStatusResponse, GetTokenStatusesRequest, GetTokenStatusesResponse, + GetTotalCreditsInPlatformRequest, GetTotalCreditsInPlatformResponse, + GetVotePollsByEndDateRequest, GetVotePollsByEndDateResponse, WaitForStateTransitionResultRequest, WaitForStateTransitionResultResponse, }; use dapi_grpc::tonic::{Code, Request, Response, Status}; @@ -660,6 +662,30 @@ impl PlatformService for QueryService { ) .await } + + async fn get_token_statuses( + &self, + request: Request, + ) -> Result, Status> { + self.handle_blocking_query( + request, + Platform::::query_token_statuses, + "get_token_statuses", + ) + .await + } + + async fn get_active_group_actions( + &self, + request: Request, + ) -> Result, Status> { + self.handle_blocking_query( + request, + Platform::::query_active_group_actions, + "get_active_group_actions", + ) + .await + } } fn query_error_into_status(error: QueryError) -> Status { diff --git a/packages/rs-drive-abci/src/query/token_queries/mod.rs b/packages/rs-drive-abci/src/query/token_queries/mod.rs index 3ffa5ac53f7..70f261b3831 100644 --- a/packages/rs-drive-abci/src/query/token_queries/mod.rs +++ b/packages/rs-drive-abci/src/query/token_queries/mod.rs @@ -2,3 +2,4 @@ mod identities_token_balances; mod identities_token_infos; mod identity_token_balances; mod identity_token_infos; +mod token_status; diff --git a/packages/rs-drive-abci/src/query/token_queries/token_status/mod.rs b/packages/rs-drive-abci/src/query/token_queries/token_status/mod.rs new file mode 100644 index 00000000000..555fce502de --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/token_status/mod.rs @@ -0,0 +1,59 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_token_statuses_request::Version as RequestVersion; +use dapi_grpc::platform::v0::get_token_statuses_response::Version as ResponseVersion; +use dapi_grpc::platform::v0::{GetTokenStatusesRequest, GetTokenStatusesResponse}; +use dpp::version::PlatformVersion; +mod v0; + +impl Platform { + /// Querying of token statuses + pub fn query_token_statuses( + &self, + GetTokenStatusesRequest { version }: GetTokenStatusesRequest, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let Some(version) = version else { + return Ok(QueryValidationResult::new_with_error( + QueryError::DecodingError( + "could not decode identity token infos query".to_string(), + ), + )); + }; + + let feature_version_bounds = &platform_version + .drive_abci + .query + .token_queries + .token_statuses; + + let feature_version = match &version { + RequestVersion::V0(_) => 0, + }; + if !feature_version_bounds.check_version(feature_version) { + return Ok(QueryValidationResult::new_with_error( + QueryError::UnsupportedQueryVersion( + "token_statuses".to_string(), + feature_version_bounds.min_version, + feature_version_bounds.max_version, + platform_version.protocol_version, + feature_version, + ), + )); + } + + match version { + RequestVersion::V0(request_v0) => { + let result = + self.query_token_statuses_v0(request_v0, platform_state, platform_version)?; + Ok(result.map(|response_v0| GetTokenStatusesResponse { + version: Some(ResponseVersion::V0(response_v0)), + })) + } + } + } +} diff --git a/packages/rs-drive-abci/src/query/token_queries/token_status/v0/mod.rs b/packages/rs-drive-abci/src/query/token_queries/token_status/v0/mod.rs new file mode 100644 index 00000000000..8f801b8d57b --- /dev/null +++ b/packages/rs-drive-abci/src/query/token_queries/token_status/v0/mod.rs @@ -0,0 +1,73 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_token_statuses_request::GetTokenStatusesRequestV0; +use dapi_grpc::platform::v0::get_token_statuses_response::get_token_statuses_response_v0::{ + TokenStatusEntry, TokenStatuses, +}; +use dapi_grpc::platform::v0::get_token_statuses_response::{ + get_token_statuses_response_v0, GetTokenStatusesResponseV0, +}; +use dpp::check_validation_result_with_data; +use dpp::tokens::status::v0::TokenStatusV0Accessors; +use dpp::validation::ValidationResult; +use dpp::version::PlatformVersion; + +impl Platform { + pub(super) fn query_token_statuses_v0( + &self, + GetTokenStatusesRequestV0 { token_ids, prove }: GetTokenStatusesRequestV0, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let token_ids: Vec<[u8; 32]> = check_validation_result_with_data!(token_ids + .into_iter() + .map(|token_id| { + token_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "token_id must be a valid identifier (32 bytes long)".to_string(), + ) + }) + }) + .collect::, QueryError>>()); + + let response = if prove { + let proof = check_validation_result_with_data!(self.drive.prove_token_statuses( + token_ids.as_slice(), + None, + platform_version, + )); + + GetTokenStatusesResponseV0 { + result: Some(get_token_statuses_response_v0::Result::Proof( + self.response_proof_v0(platform_state, proof), + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + } else { + let token_statuses = self + .drive + .fetch_token_statuses(token_ids.as_slice(), None, platform_version)? + .into_iter() + .map(|(token_id, status)| { + let paused = status.map(|token_status| token_status.paused()); + TokenStatusEntry { + token_id: token_id.to_vec(), + paused, + } + }) + .collect(); + + GetTokenStatusesResponseV0 { + result: Some(get_token_statuses_response_v0::Result::TokenStatuses( + TokenStatuses { token_statuses }, + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + }; + + Ok(QueryValidationResult::new_with_data(response)) + } +} diff --git a/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs b/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs index 1d0bdd63176..d96c796cb28 100644 --- a/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/calculate_total_tokens_balance/v0/mod.rs @@ -1,7 +1,7 @@ use crate::drive::balances::TOTAL_TOKEN_SUPPLIES_STORAGE_KEY; use crate::drive::system::misc_path; -use crate::drive::tokens::{token_balances_root_path, tokens_root_path, TOKEN_BALANCES_KEY}; -use crate::drive::{Drive, RootTree}; +use crate::drive::tokens::{tokens_root_path, TOKEN_BALANCES_KEY}; +use crate::drive::Drive; use crate::error::Error; use crate::util::grove_operations::DirectQueryType; use dpp::balances::total_tokens_balance::TotalTokensBalance; diff --git a/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/v0/mod.rs b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/v0/mod.rs index 798f2bd3d8c..a04e76bff62 100644 --- a/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/info/fetch_identity_token_infos/v0/mod.rs @@ -73,7 +73,7 @@ impl Drive { })?; match element { Some(Item(value, ..)) => Ok(( - identity_id, + token_id, Some(IdentityTokenInfo::deserialize_from_bytes(&value)?), )), None => Ok((token_id, None)), diff --git a/packages/rs-drive/src/drive/tokens/mod.rs b/packages/rs-drive/src/drive/tokens/mod.rs index e54e92e7974..30c5dd4d18f 100644 --- a/packages/rs-drive/src/drive/tokens/mod.rs +++ b/packages/rs-drive/src/drive/tokens/mod.rs @@ -18,8 +18,8 @@ pub mod estimated_costs; /// Manages freezing operations in the system. pub mod freeze; -/// Contains informational utility functions. -mod info; +/// Identity token info module, like if someone is frozen +pub mod info; /// Implements minting operations for creating new tokens. pub mod mint; @@ -36,6 +36,9 @@ pub mod unfreeze; /// Calculates the total token balance across all accounts. pub mod calculate_total_tokens_balance; +/// Token status module, like if the token is paused +pub mod status; + /// Key for accessing token status information. pub const TOKEN_STATUS_INFO_KEY: u8 = 96; diff --git a/packages/rs-drive/src/drive/tokens/status/fetch_token_status/mod.rs b/packages/rs-drive/src/drive/tokens/status/fetch_token_status/mod.rs new file mode 100644 index 00000000000..f8b590441b3 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/status/fetch_token_status/mod.rs @@ -0,0 +1,110 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::tokens::status::TokenStatus; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Fetches the Token status from the backing store. + /// Passing `apply = false` will return estimated costs (0 or Some(0) in place of actual values). + /// + /// # Arguments + /// + /// * `token_id` - The ID of the token. + /// * `apply` - Whether to actually fetch from state (true) or estimate costs (false). + /// * `transaction` - The current transaction. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - The token info of the Identity if successful, or an error. + pub fn fetch_token_status( + &self, + token_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.fetch.token_status { + 0 => self.fetch_token_status_v0(token_id, transaction, platform_version), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_token_status".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the Token status with costs (if `apply = true`) and returns associated fee result. + pub fn fetch_token_status_with_costs( + &self, + token_id: [u8; 32], + block_info: &BlockInfo, + apply: bool, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(Option, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_token_status_operations( + token_id, + apply, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the operations to get Token's status from the backing store. + /// If `apply` is false, the operations are stateless and only used for cost estimation. + /// + /// # Arguments + /// + /// * `token_id` - The ID of the token. + /// * `apply` - Whether to fetch actual stateful data (true) or just estimate costs (false). + /// * `transaction` - The current transaction. + /// * `drive_operations` - The drive operations vector to populate. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - The token info of the Identity if successful, or an error. + pub fn fetch_token_status_operations( + &self, + token_id: [u8; 32], + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.fetch.token_status { + 0 => self.fetch_token_status_operations_v0( + token_id, + apply, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_token_status_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/status/fetch_token_status/v0/mod.rs b/packages/rs-drive/src/drive/tokens/status/fetch_token_status/v0/mod.rs new file mode 100644 index 00000000000..6b7c9a1af7e --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/status/fetch_token_status/v0/mod.rs @@ -0,0 +1,70 @@ +use crate::drive::tokens::token_statuses_root_path; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::serialization::PlatformDeserializable; +use dpp::tokens::status::TokenStatus; +use dpp::version::PlatformVersion; +use grovedb::Element::Item; +use grovedb::{TransactionArg, TreeType}; + +impl Drive { + pub(super) fn fetch_token_status_v0( + &self, + token_id: [u8; 32], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.fetch_token_status_operations_v0( + token_id, + true, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_token_status_operations_v0( + &self, + token_id: [u8; 32], + apply: bool, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let direct_query_type = if apply { + DirectQueryType::StatefulDirectQuery + } else { + DirectQueryType::StatelessDirectQuery { + in_tree_type: TreeType::NormalTree, + query_target: QueryTargetValue(8), + } + }; + + let token_statuses_root_path = token_statuses_root_path(); + + match self.grove_get_raw_optional( + (&token_statuses_root_path).into(), + &token_id, + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + ) { + Ok(Some(Item(info, _))) => { + Ok(Some(TokenStatus::deserialize_from_bytes(info.as_slice())?)) + } + + Ok(None) | Err(Error::GroveDB(grovedb::Error::PathKeyNotFound(_))) => Ok(None), + + Ok(Some(_)) => Err(Error::Drive(DriveError::CorruptedElementType( + "token status was present but was not an item", + ))), + + Err(e) => Err(e), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/status/fetch_token_statuses/mod.rs b/packages/rs-drive/src/drive/tokens/status/fetch_token_statuses/mod.rs new file mode 100644 index 00000000000..9f81e5ab2ed --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/status/fetch_token_statuses/mod.rs @@ -0,0 +1,126 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::tokens::status::TokenStatus; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; +use std::collections::BTreeMap; + +impl Drive { + /// Fetches token statuses from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose infos are to be fetched. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding infos, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_token_statuses( + &self, + token_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version.drive.methods.token.fetch.token_statuses { + 0 => self.fetch_token_statuses_v0(token_ids, transaction, platform_version), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_token_statuses".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the identity's token infos with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to fetch the infos for. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result<((BTreeMap<[u8; 32], Option>), FeeResult), Error>` - A tuple containing a map of token infos and the associated fee result. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_token_statuses_with_costs( + &self, + token_ids: &[[u8; 32]], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(BTreeMap<[u8; 32], Option>, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.fetch_token_statuses_operations( + token_ids, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to fetch the identity's token infos from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the infos for. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result>, Error>` - A map of token IDs to their corresponding statuses. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn fetch_token_statuses_operations( + &self, + token_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + match platform_version.drive.methods.token.fetch.token_statuses { + 0 => self.fetch_token_statuses_operations_v0( + token_ids, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_token_statuses_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/status/fetch_token_statuses/v0/mod.rs b/packages/rs-drive/src/drive/tokens/status/fetch_token_statuses/v0/mod.rs new file mode 100644 index 00000000000..7b4fd80f11a --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/status/fetch_token_statuses/v0/mod.rs @@ -0,0 +1,76 @@ +use crate::drive::tokens::{tokens_root_path_vec, TOKEN_STATUS_INFO_KEY}; +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::serialization::PlatformDeserializable; +use dpp::tokens::status::TokenStatus; +use dpp::version::PlatformVersion; +use grovedb::Element::Item; +use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; +use std::collections::BTreeMap; + +impl Drive { + pub(super) fn fetch_token_statuses_v0( + &self, + token_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + self.fetch_token_statuses_operations_v0( + token_ids, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_token_statuses_operations_v0( + &self, + token_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result>, Error> { + let tokens_root = tokens_root_path_vec(); + + let mut query = Query::new(); + + for token_id in token_ids { + query.insert_key(token_id.to_vec()); + } + + query.set_subquery_path(vec![vec![TOKEN_STATUS_INFO_KEY]]); + + let path_query = PathQuery::new( + tokens_root, + SizedQuery::new(query, Some(token_ids.len() as u16), None), + ); + + self.grove_get_raw_path_query_with_optional( + &path_query, + false, + transaction, + drive_operations, + &platform_version.drive, + )? + .into_iter() + .map(|(_, key, element)| { + let token_id: [u8; 32] = key.try_into().map_err(|_| { + Error::Drive(DriveError::CorruptedDriveState( + "token id not 32 bytes".to_string(), + )) + })?; + match element { + Some(Item(value, ..)) => { + Ok((token_id, Some(TokenStatus::deserialize_from_bytes(&value)?))) + } + None => Ok((token_id, None)), + _ => Err(Error::Drive(DriveError::CorruptedDriveState( + "token tree for statuses should contain only items".to_string(), + ))), + } + }) + .collect() + } +} diff --git a/packages/rs-drive/src/drive/tokens/status/mod.rs b/packages/rs-drive/src/drive/tokens/status/mod.rs new file mode 100644 index 00000000000..57d88f594e0 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/status/mod.rs @@ -0,0 +1,7 @@ +#[cfg(feature = "server")] +mod fetch_token_statuses; + +#[cfg(feature = "server")] +mod fetch_token_status; +#[cfg(feature = "server")] +mod prove_token_statuses; diff --git a/packages/rs-drive/src/drive/tokens/status/prove_token_statuses/mod.rs b/packages/rs-drive/src/drive/tokens/status/prove_token_statuses/mod.rs new file mode 100644 index 00000000000..29e31ef5940 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/status/prove_token_statuses/mod.rs @@ -0,0 +1,124 @@ +mod v0; + +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::block::block_info::BlockInfo; +use dpp::fee::fee_result::FeeResult; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + /// Proves the token statuses from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs whose statuses are to be proved. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The version of the platform to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_token_statuses( + &self, + token_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.prove.token_statuses { + 0 => self.prove_token_statuses_v0(token_ids, transaction, platform_version), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_token_statuses".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Proves the token statuses with associated costs. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to prove the infos for. + /// * `block_info` - Information about the current block for fee calculation. + /// * `transaction` - The current transaction context. + /// * `platform_version` - The platform version to use. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_token_statuses_with_costs( + &self, + token_ids: &[[u8; 32]], + block_info: &BlockInfo, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result<(Vec, FeeResult), Error> { + let mut drive_operations: Vec = vec![]; + let value = self.prove_token_statuses_operations( + token_ids, + transaction, + &mut drive_operations, + platform_version, + )?; + + let fees = Drive::calculate_fee( + None, + Some(drive_operations), + &block_info.epoch, + self.config.epochs_per_era, + platform_version, + None, + )?; + + Ok((value, fees)) + } + + /// Creates the low-level operations needed to prove the Token statuses from the backing store. + /// + /// # Arguments + /// + /// * `token_ids` - A list of token IDs to query the statuses for. + /// * `transaction` - The current transaction context. + /// * `drive_operations` - A vector to store the created low-level drive operations. + /// * `platform_version` - The platform version to use for compatibility checks. + /// + /// # Returns + /// + /// * `Result, Error>` - A grovedb proof, or an error. + /// + /// # Errors + /// + /// * `DriveError::UnknownVersionMismatch` - If the platform version does not support the requested operation. + pub fn prove_token_statuses_operations( + &self, + token_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.token.prove.token_statuses { + 0 => self.prove_token_statuses_operations_v0( + token_ids, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_token_statuses_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/tokens/status/prove_token_statuses/v0/mod.rs b/packages/rs-drive/src/drive/tokens/status/prove_token_statuses/v0/mod.rs new file mode 100644 index 00000000000..f55a54a6f85 --- /dev/null +++ b/packages/rs-drive/src/drive/tokens/status/prove_token_statuses/v0/mod.rs @@ -0,0 +1,52 @@ +use crate::drive::tokens::{tokens_root_path_vec, TOKEN_IDENTITY_INFO_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::version::PlatformVersion; +use grovedb::{PathQuery, Query, SizedQuery, TransactionArg}; + +impl Drive { + pub(super) fn prove_token_statuses_v0( + &self, + token_ids: &[[u8; 32]], + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.prove_token_statuses_operations_v0( + token_ids, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn prove_token_statuses_operations_v0( + &self, + token_ids: &[[u8; 32]], + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let tokens_root = tokens_root_path_vec(); + + let mut query = Query::new(); + + for token_id in token_ids { + query.insert_key(token_id.to_vec()); + } + + query.set_subquery_path(vec![vec![TOKEN_IDENTITY_INFO_KEY]]); + + let path_query = PathQuery::new( + tokens_root, + SizedQuery::new(query, Some(token_ids.len() as u16), None), + ); + + self.grove_get_proved_path_query( + &path_query, + transaction, + drive_operations, + &platform_version.drive, + ) + } +} diff --git a/packages/rs-drive/src/open/mod.rs b/packages/rs-drive/src/open/mod.rs index 47adf7620d7..82e9a6c65c7 100644 --- a/packages/rs-drive/src/open/mod.rs +++ b/packages/rs-drive/src/open/mod.rs @@ -4,9 +4,8 @@ use crate::config::DriveConfig; use crate::drive::Drive; use crate::error::Error; use dpp::errors::ProtocolError; -use dpp::util::deserializer::ProtocolVersion; use grovedb::GroveDb; -use platform_version::version::{PlatformVersion, INITIAL_PROTOCOL_VERSION}; +use platform_version::version::PlatformVersion; use std::path::Path; use std::sync::Arc; diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs index 518e9d3098b..962053117f8 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/token_transfer_transition_action/v0/mod.rs @@ -12,7 +12,6 @@ use crate::drive::contract::DataContractFetchInfo; use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{ TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0, }; -use crate::state_transition_action::batch::batched_transition::token_transition::token_transfer_transition_action::TokenTransferTransitionAction; /// Token transfer transition action v0 #[derive(Debug, Clone)] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs index 4283f8314c0..15cfe1b3f80 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs @@ -28,6 +28,7 @@ pub struct DriveAbciQueryTokenVersions { pub identities_token_balances: FeatureVersionBounds, pub identities_token_infos: FeatureVersionBounds, pub identity_token_infos: FeatureVersionBounds, + pub token_statuses: FeatureVersionBounds, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs index abfd943ca29..592411522d4 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs @@ -94,6 +94,11 @@ pub const DRIVE_ABCI_QUERY_VERSIONS_V1: DriveAbciQueryVersions = DriveAbciQueryV max_version: 0, default_current_version: 0, }, + token_statuses: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, }, validator_queries: DriveAbciQueryValidatorVersions { proposed_block_counts_by_evonode_ids: FeatureVersionBounds { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs index 53b97598cf4..e10ff813167 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/mod.rs @@ -18,6 +18,8 @@ pub struct DriveTokenFetchMethodVersions { pub identity_token_info: FeatureVersion, pub identity_token_infos: FeatureVersion, pub identities_token_infos: FeatureVersion, + pub token_statuses: FeatureVersion, + pub token_status: FeatureVersion, } #[derive(Clone, Debug, Default)] @@ -28,6 +30,7 @@ pub struct DriveTokenProveMethodVersions { pub identity_token_info: FeatureVersion, pub identity_token_infos: FeatureVersion, pub identities_token_infos: FeatureVersion, + pub token_statuses: FeatureVersion, } #[derive(Clone, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs index 2cc010c109a..9b8f9d83adf 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_token_method_versions/v1.rs @@ -11,6 +11,8 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM identity_token_info: 0, identity_token_infos: 0, identities_token_infos: 0, + token_statuses: 0, + token_status: 0, }, prove: DriveTokenProveMethodVersions { identity_token_balance: 0, @@ -19,6 +21,7 @@ pub const DRIVE_TOKEN_METHOD_VERSIONS_V1: DriveTokenMethodVersions = DriveTokenM identity_token_info: 0, identity_token_infos: 0, identities_token_infos: 0, + token_statuses: 0, }, update: DriveTokenUpdateMethodVersions { create_token_trees: 0, 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 99513147dea..4b1685c0d80 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -231,6 +231,11 @@ pub const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { max_version: 0, default_current_version: 0, }, + token_statuses: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, }, validator_queries: DriveAbciQueryValidatorVersions { proposed_block_counts_by_evonode_ids: FeatureVersionBounds { From 6d90d83672fca836425f841b7d2c3e6802904f39 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 14 Jan 2025 03:56:23 +0700 Subject: [PATCH 59/61] updated unit tests for token history contract --- .github/package-filters/js-packages.yml | 6 + .github/package-filters/rs-packages.yml | 5 + Dockerfile | 4 + package.json | 1 + packages/token-history-contract/package.json | 12 +- .../test/unit/tokenHistoryContract.spec.js | 451 ++++++++++++++++++ .../test/unit/walletContract.spec.js | 187 -------- 7 files changed, 473 insertions(+), 193 deletions(-) create mode 100644 packages/token-history-contract/test/unit/tokenHistoryContract.spec.js delete mode 100644 packages/token-history-contract/test/unit/walletContract.spec.js diff --git a/.github/package-filters/js-packages.yml b/.github/package-filters/js-packages.yml index b42237f81b1..0c4e0260fa7 100644 --- a/.github/package-filters/js-packages.yml +++ b/.github/package-filters/js-packages.yml @@ -2,6 +2,10 @@ - .github/workflows/tests* - packages/wallet-utils-contract/** +'@dashevo/token-history-contract': &token-history-contract + - .github/workflows/tests* + - packages/token-history-contract/** + '@dashevo/dashpay-contract': &dashpay-contract - .github/workflows/tests* - packages/dashpay-contract/** @@ -30,6 +34,7 @@ - *dpns-contract - *withdrawals-contract - *wallet-utils-contract + - *token-history-contract - packages/rs-platform-serialization/** - packages/rs-platform-serialization-derive/** - packages/rs-platform-value/** @@ -80,6 +85,7 @@ dashmate: - *masternode-reward-shares-contract - *dpns-contract - *withdrawals-contract + - *token-history-contract - *wallet-lib - *dapi-client diff --git a/.github/package-filters/rs-packages.yml b/.github/package-filters/rs-packages.yml index c813323e1dd..7e31bd9992f 100644 --- a/.github/package-filters/rs-packages.yml +++ b/.github/package-filters/rs-packages.yml @@ -2,6 +2,10 @@ wallet-utils-contract: &wallet-utils-contract - .github/workflows/tests* - packages/wallet-utils-contract/** +token-history-contract: &token-history-contract + - .github/workflows/tests* + - packages/token-history-contract/** + dashpay-contract: &dashpay-contract - .github/workflows/tests* - packages/dashpay-contract/** @@ -30,6 +34,7 @@ dpp: &dpp - *dpns-contract - *withdrawals-contract - *wallet-utils-contract + - *token-history-contract - *json-schema-compatibility-validator - packages/rs-platform-serialization/** - packages/rs-platform-serialization-derive/** diff --git a/Dockerfile b/Dockerfile index 671b488fff4..7a93ed1d554 100644 --- a/Dockerfile +++ b/Dockerfile @@ -353,6 +353,7 @@ COPY --parents \ packages/feature-flags-contract \ packages/dpns-contract \ packages/wallet-utils-contract \ + packages/token-history-contract \ packages/data-contracts \ packages/strategy-tests \ packages/simple-signer \ @@ -419,6 +420,7 @@ COPY --parents \ packages/rs-drive-abci \ packages/dashpay-contract \ packages/wallet-utils-contract \ + packages/token-history-contract \ packages/withdrawals-contract \ packages/masternode-reward-shares-contract \ packages/feature-flags-contract \ @@ -508,6 +510,7 @@ COPY --parents \ packages/dashpay-contract \ packages/withdrawals-contract \ packages/wallet-utils-contract \ + packages/token-history-contract \ packages/masternode-reward-shares-contract \ packages/feature-flags-contract \ packages/dpns-contract \ @@ -628,6 +631,7 @@ COPY --from=build-dashmate-helper /platform/packages/js-grpc-common packages/js- COPY --from=build-dashmate-helper /platform/packages/dapi-grpc packages/dapi-grpc COPY --from=build-dashmate-helper /platform/packages/dash-spv packages/dash-spv COPY --from=build-dashmate-helper /platform/packages/wallet-utils-contract packages/wallet-utils-contract +COPY --from=build-dashmate-helper /platform/packages/token-history-contract packages/token-history-contract COPY --from=build-dashmate-helper /platform/packages/withdrawals-contract packages/withdrawals-contract COPY --from=build-dashmate-helper /platform/packages/masternode-reward-shares-contract packages/masternode-reward-shares-contract COPY --from=build-dashmate-helper /platform/packages/feature-flags-contract packages/feature-flags-contract diff --git a/package.json b/package.json index 89f223fcbb5..7f1b2b397cb 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "test:dashpay-contract": "ultra -r --filter \"packages/@(dashpay-contract|js-dash-sdk|js-drive|js-dapi-client|wasm-dpp|wallet-lib|dapi|platform-test-suite)\" test", "test:dpns-contract": "ultra -r --filter \"packages/@(dpns-contract|js-dash-sdk|js-drive|js-dapi-client|wasm-dpp|wallet-lib|dapi|platform-test-suite)\" test", "test:feature-flags-contract": "ultra -r --filter \"packages/@(feature-flags-contract|js-dash-sdk|js-drive|js-dapi-client|wasm-dpp|wallet-lib|dapi|platform-test-suite)\" test", + "test:token-history-contract": "ultra -r --filter \"packages/@(token-history-contract|js-dash-sdk|js-drive|js-dapi-client|wasm-dpp|wallet-lib|dapi|platform-test-suite)\" test", "test:dapi-client": "ultra -r --filter \"packages/@(js-dapi-client|wallet-lib|js-dash-sdk|platform-test-suite)\" test", "test:sdk": "ultra -r --filter \"packages/@(js-dash-sdk|platform-test-suite)\" test", "test:spv": "ultra -r --filter \"packages/@(dash-spv|js-dapi-client)\" test", diff --git a/packages/token-history-contract/package.json b/packages/token-history-contract/package.json index 2e3d19ab9d8..def4552747f 100644 --- a/packages/token-history-contract/package.json +++ b/packages/token-history-contract/package.json @@ -1,7 +1,7 @@ { - "name": "@dashevo/wallet-utils-contract", - "version": "1.6.2", - "description": "A contract and helper scripts for Wallet DApp", + "name": "@dashevo/token-history-contract", + "version": "1.8.0-dev.2", + "description": "The token history contract", "scripts": { "lint": "eslint .", "test": "yarn run test:unit", @@ -9,9 +9,9 @@ }, "contributors": [ { - "name": "Eric Britten", - "email": "eric.britten@dash.org", - "url": "https://github.com/hashengineering" + "name": "Samuel Westrich", + "email": "sam@dash.org", + "url": "https://github.com/quantumexplorer" } ], "license": "MIT", diff --git a/packages/token-history-contract/test/unit/tokenHistoryContract.spec.js b/packages/token-history-contract/test/unit/tokenHistoryContract.spec.js new file mode 100644 index 00000000000..3900303dd1d --- /dev/null +++ b/packages/token-history-contract/test/unit/tokenHistoryContract.spec.js @@ -0,0 +1,451 @@ +const crypto = require('crypto'); +const { + DashPlatformProtocol, + JsonSchemaError, +} = require('@dashevo/wasm-dpp'); +const generateRandomIdentifier = require('@dashevo/wasm-dpp/lib/test/utils/generateRandomIdentifierAsync'); +const { expect } = require('chai'); +const tokenHistoryContractDocumentsSchema = require('../../schema/v1/token-history-contract-documents.json'); + +const expectJsonSchemaError = (validationResult, errorCount = 1) => { + const errors = validationResult.getErrors(); + expect(errors) + .to + .have + .length(errorCount); + + const error = validationResult.getErrors()[0]; + expect(error) + .to + .be + .instanceof(JsonSchemaError); + + return error; +}; + +describe('Token History Contract', () => { + let dpp; + let dataContract; + let identityId; + + beforeEach(async () => { + dpp = new DashPlatformProtocol({ generate: () => crypto.randomBytes(32) }); + identityId = await generateRandomIdentifier(); + dataContract = dpp.dataContract.create(identityId, BigInt(1), tokenHistoryContractDocumentsSchema); + }); + + it('should have a valid contract definition', async () => { + expect(() => dpp.dataContract.create(identityId, BigInt(1), tokenHistoryContractDocumentsSchema)) + .to + .not + .throw(); + }); + + describe('documents', () => { + describe('burn', () => { + let rawBurnDocument; + + beforeEach(() => { + rawBurnDocument = { + tokenId: crypto.randomBytes(32), + amount: 100, + note: 'Burning tokens', + $createdAt: Math.ceil(Date.now() / 1000), + $createdAtBlockHeight: 42, + }; + }); + + describe('tokenId', () => { + it('should be defined', async () => { + delete rawBurnDocument.tokenId; + const document = dpp.document.create(dataContract, identityId, 'burn', rawBurnDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('required'); + expect(error.params.missingProperty).to.equal('tokenId'); + }); + + it('should be 32 bytes', async () => { + rawBurnDocument.tokenId = crypto.randomBytes(31); + const document = dpp.document.create(dataContract, identityId, 'burn', rawBurnDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minItems'); + expect(error.instancePath).to.equal('/tokenId'); + }); + }); + + describe('amount', () => { + it('should be defined', async () => { + delete rawBurnDocument.amount; + const document = dpp.document.create(dataContract, identityId, 'burn', rawBurnDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('required'); + expect(error.params.missingProperty).to.equal('amount'); + }); + + it('should be a non-negative integer', async () => { + rawBurnDocument.amount = -1; + const document = dpp.document.create(dataContract, identityId, 'burn', rawBurnDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + describe('$createdAt / $createdAtBlockHeight', () => { + it('should be defined', async () => { + delete rawBurnDocument.$createdAt; + const document = dpp.document.create(dataContract, identityId, 'burn', rawBurnDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('required'); + expect(error.params.missingProperty).to.equal('$createdAt'); + }); + }); + + it('should not have additional properties', async () => { + rawBurnDocument.extraProp = 123; + const document = dpp.document.create(dataContract, identityId, 'burn', rawBurnDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('additionalProperties'); + expect(error.params.additionalProperties).to.deep.equal(['extraProp']); + }); + + it('should be valid', async () => { + const document = dpp.document.create(dataContract, identityId, 'burn', rawBurnDocument); + const validationResult = await document.validate(dpp.protocolVersion); + expect(validationResult.isValid()).to.be.true(); + }); + }); + + describe('mint', () => { + let rawMintDocument; + + beforeEach(() => { + rawMintDocument = { + tokenId: crypto.randomBytes(32), + recipientId: crypto.randomBytes(32), + amount: 1000, + note: 'Minting tokens', + $createdAt: Math.ceil(Date.now() / 1000), + $createdAtBlockHeight: 50, + }; + }); + + describe('tokenId', () => { + it('should be 32 bytes', async () => { + rawMintDocument.tokenId = crypto.randomBytes(31); + const document = dpp.document.create(dataContract, identityId, 'mint', rawMintDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minItems'); + expect(error.instancePath).to.equal('/tokenId'); + }); + }); + + describe('recipientId', () => { + it('should be defined', async () => { + delete rawMintDocument.recipientId; + const document = dpp.document.create(dataContract, identityId, 'mint', rawMintDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('required'); + expect(error.params.missingProperty).to.equal('recipientId'); + }); + + it('should be 32 bytes', async () => { + rawMintDocument.recipientId = crypto.randomBytes(31); + const document = dpp.document.create(dataContract, identityId, 'mint', rawMintDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minItems'); + expect(error.instancePath).to.equal('/recipientId'); + }); + }); + + describe('amount', () => { + it('should be a non-negative integer', async () => { + rawMintDocument.amount = -1; + const document = dpp.document.create(dataContract, identityId, 'mint', rawMintDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + it('should not have additional properties', async () => { + rawMintDocument.extraField = 'foo'; + const document = dpp.document.create(dataContract, identityId, 'mint', rawMintDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('additionalProperties'); + expect(error.params.additionalProperties).to.deep.equal(['extraField']); + }); + + it('should be valid', async () => { + const document = dpp.document.create(dataContract, identityId, 'mint', rawMintDocument); + const validationResult = await document.validate(dpp.protocolVersion); + expect(validationResult.isValid()).to.be.true(); + }); + }); + + describe('transfer', () => { + let rawTransferDocument; + + beforeEach(() => { + rawTransferDocument = { + tokenId: crypto.randomBytes(32), + amount: 10, + toIdentityId: crypto.randomBytes(32), + publicNote: 'Transfer tokens', + encryptedPersonalNote: crypto.randomBytes(32), + encryptedSharedNote: crypto.randomBytes(32), + senderKeyIndex: 0, + recipientKeyIndex: 1, + rootEncryptionKeyIndex: 2, + derivationEncryptionKeyIndex: 3, + $createdAt: Math.ceil(Date.now() / 1000), + $createdAtBlockHeight: 100, + }; + }); + + describe('tokenId', () => { + it('should be 32 bytes', async () => { + rawTransferDocument.tokenId = crypto.randomBytes(31); + const document = dpp.document.create(dataContract, identityId, 'transfer', rawTransferDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minItems'); + expect(error.instancePath).to.equal('/tokenId'); + }); + }); + + describe('amount', () => { + it('should be a non-negative integer', async () => { + rawTransferDocument.amount = -1; + const document = dpp.document.create(dataContract, identityId, 'transfer', rawTransferDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + describe('toIdentityId', () => { + it('should be defined', async () => { + delete rawTransferDocument.toIdentityId; + const document = dpp.document.create(dataContract, identityId, 'transfer', rawTransferDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('required'); + expect(error.params.missingProperty).to.equal('toIdentityId'); + }); + }); + + it('should not have additional properties', async () => { + rawTransferDocument.foo = 'bar'; + const document = dpp.document.create(dataContract, identityId, 'transfer', rawTransferDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('additionalProperties'); + expect(error.params.additionalProperties).to.deep.equal(['foo']); + }); + + it('should be valid', async () => { + const document = dpp.document.create(dataContract, identityId, 'transfer', rawTransferDocument); + const validationResult = await document.validate(dpp.protocolVersion); + expect(validationResult.isValid()).to.be.true(); + }); + }); + + describe('freeze', () => { + let rawFreezeDocument; + + beforeEach(() => { + rawFreezeDocument = { + tokenId: crypto.randomBytes(32), + frozenIdentityId: crypto.randomBytes(32), + $createdAt: Math.ceil(Date.now() / 1000), + $createdAtBlockHeight: 123, + }; + }); + + describe('tokenId', () => { + it('should be defined', async () => { + delete rawFreezeDocument.tokenId; + const document = dpp.document.create(dataContract, identityId, 'freeze', rawFreezeDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('required'); + expect(error.params.missingProperty).to.equal('tokenId'); + }); + }); + + describe('frozenIdentityId', () => { + it('should be 32 bytes', async () => { + rawFreezeDocument.frozenIdentityId = crypto.randomBytes(31); + const document = dpp.document.create(dataContract, identityId, 'freeze', rawFreezeDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minItems'); + expect(error.instancePath).to.equal('/frozenIdentityId'); + }); + }); + + it('should not have additional properties', async () => { + rawFreezeDocument.something = true; + const document = dpp.document.create(dataContract, identityId, 'freeze', rawFreezeDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('additionalProperties'); + expect(error.params.additionalProperties).to.deep.equal(['something']); + }); + + it('should be valid', async () => { + const document = dpp.document.create(dataContract, identityId, 'freeze', rawFreezeDocument); + const validationResult = await document.validate(dpp.protocolVersion); + expect(validationResult.isValid()).to.be.true(); + }); + }); + + describe('unfreeze', () => { + let rawUnfreezeDocument; + + beforeEach(() => { + rawUnfreezeDocument = { + tokenId: crypto.randomBytes(32), + frozenIdentityId: crypto.randomBytes(32), + $createdAt: Math.ceil(Date.now() / 1000), + $createdAtBlockHeight: 150, + }; + }); + + describe('tokenId', () => { + it('should be 32 bytes', async () => { + rawUnfreezeDocument.tokenId = crypto.randomBytes(33); + const document = dpp.document.create(dataContract, identityId, 'unfreeze', rawUnfreezeDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('maxItems'); + expect(error.instancePath).to.equal('/tokenId'); + }); + }); + + it('should not have additional properties', async () => { + rawUnfreezeDocument.foo = 'bar'; + const document = dpp.document.create(dataContract, identityId, 'unfreeze', rawUnfreezeDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('additionalProperties'); + expect(error.params.additionalProperties).to.deep.equal(['foo']); + }); + + it('should be valid', async () => { + const document = dpp.document.create(dataContract, identityId, 'unfreeze', rawUnfreezeDocument); + const validationResult = await document.validate(dpp.protocolVersion); + expect(validationResult.isValid()).to.be.true(); + }); + }); + + describe('destroyFrozenFunds', () => { + let rawDestroyFrozenFundsDocument; + + beforeEach(() => { + rawDestroyFrozenFundsDocument = { + tokenId: crypto.randomBytes(32), + frozenIdentityId: crypto.randomBytes(32), + amount: 500, + $createdAt: Math.ceil(Date.now() / 1000), + $createdAtBlockHeight: 222, + }; + }); + + describe('frozenIdentityId', () => { + it('should be 32 bytes', async () => { + rawDestroyFrozenFundsDocument.frozenIdentityId = crypto.randomBytes(31); + const document = dpp.document.create(dataContract, identityId, 'destroyFrozenFunds', rawDestroyFrozenFundsDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minItems'); + expect(error.instancePath).to.equal('/frozenIdentityId'); + }); + }); + + describe('amount', () => { + it('should be non-negative', async () => { + rawDestroyFrozenFundsDocument.amount = -1; + const document = dpp.document.create(dataContract, identityId, 'destroyFrozenFunds', rawDestroyFrozenFundsDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + it('should not have additional properties', async () => { + rawDestroyFrozenFundsDocument.bar = 123; + const document = dpp.document.create(dataContract, identityId, 'destroyFrozenFunds', rawDestroyFrozenFundsDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('additionalProperties'); + expect(error.params.additionalProperties).to.deep.equal(['bar']); + }); + + it('should be valid', async () => { + const document = dpp.document.create(dataContract, identityId, 'destroyFrozenFunds', rawDestroyFrozenFundsDocument); + const validationResult = await document.validate(dpp.protocolVersion); + expect(validationResult.isValid()).to.be.true(); + }); + }); + + describe('emergencyAction', () => { + let rawEmergencyActionDocument; + + beforeEach(() => { + rawEmergencyActionDocument = { + tokenId: crypto.randomBytes(32), + action: 1, + $createdAt: Math.ceil(Date.now() / 1000), + $createdAtBlockHeight: 300, + }; + }); + + describe('tokenId', () => { + it('should be defined', async () => { + delete rawEmergencyActionDocument.tokenId; + const document = dpp.document.create(dataContract, identityId, 'emergencyAction', rawEmergencyActionDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('required'); + expect(error.params.missingProperty).to.equal('tokenId'); + }); + }); + + describe('action', () => { + it('should be non-negative', async () => { + rawEmergencyActionDocument.action = -5; + const document = dpp.document.create(dataContract, identityId, 'emergencyAction', rawEmergencyActionDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('minimum'); + }); + }); + + it('should not have additional properties', async () => { + rawEmergencyActionDocument.xyz = 999; + const document = dpp.document.create(dataContract, identityId, 'emergencyAction', rawEmergencyActionDocument); + const validationResult = document.validate(dpp.protocolVersion); + const error = expectJsonSchemaError(validationResult); + expect(error.keyword).to.equal('additionalProperties'); + expect(error.params.additionalProperties).to.deep.equal(['xyz']); + }); + + it('should be valid', async () => { + const document = dpp.document.create(dataContract, identityId, 'emergencyAction', rawEmergencyActionDocument); + const validationResult = await document.validate(dpp.protocolVersion); + expect(validationResult.isValid()).to.be.true(); + }); + }); + }); +}); \ No newline at end of file diff --git a/packages/token-history-contract/test/unit/walletContract.spec.js b/packages/token-history-contract/test/unit/walletContract.spec.js deleted file mode 100644 index e13506371c0..00000000000 --- a/packages/token-history-contract/test/unit/walletContract.spec.js +++ /dev/null @@ -1,187 +0,0 @@ -const crypto = require('crypto'); - -const { - DashPlatformProtocol, - JsonSchemaError, -} = require('@dashevo/wasm-dpp'); -const generateRandomIdentifier = require('@dashevo/wasm-dpp/lib/test/utils/generateRandomIdentifierAsync'); - -const { expect } = require('chai'); -const walletContractDocumentsSchema = require('../../schema/v1/token-history-contract-documents.json'); - -const expectJsonSchemaError = (validationResult, errorCount = 1) => { - const errors = validationResult.getErrors(); - expect(errors) - .to - .have - .length(errorCount); - - const error = validationResult.getErrors()[0]; - expect(error) - .to - .be - .instanceof(JsonSchemaError); - - return error; -}; - -describe('Wallet Contract', () => { - let dpp; - let dataContract; - let identityId; - - beforeEach(async () => { - dpp = new DashPlatformProtocol( - { generate: () => crypto.randomBytes(32) }, - ); - - identityId = await generateRandomIdentifier(); - - dataContract = dpp.dataContract.create(identityId, BigInt(1), walletContractDocumentsSchema); - }); - - it('should have a valid contract definition', async () => { - expect(() => dpp.dataContract.create(identityId, BigInt(1), walletContractDocumentsSchema)) - .to - .not - .throw(); - }); - - describe('documents', () => { - describe('txMetadata', () => { - let rawTxMetadataDocument; - - beforeEach(() => { - rawTxMetadataDocument = { - keyIndex: 0, - encryptionKeyIndex: 100, - encryptedMetadata: crypto.randomBytes(64), - }; - }); - - describe('keyIndex', () => { - it('should be defined', async () => { - delete rawTxMetadataDocument.keyIndex; - - const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - const validationResult = document.validate(dpp.protocolVersion); - const error = expectJsonSchemaError(validationResult); - - expect(error.keyword) - .to - .equal('required'); - expect(error.params.missingProperty) - .to - .equal('keyIndex'); - }); - - it('should be a non-negative integer', async () => { - rawTxMetadataDocument.keyIndex = -1; - const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - const validationResult = document.validate(dpp.protocolVersion); - const error = expectJsonSchemaError(validationResult); - expect(error.keyword).to.equal('minimum'); - }); - }); - - describe('encryptionKeyIndex', () => { - it('should be defined', async () => { - delete rawTxMetadataDocument.encryptionKeyIndex; - - const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - const validationResult = document.validate(dpp.protocolVersion); - const error = expectJsonSchemaError(validationResult); - - expect(error.keyword) - .to - .equal('required'); - expect(error.params.missingProperty) - .to - .equal('encryptionKeyIndex'); - }); - - it('should be a non-negative integer', async () => { - rawTxMetadataDocument.encryptionKeyIndex = -1; - const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - const validationResult = document.validate(dpp.protocolVersion); - const error = expectJsonSchemaError(validationResult); - expect(error.keyword).to.equal('minimum'); - }); - }); - - describe('encryptedMetadata', () => { - it('should be defined', async () => { - delete rawTxMetadataDocument.encryptedMetadata; - - const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - const validationResult = document.validate(dpp.protocolVersion); - const error = expectJsonSchemaError(validationResult); - - expect(error.keyword) - .to - .equal('required'); - expect(error.params.missingProperty) - .to - .equal('encryptedMetadata'); - }); - - it('should be not shorter than 32 bytes', async () => { - rawTxMetadataDocument.encryptedMetadata = crypto.randomBytes(31); - - const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - const validationResult = document.validate(dpp.protocolVersion); - const error = expectJsonSchemaError(validationResult); - - expect(error.keyword) - .to - .equal('minItems'); - expect(error.instancePath) - .to - .equal('/encryptedMetadata'); - }); - - it('should be not longer than 4096 bytes', async () => { - rawTxMetadataDocument.encryptedMetadata = crypto.randomBytes(4097); - - const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - const validationResult = document.validate(dpp.protocolVersion); - const error = expectJsonSchemaError(validationResult); - - expect(error.keyword) - .to - .equal('maxItems'); - expect(error.instancePath) - .to - .equal('/encryptedMetadata'); - }); - }); - - it('should not have additional properties', async () => { - rawTxMetadataDocument.someOtherProperty = 42; - - const document = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - const validationResult = document.validate(dpp.protocolVersion); - const error = expectJsonSchemaError(validationResult); - - expect(error.keyword) - .to - .equal('additionalProperties'); - expect(error.params.additionalProperties) - .to - .deep - .equal(['someOtherProperty']); - }); - - it('should be valid', async () => { - const txMetadata = dpp.document.create(dataContract, identityId, 'txMetadata', rawTxMetadataDocument); - - const result = await txMetadata.validate(dpp.protocolVersion); - - expect(result.isValid()) - .to - .be - .true(); - }); - }); - }); -}); From d83ef09820a6a84a0df09146dcd8eb6144fb8519 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 14 Jan 2025 06:52:35 +0700 Subject: [PATCH 60/61] group info queries --- .../protos/platform/v0/platform.proto | 85 ++++++++++++ .../document_type/property/mod.rs | 3 +- packages/rs-dpp/src/lib.rs | 2 + .../src/query/group_queries/group_info/mod.rs | 53 ++++++++ .../query/group_queries/group_info/v0/mod.rs | 95 +++++++++++++ .../query/group_queries/group_infos/mod.rs | 53 ++++++++ .../query/group_queries/group_infos/v0/mod.rs | 127 ++++++++++++++++++ .../src/query/group_queries/mod.rs | 2 + packages/rs-drive-abci/src/query/mod.rs | 1 + packages/rs-drive-abci/src/query/service.rs | 16 ++- .../drive/group/fetch/fetch_group_info/mod.rs | 103 ++++++++++++++ .../group/fetch/fetch_group_info/v0/mod.rs | 83 ++++++++++++ .../group/fetch/fetch_group_infos/mod.rs | 99 ++++++++++++++ .../group/fetch/fetch_group_infos/v0/mod.rs | 79 +++++++++++ .../rs-drive/src/drive/group/fetch/mod.rs | 3 + .../rs-drive/src/drive/group/fetch/queries.rs | 47 +++++++ .../group/insert/add_new_groups/v0/mod.rs | 25 +++- packages/rs-drive/src/drive/group/mod.rs | 116 +++++++++++++++- .../rs-drive/src/drive/group/prove/mod.rs | 2 + .../drive/group/prove/prove_group_info/mod.rs | 99 ++++++++++++++ .../group/prove/prove_group_info/v0/mod.rs | 45 +++++++ .../group/prove/prove_group_infos/mod.rs | 99 ++++++++++++++ .../group/prove/prove_group_infos/v0/mod.rs | 50 +++++++ .../src/drive/tokens/apply_status/v0/mod.rs | 1 - .../for_token_status_infos/mod.rs | 2 - .../for_token_status_infos/v0/mod.rs | 1 - .../token_transition/mod.rs | 2 +- .../drive_abci_query_versions/mod.rs | 7 + .../drive_abci_query_versions/v1.rs | 20 ++- .../drive_group_method_versions/mod.rs | 7 +- .../drive_group_method_versions/v1.rs | 7 +- .../src/version/mocks/v2_test.rs | 20 ++- 32 files changed, 1326 insertions(+), 28 deletions(-) create mode 100644 packages/rs-drive-abci/src/query/group_queries/group_info/mod.rs create mode 100644 packages/rs-drive-abci/src/query/group_queries/group_info/v0/mod.rs create mode 100644 packages/rs-drive-abci/src/query/group_queries/group_infos/mod.rs create mode 100644 packages/rs-drive-abci/src/query/group_queries/group_infos/v0/mod.rs create mode 100644 packages/rs-drive-abci/src/query/group_queries/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_group_info/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_group_info/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_group_infos/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/fetch_group_infos/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/group/fetch/queries.rs create mode 100644 packages/rs-drive/src/drive/group/prove/mod.rs create mode 100644 packages/rs-drive/src/drive/group/prove/prove_group_info/mod.rs create mode 100644 packages/rs-drive/src/drive/group/prove/prove_group_info/v0/mod.rs create mode 100644 packages/rs-drive/src/drive/group/prove/prove_group_infos/mod.rs create mode 100644 packages/rs-drive/src/drive/group/prove/prove_group_infos/v0/mod.rs diff --git a/packages/dapi-grpc/protos/platform/v0/platform.proto b/packages/dapi-grpc/protos/platform/v0/platform.proto index 945bd3c2b18..71f65837bc2 100644 --- a/packages/dapi-grpc/protos/platform/v0/platform.proto +++ b/packages/dapi-grpc/protos/platform/v0/platform.proto @@ -60,7 +60,9 @@ service Platform { rpc getIdentityTokenInfos(GetIdentityTokenInfosRequest) returns (GetIdentityTokenInfosResponse); rpc getIdentitiesTokenInfos(GetIdentitiesTokenInfosRequest) returns (GetIdentitiesTokenInfosResponse); rpc getTokenStatuses(GetTokenStatusesRequest) returns (GetTokenStatusesResponse); + rpc getGroupInfo(GetGroupInfoRequest) returns (GetGroupInfoResponse); rpc getActiveGroupActions(GetActiveGroupActionsRequest) returns (GetActiveGroupActionsResponse); +// rpc getClosedGroupActions(GetClosedGroupActionsRequest) returns (GetClosedGroupActionsResponse); } // Proof message includes cryptographic proofs for validating responses @@ -1396,6 +1398,89 @@ message GetTokenStatusesResponse { } } +message GetGroupInfoRequest { + message GetGroupInfoRequestV0 { + bytes contract_id = 1; + uint32 group_contract_position = 2; + bool prove = 3; + } + oneof version { + GetGroupInfoRequestV0 v0 = 1; + } +} + +message GetGroupInfoResponse { + message GetGroupInfoResponseV0 { + message GroupMemberEntry { + bytes member_id = 1; + uint32 power = 2; + } + + message GroupInfoEntry { + repeated GroupMemberEntry members = 1; + uint32 group_required_power = 2; + } + + message GroupInfo { + optional GroupInfoEntry group_info = 1; + } + + oneof result { + GroupInfo group_info = 1; + Proof proof = 2; + } + ResponseMetadata metadata = 4; + } + oneof version { + GetGroupInfoResponseV0 v0 = 1; + } +} + +message GetGroupInfosRequest { + message StartAtGroupContractPosition { + uint32 start_group_contract_position = 1; + bool start_group_contract_position_included = 2; + } + + message GetGroupInfosRequestV0 { + bytes contract_id = 1; + optional StartAtGroupContractPosition start_at_group_contract_position = 2; + optional uint32 count = 3; + bool prove = 4; + } + oneof version { + GetGroupInfosRequestV0 v0 = 1; + } +} + +message GetGroupInfosResponse { + message GetGroupInfosResponseV0 { + message GroupMemberEntry { + bytes member_id = 1; + uint32 power = 2; + } + + message GroupPositionInfoEntry { + uint32 group_contract_position = 1; + repeated GroupMemberEntry members = 2; + uint32 group_required_power = 3; + } + + message GroupInfos { + repeated GroupPositionInfoEntry group_infos = 1; + } + + oneof result { + GroupInfos group_infos = 1; + Proof proof = 2; + } + ResponseMetadata metadata = 4; + } + oneof version { + GetGroupInfosResponseV0 v0 = 1; + } +} + message GetActiveGroupActionsRequest { message GetActiveGroupActionsRequestV0 { bytes contract_id = 1; diff --git a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs index 927fb561a1a..e95fa7560aa 100644 --- a/packages/rs-dpp/src/data_contract/document_type/property/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/property/mod.rs @@ -1730,6 +1730,7 @@ impl DocumentPropertyType { } pub fn encode_u16(val: u16) -> Vec { + //todo this should just be to_be_bytes (and for all unsigned integers) // Positive integers are represented in binary with the signed bit set to 0 // Negative integers are represented in 2's complement form @@ -1754,7 +1755,7 @@ impl DocumentPropertyType { wtr } - /// Decodes an unsigned integer on 32 bits. + /// Decodes an unsigned integer on 16 bits. pub fn decode_u16(val: &[u8]) -> Option { // Flip the sign bit // to deal with interaction between the domains diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index e4cc1bd7f2b..af7195d65cf 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -85,6 +85,8 @@ pub mod prelude { pub type CoreBlockHeight = u32; pub type TimestampMillis = u64; + pub type StartAtIncluded = bool; + pub type TimestampIncluded = bool; pub type Revision = u64; pub type IdentityNonce = u64; diff --git a/packages/rs-drive-abci/src/query/group_queries/group_info/mod.rs b/packages/rs-drive-abci/src/query/group_queries/group_info/mod.rs new file mode 100644 index 00000000000..00dcdac6c42 --- /dev/null +++ b/packages/rs-drive-abci/src/query/group_queries/group_info/mod.rs @@ -0,0 +1,53 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_group_info_request::Version as RequestVersion; +use dapi_grpc::platform::v0::get_group_info_response::Version as ResponseVersion; +use dapi_grpc::platform::v0::{GetGroupInfoRequest, GetGroupInfoResponse}; +use dpp::version::PlatformVersion; +mod v0; + +impl Platform { + /// Querying of group info + pub fn query_group_info( + &self, + GetGroupInfoRequest { version }: GetGroupInfoRequest, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let Some(version) = version else { + return Ok(QueryValidationResult::new_with_error( + QueryError::DecodingError("could not decode group info query".to_string()), + )); + }; + + let feature_version_bounds = &platform_version.drive_abci.query.group_queries.group_info; + + let feature_version = match &version { + RequestVersion::V0(_) => 0, + }; + if !feature_version_bounds.check_version(feature_version) { + return Ok(QueryValidationResult::new_with_error( + QueryError::UnsupportedQueryVersion( + "group_info".to_string(), + feature_version_bounds.min_version, + feature_version_bounds.max_version, + platform_version.protocol_version, + feature_version, + ), + )); + } + + match version { + RequestVersion::V0(request_v0) => { + let result = + self.query_group_info_v0(request_v0, platform_state, platform_version)?; + Ok(result.map(|response_v0| GetGroupInfoResponse { + version: Some(ResponseVersion::V0(response_v0)), + })) + } + } + } +} diff --git a/packages/rs-drive-abci/src/query/group_queries/group_info/v0/mod.rs b/packages/rs-drive-abci/src/query/group_queries/group_info/v0/mod.rs new file mode 100644 index 00000000000..a5175ac3cff --- /dev/null +++ b/packages/rs-drive-abci/src/query/group_queries/group_info/v0/mod.rs @@ -0,0 +1,95 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_group_info_request::GetGroupInfoRequestV0; +use dapi_grpc::platform::v0::get_group_info_response::get_group_info_response_v0::{ + GroupInfo, GroupInfoEntry, GroupMemberEntry, +}; +use dapi_grpc::platform::v0::get_group_info_response::{ + get_group_info_response_v0, GetGroupInfoResponseV0, +}; +use dpp::check_validation_result_with_data; +use dpp::data_contract::group::accessors::v0::GroupV0Getters; +use dpp::identifier::Identifier; +use dpp::validation::ValidationResult; +use dpp::version::PlatformVersion; +use drive::error::query::QuerySyntaxError; + +impl Platform { + pub(super) fn query_group_info_v0( + &self, + GetGroupInfoRequestV0 { + contract_id, + group_contract_position, + prove, + }: GetGroupInfoRequestV0, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let contract_id: Identifier = + check_validation_result_with_data!(contract_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "token_id must be a valid identifier (32 bytes long)".to_string(), + ) + })); + + if group_contract_position > u16::MAX as u32 { + return Ok(QueryValidationResult::new_with_error(QueryError::Query( + QuerySyntaxError::InvalidParameter(format!( + "group contract position {} can not be over u16::MAX", + group_contract_position + )), + ))); + } + + let response = if prove { + let proof = check_validation_result_with_data!(self.drive.prove_group_info( + contract_id, + group_contract_position as u16, + None, + platform_version, + )); + + GetGroupInfoResponseV0 { + result: Some(get_group_info_response_v0::Result::Proof( + self.response_proof_v0(platform_state, proof), + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + } else { + let group_info = self + .drive + .fetch_group_info( + contract_id, + group_contract_position as u16, + None, + platform_version, + )? + .map(|group| { + let members = group + .members() + .into_iter() + .map(|(member_id, power)| GroupMemberEntry { + member_id: member_id.to_vec(), + power: *power, + }) + .collect(); + GroupInfoEntry { + members, + group_required_power: group.required_power(), + } + }); + + GetGroupInfoResponseV0 { + result: Some(get_group_info_response_v0::Result::GroupInfo(GroupInfo { + group_info, + })), + metadata: Some(self.response_metadata_v0(platform_state)), + } + }; + + Ok(QueryValidationResult::new_with_data(response)) + } +} diff --git a/packages/rs-drive-abci/src/query/group_queries/group_infos/mod.rs b/packages/rs-drive-abci/src/query/group_queries/group_infos/mod.rs new file mode 100644 index 00000000000..c21304bb75f --- /dev/null +++ b/packages/rs-drive-abci/src/query/group_queries/group_infos/mod.rs @@ -0,0 +1,53 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_group_infos_request::Version as RequestVersion; +use dapi_grpc::platform::v0::get_group_infos_response::Version as ResponseVersion; +use dapi_grpc::platform::v0::{GetGroupInfosRequest, GetGroupInfosResponse}; +use dpp::version::PlatformVersion; +mod v0; + +impl Platform { + /// Querying of group infos + pub fn query_group_infos( + &self, + GetGroupInfosRequest { version }: GetGroupInfosRequest, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let Some(version) = version else { + return Ok(QueryValidationResult::new_with_error( + QueryError::DecodingError("could not decode group infos query".to_string()), + )); + }; + + let feature_version_bounds = &platform_version.drive_abci.query.group_queries.group_infos; + + let feature_version = match &version { + RequestVersion::V0(_) => 0, + }; + if !feature_version_bounds.check_version(feature_version) { + return Ok(QueryValidationResult::new_with_error( + QueryError::UnsupportedQueryVersion( + "group_infos".to_string(), + feature_version_bounds.min_version, + feature_version_bounds.max_version, + platform_version.protocol_version, + feature_version, + ), + )); + } + + match version { + RequestVersion::V0(request_v0) => { + let result = + self.query_group_infos_v0(request_v0, platform_state, platform_version)?; + Ok(result.map(|response_v0| GetGroupInfosResponse { + version: Some(ResponseVersion::V0(response_v0)), + })) + } + } + } +} diff --git a/packages/rs-drive-abci/src/query/group_queries/group_infos/v0/mod.rs b/packages/rs-drive-abci/src/query/group_queries/group_infos/v0/mod.rs new file mode 100644 index 00000000000..88787fef920 --- /dev/null +++ b/packages/rs-drive-abci/src/query/group_queries/group_infos/v0/mod.rs @@ -0,0 +1,127 @@ +use crate::error::query::QueryError; +use crate::error::Error; +use crate::platform_types::platform::Platform; +use crate::platform_types::platform_state::PlatformState; +use crate::query::QueryValidationResult; +use dapi_grpc::platform::v0::get_group_infos_request::GetGroupInfosRequestV0; +use dapi_grpc::platform::v0::get_group_infos_response::get_group_infos_response_v0::{ + GroupInfos, GroupMemberEntry, GroupPositionInfoEntry, +}; +use dapi_grpc::platform::v0::get_group_infos_response::{ + get_group_infos_response_v0, GetGroupInfosResponseV0, +}; +use dpp::check_validation_result_with_data; +use dpp::data_contract::group::accessors::v0::GroupV0Getters; +use dpp::identifier::Identifier; +use dpp::validation::ValidationResult; +use dpp::version::PlatformVersion; +use drive::error::query::QuerySyntaxError; + +impl Platform { + pub(super) fn query_group_infos_v0( + &self, + GetGroupInfosRequestV0 { + contract_id, + start_at_group_contract_position, + count, + prove, + }: GetGroupInfosRequestV0, + platform_state: &PlatformState, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let config = &self.config.drive; + let contract_id: Identifier = + check_validation_result_with_data!(contract_id.try_into().map_err(|_| { + QueryError::InvalidArgument( + "token_id must be a valid identifier (32 bytes long)".to_string(), + ) + })); + + let limit = count + .map_or(Some(config.default_query_limit), |limit_value| { + if limit_value == 0 + || limit_value > u16::MAX as u32 + || limit_value as u16 > config.default_query_limit + { + None + } else { + Some(limit_value as u16) + } + }) + .ok_or(drive::error::Error::Query(QuerySyntaxError::InvalidLimit( + format!("limit greater than max limit {}", config.max_query_limit), + )))?; + + let start_at_group_contract_position = match start_at_group_contract_position { + None => None, + Some(start_at_group_contract_position) => { + if start_at_group_contract_position.start_group_contract_position > u16::MAX as u32 + { + return Ok(QueryValidationResult::new_with_error(QueryError::Query( + QuerySyntaxError::InvalidParameter(format!( + "start group contract position {} can not be over u16::MAX", + start_at_group_contract_position.start_group_contract_position + )), + ))); + } + Some(( + start_at_group_contract_position.start_group_contract_position as u16, + start_at_group_contract_position.start_group_contract_position_included, + )) + } + }; + + let response = if prove { + let proof = check_validation_result_with_data!(self.drive.prove_group_infos( + contract_id, + start_at_group_contract_position, + Some(limit), + None, + platform_version, + )); + + GetGroupInfosResponseV0 { + result: Some(get_group_infos_response_v0::Result::Proof( + self.response_proof_v0(platform_state, proof), + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + } else { + let group_infos = self + .drive + .fetch_group_infos( + contract_id, + start_at_group_contract_position, + Some(limit), + None, + platform_version, + )? + .into_iter() + .map(|(group_contract_position, group)| { + let members = group + .members() + .into_iter() + .map(|(member_id, power)| GroupMemberEntry { + member_id: member_id.to_vec(), + power: *power, + }) + .collect(); + GroupPositionInfoEntry { + group_contract_position: group_contract_position as u32, + members, + group_required_power: group.required_power(), + } + }) + .collect(); + + GetGroupInfosResponseV0 { + result: Some(get_group_infos_response_v0::Result::GroupInfos( + GroupInfos { group_infos }, + )), + metadata: Some(self.response_metadata_v0(platform_state)), + } + }; + + Ok(QueryValidationResult::new_with_data(response)) + } +} diff --git a/packages/rs-drive-abci/src/query/group_queries/mod.rs b/packages/rs-drive-abci/src/query/group_queries/mod.rs new file mode 100644 index 00000000000..b9ae74339a8 --- /dev/null +++ b/packages/rs-drive-abci/src/query/group_queries/mod.rs @@ -0,0 +1,2 @@ +mod group_info; +mod group_infos; diff --git a/packages/rs-drive-abci/src/query/mod.rs b/packages/rs-drive-abci/src/query/mod.rs index 98bad2d269c..0e161b1ae19 100644 --- a/packages/rs-drive-abci/src/query/mod.rs +++ b/packages/rs-drive-abci/src/query/mod.rs @@ -1,5 +1,6 @@ mod data_contract_based_queries; mod document_query; +mod group_queries; mod identity_based_queries; mod prefunded_specialized_balances; mod proofs; diff --git a/packages/rs-drive-abci/src/query/service.rs b/packages/rs-drive-abci/src/query/service.rs index 224276e82a7..f0a8f8784e5 100644 --- a/packages/rs-drive-abci/src/query/service.rs +++ b/packages/rs-drive-abci/src/query/service.rs @@ -21,8 +21,8 @@ use dapi_grpc::platform::v0::{ GetDataContractResponse, GetDataContractsRequest, GetDataContractsResponse, GetDocumentsRequest, GetDocumentsResponse, GetEpochsInfoRequest, GetEpochsInfoResponse, GetEvonodesProposedEpochBlocksByIdsRequest, GetEvonodesProposedEpochBlocksByRangeRequest, - GetEvonodesProposedEpochBlocksResponse, GetIdentitiesBalancesRequest, - GetIdentitiesBalancesResponse, GetIdentitiesContractKeysRequest, + GetEvonodesProposedEpochBlocksResponse, GetGroupInfoRequest, GetGroupInfoResponse, + GetIdentitiesBalancesRequest, GetIdentitiesBalancesResponse, GetIdentitiesContractKeysRequest, GetIdentitiesContractKeysResponse, GetIdentitiesTokenBalancesRequest, GetIdentitiesTokenBalancesResponse, GetIdentitiesTokenInfosRequest, GetIdentitiesTokenInfosResponse, GetIdentityBalanceAndRevisionRequest, @@ -675,6 +675,18 @@ impl PlatformService for QueryService { .await } + async fn get_group_info( + &self, + request: Request, + ) -> Result, Status> { + self.handle_blocking_query( + request, + Platform::::query_group_info, + "get_group_info", + ) + .await + } + async fn get_active_group_actions( &self, request: Request, diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_group_info/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_group_info/mod.rs new file mode 100644 index 00000000000..b67a145b526 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_group_info/mod.rs @@ -0,0 +1,103 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::group::Group; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::HashMap; + +mod v0; + +impl Drive { + /// Fetches the `Group` for the given contract and group contract position. + /// + /// This function queries the GroveDB to fetch the `Group` associated with a specific contract + /// and group contract position. The method selects the appropriate version of + /// `fetch_group_info` based on the `platform_version` provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `transaction`: The transaction argument used for the query. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Group)`: The `Group` for the specified action ID and contract position. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub fn fetch_group_info( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.fetch.fetch_group_info { + 0 => self.fetch_group_info_v0( + contract_id, + group_contract_position, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_group_info".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the `Group` and adds corresponding operations to the drive for the given action ID and group contract position. + /// + /// This function is similar to `fetch_group_info` but also adds operations to the drive for state changes or queries. + /// Additionally, it supports cost estimation by interacting with the layer information if provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to an optional `HashMap` containing + /// layer information used for cost estimation. + /// - `transaction`: The transaction argument used for the query. + /// - `drive_operations`: A mutable reference to a vector that stores low-level drive operations. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Group)`: The `Group` for the specified contract ID and contract position, along with any added operations. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub(crate) fn fetch_group_info_and_add_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.fetch.fetch_group_info { + 0 => self.fetch_group_info_and_add_operations_v0( + contract_id, + group_contract_position, + estimated_costs_only_with_layer_info, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_group_info_and_add_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_group_info/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_group_info/v0/mod.rs new file mode 100644 index 00000000000..6c608e6bf8a --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_group_info/v0/mod.rs @@ -0,0 +1,83 @@ +use std::collections::HashMap; + +use crate::drive::group::{group_path, GROUP_INFO_KEY}; +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use crate::util::grove_operations::DirectQueryType; +use crate::util::grove_operations::QueryTarget::QueryTargetValue; +use dpp::data_contract::group::Group; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::serialization::PlatformDeserializable; +use dpp::version::PlatformVersion; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg, TreeType}; + +impl Drive { + pub(super) fn fetch_group_info_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_path(contract_id.as_ref(), &group_contract_position_bytes); + + let maybe_group = self + .grove_get_raw_optional_item( + (&path).into(), + GROUP_INFO_KEY, + DirectQueryType::StatefulDirectQuery, + transaction, + &mut vec![], + &platform_version.drive, + )? + .map(|value| Group::deserialize_from_bytes(&value)) + .transpose()?; + + Ok(maybe_group) + } + + pub(super) fn fetch_group_info_and_add_operations_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + estimated_costs_only_with_layer_info: &mut Option< + HashMap, + >, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let group_contract_position_bytes = group_contract_position.to_be_bytes().to_vec(); + // Construct the GroveDB path for the action signers + let path = group_path(contract_id.as_ref(), &group_contract_position_bytes); + + // no estimated_costs_only_with_layer_info, means we want to apply to state + let direct_query_type = if estimated_costs_only_with_layer_info.is_none() { + DirectQueryType::StatefulDirectQuery + } else { + DirectQueryType::StatelessDirectQuery { + in_tree_type: TreeType::NormalTree, + query_target: QueryTargetValue(8), + } + }; + + let maybe_group = self + .grove_get_raw_optional_item( + (&path).into(), + GROUP_INFO_KEY, + direct_query_type, + transaction, + drive_operations, + &platform_version.drive, + )? + .map(|value| Group::deserialize_from_bytes(&value)) + .transpose()?; + + Ok(maybe_group) + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_group_infos/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_group_infos/mod.rs new file mode 100644 index 00000000000..b05c9a24a3d --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_group_infos/mod.rs @@ -0,0 +1,99 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::group::Group; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::prelude::StartAtIncluded; +use grovedb::TransactionArg; +use platform_version::version::PlatformVersion; +use std::collections::BTreeMap; + +mod v0; +impl Drive { + /// Fetches the `Group` for the given contract. + /// + /// This function queries the GroveDB to fetch the potentially many `Group`s associated with a + /// specific contract. The method selects the appropriate version of + /// `fetch_group_infos` based on the `platform_version` provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `transaction`: The transaction argument used for the query. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Group)`: The `Group` for the specified action ID and contract position. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub fn fetch_group_infos( + &self, + contract_id: Identifier, + start_group_contract_position: Option<(GroupContractPosition, StartAtIncluded)>, + limit: Option, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.fetch.fetch_group_infos { + 0 => self.fetch_group_infos_v0( + contract_id, + start_group_contract_position, + limit, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_group_infos".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Fetches the `Group` and adds corresponding operations to the drive for the given action ID and group contract position. + /// + /// This function is similar to `fetch_group_info` but also adds operations to the drive for state changes or queries. + /// Additionally, it supports cost estimation by interacting with the layer information if provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `transaction`: The transaction argument used for the query. + /// - `drive_operations`: A mutable reference to a vector that stores low-level drive operations. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Group)`: The `Group` for the specified contract ID and contract position, along with any added operations. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub(crate) fn fetch_group_infos_operations( + &self, + contract_id: Identifier, + start_group_contract_position: Option<(GroupContractPosition, StartAtIncluded)>, + limit: Option, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.fetch.fetch_group_infos { + 0 => self.fetch_group_infos_operations_v0( + contract_id, + start_group_contract_position, + limit, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "fetch_group_infos_and_add_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/fetch_group_infos/v0/mod.rs b/packages/rs-drive/src/drive/group/fetch/fetch_group_infos/v0/mod.rs new file mode 100644 index 00000000000..f4b42fded44 --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/fetch_group_infos/v0/mod.rs @@ -0,0 +1,79 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::group::Group; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::prelude::StartAtIncluded; +use dpp::serialization::PlatformDeserializable; +use dpp::version::PlatformVersion; +use grovedb::query_result_type::QueryResultType; +use grovedb::Element::Item; +use grovedb::TransactionArg; +use std::collections::BTreeMap; + +impl Drive { + pub(super) fn fetch_group_infos_v0( + &self, + contract_id: Identifier, + start_group_contract_position: Option<(GroupContractPosition, StartAtIncluded)>, + limit: Option, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.fetch_group_infos_operations_v0( + contract_id, + start_group_contract_position, + limit, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn fetch_group_infos_operations_v0( + &self, + contract_id: Identifier, + start_group_contract_position: Option<(GroupContractPosition, StartAtIncluded)>, + limit: Option, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let path_query = Self::group_infos_for_contract_id_query( + contract_id.to_buffer(), + start_group_contract_position, + limit, + ); + + self.grove_get_raw_path_query( + &path_query, + transaction, + QueryResultType::QueryKeyElementPairResultType, + drive_operations, + &platform_version.drive, + )? + .0 + .to_key_elements_btree_map() + .into_iter() + .map(|(key, element)| { + let group_contract_position: GroupContractPosition = + GroupContractPosition::from_be_bytes(key.try_into().map_err(|_| { + Error::Drive(DriveError::CorruptedDriveState( + "group contract position not encoded on 2 bytes as expected".to_string(), + )) + })?); + match element { + Item(value, ..) => Ok(( + group_contract_position, + Group::deserialize_from_bytes(&value)?, + )), + _ => Err(Error::Drive(DriveError::CorruptedDriveState( + "token tree for infos should contain only items".to_string(), + ))), + } + }) + .collect() + } +} diff --git a/packages/rs-drive/src/drive/group/fetch/mod.rs b/packages/rs-drive/src/drive/group/fetch/mod.rs index 11fa39cbcef..8df377a7a90 100644 --- a/packages/rs-drive/src/drive/group/fetch/mod.rs +++ b/packages/rs-drive/src/drive/group/fetch/mod.rs @@ -2,3 +2,6 @@ mod fetch_action_id_has_signer; mod fetch_action_id_info; mod fetch_action_id_info_keep_serialized; mod fetch_action_id_signers_power; +mod fetch_group_info; +mod fetch_group_infos; +mod queries; diff --git a/packages/rs-drive/src/drive/group/fetch/queries.rs b/packages/rs-drive/src/drive/group/fetch/queries.rs new file mode 100644 index 00000000000..9cd51101d7c --- /dev/null +++ b/packages/rs-drive/src/drive/group/fetch/queries.rs @@ -0,0 +1,47 @@ +use crate::drive::group::group_contract_path_vec; +use crate::drive::Drive; +use crate::query::{Query, QueryItem}; +use dpp::data_contract::GroupContractPosition; +use grovedb::{PathQuery, SizedQuery}; +use std::ops::RangeFull; + +impl Drive { + /// The query for a single group info inside a contract. + pub fn group_info_for_contract_id_and_group_contract_position_query( + contract_id: [u8; 32], + group_contract_position: GroupContractPosition, + ) -> PathQuery { + let group_contract_path = group_contract_path_vec(&contract_id); + PathQuery::new_single_key( + group_contract_path, + group_contract_position.to_be_bytes().to_vec(), + ) + } + + /// The query for the group infos inside a contract. + pub fn group_infos_for_contract_id_query( + contract_id: [u8; 32], + start_at: Option<(GroupContractPosition, bool)>, + limit: Option, + ) -> PathQuery { + let group_contract_path = group_contract_path_vec(&contract_id); + let mut query = Query::new_with_direction(true); + if let Some((start_at, start_at_included)) = start_at { + if start_at_included { + query.insert_item(QueryItem::RangeFrom(start_at.to_be_bytes().to_vec()..)) + } else { + query.insert_item(QueryItem::RangeAfter(start_at.to_be_bytes().to_vec()..)) + } + } else { + query.insert_item(QueryItem::RangeFull(RangeFull)) + } + PathQuery { + path: group_contract_path, + query: SizedQuery { + query, + limit, + offset: None, + }, + } + } +} diff --git a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs index 2064aecb6d9..fca42c743dd 100644 --- a/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs +++ b/packages/rs-drive/src/drive/group/insert/add_new_groups/v0/mod.rs @@ -1,5 +1,6 @@ use crate::drive::group::{ - group_contract_path, group_path, group_root_path, GROUP_ACTIONS_KEY, GROUP_INFO_KEY, + group_contract_path, group_path, group_root_path, GROUP_ACTIVE_ACTIONS_KEY, + GROUP_CLOSED_ACTIONS_KEY, GROUP_INFO_KEY, }; use crate::drive::Drive; use crate::error::Error; @@ -134,6 +135,15 @@ impl Drive { let serialized_group_info = group.serialize_to_bytes()?; let info_item = Element::Item(serialized_group_info, None); + + self.batch_insert_empty_tree( + group_path, + DriveKeyInfo::KeyRef(GROUP_ACTIVE_ACTIONS_KEY), + None, + &mut batch_operations, + &platform_version.drive, + )?; + self.batch_insert( PathKeyElementInfo::PathFixedSizeKeyRefElement::<3>(( group_path, @@ -146,7 +156,7 @@ impl Drive { self.batch_insert_empty_tree( group_path, - DriveKeyInfo::KeyRef(GROUP_ACTIONS_KEY), + DriveKeyInfo::KeyRef(GROUP_CLOSED_ACTIONS_KEY), None, &mut batch_operations, &platform_version.drive, @@ -172,6 +182,15 @@ impl Drive { let serialized_group_info = group.serialize_to_bytes()?; let info_item = Element::Item(serialized_group_info, None); + + self.batch_insert_empty_tree( + group_path, + DriveKeyInfo::KeyRef(GROUP_ACTIVE_ACTIONS_KEY), + None, + &mut batch_operations, + &platform_version.drive, + )?; + self.batch_insert( PathKeyElementInfo::PathFixedSizeKeyRefElement::<3>(( group_path, @@ -184,7 +203,7 @@ impl Drive { self.batch_insert_empty_tree( group_path, - DriveKeyInfo::KeyRef(GROUP_ACTIONS_KEY), + DriveKeyInfo::KeyRef(GROUP_CLOSED_ACTIONS_KEY), None, &mut batch_operations, &platform_version.drive, diff --git a/packages/rs-drive/src/drive/group/mod.rs b/packages/rs-drive/src/drive/group/mod.rs index b6f530ccd81..ca5162dbbd5 100644 --- a/packages/rs-drive/src/drive/group/mod.rs +++ b/packages/rs-drive/src/drive/group/mod.rs @@ -4,12 +4,20 @@ use dpp::data_contract::GroupContractPosition; mod estimated_costs; mod fetch; mod insert; +mod prove; +// We should have +// GROUP_ACTIVE_ACTIONS_TREE +// / \ +// GROUP_INFO GROUP_CLOSED_ACTIONS_TREE /// The key used to identify the group information in storage. pub const GROUP_INFO_KEY: &[u8; 1] = b"I"; /// The key used to identify the group actions in storage. -pub const GROUP_ACTIONS_KEY: &[u8; 1] = b"M"; +pub const GROUP_ACTIVE_ACTIONS_KEY: &[u8; 1] = b"M"; + +/// The key used to identify the group actions in storage. +pub const GROUP_CLOSED_ACTIONS_KEY: &[u8; 1] = b"X"; /// The key used to identify the action information in storage. pub const ACTION_INFO_KEY: &[u8; 1] = b"I"; @@ -77,7 +85,7 @@ pub fn group_action_root_path<'a>( Into::<&[u8; 1]>::into(RootTree::GroupActions), contract_id, group_contract_position_bytes, - GROUP_ACTIONS_KEY, + GROUP_ACTIVE_ACTIONS_KEY, ] } @@ -91,7 +99,7 @@ pub fn group_action_root_path_vec( vec![RootTree::GroupActions as u8], contract_id.to_vec(), group_contract_position.to_be_bytes().to_vec(), - GROUP_ACTIONS_KEY.to_vec(), + GROUP_ACTIVE_ACTIONS_KEY.to_vec(), ] } @@ -106,7 +114,7 @@ pub fn group_action_path<'a>( Into::<&[u8; 1]>::into(RootTree::GroupActions), contract_id, group_contract_position_bytes, - GROUP_ACTIONS_KEY, + GROUP_ACTIVE_ACTIONS_KEY, action_id, ] } @@ -122,7 +130,7 @@ pub fn group_action_path_vec( vec![RootTree::GroupActions as u8], contract_id.to_vec(), group_contract_position.to_be_bytes().to_vec(), - GROUP_ACTIONS_KEY.to_vec(), + GROUP_ACTIVE_ACTIONS_KEY.to_vec(), action_id.to_vec(), ] } @@ -138,7 +146,7 @@ pub fn group_action_signers_path<'a>( Into::<&[u8; 1]>::into(RootTree::GroupActions), contract_id, group_contract_position_bytes, - GROUP_ACTIONS_KEY, + GROUP_ACTIVE_ACTIONS_KEY, action_id, ACTION_SIGNERS_KEY, ] @@ -155,7 +163,101 @@ pub fn group_action_signers_path_vec( vec![RootTree::GroupActions as u8], contract_id.to_vec(), group_contract_position.to_be_bytes().to_vec(), - GROUP_ACTIONS_KEY.to_vec(), + GROUP_ACTIVE_ACTIONS_KEY.to_vec(), + action_id.to_vec(), + ACTION_SIGNERS_KEY.to_vec(), + ] +} + +/// Group action path +#[cfg(any(feature = "server", feature = "verify"))] +pub fn group_closed_action_root_path<'a>( + contract_id: &'a [u8], + group_contract_position_bytes: &'a [u8], +) -> [&'a [u8]; 4] { + [ + Into::<&[u8; 1]>::into(RootTree::GroupActions), + contract_id, + group_contract_position_bytes, + GROUP_CLOSED_ACTIONS_KEY, + ] +} + +/// Group action path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub fn group_closed_action_root_path_vec( + contract_id: &[u8], + group_contract_position: GroupContractPosition, +) -> Vec> { + vec![ + vec![RootTree::GroupActions as u8], + contract_id.to_vec(), + group_contract_position.to_be_bytes().to_vec(), + GROUP_CLOSED_ACTIONS_KEY.to_vec(), + ] +} + +/// Group path +#[cfg(any(feature = "server", feature = "verify"))] +pub fn group_closed_action_path<'a>( + contract_id: &'a [u8], + group_contract_position_bytes: &'a [u8], + action_id: &'a [u8], +) -> [&'a [u8]; 5] { + [ + Into::<&[u8; 1]>::into(RootTree::GroupActions), + contract_id, + group_contract_position_bytes, + GROUP_CLOSED_ACTIONS_KEY, + action_id, + ] +} + +/// Group path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub fn group_closed_action_path_vec( + contract_id: &[u8], + group_contract_position: GroupContractPosition, + action_id: &[u8], +) -> Vec> { + vec![ + vec![RootTree::GroupActions as u8], + contract_id.to_vec(), + group_contract_position.to_be_bytes().to_vec(), + GROUP_CLOSED_ACTIONS_KEY.to_vec(), + action_id.to_vec(), + ] +} + +/// Group path +#[cfg(any(feature = "server", feature = "verify"))] +pub fn group_closed_action_signers_path<'a>( + contract_id: &'a [u8], + group_contract_position_bytes: &'a [u8], + action_id: &'a [u8], +) -> [&'a [u8]; 6] { + [ + Into::<&[u8; 1]>::into(RootTree::GroupActions), + contract_id, + group_contract_position_bytes, + GROUP_CLOSED_ACTIONS_KEY, + action_id, + ACTION_SIGNERS_KEY, + ] +} + +/// Group path vector +#[cfg(any(feature = "server", feature = "verify"))] +pub fn group_closed_action_signers_path_vec( + contract_id: &[u8], + group_contract_position: GroupContractPosition, + action_id: &[u8], +) -> Vec> { + vec![ + vec![RootTree::GroupActions as u8], + contract_id.to_vec(), + group_contract_position.to_be_bytes().to_vec(), + GROUP_CLOSED_ACTIONS_KEY.to_vec(), action_id.to_vec(), ACTION_SIGNERS_KEY.to_vec(), ] diff --git a/packages/rs-drive/src/drive/group/prove/mod.rs b/packages/rs-drive/src/drive/group/prove/mod.rs new file mode 100644 index 00000000000..c6fa82c789e --- /dev/null +++ b/packages/rs-drive/src/drive/group/prove/mod.rs @@ -0,0 +1,2 @@ +mod prove_group_info; +mod prove_group_infos; diff --git a/packages/rs-drive/src/drive/group/prove/prove_group_info/mod.rs b/packages/rs-drive/src/drive/group/prove/prove_group_info/mod.rs new file mode 100644 index 00000000000..5fd307c25ee --- /dev/null +++ b/packages/rs-drive/src/drive/group/prove/prove_group_info/mod.rs @@ -0,0 +1,99 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::group::Group; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use grovedb::batch::KeyInfoPath; +use grovedb::{EstimatedLayerInformation, TransactionArg}; +use platform_version::version::PlatformVersion; +use std::collections::HashMap; + +mod v0; + +impl Drive { + /// Proves the `Group` for the given contract and group contract position. + /// + /// This function queries the GroveDB to prove the `Group` associated with a specific contract + /// and group contract position. The method selects the appropriate version of + /// `prove_group_info` based on the `platform_version` provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `transaction`: The transaction argument used for the query. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Group)`: The `Group` for the specified action ID and contract position. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub fn prove_group_info( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.prove.prove_group_info { + 0 => self.prove_group_info_v0( + contract_id, + group_contract_position, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_group_info".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Proves the `Group` and adds corresponding operations to the drive for the given action ID and group contract position. + /// + /// This function is similar to `prove_group_info` but also adds operations to the drive for state changes or queries. + /// Additionally, it supports cost estimation by interacting with the layer information if provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `estimated_costs_only_with_layer_info`: A mutable reference to an optional `HashMap` containing + /// layer information used for cost estimation. + /// - `transaction`: The transaction argument used for the query. + /// - `drive_operations`: A mutable reference to a vector that stores low-level drive operations. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Group)`: The `Group` for the specified contract ID and contract position, along with any added operations. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub(crate) fn prove_group_info_operations( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.prove.prove_group_info { + 0 => self.prove_group_info_operations_v0( + contract_id, + group_contract_position, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_group_info_and_add_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/prove/prove_group_info/v0/mod.rs b/packages/rs-drive/src/drive/group/prove/prove_group_info/v0/mod.rs new file mode 100644 index 00000000000..0dd20e36e01 --- /dev/null +++ b/packages/rs-drive/src/drive/group/prove/prove_group_info/v0/mod.rs @@ -0,0 +1,45 @@ +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + pub(super) fn prove_group_info_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.prove_group_info_operations_v0( + contract_id, + group_contract_position, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn prove_group_info_operations_v0( + &self, + contract_id: Identifier, + group_contract_position: GroupContractPosition, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let path_query = Drive::group_info_for_contract_id_and_group_contract_position_query( + contract_id.to_buffer(), + group_contract_position, + ); + self.grove_get_proved_path_query( + &path_query, + transaction, + drive_operations, + &platform_version.drive, + ) + } +} diff --git a/packages/rs-drive/src/drive/group/prove/prove_group_infos/mod.rs b/packages/rs-drive/src/drive/group/prove/prove_group_infos/mod.rs new file mode 100644 index 00000000000..27b153c2b19 --- /dev/null +++ b/packages/rs-drive/src/drive/group/prove/prove_group_infos/mod.rs @@ -0,0 +1,99 @@ +use crate::drive::Drive; +use crate::error::drive::DriveError; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::group::Group; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::prelude::StartAtIncluded; +use grovedb::TransactionArg; +use platform_version::version::PlatformVersion; +use std::collections::BTreeMap; + +mod v0; +impl Drive { + /// Proves the `Group` for the given contract. + /// + /// This function queries the GroveDB to prove the potentially many `Group`s associated with a + /// specific contract. The method selects the appropriate version of + /// `prove_group_infos` based on the `platform_version` provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `transaction`: The transaction argument used for the query. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Group)`: The `Group` for the specified action ID and contract position. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub fn prove_group_infos( + &self, + contract_id: Identifier, + start_group_contract_position: Option<(GroupContractPosition, StartAtIncluded)>, + limit: Option, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.prove.prove_group_infos { + 0 => self.prove_group_infos_v0( + contract_id, + start_group_contract_position, + limit, + transaction, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_group_infos".to_string(), + known_versions: vec![0], + received: version, + })), + } + } + + /// Proves the `Group` and adds corresponding operations to the drive for the given action ID and group contract position. + /// + /// This function is similar to `prove_group_info` but also adds operations to the drive for state changes or queries. + /// Additionally, it supports cost estimation by interacting with the layer information if provided. + /// + /// # Parameters + /// - `contract_id`: The identifier of the contract that the action belongs to. + /// - `group_contract_position`: The position of the group contract in the data structure. + /// - `transaction`: The transaction argument used for the query. + /// - `drive_operations`: A mutable reference to a vector that stores low-level drive operations. + /// - `platform_version`: The version of the platform that determines the correct method version. + /// + /// # Returns + /// - `Ok(Group)`: The `Group` for the specified contract ID and contract position, along with any added operations. + /// - `Err(Error)`: If an error occurs, a generic error is returned. + /// + /// # Errors + /// - `DriveError::UnknownVersionMismatch`: If the `platform_version` does not match any known versions. + pub(crate) fn prove_group_infos_operations( + &self, + contract_id: Identifier, + start_group_contract_position: Option<(GroupContractPosition, StartAtIncluded)>, + limit: Option, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + match platform_version.drive.methods.group.prove.prove_group_infos { + 0 => self.prove_group_infos_operations_v0( + contract_id, + start_group_contract_position, + limit, + transaction, + drive_operations, + platform_version, + ), + version => Err(Error::Drive(DriveError::UnknownVersionMismatch { + method: "prove_group_infos_and_add_operations".to_string(), + known_versions: vec![0], + received: version, + })), + } + } +} diff --git a/packages/rs-drive/src/drive/group/prove/prove_group_infos/v0/mod.rs b/packages/rs-drive/src/drive/group/prove/prove_group_infos/v0/mod.rs new file mode 100644 index 00000000000..d1260102bd8 --- /dev/null +++ b/packages/rs-drive/src/drive/group/prove/prove_group_infos/v0/mod.rs @@ -0,0 +1,50 @@ +use crate::drive::Drive; +use crate::error::Error; +use crate::fees::op::LowLevelDriveOperation; +use dpp::data_contract::GroupContractPosition; +use dpp::identifier::Identifier; +use dpp::prelude::StartAtIncluded; +use dpp::version::PlatformVersion; +use grovedb::TransactionArg; + +impl Drive { + pub(super) fn prove_group_infos_v0( + &self, + contract_id: Identifier, + start_group_contract_position: Option<(GroupContractPosition, StartAtIncluded)>, + limit: Option, + transaction: TransactionArg, + platform_version: &PlatformVersion, + ) -> Result, Error> { + self.prove_group_infos_operations_v0( + contract_id, + start_group_contract_position, + limit, + transaction, + &mut vec![], + platform_version, + ) + } + + pub(super) fn prove_group_infos_operations_v0( + &self, + contract_id: Identifier, + start_group_contract_position: Option<(GroupContractPosition, StartAtIncluded)>, + limit: Option, + transaction: TransactionArg, + drive_operations: &mut Vec, + platform_version: &PlatformVersion, + ) -> Result, Error> { + let path_query = Self::group_infos_for_contract_id_query( + contract_id.to_buffer(), + start_group_contract_position, + limit, + ); + self.grove_get_proved_path_query( + &path_query, + transaction, + drive_operations, + &platform_version.drive, + ) + } +} diff --git a/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs b/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs index d7efeb25e47..a7e05f9973d 100644 --- a/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/apply_status/v0/mod.rs @@ -87,7 +87,6 @@ impl Drive { if let Some(estimated_costs_only_with_layer_info) = estimated_costs_only_with_layer_info { Self::add_estimation_costs_for_token_status_infos( - token_id, estimated_costs_only_with_layer_info, &platform_version.drive, )?; diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/mod.rs index c72eb62ba47..59cb58e5461 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/mod.rs @@ -30,7 +30,6 @@ impl Drive { /// # Errors /// This function will return an error if the provided `drive_version` does not match a known version. pub(crate) fn add_estimation_costs_for_token_status_infos( - token_id: [u8; 32], estimated_costs_only_with_layer_info: &mut HashMap, drive_version: &DriveVersion, ) -> Result<(), Error> { @@ -42,7 +41,6 @@ impl Drive { { 0 => { Self::add_estimation_costs_for_token_status_infos_v0( - token_id, estimated_costs_only_with_layer_info, ); Ok(()) diff --git a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/v0/mod.rs b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/v0/mod.rs index 1933c9fd3fe..e58d350af86 100644 --- a/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/v0/mod.rs +++ b/packages/rs-drive/src/drive/tokens/estimated_costs/for_token_status_infos/v0/mod.rs @@ -14,7 +14,6 @@ pub const ESTIMATED_TOKEN_STATUS_INFO_SIZE_BYTES: u32 = 32; impl Drive { pub(super) fn add_estimation_costs_for_token_status_infos_v0( - token_id: [u8; 32], estimated_costs_only_with_layer_info: &mut HashMap, ) { // we have constructed the top layer so contract/documents tree are at the top diff --git a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs index 06c9087dcf9..af779c91c2c 100644 --- a/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs +++ b/packages/rs-drive/src/state_transition_action/batch/batched_transition/token_transition/mod.rs @@ -28,7 +28,7 @@ use dpp::identifier::Identifier; use dpp::prelude::{DataContract, IdentityNonce}; use dpp::ProtocolError; use crate::error::Error; -use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::{TokenBaseTransitionAction, TokenBaseTransitionActionAccessorsV0}; +use crate::state_transition_action::batch::batched_transition::token_transition::token_base_transition_action::TokenBaseTransitionAction; use crate::state_transition_action::batch::batched_transition::token_transition::token_burn_transition_action::{TokenBurnTransitionAction, TokenBurnTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_freeze_transition_action::{TokenFreezeTransitionAction, TokenFreezeTransitionActionAccessorsV0}; use crate::state_transition_action::batch::batched_transition::token_transition::token_unfreeze_transition_action::{TokenUnfreezeTransitionAction, TokenUnfreezeTransitionActionAccessorsV0}; diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs index 15cfe1b3f80..7faf75df460 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/mod.rs @@ -15,6 +15,7 @@ pub struct DriveAbciQueryVersions { pub data_contract_based_queries: DriveAbciQueryDataContractVersions, pub voting_based_queries: DriveAbciQueryVotingVersions, pub system: DriveAbciQuerySystemVersions, + pub group_queries: DriveAbciQueryGroupVersions, } #[derive(Clone, Debug, Default)] @@ -31,6 +32,12 @@ pub struct DriveAbciQueryTokenVersions { pub token_statuses: FeatureVersionBounds, } +#[derive(Clone, Debug, Default)] +pub struct DriveAbciQueryGroupVersions { + pub group_info: FeatureVersionBounds, + pub group_infos: FeatureVersionBounds, +} + #[derive(Clone, Debug, Default)] pub struct DriveAbciQueryIdentityVersions { pub identity: FeatureVersionBounds, diff --git a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs index 592411522d4..e4bb8e03fb3 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions/drive_abci_query_versions/v1.rs @@ -1,8 +1,8 @@ use crate::version::drive_abci_versions::drive_abci_query_versions::{ - DriveAbciQueryDataContractVersions, DriveAbciQueryIdentityVersions, - DriveAbciQueryPrefundedSpecializedBalancesVersions, DriveAbciQuerySystemVersions, - DriveAbciQueryTokenVersions, DriveAbciQueryValidatorVersions, DriveAbciQueryVersions, - DriveAbciQueryVotingVersions, + DriveAbciQueryDataContractVersions, DriveAbciQueryGroupVersions, + DriveAbciQueryIdentityVersions, DriveAbciQueryPrefundedSpecializedBalancesVersions, + DriveAbciQuerySystemVersions, DriveAbciQueryTokenVersions, DriveAbciQueryValidatorVersions, + DriveAbciQueryVersions, DriveAbciQueryVotingVersions, }; use versioned_feature_core::FeatureVersionBounds; @@ -193,4 +193,16 @@ pub const DRIVE_ABCI_QUERY_VERSIONS_V1: DriveAbciQueryVersions = DriveAbciQueryV default_current_version: 0, }, }, + group_queries: DriveAbciQueryGroupVersions { + group_info: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + group_infos: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, }; diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs index 01359a50255..20ebc594662 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/mod.rs @@ -16,10 +16,15 @@ pub struct DriveGroupFetchMethodVersions { pub fetch_action_id_info: FeatureVersion, pub fetch_action_id_info_keep_serialized: FeatureVersion, pub fetch_action_id_has_signer: FeatureVersion, + pub fetch_group_info: FeatureVersion, + pub fetch_group_infos: FeatureVersion, } #[derive(Clone, Debug, Default)] -pub struct DriveGroupProveMethodVersions {} +pub struct DriveGroupProveMethodVersions { + pub prove_group_info: FeatureVersion, + pub prove_group_infos: FeatureVersion, +} #[derive(Clone, Debug, Default)] pub struct DriveGroupInsertMethodVersions { diff --git a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs index a28f8f1d788..365678957b7 100644 --- a/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs +++ b/packages/rs-platform-version/src/version/drive_versions/drive_group_method_versions/v1.rs @@ -9,8 +9,13 @@ pub const DRIVE_GROUP_METHOD_VERSIONS_V1: DriveGroupMethodVersions = DriveGroupM fetch_action_id_info: 0, fetch_action_id_info_keep_serialized: 0, fetch_action_id_has_signer: 0, + fetch_group_info: 0, + fetch_group_infos: 0, + }, + prove: DriveGroupProveMethodVersions { + prove_group_info: 0, + prove_group_infos: 0, }, - prove: DriveGroupProveMethodVersions {}, insert: DriveGroupInsertMethodVersions { add_new_groups: 0, add_group_action: 0, 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 4b1685c0d80..b4f5f2d056a 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -16,10 +16,10 @@ use crate::version::dpp_versions::dpp_voting_versions::v2::VOTING_VERSION_V2; use crate::version::dpp_versions::DPPVersion; use crate::version::drive_abci_versions::drive_abci_method_versions::v1::DRIVE_ABCI_METHOD_VERSIONS_V1; use crate::version::drive_abci_versions::drive_abci_query_versions::{ - DriveAbciQueryDataContractVersions, DriveAbciQueryIdentityVersions, - DriveAbciQueryPrefundedSpecializedBalancesVersions, DriveAbciQuerySystemVersions, - DriveAbciQueryTokenVersions, DriveAbciQueryValidatorVersions, DriveAbciQueryVersions, - DriveAbciQueryVotingVersions, + DriveAbciQueryDataContractVersions, DriveAbciQueryGroupVersions, + DriveAbciQueryIdentityVersions, DriveAbciQueryPrefundedSpecializedBalancesVersions, + DriveAbciQuerySystemVersions, DriveAbciQueryTokenVersions, DriveAbciQueryValidatorVersions, + DriveAbciQueryVersions, DriveAbciQueryVotingVersions, }; use crate::version::drive_abci_versions::drive_abci_structure_versions::v1::DRIVE_ABCI_STRUCTURE_VERSIONS_V1; use crate::version::drive_abci_versions::drive_abci_validation_versions::v1::DRIVE_ABCI_VALIDATION_VERSIONS_V1; @@ -330,6 +330,18 @@ pub const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { default_current_version: 0, }, }, + group_queries: DriveAbciQueryGroupVersions { + group_info: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + group_infos: FeatureVersionBounds { + min_version: 0, + max_version: 0, + default_current_version: 0, + }, + }, }, }, dpp: DPPVersion { From 06d3c25291f110d9a300ed60609c85f32d3f8e4c Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Tue, 14 Jan 2025 07:15:38 +0700 Subject: [PATCH 61/61] temp disable some queries --- .../protos/platform/v0/platform.proto | 2 +- packages/rs-drive-abci/src/query/service.rs | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/dapi-grpc/protos/platform/v0/platform.proto b/packages/dapi-grpc/protos/platform/v0/platform.proto index 71f65837bc2..81da1144434 100644 --- a/packages/dapi-grpc/protos/platform/v0/platform.proto +++ b/packages/dapi-grpc/protos/platform/v0/platform.proto @@ -61,7 +61,7 @@ service Platform { rpc getIdentitiesTokenInfos(GetIdentitiesTokenInfosRequest) returns (GetIdentitiesTokenInfosResponse); rpc getTokenStatuses(GetTokenStatusesRequest) returns (GetTokenStatusesResponse); rpc getGroupInfo(GetGroupInfoRequest) returns (GetGroupInfoResponse); - rpc getActiveGroupActions(GetActiveGroupActionsRequest) returns (GetActiveGroupActionsResponse); +// rpc getActiveGroupActions(GetActiveGroupActionsRequest) returns (GetActiveGroupActionsResponse); // rpc getClosedGroupActions(GetClosedGroupActionsRequest) returns (GetClosedGroupActionsResponse); } diff --git a/packages/rs-drive-abci/src/query/service.rs b/packages/rs-drive-abci/src/query/service.rs index f0a8f8784e5..9ce866c7cf5 100644 --- a/packages/rs-drive-abci/src/query/service.rs +++ b/packages/rs-drive-abci/src/query/service.rs @@ -687,17 +687,17 @@ impl PlatformService for QueryService { .await } - async fn get_active_group_actions( - &self, - request: Request, - ) -> Result, Status> { - self.handle_blocking_query( - request, - Platform::::query_active_group_actions, - "get_active_group_actions", - ) - .await - } + // async fn get_active_group_actions( + // &self, + // request: Request, + // ) -> Result, Status> { + // self.handle_blocking_query( + // request, + // Platform::::query_active_group_actions, + // "get_active_group_actions", + // ) + // .await + // } } fn query_error_into_status(error: QueryError) -> Status {