diff --git a/packages/rs-dpp/src/data_contract/accessors/mod.rs b/packages/rs-dpp/src/data_contract/accessors/mod.rs index bbdd413de6..52b1076c3a 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 b53d89a2ee..9d23a0e837 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 0000000000..8c51014c0a --- /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 0000000000..866a400658 --- /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 5cfe1f5541..30cf70ffa6 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 0000000000..538297c578 --- /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 457eb0a730..55f8699692 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 d27856454b..d609e535e3 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 67f36a11ac..de7c8cbac7 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 667b11da30..23d1be1113 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 e555f61f23..554d9ba475 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 2164b339f1..e9fa0a7a0a 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 31cc248135..302a6d1004 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 0ae1c2b973..fee916e038 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 30824d49d5..6a6957746a 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 563b8fa725..7ab114c61d 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 29848b7170..cd1dcdc6b7 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 11ab6dc928..fe7ebe5c69 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 0000000000..4a0fa2eb39 --- /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 8219bad9d2..1980cdf712 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 0000000000..7a62530a15 --- /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 0000000000..eb42514dfa --- /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 403f48d6ab..7bc82048e3 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 d800225ad9..fc32d25e6a 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 0000000000..c80eb72789 --- /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 0000000000..4c3fffd78f --- /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 e6b2b223f0..fc42ebf078 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 5e8f2c660a..4833f51e09 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 04a74dfaae..56c7a7456d 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 9bed296313..1d73a19756 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 822d6a3fbf..80173ab4d6 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 b02870222b..10b60444b5 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 c20c622ede..bf72f96f5f 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 54a49ff5ae..0724d67cc6 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 5271a915b7..0ec720a46f 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 6b45125d36..d99a0f8894 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 fd19381a0e..21f92e04f6 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 45c08e8d08..00e127de78 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 fd678a81d7..60177192fa 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 13150a88b9..fb695fab47 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 cc5ee8a348..acebdbcf65 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 6617c4ccc4..ec20c751ec 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 d385fc4b38..d71c5843cc 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 d3ea4825f7..99e612f75b 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 5ab0a46da4..b94e4bd89c 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 bcf858b3dc..ea9508b702 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, }, };