From a5a16c40ed845bd17fb4c603e70e4cd35225c874 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Fri, 20 Dec 2024 21:32:42 +0700 Subject: [PATCH] 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,