From 5e9c441a8c2055694f19e2c3f5ccc65e9f2c5a39 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 2 May 2024 14:14:12 +0700 Subject: [PATCH 01/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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/28] 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,